VIM: Mappable (unused) shortcut letters? - vim

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 ?

Related

Inserting text through vim mapping is slow

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).

Recommended vim keymap "namespaces" for custom keymaps?

Vim seems to have bound every key on the keyboard with actions. If I wanted to create some custom keymaps for often-executed commands, are there any keys that are recommended that I use or that are intended to be overridden?
You're right, for often-invoked mappings, the default <Leader> of \ isn't optimal. Some people reassign via mapleader, but if you use many plugins, that again leads to contention and long <Leader>abc... mappings.
My approach is to keep the leader, and start the few quick and often-used mappings with , instead. The original functionality of , isn't that important, but I've reassigned it to ' (for which I can alternatively use `; I don't usually need line-only jumps):
:noremap ' ,
In addition, you have the function keys for very quick access (though you have to lift the hand from the home row). If you're mainly in GVIM, you can also map all Shift / Ctrl / Alt combinations; in the terminal, these might not work.
Finally, there are some unused combinations. For example, yr (though there's yank and replace, there's no r motion), or q followed by any non-(writable-) register: q., q#, ...
I'll assume you don't want to use a <leader> mapping.
There are an infinite number of possible mappings, you can check if one you are thinking of is in use by a plugin via::map, :nmap and :imap.
You can check default mappings using :help
You may also be interested in Tim Pope's thought on the subject:
leader maps are pretty lame

remap or ignore spacebar in vi

Vim/vi shortcuts are awesome, but there is one behavior that I would be very happy if it could be configured. My machine uses Brazilian Portuguese(abnt2) keyboard map,and some accents(like caret) needs an extra spacebar to be print, obviously because they wait/expect another character, mostly vowels. Example of the "cut until you find an empty line":
d/^$
Keystrokes actually needed on br-abnt2:
d / <shift + ~ , spacebar>(to result ^) $ <enter>
I could use { d } as it is explained on this awesome thread, but i would benefit much more on other accents(backslash) where the extra backspace trick is needed, and most important, without change my keyboard mapping to "US" for example.
Edit: I also know that this is a keymap limitation, since our language expect something after the accent, and this is why i'm asking if there is a way to circunvent this limitation inside vim.
Any ideas?
The problem does not come from the editor, but your keymap. In fact, the caret is set to be a "dead key". Meaning that it should wait for other input before being printed.
What you probably need is a new keymap that has the caret as a non dead-key. As for example, uk-gb map has caret on the key as well as another dead-key ( if I remember correctly).
If you don't want/can't remap your keyboard, you can use vim mapping function do act so.
Just choose an unused key and map it like this:
imap g ^
This will insert ^ while typing g on insert mode (other mapping for other- mode exists, nmap, ...).
For example, to use the vim mapping in the vim command-line, you shall use :
cmap g ^
Then your example will be working.

Vim custom keybinding conventions?

In Emacs, key sequences beginning with C-c are, by convention, reserved for individual users to set. I think there is at least one more convention, too.
What, if any, are Vim's conventions for custom key bindings?
You can use commands prefixed with your <leader> key as a convention to separate your own individual keymaps from default ones.
Set your <leader> key with a like this in your .vimrc file:
let mapleader = "_"
Then you can create key mappings that are prefixed with whatever you set your leader to like this:
nnoremap <leader><space> :noh<cr>
For more info see here
In Emacs, I would't say it was so much of a a convention, as much of a popular choice.
In Vim there is not even that, and although Ctrl+something or the F keys are popular, it is far from being a wide spread "convention".
A lot of Vim users just use the default "letter operations" in normal mode, with which they accomplish in text editing, what a majority of Emacs users must depend on functions.
There is a backslash which does nothing by default, only being the default value of mapping leader (both mapleader and maplocalleader). This leader is used in plugins and I strongly suggest to leave it for them only, using keys that have default actions attached, but that are not much useful. Common keys are , (repeats t/T/f/F motion in the opposite direction) and _ (moves one line downward, on the first non-blank character), you can also check which ones you don’t use (I, for example, don’t use + and -, latter is good replacement for _). The reasons why I unlike #stonesam92 suggest not to set mapleader to them and instead put your own leader in your mappings directly are the following:
It makes plugins possibly add mappings conflicting with your own ones.
You get used to typing ,a, _a or whatever, not to <Leader>a.
It makes mapping commands work differently depending on their location in the vimrc (<Leader> is computed only once, if you change mapleader afterwards already defined mappings won’t change).
It obfuscates the reading: you have to always remember, what <Leader> is.
If you are writing plugin, always use <Leader> and also leave the user the better way to customize them, two common solutions are using global options and using hasmapto:
" Global option
if !exists('g:plugin_mapping_key')
let g:plugin_mapping_key='<Leader>a'
endif
execute 'nnoremap '.g:plugin_mapping_key.' :DoSomething<CR>'
" hasmapto
nnoremap <Plug>PluginDoSomething :DoSomething<CR>
if !hasmapto('<Plug>PluginDoSomething', 'n', 0)
nmap <Leader>a <Plug>PluginDoSomething
endif

Case-sensitive keyboard shortcuts

I'd like some map/remap/nmap/etc. commands to be case sensitive, e.g. "<C-I>" vs. "<C-i>".
I checked Google and :help map, but was unable to find this.
It appears you currently can't combine control with case-sensitivity in vim or gvim (I'm using 7.2). I might expect this to be a limitation of terminals for the former, but not the latter.
I tested it by typing this in a buffer:
map <c-i> :echo "c-i"<cr>
map <c-s-i> :echo "c-s-i"<cr>
Yank those lines, then :#" (when executes register " as commands). Verifying the maps with :map <c-i> and <c-s-i> shows the problem: <c-i> is <tab>, and only the last one takes effect, with the shift being ignored.
For alt, <a-i> and <a-s-i> do work as expected in gvim
In terminal vim, those two get mapped to é and É (at least here, check with ":map <a-i>" as above), and typing é/É directly (I use dead keys) does invoke the mapping. Actually doing a-i or a-s-i just enters insert mode.
Of course, non-control and non-alt maps work case-sensitively.
Add S for Shift
<C-S-i>
If you use your Caps Lock, (1) what on earth for?, and (2) you'll have problems. See here if this is your situation.
My bad.
Cannot be done, by design, with printable characters. The approach above does work with F1 et al, such as <C-S-F8>. See this thread for more.
My workaround would be to map it to something entirely different and obscure, and use AutoHotkey or similar to substitute the combination only for the uppercase variant.
Docs say that "CTRL-A and CTRL-a are equivalent".
Relevant part from :help notation
CTRL-{char} {char} typed as a control character; that is, typing {char}
while holding the CTRL key down. The case of {char} does not
matter; thus CTRL-A and CTRL-a are equivalent. But on some
terminals, using the SHIFT key will produce another code,
don't use it then.
(not intended as an answer, but as relevant info for anybody comming from search engine regarding case sensitivity)

Resources