select mode mapping issue - vim

I’ve installed the Snippets Vim plugin. Suppose I’m editing a C file. When I type if<tab> in insert mode, the text expands to
if (/* condition */)
{
}
and now, I’m in select mode (indicated in the status line by --select--).
I have a mapping in my ~/.vimrc: snoremap <c-f> <bs>, which means I want to use Ctrl-f to delete the text when I’m in select mode.
However, when I type <c-f> to delete the text, the text is deleted as expected, but I am dropped into normal mode instead of insert mode as I want.
So, is anyone able to figure this out?
And more—add this mappping:
vnoremap <c-f> <bs>
<c-f> doesn't work at all. Please help with this also.

The help for select mode (:help Select-mode) says:
Printable characters, <NL> and <CR> cause the selection to be deleted, and
Vim enters Insert mode. The typed character is inserted.
I don’t see any other case where a command in select mode ends by entering insert mode (although of course I could be missing something).
So this could be a peculiarity of the plugin, but it also could just be how select mode handles commands. In the meantime, you can add i to the end of your <c-f> mapping:
snoremap <c-f> <bs>i

Related

Mapping select-all, copy, paste in vim

I have the following map in my vimrc:
nnoremap <C-a> ggVG
nnoremap <C-c> "*yy (might be because I'm in visual mode here?)
nnoremap <C-v> "*p
The select-all (ctrl-a) and the paste (ctrl-p) works, but the (ctrl-c) does not work with that shortcut, though it works if I manually type in the command after doing ctrl-c.
What needs to be fixed here?
The first issue I would like to address is that your mapping for copying the text, nnoremap <C-c> "*yy, will only work in normal mode. When you select text in Vim, you enter visual mode, and the first n of nnoremap makes the mapping work in normal mode only.
You can make your mapping work by using noremap (all modes), vnoremap (visual and select mode), or xnoremap (visual mode only), like this:
vnoremap <C-c> "*y
You can find more information about mappings in the documentation.
Another thing to note is that the default function of Ctrl-c is to cancel/interrupt the current command. For example, if you enter insert mode and press Ctrl-c, you will exit insert mode and go back to normal mode. With your original mappings, it will cancel the selection (exits visual mode) without copying anything.
This works for me in Neovim but I believe it should also work in Vim as well. To yank all the content I have the following mapping in my configuration:
nnoremap <leader>ya ggVGy<C-O>
Details:
gg: go to the first line
V: select the first line
G: go to the last line
y: yank selection
<C-O>: go to the previous cursor position

Assigning save (:w<cr>) to <leader>w in vim

I want to be able to save a file in vim while in the insert mode. I thought of using the following shortcut:
inoremap <leader>w <Esc>:w<cr>
While the shortcut saves the file in the insert mode, it leaves the cursor one spot ahead of where the cursor would be if I physically typed out the keys
Esc :w followed by Enter. This is a problem because when I use the shortcut whenever I am at the end of a line, it takes me to the next line, and I have to then come back to the spot where I initiated the save.
Any help would be appreciated on how I can map <leader>w to the exact actions that occur in Vim when I physically type out the Esc :w followed by Enter key sequence.
I should add that if I instead use the following key-mapping, things work exactly as I want:
inoremap <C-s> <esc>:w<CR>
However, I would like to avoid pressing CTRL and s at the same time. It is possible there is some problem with the <leader>, but I cannot figure out what it is (I am using , as my leader key).
Though one could discuss the suitability of your insert-mode mapping, the root cause of your problem is a trailing space in the mapping definition; i.e. Vim reads this as follows:
inoremap <leader>w <Esc>:w<cr><Space>
You'll even see this in the :imap <Leader>w output! <Space> in normal mode advances the cursor one to the right (like l); that explains the unexpected move.
Try this instead:
inoremap <silent> <leader>w <C-o>:w<CR>
The idea is Ctrl-o can be used to run commands directly from insert mode. See :help i_CTRL-O for details.
Why not simply doing
inoremap <leader>w <Esc>h:w<cr>
(not the additional h for going back one character)?

How to make z= look like ctrl-x s in vim spell check

