从omnifunc调用时,getbufline缺少当前行

时间:2015-11-10 02:06:50

标签: vim vim-plugin viml

我正在尝试为vim编写一个插件,允许我为给定的语言定义一个自定义的omnifunc。

除了我呼叫getbufline(为了获取当前缓冲区的内容)之外,我能够使这几乎工作,结果包含一个空行而不是当前行line的内容。

这是我目前正在使用的功能:

function! statemachine#GetCurrBuffContents()
  return join(getbufline(bufname('%'), 1, "$"), "\n")
endfunction

关于这一点的奇怪之处在于,如果我通过echom statemachine#GetCurrBuffContents()从vim调用我的函数,那么我会看到输出符合预期,即每行以\n字符分隔。

实施例: 缓冲区包含以下内容

input signal x
out

state State2
if x == false goto State2
end

如果我在光标位于第2行时点击c-x c-o(触发omnicompletion),我会看到以下内容(我在插件中回显):

input signal x^@^@^@state State2^@if x == false goto State2^@end

如果我运行echom statemachine#GetCurrBuffContents(),我会看到以下内容:

input signal x^@input^@^@state State2^@if x == false goto State2^@end

以下是相关代码: https://github.com/scottopell/vim-statemachine/blob/3c3c3803f24031cce676e3988daaff12c269142a/autoload/statemachine.vim#L33

编辑:现在它已修复,这是我目前使用的代码。请参阅Ingor关于代码存在的原因的答案

1 个答案:

答案 0 :(得分:1)

在Vim第二次调用完成函数(cp。:help complete-functions)以获取候选列表之前,Vim删除了完成基数(由第一次调用确定) 。这样做的好处是缓冲区搜索(大多数完成所做的)不包括当前位置(它只能完成自身)。您的示例在光标前只有一个单词,因此您会看到“整行”消失。

如果您确实需要为上下文提供“完整”缓冲区内容,则需要在当前位置手动拼接基础;基地传回给你了。但是大多数当前缓冲区的完成并没有将整个缓冲区捕获到一个字符串中,而是使用search()(临时和不可见地)将光标移动到实际缓冲区中以获得匹配。您可以查看我的CompleteHelper plugin以获取此类实用程序功能。

PS:您可以使用getbufline(bufname('%'), 1, "$")代替getline(1, "$")