4

In Vim, C-x C-l performs line completion. However, it expects the prefix of the currently typed line to match the prefix of another line. For example, consider that | below denotes the cursor position:

; A sentence I would like to auto complete.
...
A sentence|

When I press C-x C-l, line completion obviously fails because the current line does not start with a semicolon. Is there a way of performing "line" completion that disregards line prefixes?

  • 3
    To what extent would you define a prefix? Are you looking to just find the first instance of your previously typed string and then fill in til <eol>? – jecxjo May 5 '16 at 16:27
  • I also thought to ask this question! – SibiCoder May 5 '16 at 16:46
  • @jecxjo I would define a prefix as everything that appears on the current line from the beginning to the cursor position. What I would like is to search for the prefix of the current line in the whole buffer (even inside other lines) and complete the part of the matched line til <eol>. – s3rvac May 5 '16 at 18:18
4

It's ... built-in. It's just not line completion, because, you're saying it, it's not an entire line you want to complete.

If we start from your example:

; A sentence I would like to auto complete.
...
A sentence|

If I now press C-n, followed by C-x C-n (secret sauce! - context completion) it will complete the following word. Press C-x C-n repeatedly to further complete the next words. If it doesn't work, try it from a vim -N -u NONE and go from there.

You should probably use a more complex example, one that have multiple variants, e.g.:

; A sentence I would like to auto complete.
; A sentence you don't like to complete.
...
A sentence|

In this case, when you hit a "branch" with options (e.g. I or you), you should select the continuation you want using the usual C-p / C-n keys, then go on with C-x C-n as before.

You can find the docs at :h i_CTRL-X_CTRL-N, in the 2nd part (quoted, for reference):

    CTRL-N          Search forward for next matching keyword.  This
                    keyword replaces the previous matching keyword.

    CTRL-P          Search backwards for next matching keyword.  This
                    keyword replaces the previous matching keyword.

    CTRL-X CTRL-N or
    CTRL-X CTRL-P   Further use of CTRL-X CTRL-N or CTRL-X CTRL-P will
                    copy the words following the previous expansion in
                    other contexts unless a double CTRL-X is used.
  • Nice. I knew that it was possible to complete multiple lines by using C-x C-l repeatedly, but I had no idea the same works for C-x C-n. – s3rvac May 6 '16 at 13:01
2

Here is a single line solution.

:inoremap <C-X><C-L> <ESC>mm:/<C-R>=substitute(getline('.'), '\n\+$', '', '')<CR><CR>ggn"*y$'mo<ESC>"*p<ESC>k"_d:nohl<CR>A

Mapping to Insert Mode CTRL+x CTRL+l

  • <Esc>mm Exit insert mode and mark location
  • :/<C-R>=substitute(getline('.'), '\n\+$', '', '')<CR><CR> Search for contents of this line, removing any new lines at the end
  • ggn Go to top of file and search for first match.
  • `"*y$" Yank from cursor (first match location) to end of line
  • 'm Go back to original edit line
  • o<esc>"*p Past yank to next line, goofy because we didn't yank a full line, but from cursor to end
  • k"_d Move back up to original line and delete it
  • :nohl<CR> if you have search highlighting it is cleared
  • A append to end of line to continue writing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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