basyura's blog

あしたになったらほんきだす。

neocomplete 補完時の動作

neocomplete の source を書きたいのだけど、context に何が入ってくるのかよく分からんので調べてみる。

{context}				neocomplete-notation-{context}
			A dictionary to give context information.
			The followings are the primary information.
			The global context information can be acquired
			by |neocomplete#get_context()|.

			input			(String)
				The input string of current line.

			complete_pos		(Number)
				The complete position of current source.

			complete_str		(String)
				The complete string of current source.

			source__{name}		(Unknown)	(Optional)
				Additional source information.
				Note: Recommend sources save
				variables instead of s: variables.
input
カーソル行のカーソル位置までの入力文字列
complete_str
補完対象の文字列
complete_pos
補完開始位置。この位置から補完候補で書き換わる

これが gather_candidates(context) で呼ばれたさいにどういう値が入っているのかを見てみる。|がカーソル位置。

単語を入力

abc|

input abc
complete_str abc
complete_pos 0


補完の開始位置は先頭(0)で、入力内容(abc)と補完対象(abc)が同じ

2 つ目の単語を入力

abc def|

input abc def
complete_str def
complete_pos 4


補完の開始位置は 2 つ目の単語の先頭 (4) で、入力内容はその行の内容 (abc def) で、補完対象は 2 つ目の単語 (def)。

2 つめの単語でメソッド呼び出し (.) 相当を入力

abc def.ghi|

input abc def.ghi
complete_str ghi
complete_pos 8


補完の開始位置は 2 つ目の単語の . で、入力内容はその行の内容 (abc def.ghi) で、補完対象は 2 つ目の単語の . 以降。

開始位置の文字を取得する

abc.d|

echo a:context.input[complete_pos]
" => d

補完開始位置の前の文字列を取得するには

let pos = a:context.complete_pos - 1
let word = ""
if pos > 0 && a:context.input[pos] == '.'
  while 1
    let pos = pos -1  
    let chr = a:context.input[pos]
    if chr == '' || chr == ' ' || chr == '('
      break
    endif
    let word = chr . word
  endwhile
endif

ゴリるしかない?