Vim脚本:通过文件名路径切换缓冲区

3

我有一段vimscript代码需要切换到特定的缓冲区,该缓冲区可以通过全路径、部分路径或仅名称来指定。

例如:

我在目录/home/user/code中,并且已经打开了3个vim缓冲区foo.pysrc/foo.pysrc/bar.py

  • 如果脚本被告知要切换到缓冲区/home/user/code/foo.py,它将切换到缓冲区foo.py

  • 如果被告知要切换到user/code/src/foo.py,它将切换到缓冲区src/foo.py

  • 如果被告知要切换到foo.py,它将切换到缓冲区foo.py

  • 如果被告知要切换到bar.py,它将切换到缓冲区src/bar.py

我能想到的最简单的解决方案是以某种方式获取存储在变量中的缓冲区列表并使用试错法。

如果该解决方案能够跨平台实现就更好了,但至少需要在Linux上运行。

2个回答

7
bufname() / bufnr()函数可以通过部分文件名查找已加载的缓冲区。您可以通过添加$将匹配锚定到结尾,如下所示:
echo bufnr('/src/foo.py$')

微笑 我知道vim会有一个函数来做这件事。谢谢。 - Sudo Bash

0

我找到了一种使用vimscript中的python实现此操作的方法。使用python,我能够从vim.buffers[i].name获取所有缓冲区的名称,并使用os.pathos.sep来处理要切换到哪个缓冲区。

最终,我决定如果请求切换到的缓冲区不明确,则拒绝执行任何操作,这样会更有帮助。

以下是代码:

"Given a file, full path, or partial path, this will try to change to the
"buffer which may match that file. If no buffers match, it returns 1. If
"multiple buffers match, it returns 2. It returns 0 on success
function s:GotoBuffer(buf)
python << EOF
import vim, os
buf = vim.eval("a:buf")

#split the paths into lists of their components and reverse.
#e.g. foo/bar/baz.py becomes ['foo', 'bar', 'baz.py']
buf_path = os.path.normpath(buf).split(os.sep)[::-1]
buffers = [os.path.normpath(b.name).split(os.sep)[::-1] for b in vim.buffers]
possible_buffers = range(len(buffers))

#start eliminating incorrect buffers by their filenames and paths
for component in xrange(len(buf_path)):
    for b in buffers:
        if len(b)-1 >= component and b[component] != buf_path[component]:
            #This buffer doesn't match. Eliminate it as a posibility.
            i = buffers.index(b)
            if i in possible_buffers: possible_buffers.remove(i)

if len(possible_buffers) > 1: vim.command("return 2")
#delete the next line to allow ambiguous switching
elif not possible_buffers: vim.command("return 1") 
else:
    vim.command("buffer " + str(possible_buffers[-1] + 1))
EOF
endfunction

编辑:上述代码似乎存在一些错误。我不会修复它们,因为有另一个答案要好得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接