What I want to do: How can I create a custom keybinding in vim to write "hello world" while in insert mode, by first holding down 'w' then pressing '2'?
Note, I don't want my command invoked by pressing w then 2 -- the w key must be held down then 2 pressed. Note also, that if the 2 key is first held down then w pressed, the command should not be called.
The reason for wanting w to first be held down then pressing 2 is that, if I wanted to type "w2" literally I could do that by pressing+depressing w then pressing 2
Did you try TextExpander or, even better, TypeIt4Me?
Anyway, the exact mechanism you describe is not possible in Vim in insert mode natively. Since w is not a modifier key you can't keep it pressed and expect Vim to register the second keypress.
The closer I could think of is arpeggio which lets you map things to simultaneously pressed keys.
type :inoreab w2 hello world or write inoreab w2 hello world in your .vimrc
then when you are in INSERT mode, type w2<space>, the two words will be up there.
leader key (<leader>) could be anykey, user can map it by himself. default is \. btw, I don't think it is a good idea to map w as leader key. it conflict with w (word forward) in normal mode.
I mapped , (comma) as leader key.
more detail pls check :h <leader>
EDIT for OP's comment
Can I somehow do this without having to press <space>?
Yes you can.( However I don't recommend that way.)
you could go mapping way to skip the space.
:inoremap w2 hello world
note that if you have that mapping, in INSERT mode, anytime you press w2 "hello world" will be immediately there. I am not sure if it is convenient for you, for me not.
Related
i have this in my config file:
nnoremap a a
vnoremap a A
and pressing a in visual mode takes 2 seconds to do the action
why is this happening? is this a bad practice?
This problem is being caused by the fact that you have something else mapped (either in visual mode or in all modes) that starts with 'a'.
Imagine I map 2 different commands in my .vimrc (or as you called it, config file)
vnoremap a A
vnoremap ab D
Here, when I press 'a' in visual mode, I want it to append text.
When I press 'ab' I want it to delete a row for me instead.
I now reach over to my keyboard and I press 'ab'. How does vim know I wanted to delete a line and not just append the letter 'b' to the text? Both require the same keypresses.
So to tell the difference, when I hit the 'a' key, vim waits a second to see which command I choose, If I press 'b' quickly it will realize that this is actually the instruction 'ab' which means 'D' which means delete.
If I press 'a' and wait a second, vim will accept that I was issuing the instruction 'a' which means 'A' which means append. I then hit 'b' and the letter 'b' is appended to the text.
If you want it to stop, you will have to go through your .vimrc and change your mappings to not overlap (start with the same letters) as much, or you can type
:h leader
in vim and learn about mapleaders, which will make it much easier for you to plan your mappings. I have my mapleader set to space personally but many people also like to use commas or some other key of their choosing.
tldr: Vim is waiting a second to see if you are going to press another key and issue a different command
In (Neo)Vim, I want to configure a key as if it passed through one-way mirror.
For example, in normal mode, when I type <Leader>, the command :echo "w: Separate Window f: Open File c: Configure Settings" run (so I can get help from at the bottom of the screen), but the <Leader> still has influence on following keys --- such as w, f, c, and so on --- and <Leader><KEY> works properly.
I mapped lots keys with <Leader>, so it will be very helpful for me to display a short manual about keys follow <Leader> at the bottom of the screen when I type <Leader>.
Thanks.
First, <leader> is not a special key at all. It's a placeholder expanded by Vim to the current value of mapleader whenever it is used. Assuming your mapleader is , (as instructed in :help mapleader), the mapping below:
nnoremap <leader>f :find *
will be registered as:
nnoremap ,f :find *
Second, when Vim detects that the key you just pressed is part of several custom or built-in commands it waits a bit for you to press more keys in order to decide what to do. With , as your mapleader, pressing , will always puzzle Vim because , is an actual command in its own right and you have a bunch of custom mappings starting with ,. In this situation, Vim waits for a full second before deciding you actually wanted , and not ,f.
Third, you would almost certainly need to write a completely separate mapping mechanism for achieving you idea. A mechanism that would:
listen to key presses,
trigger a specific function when you press <leader>,
that prints something helpful in the command-line,
and waits indefinitely for another key to be pressed.
This doesn't sound trivial at all. Did you take a look at the "scripts" section of http://www.vim.org?
Four, the whole point of a mapping is to map a common action to an easy to remember shortcut. You definitely have too many mappings if you can't remember all of them. Maybe it's time to reconsider the root issue instead of looking for a workaround?
You can do that with the following mapping:
:nnoremap <Leader> :echo "w: Separate Window f: Open File c: Configure Settings"<Bar>call feedkeys((exists('g:mapleader') ? g:mapleader : '\'), 't')<CR>
This uses feedkeys() to send the <Leader> again after the help has been shown. However, this solution has the key timeout downsides already mentioned by #romainl: The message will only appear after the 'timeoutlen' delay, and then you have to press the correct mapping key within 'timeoutlen'.
alternative
I would rather print the help on <Leader><Leader>. There are no timeout issues here. If you have pressed <Leader> and then fail to remember what's the next key, just press <Leader> again, read the help, and then start again with the (now memorized) full mapping!
I am trying to modify my vimrc in the following way:
map <S-Up> <C-U>
map <S-Down> <C-D>
map <S-.> G
in order to :
move the screen up by pressing Shift+Up
move the screen down by pressing Shift+Down
go to a specific line by typing the line number then Shift+. (instead of typing line number then G)
But none of those mappings work.
I've browsed google and SO to figure out what I'm doing wrong but no luck.
Anyone can give any pointer?
Instead of <S-.> (assuming an US-English keyboard layout that has . and > on the same key), you can just write >. Then, the mapping will work.
In the graphical GVIM, your <S-Up> will work as well. In the terminal, things are complicated. For me (gnome-terminal), pressing Shift + ↑ does not send anything to Vim (to check, press :<C-v>, then the keys, and observe what gets inserted literally). For (unshifted) <Up>, I get ^[OA, the expected keycode.
So, if this is mostly about the terminal, it may make sense to select different (more ordinary) keys (cursor keys are frowned upon by Vim users, anyway :-).
I want to map 'space+u' as 'Ctrl+u', I have this at my config:
nnoremap <space>u <C-u>
But it isn't work as Ctrl+u. When I press 'space+u', firstly it works fine, but when I press 'u' second time - it works an 'undo' (I'm holding 'space' since first time). I want to make it works as , when I press 'Ctrl', hold it and can hit 'u' any times I want.
What can I do?
The mapping you made means "space first, then u in succession". Not simultaneous action there, which explains the behavior for subsequent calls.
Vim listens to key press events; the system reports it that this-and-that key was typed, with that-and-that modifier (ctrl, super). Few applications would understand to check arbitrary combinations of keys being held (outside of games).
For this sort of hacks there is an established project for Linux systems called https://github.com/alols/xcape. In combination of xcape and xmodmap you can basically map <space> as a modifier key like less used Hyper key (this is the part for xmodmap). Then you would use xcape to make sure that pressing space in isolation would result in a space character. People have used xcape to map return as a right Ctrl key (while Caps Lock would act as the left Ctrl).
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.