6

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?

s3rvac
  • 549
  • 3
  • 10
  • 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 05 '16 at 16:27
  • I also thought to ask this question! – SibiCoder May 05 '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 05 '16 at 18:18

2 Answers2

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.
VanLaser
  • 9,700
  • 2
  • 24
  • 34
  • 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 06 '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.
jecxjo
  • 2,660
  • 13
  • 24