光标下的Vim选项卡放置文件

时间:2019-01-24 02:29:56

标签: linux vim

我正在研究一个c ++项目,并使用vim作为编辑器。

http://vim.wikia.com/wiki/Open_file_under_cursor开始,我知道我可以使用 <c-w>gf(Ctrl-w gf) 可以在光标或新选项卡中的选择下打开,这非常好,除了1件事,可以打开同一文件的多个选项卡,而我更愿意如果已打开则跳至它

:tab drop可以完成工作(http://vim.wikia.com/wiki/Edit_a_file_or_jump_to_it_if_already_open

但是如何将<c-w>gf:tab drop结合起来?

Vim open file under cursor提供了一些线索,但仅适用于光标下方,不适用于选择(可视模式)。

我知道这是一个非常具体的问题,希望有人可以提供帮助!

谢谢!

2 个答案:

答案 0 :(得分:0)

您要的是:help 'switchbuf'功能,即usetab值:

     useopen      If included, jump to the first open window that
                  contains the specified buffer (if there is one).
                  [...]
     usetab       Like "useopen", but also consider windows in other tab
                  pages.

不幸的是,该选项不适用于<C-W>gf命令。但是,您可以重新映射它以使用:tab drop

:nnoremap <silent> <C-w>gf :execute 'tab drop' fnameescape(expand('<cfile>'))<CR>

要处理其他工作目录,必须在当前文件的目录之前添加

:nnoremap <silent> <C-w>gf :execute 'tab drop' fnameescape(expand('%:h') . '/' . expand('<cfile>'))<CR>

但是,绝对目录将不再起作用。要解决这些问题,我们可以先更改为当前目录:

:nnoremap <silent> <C-w>gf :execute 'cd' fnameescape(expand('%:h')) <Bar>  execute 'tab drop' fnameescape(expand('<cfile>'))<CR>

即使如此,我给出的仿真也不是100%相同。 gf使用'path'选项来查找文件,<cfile>不使用。您必须使用findfile()自己实现该查找。一种更简单的选择是:help c_CTRL-R_CTRL-P,但是它需要扩展路径,并且对于常规文件失败,而gf可以同时处理这两种情况。

答案 1 :(得分:0)

正如您从我的其他答案中发现的那样,很难模拟<C-w>gf命令,并且有很多极端情况。

获取所需内容的另一种方法仍然依靠原始的<C-w>gf命令(无条件)打开一个新选项卡,然后检查是否在另一个选项卡中已经打开了相同的缓冲区,如果是,请关闭当前(新)标签页,而是转到另一页。这会引起一些闪烁,但是应该更健壮。

nnoremap <C-w>gf <C-w>gf:call FavorExistingTabPage()<CR>

function! FavorExistingTabPage()
    let l:bufNr = bufnr('')
    for l:i in range(1, tabpagenr('$'))
        if l:i == tabpagenr()
            continue    " Skip current.
        endif
        let l:winIndex = index(tabpagebuflist(l:i), l:bufNr)
        if l:winIndex != -1
            " We found the buffer elsewhere.
            if l:i >= tabpagenr()
                let l:i -= 1 " Adapt to removal of tab page before the current.
            endif

            close!

            execute l:i . 'tabnext'
            execute (l:winIndex + 1) . 'wincmd w'
            break
        endif
    endfor
endfunction

注意:这将使用它可以找到的第一个标签页中的第一个窗口;您可以对算法进行调整,以使其优先于当前缓冲区而不是当前缓冲区。