在Vim Script中有没有一种方法可以获取缓冲区的行数?

11

有没有一种方法可以获取Vim缓冲区中的行数,而不仅仅是当前缓冲区的行数?

使用line('$')可以获得当前缓冲区最后一行的行号,从而得到行数。使用getbufline({expr}, 1 , '$')可以获取由{expr}表示的缓冲区的行字符串列表,列表大小即为行数。

使用getbufline会导致在内存中复制整个文件,以获取它包含的行数。 line可以完成任务,但仅适用于当前缓冲区。

假定通过脚本来完成此操作,而非交互式操作,并且尽可能地减少开销,例如使用line('$')

2个回答

8
如果您的vim是使用python编译并且版本不早于7.3.569,您可以使用以下命令:
python import vim
let numlines=pyeval('len(vim.buffers['.({expr}-1).'])')

使用支持Python的旧版Vim,您可以使用以下方法:
python import vim
python vim.command('let numlines='+str(len(vim.buffers[int(vim.eval('{expr}'))-1])))

测试结果表明,在一个11 MiB的日志文件中,第一种方法比len(getbufline({expr}, 1, '$'))快209倍 (0.000211秒 vs 0.044122秒)。请注意,vim.buffers中的缓冲区索引从零开始,而不是从一开始。


出于好奇,你是如何进行性能分析并获得时间数据的? - oblitum
1
通常情况下,性能分析可以在 :h :profile 中找到相关信息。但是对于一行命令,有一个更简单的方法:let rt=reltime() | {do action} | echom reltimestr(reltime(rt)) - ZyX
1
请注意,如果缓冲区没有加载到内存中,则此方法无效。例如,在执行 vi a.txt b.txt 命令后,a.txt 文件已经被加载并准备好进行编辑。而加载 b.txt 文件则会被推迟,直到首次切换到该缓冲区时才会进行。 - doraemon

0
自Vim 8.1.1967(2019年9月)起,您可以将窗口ID作为第二个参数传递给line()。现在它只是简单地:
line('$', bufwinid(bufnr))

其中bufnr是缓冲区编号。


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