So in insert mode if you hit ctrl-x s on a misspelled word you get a nicely formatted popup menu of spelling suggestions. This is awesome.
The comparable command in normal mode (z=), however, gives a bland plain-text list that eats the whole screen.
I've partially solved this by adding the following keybinding in my .vimrc:
nnoremap <Leader>s ea<C-X><C-S>
This works perfectly and hitting s in normal mode gives me the same drop down... The only problem is I'm now left in insert mode at the end of everything. Is there some way to get the drop down style selection and end up in normal mode after the replace is all said and done?
You can't do it directly. The popup menu you're thinking of is specifically referred to as "insert mode completion".
However, you're halfway there, by mapping a key that enters insert mode and starts the completion. Now all you need is to map a key that selects the entry (like the 'enter' key) to also exit insert mode.
You should test the return value of pumvisible() in your mapping, to prevent it firing when you don't want. Example (from comments):
inoremap <expr> <CR> pumvisible() ? "\<C-y><Esc>" : "\<CR>"
Perhaps you could also set a variable or something, or use a key you won't use to end actual insert mode completion.

Vim insert mode: unambiguous key binding that always works as expected?

Background:
Sometimes when editing in vim it is possible to have extra characters in a file that the user did not expect to be there because he was in "insert mode" when in a hurry and rushing to get something finished.
Fortunately, even if the user is rushing, pressing ESC a couple of times is always sufficient to get them out of insert mode and into normal mode, with no surprises.
Question:
Is there a key binding that works the same way for insert mode? Pressing "i" can get you into insert mode, but if you press it multiple times, you will start inserting the letter "i" into the file.
Goal:
The goal is to have some key binding for getting back into insert mode that the user can even press multiple times with eyes closed, and still not worry about "surprises" of unexpected characters being put into the file.
<C-o>i should do the trick. <C-o> gets you temporarily to normal mode, but for only one command, if that command is "go to insert mode" than well, you simply return there.
Edit: I could reproduce your error message now, and it seems the easiest thing to do is this:
:nmap <C-i> i
:imap <C-i> <C-o>i
If do not map <C-i> in insert mode, but in normal mode only, then repeatedly hitting <C-i> will be idempotent.
Thanks to Benoit for mentioning that <C-i> inserts a tab in insert mode.
You should do a mapping that behaves differently in the distinct modes:
:inoremap <F1> <NOP>
:nnoremap <F1> i
:vnoremap <F1> <esc>i
:cnoremap <F1> <C-C>i
:onoremap <F1> <esc>i
Hitting F1 will go to insert mode then.
You can also toggle the 'insertmode' setting (:set insertmode): in this mode, the Insert mode is the default mode (to which you switch with Escape, and you go to normal mode with CTRL-L.
The answer given by bitmask works, but it apparently has the side-effect of producing the error message:
E37: No write since last change (add ! to override)
Unless you have configured your vimrc to turn that message off.
But another alternative that seems to work without producing error messages:
CTRL-C i
Which seems to work on standard vim.

How to create a mapping for Insert mode but not for the autocomplete submode in Vim?

I have these insert mode mappings in my .vimrc file:
imap <C-e> <C-o>A
imap <C-a> <C-o>I
They make Ctrl-A and Ctrl-E move the cursor to the start and end of the line without leaving insert mode, a la emacs keybindings.
However, I just realized that the Ctrl-E mapping introduces a conflict with the autocompletion submode. The documentation in :help complete_CTRL-E states:
When completion is active, you can use CTRL-E to stop it and go back to the originally typed text.
Thus, my Ctrl-E mapping interferes with this. Is there a way that I can make Ctrl-E jump to the end of the line only if auto-completion is not active?
There is no proper way to test whether the
Ctrl+X-completion mode is active or not.
However, the following two workarounds are possible.
1. If one uses the popup menu to choose from the list of available
completions (especially in the case of menuone set in the completeopt
option), an acceptable solution might be the mapping
inoremap <expr> <c-e> pumvisible() ? "\<c-e>" : "\<c-o>A"
2. A general solution can be based on a side effect: In the
completion submode, it is disallowed to enter Insert mode recursively
(see :helpgrep Note: While completion), so if an attempt to do so
fails, we can suppose that we are in the midst of a completion:
inoremap <c-e> <c-r>=InsCtrlE()<cr>
function! InsCtrlE()
try
norm! i
return "\<c-o>A"
catch
return "\<c-e>"
endtry
endfunction

Resources