diff --git a/package.json b/package.json index a63924a..ae36c17 100644 --- a/package.json +++ b/package.json @@ -485,6 +485,8 @@ "vsplit.plain", "vsplit.intelligent", "tab", + "drop.select", + "drop.tab", "previousBuffer", "previousWindow", "sourceWindow" @@ -498,6 +500,8 @@ "Open action use plain vsplit", "Open action use intelligent vsplit", "Open action use tab", + "Open action use drop, fall back to select strategy", + "Open action use drop, fall back to tab strategy", "Open action use last used buffer", "Open action use last used window", "Open action use the window where explorer opened" diff --git a/readme.md b/readme.md index b75362f..9aca2e7 100644 --- a/readme.md +++ b/readme.md @@ -659,7 +659,7 @@ Type:
{
         /**
          * Strategy for open action
          */
-        'open-action-strategy'?: 'select' | 'split' | 'split.plain' | 'split.intelligent' | 'vsplit' | 'vsplit.plain' | 'vsplit.intelligent' | 'tab' | 'previousBuffer' | 'previousWindow' | 'sourceWindow';
+        'open-action-strategy'?: 'select' | 'split' | 'split.plain' | 'split.intelligent' | 'vsplit' | 'vsplit.plain' | 'vsplit.intelligent' | 'tab' | 'drop.select' | 'drop.tab' | 'previousBuffer' | 'previousWindow' | 'sourceWindow';
         /**
          * quit explorer when open action
          */
@@ -867,7 +867,7 @@ Type: 
number
Default:
30
explorer.openAction.strategy: Strategy for open action. -Type:
'select' | 'split' | 'split.plain' | 'split.intelligent' | 'vsplit' | 'vsplit.plain' | 'vsplit.intelligent' | 'tab' | 'previousBuffer' | 'previousWindow' | 'sourceWindow'
Default:
"select"
+Type:
'select' | 'split' | 'split.plain' | 'split.intelligent' | 'vsplit' | 'vsplit.plain' | 'vsplit.intelligent' | 'tab' | 'drop.select' | 'drop.tab' | 'previousBuffer' | 'previousWindow' | 'sourceWindow'
Default:
"select"
explorer.openAction.select.filter: Filter windows for select strategy. diff --git a/src/actions/globalActions.ts b/src/actions/globalActions.ts index d930977..daa2b08 100644 --- a/src/actions/globalActions.ts +++ b/src/actions/globalActions.ts @@ -47,6 +47,8 @@ export function loadGlobalActions(action: ActionExplorer) { 'vsplit.intelligent': 'use vim vsplit, but keep the explorer in the original position', tab: 'vim tab', + 'drop.select': 'use vim drop, fall back to select strategy', + 'drop.tab': 'use vim drop, fall back to tab strategy', previousBuffer: 'use last used buffer', previousWindow: 'use last used window', sourceWindow: 'use the window where explorer opened', @@ -100,7 +102,7 @@ export function loadGlobalActions(action: ActionExplorer) { { select: true, args: openActionArgs, - menus: openActionMenu as Record, + menus: openActionMenu, }, ); action.addNodeAction( diff --git a/src/actions/openAction.ts b/src/actions/openAction.ts index fc9cf1a..89ffd75 100644 --- a/src/actions/openAction.ts +++ b/src/actions/openAction.ts @@ -5,18 +5,16 @@ import type { ParsedPosition } from '../arg/parseArgs'; import type { Explorer } from '../explorer'; import type { BaseTreeNode, ExplorerSource } from '../source/source'; import type { OpenCursorPosition, OpenStrategy } from '../types'; -import { hasOwnProperty, selectWindowsUI } from '../util'; +import { hasOwnProperty, selectWindowsUI, winidByBufnr } from '../util'; class OpenActionContext { nvim: Neovim; explorerPosition: ParsedPosition; - openByWinnr: (winnr: number) => void | Promise; constructor( public explorer: Explorer, public source: ExplorerSource, public cursorPosition: OpenCursorPosition | undefined, - originalOpenByWinnr: ((winnr: number) => void | Promise) | undefined, public getFullpath: () => string | Promise, private quitOnOpenNotifier: () => Notifier | Promise, public explorerWinid: number | undefined, @@ -25,22 +23,32 @@ class OpenActionContext { // explorer position this.explorerPosition = explorer.argValues.position; + } + + async openByWinnr(winnr: number) { + const openNotifier = await this.openFilepathNotifier('edit'); + await this.openWrap(() => { + this.nvim.command(`${winnr}wincmd w`, true); + openNotifier.notify(); + if (workspace.isVim) { + // Avoid vim highlight not working, + // https://github.com/weirongxu/coc-explorer/issues/113 + this.nvim.command('redraw', true); + } + }); + } - // open by winnr - this.openByWinnr = - originalOpenByWinnr ?? - (async (winnr: number) => { - const openNotifier = await this.openFilepathNotifier('edit'); - await this.openWrap(() => { - this.nvim.command(`${winnr}wincmd w`, true); - openNotifier.notify(); - if (workspace.isVim) { - // Avoid vim highlight not working, - // https://github.com/weirongxu/coc-explorer/issues/113 - this.nvim.command('redraw', true); - } - }); - }); + async openByWinid(winid: number) { + const openNotifier = await this.openFilepathNotifier('edit'); + await this.openWrap(() => { + this.nvim.call('win_gotoid', [winid], true); + openNotifier.notify(); + if (workspace.isVim) { + // Avoid vim highlight not working, + // https://github.com/weirongxu/coc-explorer/issues/113 + this.nvim.command('redraw', true); + } + }); } private jumpToNotify() { @@ -201,6 +209,29 @@ class OpenActions { await this.splitIntelligent('vsplit', 'vsplit.plain'); } + private async dropOr(fallback: () => Promise) { + const ctx = this.ctx; + const fullpath = await ctx.getFullpath(); + const bufManager = ctx.explorer.explorerManager.bufManager; + const buf = bufManager.getBufferNode(fullpath); + if (buf) { + const winid = await winidByBufnr(buf.bufnr); + if (winid) { + await ctx.openByWinid(winid); + return; + } + } + await fallback(); + } + + async 'drop.select'() { + await this.dropOr(() => this.select()); + } + + async 'drop.tab'() { + await this.dropOr(() => this.tab()); + } + async tab() { const ctx = this.ctx; const openNotifier = await ctx.openFilepathNotifier('tabedit'); @@ -250,11 +281,9 @@ export async function openAction( node: BaseTreeNode, getFullpath: () => string | Promise, { - openByWinnr, openStrategy, cursorPosition, }: { - openByWinnr?: (winnr: number) => void | Promise; openStrategy?: OpenStrategy; cursorPosition?: OpenCursorPosition; }, @@ -276,7 +305,6 @@ export async function openAction( explorer, source, cursorPosition, - openByWinnr, getFullpath, quitOnOpenNotifier, explorerWinid, diff --git a/src/types/pkg-config.d.ts b/src/types/pkg-config.d.ts index e5cd7ae..f87b5eb 100644 --- a/src/types/pkg-config.d.ts +++ b/src/types/pkg-config.d.ts @@ -62,6 +62,8 @@ export interface Explorer { | 'vsplit.plain' | 'vsplit.intelligent' | 'tab' + | 'drop.select' + | 'drop.tab' | 'previousBuffer' | 'previousWindow' | 'sourceWindow'; @@ -237,6 +239,8 @@ export interface Explorer { | 'vsplit.plain' | 'vsplit.intelligent' | 'tab' + | 'drop.select' + | 'drop.tab' | 'previousBuffer' | 'previousWindow' | 'sourceWindow'; diff --git a/yarn.lock b/yarn.lock index 6947a04..beda845 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2949,10 +2949,10 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isbinaryfile@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.2.tgz#fe6e4dfe2e34e947ffa240c113444876ba393ae0" - integrity sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg== +isbinaryfile@^4.0.0: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== isexe@^2.0.0: version "2.0.0"