3

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

例如:

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

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

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

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

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

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

如果解决方案是跨平台的就好了,但它至少需要在 Linux 上运行。

4

2 回答 2

7

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

echo bufnr('/src/foo.py$')
于 2012-11-27T09:27:40.480 回答
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

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

于 2012-11-27T06:42:01.497 回答