Inserting text through vim mapping is slow - vim

In my .vimrc I created the following mapping. Basically I want VIM to insert some text when pressing <leader>c.
The mapping is defined as follows:
map <leader>c iHELLO WORLD<Esc>;w<CR>
The second part of the map works (it exits insert mode correctly), but it takes about a second for it to actually go from normal mode to insert mode and insert the text.
I imagine this might be related to setting in my .vimrc. You can take a look at that here.

You probably have another mapping that shares a common prefix (<leader>c), and so Vim is waiting to see if you are going to type out any disambiguating characters before assuming you meant "just <leader>c".
You can avoid this by picking a non-ambiguous mapping, changing the other mapping, or reducing 'timeoutlen' from its default value of 1000 (ms).
To find out what the conflicting mapping might be, try :map <leader>c and inspect the output.

You must have multiple <leader>c-mappings. Vim has to wait to disambiguate for timeoutlen ms to see if you’re going to type <leader>cx (where x is anything`).
You can see your related mappings with verbose map <leader>c. Then either remove the others or extend yours to be something like <leader>ch (h as “Hello” mnemonic).

Related

Doing an insert remapping for commenter

I am trying to do a remapping when I'm in insert mode to insert a comment but am having a tough time figuring out what all the keys map to. What I am trying to do is:
:inoremap leadercspace ==> escleadercspacei
Basically, if I'm in insert mode I want to get out of insert mode to insert the comment (leader+c+space) and then go back into insert mode.
What would the correct :inoremap mapping for this be? What I have right now is:
:inoremap <leader>c<space> <Esc><Leader>c<space>i
But this doesn't seem to work (at least the latter half of it -- it does seem to be executing the mapping command). Note: the plugin I'm trying to remap is:
https://github.com/preservim/nerdcommenter
[count]<leader>c<space> |NERDCommenterToggle|
Toggles the comment state of the selected line(s). If the topmost selected line is commented, all selected lines are uncommented and vice versa.
From vim doc (:help nore):
Disallow mapping of {rhs}, to avoid nested and recursive mappings
In other words, the nore part forbids mapping to be applied to the rhs (right hand side).
So in your case, the <Esc><Leader>c<space>i doesn't trigger the VimCommenter mapping for that reason.
To allow recursion, you can take off the nore:
:imap <leader>c<space> <Esc><Leader>c<space>i
My recommendation is that, instead of creating an insert-mode mapping for this purpose, just use the native Ctrl+O mapping to run a single Normal mode command from Insert mode.
Assuming your leader key is set to the default \, you can use:
Ctrl+O, \, c, Space
You'll be left in Insert mode at the end of this sequence.
The advantages of this approach over an insert mode mapping are:
You don't need any extra configuration, since Ctrl+O is a native Vim command.
This works for any Normal mode command, so you don't need to add extra mappings for other commands you might want to be able to access from Insert mode.
Adding a multi-character mapping in Insert mode starting with <Leader> means Vim will always pause and hold if you insert the leader character. In this case, it will also pause when you insert <Leader> and c. I find that avoiding this kind of mappings of otherwise printable characters is usually best.

Why does vim use registers for almost every command?

I love the simplicity of composing commands that have semantic meaning. Like, for example cib reads like a sentence change in brackets - wonderful.
But why does vim need to copy the old contents into my clipboard? Nowhere in that command have I suggested I want to copy it and the problem goes much deeper.
dw diw etc all copy to the my clipboard/register as well. Why? It seems like this abandons the semantic value of these commands and I would say it is unexpected behaviour.
Am I using these commands wrong, or is there some way to completely disable this feature? Currently I have done a few remappings like this:
nnoremap dd "_dd
nnoremap cc "_cc
but I would like to not do that for every single possible combination of non-explicit copying.
By default, most of the commands you're talking about use the unnamed register, ". It sounds like you're dealing with the clipboard being overwritten for all these things too, which can be a symptom of setting clipboard to unnamed or unnamed_plus.
To go back to standard, you can probably do set clipboard=, if the output of set clipboard? is one of those two options.
*'clipboard'* *'cb'*
'clipboard' 'cb' string (default "autoselect,exclude:cons\|linux"
for X-windows, "" otherwise)
global
{not in Vi}
{only in GUI versions or when the |+xterm_clipboard|
feature is included}
This option is a list of comma separated names.
These names are recognized:
*clipboard-unnamed*
unnamed When included, Vim will use the clipboard register '*'
for all yank, delete, change and put operations which
would normally go to the unnamed register. When a
register is explicitly specified, it will always be
used regardless of whether "unnamed" is in 'clipboard'
or not. The clipboard register can always be
explicitly accessed using the "* notation. Also see
|gui-clipboard|.
*clipboard-unnamedplus*
unnamedplus A variant of the "unnamed" flag which uses the
clipboard register '+' (|quoteplus|) instead of
register '*' for all yank, delete, change and put
operations which would normally go to the unnamed
register. When "unnamed" is also included to the
option, yank operations (but not delete, change or
put) will additionally copy the text into register
'*'.
Only available with the |+X11| feature.
Availability can be checked with:
if has('unnamedplus')
I'll offer a dissenting view, and suggest that you are likely using Vim non-idiomatically. This is in no way unexpected behaviour. Are you using cib as a preparation for pasting, so that cib screws it up? Do vibp instead.
dw diw etc all copy to the my clipboard/register as well. Why? It seems like this abandons the semantic value of these commands and I would say it is unexpected behaviour.
d then p is the normal Vim idiom for cut-and-paste (i.e. move text). This is an operation I do every day, multiple times per day, and it would be really annoying if d did not also yank. You seem to think d is equivalent of Del on other text editors; it is rather the equivalent of ctrl-x (cut). To cancel this, you'd do "_d as you said; I find that I hardly ever need it.
As an advanced example, the default semantics of c and visual-mode p makes it trivial to exchange two objects; for example:
I drank all their food and ate all their whiskey.
Go to "drank", diw (delete the word and yank it), go to "ate", viwp (select a word and paste over it, yanking the previous content), ctrl-o to go back to where "drank" was and P (paste before cursor):
I ate all their food and drank all their whiskey.
(I also have a plugin which defines "function parameter" as a text object, so I use the same idiom in coding if I mix up, or refactor, the parameter order.)
The only thing I want to prevent more commonly is yank-on-paste in visual mode (so that I can paste the same content multiple times); for this, I use
xnoremap <expr> P '"_d"'.v:register.'P'
(from here). This only remaps P in visual mode (which is otherwise identical to p in visual mode). Neither p nor P outside visual mode yank, so it's a non-issue.

How can I map these five keyboard actions to a single key in Vim?

I want to map a key so that it will do the following actions in Vim. Suppose I am editing a file; I want it set up so that if I press F2, I will accomplish the same thing I would if I did the following:
press ESC
type colon (:)
type w
press Enter
press ESC again
type i to go back to insert mode
Is this possible?
Yes it's possible, but it doesn't do what you want if the cursor is at the end of line.
To get file saved on F2 in insert mode, use the following mapping:
:imap <F2> <C-O>:w<CR>
Literal answer: Yes. You can use this:
:inoremap <F2> <Esc>:w<CR>I
but it won’t do exactly what you want (the cursor will be at the wrong place).
Anton beat me to the less literal (but correct) answer.
The best answer, though, is this: Don't use Vim incorrectly. You should never spend so much time in insert mode that you need a shortcut to get out of it, save the file, and then get back in. With all other editors, you’re in “insert mode” all the time, and only temporarily pop into a menu or dialog or whatever; in Vim, you should learn to reverse this. Only pop into insert mode to edit or add something; never use arrow keys to move the cursor while in insert mode; spend the majority of your time in command (normal) mode, and after a bit of adjustment to the new paradigm, you will find that your editing speed has increased.
Writing the mapping is almost easier than your description.
First, you need to determine from which mode the mapping will be used, because that determines what :map variant you will use. You’ll probably want to use this in insert mode, so you’ll use :inoremap.
The format of the mapping is:
:..noremap {keys} {rhs}
You want <F2> (see :help key-notation) for keys. For {rhs}, just concatenate the keys listed in your description.
To persist the mapping, add it to ~/.vimrc. (See :help vimrc.)
P.S. The alternative given by Anton Kovalenko is probably better for what you’re trying to do, but here I’ve given you the general recipe for future key mappings.

In some moments vim works noticeably slowly

In some moments vim works noticeably slow. When I'm in normal mode in 100 line file, type "O" (uppercase letter o) it appears about 1-2 seconds and only then above of current line new empty line is created in insert mode (that is normal behavior). And I want to know possible reasons why this happens...
I have quite powerful computer, So the problem is not in computer.
Are you hitting <Esc> then O in very rapid succession? If so, you are seeing the delay due to certain terminal escape sequences beginning with <Esc>O. Vim has to wait to see if you are actually typing one of those sequences.
To see this for yourself, in insert mode type <Esc>OA and your cursor should move up. Pressing <Ctrl-v><Up> in insert mode will show you the escape code generated.
Type :map O
If you have a normal mapping starting with a capital O, it might be possible that Vim is waiting for a timeout to be sure that you are not starting to type a complex command.
Typically, the timeout default is of 1 second.
See :help timeout and :help timeoutlen.
If you do have a mapping starting with O, you can find where it is defined with :verbose map. You can then disable it or modify it (or remove the plugin defining the mapping).
May be you have a redefined key binding that starts with "O"... so VIM must wait to see if you are going to type the following keys

VIM: Mappable (unused) shortcut letters?

I'm trying to create two mappings which are efficient for myself:
map X ddp
Which I'd use to delete and paste in one go.
map X "_dw
Which would delete a word without yanking into a register.
However I don't want to break any existing, useful shortcuts so I'm wondering what keys I could use - any suggestions? Am I being too uptidy?
vim help has a section :he map-which-keys
1.7 WHAT KEYS TO MAP *map-which-keys*
If you are going to map something, you will need to choose which key(s) to use
for the {lhs}. You will have to avoid keys that are used for Vim commands,
otherwise you would not be able to use those commands anymore. Here are a few
suggestions:
- Function keys <F2>, <F3>, etc.. Also the shifted function keys <S-F1>,
<S-F2>, etc. Note that <F1> is already used for the help command.
- Meta-keys (with the ALT key pressed). |:map-alt-keys|
- Use the '_' or ',' character and then any other character. The "_" and ","
commands do exist in Vim (see |_| and |,|), but you probably never use them.
- Use a key that is a synonym for another command. For example: CTRL-P and
CTRL-N. Use an extra character to allow more mappings.
See the file "index" for keys that are not used and thus can be mapped without
losing any builtin function. You can also use ":help {key}^D" to find out if
a key is used for some command. ({key} is the specific key you want to find
out about, ^D is CTRL-D).
Many Vim plugins use an initial <Leader> to start their key sequences; this is an (otherwise normally) unused key that is configurable by the user.
*<Leader>* *mapleader*
To define a mapping which uses the "mapleader" variable, the special string
"<Leader>" can be used. It is replaced with the string value of "mapleader".
If "mapleader" is not set or empty, a backslash is used instead. Example:
:map <Leader>A oanother line<Esc>
Works like:
:map \A oanother line<Esc>
But after:
:let mapleader = ","
It works like:
:map ,A oanother line<Esc>
Note that the value of "mapleader" is used at the moment the mapping is
defined. Changing "mapleader" after that has no effect for already defined
mappings.
Every single ASCII character, upper and lower case, is used for something in Vim. So you're going to wind up overwriting something--just pick something that you don't use. It may help to use a common idiom for your own extensions. I use a leading comma, for example:
map ,w :w!<CR>
map ,e :e #<CR>
imap ,, <ESC>
(The last is particularly useful for me, since I pretty much never need to write two consecutive commas in insert mode, and it's nice not to have to go all the way to the Esc key.)
Typically I use control + [letter] or alt + [letter] for most mappings and it's safe, but watch out for 'w' since that's needed for window commands. You might also be interested in arpeggio.vim which lets you create mappings to simultaneously pressed groups of keys - it will massively expand the possibilities for your mappings with no danger of over-mapping something. For example, you could map "dp" (pressed simultaneously) to execute "ddp" to delete and paste in one command.
Uhmm, no, don't. When creating your mappings try not to overwrite anything ... not so much because you don't use the command you're overmapping, but because some plugin which you have/or will have maybe using it.
And then you overmap it, and then you have to worry.
Personally, for commands such as you gave as an example, I like Ctrl+some key combinations. There are a lot of free ones in vim, and the letters on the left side near Ctrl make a nice pair then.
Btw, what are you trying to do with those mappings ... I understand the second one (delete word by word), but the first doesn't make sense to me. What is it supposed to do ? Transpose lines ?

Resources