vimscript:按文件名路径切换到缓冲区

时间:2012-11-27 02:52:53

标签: path buffer filenames vim

我有一个需要切换到特定缓冲区的vimscript。该缓冲区将由完整路径,部分路径或其名称指定。

例如:

我在/home/user/code目录中,我有3个vim缓冲区,foo.py src/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 个答案:

答案 0 :(得分:6)

bufname() / bufnr()函数可以通过部分文件名查找加载的缓冲区。您可以通过附加$来将匹配锚定到最后,如下所示:

echo bufnr('/src/foo.py$')

答案 1 :(得分: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

编辑:以上代码似乎有一些错误。我不打算修复它们,因为还有另一个答案要好得多。