VIM:检查文件是否在当前选项卡中打开?窗口? (并激活它)

时间:2012-01-12 17:55:56

标签: vim

在vim中,您可以使用bufexists检查当前缓冲区中的文件是否已打开。对于短文件名(非完整路径),您可以使用bufexists(bufname('filename'))检查它是否已打开。

有没有办法检查文件是否在标签中打开

我最接近的解决方法是执行以下操作:

:tabdo if bufnr(bufname('filename')) in tabpagebuflist(): echo "Yes"

但是,那种pythonic伪代码...我不知道如何让它在vim中工作。我的目标是使用外部AppleScript检查文件是否已打开,如果是,则转到该文件中的一行。

理想情况下,我希望能够搜索不同的GUI窗口,但我收集了(例如Open vim tab in new (GUI) window?)在VIM中使用不同GUI窗口非常具有挑战性/不可能。

2 个答案:

答案 0 :(得分:6)

我的不耐烦和良好的文档使我变得更好......这是解决方案(在Check if current tab is empty in vimOpen vim tab in new (GUI) window?的帮助下)。来源位于https://github.com/keflavich/macvim-skim

function! WhichTab(filename)
    " Try to determine whether file is open in any tab.  
    " Return number of tab it's open in
    let buffername = bufname(a:filename)
    if buffername == ""
        return 0
    endif
    let buffernumber = bufnr(buffername)

    " tabdo will loop through pages and leave you on the last one;
    " this is to make sure we don't leave the current page
    let currenttab = tabpagenr()
    let tab_arr = []
    tabdo let tab_arr += tabpagebuflist()

    " return to current page
    exec "tabnext ".currenttab

    " Start checking tab numbers for matches
    let i = 0
    for tnum in tab_arr
        let i += 1
        echo "tnum: ".tnum." buff: ".buffernumber." i: ".i
        if tnum == buffernumber
            return i
        endif
    endfor

endfunction

function! WhichWindow(filename)
    " Try to determine whether the file is open in any GVIM *window*
    let serverlist = split(serverlist(),"\n")

    "let currentserver = ????
    for server in serverlist
        let remotetabnum = remote_expr(server, 
            \"WhichTab('".a:filename."')")
        if remotetabnum != 0
            return server
        endif
    endfor

endfunction

然后像这样使用:

exec "tabnext ".WhichTab('my_filename')

echo remote_foreground( WhichWindow('my_filename') )

或者,从命令行,这是使用WhichTab转到文件特定行的脚本:

#!/bin/bash

file="$1"
line="$2"

for server in `mvim --serverlist` 
do
    foundfile=`mvim --servername $server --remote-expr "WhichTab('$file')"`
    if [[ $foundfile > 0 ]]
    then
        mvim --servername $server --remote-expr "foreground()" 
        mvim --servername $server --remote-send ":exec \"tabnext $foundfile\" <CR>"
        mvim --servername $server --remote-send ":$line <CR>"
    fi
done

答案 1 :(得分:3)

我会回复keflavich,但我还不能......

我正在研究类似的问题,我想在gvim中打开文件时模仿gvim --remote-tab-silent的行为。我找到了你的这个WhichTab脚本,但是在任何给定标签中打开了多个窗口时遇到了问题。如果在选项卡内部拆分窗口,那么tabpagebuflist()将返回多个缓冲区,因此在List中使用缓冲区编号位置的方法不起作用。这是我解决这种可能性的解决方案。

" Note: returns a list of tabnos where the buf is found or 0 for none.
"               tabnos start at 1, so 0 is always invalid
function! WhichTabNo(bufNo)
    let tabNos = []
    for tabNo in range(1, tabpagenr("$"))
        for bufInTab in tabpagebuflist(tabNo)
            if (bufInTab == a:bufNo)
                call add(tabNos, tabNo)
            endif
        endfor
    endfor
    let numBufsFound = len(tabNos)
    return (numBufsFound == 0) ? 0 : tabNos
endfunction

我想我可以返回tabNos,这将是一个空的列表,被评估为标量0,但我刚刚学习了vimscript并且对它的动态类型行为的细节不太满意,所以我就离开了它就像现在一样。