1

I'm currently trying to write a plugin for vim that will allow me to define a custom omnifunc for a given language.

I am able to get this almost working, aside from the fact that when I call out to getbufline (in order to get the contents of the current buffer), the results contain an empty line instead of the current line's contents.

Here is the function I'm currently using:

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

The odd part about this, is that if I call my function from vim via echom statemachine#GetCurrBuffContents() then I see the output as expected, ie, each line separated by a \n character.

Example: Buffer contains the following

input signal x
out

state State2
if x == false goto State2
end

If I hit c-x c-o (to trigger omnicompletion) while the cursor is on line 2, I see the following (I echo it out inside my plugin):

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

If I run echom statemachine#GetCurrBuffContents(), I see the following:

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

Here's the relevant code: https://github.com/scottopell/vim-statemachine/blob/3c3c3803f24031cce676e3988daaff12c269142a/autoload/statemachine.vim#L33

EDIT: now that it's fixed, here is the code that I'm currently using. See Ingor's answer as to why that code exists

ScottO
  • 1,573
  • 2
  • 11
  • 14

1 Answers1

1

Before Vim invokes the completion function for the second time (cp. :help complete-functions) to obtain the list of candidates, Vim removes the completion base (which was determined by the first invocation). The benefit of that is a buffer search (what most completions do) doesn't include the current position (which would just complete to itself). Your example has only a single word in front of the cursor, so you see the "entire line" disappearing.

If you really need to have the "full" buffer contents for context, you need to manually splice in the base at the current position; the base got passed back to you. But most current-buffer completions do not grab the whole buffer into a string, but rather use search() to (temporarily and invisibly) move the cursor around in the actual buffer to obtain the matches. You can look at my CompleteHelper plugin for such utility functions.

PS: Instead of getbufline(bufname('%'), 1, "$"), you can use getline(1, "$") instead.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • Thanks for the help! I'll splice in base for now. If most completion functions don't take the full buffer into account, how do they decide what defined variables/functions etc may occur at the current point? – ScottO Nov 11 '15 at 23:32
  • Of course they do consider the completion base before the cursor, it's just that this particular base isn't offered as a possible candidate (because it would complete to itself). – Ingo Karkat Nov 12 '15 at 19:21