Mapping in vimrc causes bizarre arrow behaviour

后端 未结 5 1147
孤街浪徒
孤街浪徒 2020-11-30 09:53

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 perso

相关标签:
5条回答
  • 2020-11-30 10:24

    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
    
    0 讨论(0)
  • 2020-11-30 10:30

    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.

    0 讨论(0)
  • 2020-11-30 10:32

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

    0 讨论(0)
  • 2020-11-30 10:40

    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
    
    0 讨论(0)
  • 2020-11-30 10:49

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

    0 讨论(0)
提交回复
热议问题