I have a few vim shortcuts to insert Greek and math characters. (for nicer looking comments and Haskell code.) Unfortunately, the "forall" character seems to insert ∀þX instead of just ∀. Does this behavior happen for you, and is there a workaround?
imap <expr> <A-a> "α"
imap <expr> <A-b> "β"
imap <expr> <A-g> "γ"
imap <expr> <A-l> "λ"
imap <expr> <S-A-f> "∀"
imap <expr> <S-A-e> "∃"
You'll have to use gvim in order to use the "Alt" key combinations; you can change the "A" to a "C" and try to use it in vim if desirable. The same error comes up for me.
(It also seems that I can't map both "alt+key" and "shift+alt+key", but I'll worry about that when it becomes a problem.)
It looks like one of the bugs related to «0x80 byte starts an escape sequence» problem: in UTF-8 ∀ is \xe2\x88\x80... you see the last byte, do you? If you want to use it you should change mapping to
inoremap <expr> <S-A-f> "\u2200"
Also note the nore: don't use *map unless you know why you prefer it to nore version, it may save you from troubles when your vimrc grows. Another option is
inoremap <S-A-f> ∀
Related
I am writing a vim script which may need to map the key to trigger a function, but it looks like whatever I write in the imap command, the mapping is not worked.
For testing purpose , I set map the to like:
imap <Space> <Esc>
So I should escape from the insert mode when I press a space.But it seems not working... Is it possible to imap in vim? If not, I will find another way to work around.
It's so strange to answer my own question , but I found a solution after all. mapping-enter-key-in-vim In this question, the answer is
inoremap <buffer> <Space> <esc>
Another problem is that AutoPairs is overriding setting.... So my setting is not working.
I am a happy VIM user, although I admit I'm quite far from being fluent. I found this nice post:
Vim clear last search highlighting and I thought I'd become a better person if I didn't have to hammer away a random character sequence every time I did a search. Now, I'm also using the vimrc config from here:
http://amix.dk/vim/vimrc.html
and the problem I have is that when I add the line nnoremap <esc> :noh<return><esc> to it (it doesn't seem to make a difference where I put it) I get awkward behaviour when I use arrows in command mode, namely letters from A to D appear in a newline and I get switched to insert mode.
There has to be some mapping conflict but for the life of me I can't figure out where it is.
EDIT: As it follows from the answers it turns out the Ultimate vimrc part is not relevant, the mentioned nnoremap command will cause altered arrow behaviour even if it's the only vimrc entry. Changing title to a more informative one.
PS. I know I shouldn't use arrows, hopefully I'll get there one day.
The mapping
nnoremap <esc> :noh<return><esc>
will conflict with so called "grey keys" and I believe that it should be used either in GVim only or in terminal Vim by someone who does not use special keys like arrows.
From what I know (and guess) how Vim processes keys, I would say that it's impossible to do anything with this. For Vim to recognize special key all its components should go in a row, so when you press Arrow Left Vim gets the following sequence of codes:
<esc> [ D
But after your mapping Arrow Left becomes:
: n o h l <cr> <esc>
[ D
Vim sees two separate sequences and treats <esc> as a single press of Escape key, thus next two codes of Left Arrow key lose their special meaning.
So I suggest you to map :noh to some other key sequence (e.g. to one starting with <leader>, see :help mapleader; I don't recommend you to use F-keys, using them is as bad as using of arrow keys).
The cause had been explained well, but solution was not mentioned. However there is a straight one.
If you’ll tell to Vim explicitly that there are key sequences starting from <esc>[
:nnoremap <silent><esc> :noh<CR>
:nnoremap <esc>[ <esc>[
than when single <esc> will be pressed Vim will wait for a second (or different time, see :h 'timeoutlen') or for a next key (second <esc> for example) and only then replace it with :noh<CR>.
This solution preserves the ESC mapping to :nohlsearch.
The comment on this answer explaining why this is happening tells us that the root cause is the TermResponse behavior of vim. This can be compensated for by wrapping the mapping in an autocommand for the TermResponse event.
This ensures that the binding doesn't happen until after the term response is set, which prevents Esc from also sending a string like ]>1;3201;0c to vim.
Change your line in vimrc to this:
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
The augroup commands are not strictly necessary, but they prevent multiple mappings when you reload your vimrc without quitting vim.
EDIT: If you also use a graphical vim like Gvim or Macvim, the TermResponse event will not fire. Assuming you use a single vimrc, you'll need some additional code like
if has('gui_running')
nnoremap <silent> <esc> :nohlsearch<return><esc>
else
" code from above
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
end
Problem is that when you press an arrow terminal emits something like <Esc>OA. Vim part that supports terminal seems to use the same mapping mechanism to do the job as you are using: while nmap <Esc>OA will tell you nothing, call feedkeys("\eOA") will move one line up and call feedkeys("\eOA", 'n') will add letter A beyond current line. With your mapping being noremappable you forbid vim to use <Esc> as a part of the key. The problem is that you need remappable mapping here, but can have remappable mapping without it being recursive as well only if it starts with {lhs}, but <Esc>:noh<CR>OA is not going to work. I thought the following code will (it uses <expr> and function with side effect to make <Esc> be the first character of the actual {rhs} and still launch :noh), but in fact it does not:
function s:NoHlSearch()
nohlsearch
return "\e"
endfunction
nmap <expr> <Esc> <SID>NoHlSearch()
. I have no other idea how to solve the problem of having non-recursive remappable mapping which includes {lhs} but not at the start.
I have had good luck with this
if $TERM =~ 'xterm'
set noek
endif
nnoremap <silent> <esc> <esc>:noh<cr>
The disadvantage is that function keys can not be used in insert mode.
:h ek
How can I map a sequence in vim conditionally to run any of two external programs in such way that the screen is not cleared to show the else clause?
For example:
:nmap <c-l> :if filereadable('Makefile')<CR>!make<CR>else<CR>!ls<CR>endif<CR>
ctrl+m executes make but then clears the screen and prints the following at the bottom of it:
: else
: !ls
: endif
Press ENTER or type command to continue
You can use an expression mapping (:help map-expr)
:nnoremap <expr> <c-m> filereadable('Makefile') ? ':make<CR>' : ':!ls<CR>'
Notes:
You should use :noremap; it makes the mapping immune to remapping and recursion.
<C-m> is the same as <CR>; there's currently no way to distinguish the two; better use different keys. See this answer for more information.
you need map <expr>
e.g.:
nnoremap <expr> <c-t> line('.')>=6? ':!ls<cr>' : ':!seq 10<cr>'
in your example:
:nnoremap <expr> <c-m> filereadable('Makefile') ? ':make<CR>' : ':!ls<CR>'
for detail info:
:h :map-<expr>
note that, if you map <c-m>, the Enter will follow that mapping too. better use another key combination, unless you intend to do so.
I am a happy VIM user, although I admit I'm quite far from being fluent. I found this nice post:
Vim clear last search highlighting and I thought I'd become a better person if I didn't have to hammer away a random character sequence every time I did a search. Now, I'm also using the vimrc config from here:
http://amix.dk/vim/vimrc.html
and the problem I have is that when I add the line nnoremap <esc> :noh<return><esc> to it (it doesn't seem to make a difference where I put it) I get awkward behaviour when I use arrows in command mode, namely letters from A to D appear in a newline and I get switched to insert mode.
There has to be some mapping conflict but for the life of me I can't figure out where it is.
EDIT: As it follows from the answers it turns out the Ultimate vimrc part is not relevant, the mentioned nnoremap command will cause altered arrow behaviour even if it's the only vimrc entry. Changing title to a more informative one.
PS. I know I shouldn't use arrows, hopefully I'll get there one day.
The mapping
nnoremap <esc> :noh<return><esc>
will conflict with so called "grey keys" and I believe that it should be used either in GVim only or in terminal Vim by someone who does not use special keys like arrows.
From what I know (and guess) how Vim processes keys, I would say that it's impossible to do anything with this. For Vim to recognize special key all its components should go in a row, so when you press Arrow Left Vim gets the following sequence of codes:
<esc> [ D
But after your mapping Arrow Left becomes:
: n o h l <cr> <esc>
[ D
Vim sees two separate sequences and treats <esc> as a single press of Escape key, thus next two codes of Left Arrow key lose their special meaning.
So I suggest you to map :noh to some other key sequence (e.g. to one starting with <leader>, see :help mapleader; I don't recommend you to use F-keys, using them is as bad as using of arrow keys).
The cause had been explained well, but solution was not mentioned. However there is a straight one.
If you’ll tell to Vim explicitly that there are key sequences starting from <esc>[
:nnoremap <silent><esc> :noh<CR>
:nnoremap <esc>[ <esc>[
than when single <esc> will be pressed Vim will wait for a second (or different time, see :h 'timeoutlen') or for a next key (second <esc> for example) and only then replace it with :noh<CR>.
This solution preserves the ESC mapping to :nohlsearch.
The comment on this answer explaining why this is happening tells us that the root cause is the TermResponse behavior of vim. This can be compensated for by wrapping the mapping in an autocommand for the TermResponse event.
This ensures that the binding doesn't happen until after the term response is set, which prevents Esc from also sending a string like ]>1;3201;0c to vim.
Change your line in vimrc to this:
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
The augroup commands are not strictly necessary, but they prevent multiple mappings when you reload your vimrc without quitting vim.
EDIT: If you also use a graphical vim like Gvim or Macvim, the TermResponse event will not fire. Assuming you use a single vimrc, you'll need some additional code like
if has('gui_running')
nnoremap <silent> <esc> :nohlsearch<return><esc>
else
" code from above
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
end
Problem is that when you press an arrow terminal emits something like <Esc>OA. Vim part that supports terminal seems to use the same mapping mechanism to do the job as you are using: while nmap <Esc>OA will tell you nothing, call feedkeys("\eOA") will move one line up and call feedkeys("\eOA", 'n') will add letter A beyond current line. With your mapping being noremappable you forbid vim to use <Esc> as a part of the key. The problem is that you need remappable mapping here, but can have remappable mapping without it being recursive as well only if it starts with {lhs}, but <Esc>:noh<CR>OA is not going to work. I thought the following code will (it uses <expr> and function with side effect to make <Esc> be the first character of the actual {rhs} and still launch :noh), but in fact it does not:
function s:NoHlSearch()
nohlsearch
return "\e"
endfunction
nmap <expr> <Esc> <SID>NoHlSearch()
. I have no other idea how to solve the problem of having non-recursive remappable mapping which includes {lhs} but not at the start.
I have had good luck with this
if $TERM =~ 'xterm'
set noek
endif
nnoremap <silent> <esc> <esc>:noh<cr>
The disadvantage is that function keys can not be used in insert mode.
:h ek
I'd like to use two "controls" as a toggle key to switch between normal mode and insert mode in Vim. So I add the following two lines into my .vimrc
nmap <C-><C-> i
imap <C-><C-> <ESC>
But it doesn't work. What's wrong with the above two lines?
It seems you are trying to map Ctrl+Space to toggle insert mode.
nnoremap <C-space> i
imap <C-space> <Esc>
(Came from this Vim tip (marked obsolete, but there's a link to a more rich document on avoiding which includes the tip).)
Remember that this is not guaranteed to work across all terminals and platforms. Some terminals and platforms may eat a given Ctrl+something shortcut, while others don't, so find one that works in your environment.
nnoremap <silent><C-space> :startinsert
inoremap <silent><C-space> <C-O>:stopinsert
That's definitely not going to work. You could use an F key instead.
nnoremap <C-SPACE> i
inoremap <C-SPACE> <ESC>l
works perfectly with GVIM 7.4