1

Is there a way to perform a completion similar to <c-x><c-l>, but completes lines based on an arbitrary substring rather than a leading prefix of the line? I'm especially interested in a way of doing this without using a plugin, assuming one exists.

<c-x><c-l> in insert mode completes an entire line, (taking indentation into account).

For example, in the following buffer let @ denote where the cursor is

import foo
import bar
imp@

If I then type <c-x><c-l>, the contents of the buffer become

import foo
import bar
import bar

However, I frequently want to complete lines (especially Python imports or repetitive assignments) using a substring rather than a leading prefix of a line.

I'd like to be able to do something equivalent to the following:

import foo
import bar
fo@

which would become the following after the almost-<c-x><c-l>-but-not-quite completion.

import foo
import bar
import foo

1 Answer 1

1

You can use a user defined complete function to implement this kind of custom completion.

See :help complete-function for how to write such a function.

For example, the function below will use the beginning of the current line as the pattern to search, and will try to match it as a substring, on all the other lines in the same buffer:

function! CompleteLine(findstart, base)
  if a:findstart == 1
    return indent('.')
  endif
  let current = line('.')
  let pattern = '\V\<'.escape(trim(a:base), '\')
  let result = []
  for i in range(1, line('$'))
    if i == current
      continue
    endif
    let l = trim(getline(i))
    if match(l, pattern) >= 0
      call add(result, l)
    endif
  endfor
  return result
endfunction

The function is using \< as an anchor to match the start of the current line at a word boundary only. So fo will match import foo and for i in alist: but not logging.info('...') since the fo is not at a word boundary on the latter. (info would match it.)

It is also skipping the indent in the current line for the pattern, and in the match lines suggested as completion, so it will also preserve the indentation of the current line.

You can enable this user defined complete function with:

set completefunc=CompleteLine

And you can use it with <C-X><C-U> (see :help i_CTRL-X_CTRL-U.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.