Reputation: 360
I often like to complete more just a Vim keyword. For example, I want to complete an arbitrary pathname or something like self.logger.debug("...")
which I already have somewhere in my text file.
C-n and C-p use the 'iskeyword'
option and thus only complete Vim keywords.
What is the best way to implement a space-separated word completion?
inoremap <C-m> ???
My only idea is to change 'iskeyword'
, use normal word completion, and reset 'iskeyword'
it after that.
Upvotes: 2
Views: 430
Reputation: 172590
I have written a plugin that is powered by my CompleteHelper plugin that does just that:
The WORDComplete plugin finds matches for WORDs that start with the non-blank characters in front of the cursor and end at the next whitespace. By default, it is triggered in insert mode with <C-x><C-w>
. Like the built-in completions, the source buffers it considers can be configured.
Upvotes: 1
Reputation: 45117
Both @Ingo Karkat and @Luc Hermitte provide excellent solutions. However if you want to do this natively then Vim provides some solutions which might help you. Typically completion uses plain <c-n>
/<c-p
> however there is an completion submode accessed via <c-x>
.
Use <c-x><c-f>
to start completing a filename. You can use <c-n>
/<c-p>
just like you normally would after you have started completion to move between options. If the completion ends in a directory (e.g. /usr/bin/
) then just execute <c-x><c-f>
to start completion into that directory.
If you are commonly using the same line, but it isn't worth making a snippet or an abbreviation, then type the start of the line you wish then <c-x><c-l
> to start line completion. Then just use <c-n>
/<c-p>
as you normally would.
You can use <c-x><c-n>
/<c-x><c-p>
to complete another word that follows the current word. This one is sort of tough to explain without just trying it.
Let's say you have the following text:
self.logger.debug("foo")
Let's say you would like another self.logger.debug
somewhere else.
sel
then use <c-p>
to as you normally would complete to self
<c-x><c-p>
to complete to self.logger
(may need to do some <c-p>
/<c-n>
to get to .logger
).self.logger
is completed then use <c-x><c-p>
again for the .debugger
part.Note: this does use iskeyword
so it may not complete exactly as you want, but should be pretty close.
:h ins-completion
:h compl-whole-line
:h compl-current
:h compl-filename
:h 'complete'
Upvotes: 3
Reputation: 32946
IMO, snippets are the best way to proceed in your case -- as you certainly don't want to change 'iskeyword'
option (it'd trigger too many undesired side-effects, and as you said you'd need to restore it afterward, which is not trivial if possible at all). You could use abbreviations or mappings, but then you'd loose the "completion" feeling/feature you'd get with snippet plugins.
There exist plenty different snippet plugins. I'm quite sure there are plenty answers here on SO, or on vi.SE which describe the existing plugins.
For pathnames, you have i_CTRL-X_CTRL-f
, but indeed it stops at each directory. In that case you could may be override i_CTRL-X_CTRL-f
to alter &isk
(and key sequences that valid/abort completion), trigger the completion, and then restore &isk
and the mappings when you validate/abort the completion. This restoration at the end of completion is what some snippet plugins do. That's what I do in the core functions used in mu-template to take care of the completion. (Explanations of how this works on vi.SE)
Upvotes: 1