Completion before and after word vim

239 views Asked by At

I added a dictionnary with this kind of words :

foo.bar
this.is.a.test

I did :set iskeyword+=. to have completion works despite dots :

When I type fo<TAB> --> foo.bar

But I would like to have also this kind of completion :

test<TAB> --> this.is.a.test

I mean, I won't type always the beginning of a word.

I hope I was clear

Thanks in advance

2

There are 2 answers

4
Peter Rincker On

With insert mode's <c-x><c-p> after <c-p>/<c-n> you can complete words that follow the previous completion. This assumes that the words appear before together. This means you do not need to add . to 'iskeyword' (It is better that you don't!).

As for completing via the end of words that is probably best done via a custom completion as @Ingo Karkat suggests. However I personally have not come across a need for such a completion.

How to use <c-x><c-p> following <c-p>/<c-n>

  • type out the first word or part of it. e.g test in the example
  • hit <c-p> to start the completion and open the completion menu
  • find the correct completion via <c-n> or <c-p> (optional)
  • hit <c-x><c-p> to complete the next word e.g .is in the example
  • find the correct completion via <c-n> or <c-p> (optional)
  • repeat the <c-x><c-p> and <c-p>/<c-n> steps as needed

So all together: test<c-p><c-x><c-p><c-x><c-p><c-x><c-p> will yield this.is.a.test.

Conclusion

Using <c-x><c-p> is tricky to explain but much easier to understand after trying it a few times. Trust me it is worth it. You can also do similar tricks with whole line completion, i.e. <c-x><c-l>. Do yourself a favor and just read all of :h ins-completion you will be better for it.

Aside about using <tab> for completion

Vim offers various completion options. e.g whole line completion via <c-x><c-l>, tags: <c-x><c-]>, filename: <c-x><c-f>, and more. Often using a clever <tab> mapping or plugin like SuperTab for completion hides these other completion modes by making them feel less familiar. Note: SuperTab is/was notorious for causing conflicts or bad behavior.

For more help see:

:h i_ctrl-x_ctrl-p
:h ins-completion
:h 'complete'
:h 'completeopt'
0
Ingo Karkat On

The built-in completions always offer matches that start with the completion base. However, you can write a custom completion that implements different strategies.

If your dictionary is a loaded buffer (not the built-in dictionary completion :help i_CTRL-X_CTRL-K), my CompleteHelper plugin makes it easier to implement the extraction of matches. With it, the BidiComplete plugin offers something related: Completion of this.is.a.test when the cursor is to the left of |test. (I also have a MiddleEndComplete plugin in the works that may be close to what you want.)