首页 文章

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

提问于
浏览
4

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

有没有办法检查文件是否在选项卡中打开?

我最接近的解决方法是做类似的事情:

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

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

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

2 回答

  • 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
    
  • 3

    我回复凯夫拉维奇,但我还不能......

    我正在研究一个类似的问题,我想在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,并且对它的动态类型行为的细节还不太满意,所以我就这样离开了现在 .

相关问题