By default, supertab is inserting a regular tab when the previous character is a space.
I would like to keep this behaviour but with the following exception: if the previous character is a space but the preceding word is import, autocomplete.
For instance (| denotes the cursor position)
from numpy import |<tab> should display completions,
for |<tab> should insert a tab.
I'm aware of g:SuperTabNoCompleteAfter but I'm not sure how to obtain the desired result.
supertab has the ability to consider the preceding text to choose a completion type. You need to teach the plugin about the import context, and configure it to use a custom completion, e.g. user completion (<C-x><C-u>). Then implement the corresponding completion (or find another plugin that already does this), and you should be good.
References
context completion at :help supertab-defaultcompletion
completion contexts at :help supertab-completioncontexts
Writing a custom completion at :help complete-functions.
Related
I want to type
tag {
}
When I hit 'enter' after {, my cursor is 2 spaces indented (in column 3). (Tab is 2 spaces for me.) Then, when I type } (still in column 3), I want } to shift to column 1.
When I do this in a .cpp file, the cursor moves automatically to column 1.
When I do this in another file (.wiki in my case), it does not move. The } appears in column 3.
I thought this was controlled by 'autoindent' and 'smartindent', both of which are set in case of wiki file. What am I missing?
What other configuration information can I provide to help debug? How can I compare the configuration options between cpp file and wiki file?
(Edit for clarity: I am using the '.wiki' filetype defined in vimwiki plugin.)
The problem comes from the way the plugin handles lists' editing. Which is surprising, because the tag { } construct probably shouldn't be treated as one. To insert a new list marker, the plugin redefines a few mappings, they are mentioned in :help vimwiki-lists. Namely, o and O in normal mode, and <CR> in insert mode. Things they are mapped to have more-or-less the same behaviour when it comes to interaction with smartindent: they disable deindenting by inserting and deleting a dummy character on the new line (see, for example, here). This works because deindentation, as per :help smartindent, happens only if the closing brace is the first thing you type on the line.
This can be disabled by removing relevant mappings, but doing so will also break the lists system of the plugin. To fix that, you can duplicate those mappings using some other keys.
This might be worth discussing with the plugin's author, I don't think treating everything as a part of a list for indentation purposes is really what they indended.
Is it possible with Vim itself or a plugin to display the autocomplete option inline?
If not is there a way to display text in vim without inserting it into the buffer?
You can disable the popup menu (:help popupmenu-completion; it usually displays [a subset of] the available choices) by removing menu[one] from the 'completeopt' option. Then, the first candidate (or longest common part) is directly inserted into the buffer, and <C-n> cycles through candidates at that location. To remove the current suggested completion and return to the original state before the completion, press <C-e>.
That technically still (if only temporarily) inserts the candidate into the buffer, but I think it closely fits what you're asking for, and is built-in. To display text without inserting, there's currently only a (rather crude) workaround of using the :help conceal feature to change the appearance of individual characters (for a static text, matching the exact location in the buffer via \%l and \%c) into something else via matchadd(). However, this only works if there's existing text; it wouldn't work at the end of a line. Currently, a generic overlay feature is being discussed on the the vim_dev mailing list, but it is in very early stages.
Is there a weak visual indicator of all the texts that match the current selection? Similar to most text editors.
How I can achieve the same behavior?
You can certainly build something like that, using an :autocmd that obtains the current selection, and then either using default search highlighting (by modifying register /), or using matchadd() to add separate highlighting (but in contrast to search, that would be window-local by default). To make this robust and non-interfering with common tasks in Vim, that would be much more than a simple one-liner I could post here, though.
I must know, because I've implemented such as part of my SearchHighlighting plugin. With that plugin, this can be enabled via
:SearchAutoHighlighting selection
Because my plugin contains that functionality only as a small part (of more comprehensive search tweaks and additions), also have a look at the following alternatives, which are more targeted to what you're asking for, taken from the alternatives list of my plugin:
highlight_word_under_cursor.vim implements the search
auto-highlighting of the whole and optionally current word.
HiCursorWords highlights the word under the cursor, with
optional delay and limited to certain syntax groups.
Matchmaker highlights the word
under the cursor with matchadd(), not the current search pattern.
vim-cursorword automatically underlines the current word
in the current window (like :SearchAutoHighlighting), but uses :match
instead of search
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.
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>.
Filename completion
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.
Whole line completion
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.
Multi-word completion
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.
So type: sel then use <c-p> to as you normally would complete to self
Then use <c-x><c-p> to complete to self.logger (may need to do some <c-p>/<c-n> to get to .logger).
Once 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.
For more help
:h ins-completion
:h compl-whole-line
:h compl-current
:h compl-filename
:h 'complete'
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)
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.
Omnicompletion is working, but it automatically inserts the first result.
What I'd like to do is open the omnicomplete menu, then be able to type to narrow down the results, then hit enter or tab or space or something to insert the selected menu item.
Is this possible?
The command you are looking for is:
:set completeopt+=longest
It will insert the longest common prefix of all the suggestions, then you can type and delete to narrow down or expand results.
set wildmenu
set wildmode=list:longest,full
Found here.
There is also a great plugin for all of your completion needs called SuperTab continued.
This plugin might do what you are after: autocomplpop
Or you can try and make Vim completion popup menu work just like in an IDE.
This is the general Vim completion behaviour. For a complete overview, you can do
:he compl-current
But for your specific case (which you require the completion to be in state 2 or 3 (described in the document above). You can simply use Backspace, or Control-H to jump from state one to state two. In state 2 you can narrow the search by typing regular characters. So to complete completion with narrowing:
compl<C-X><C-P><BS>letion
It is totally backwards, I know, but that's how it works.
Edit: You can use the Down arrow key too isntead of Control-H or Backspace, and it has the benefit of not deleting a character.