在 vim 输入模式下将向上和向下箭头重新映射到 gj-gk,而不使用?

在 vim 输入模式下将向上和向下箭头重新映射到 gj-gk,而不使用?

我已将箭头键映射为在视觉线模式下移动,而将hjkl键保留为正常的逻辑线移动:

" Visual movement with the arrows and End-Home 
nnoremap <Down> gj
nnoremap <Up> gk
vnoremap <Down> gj
vnoremap <Up> gk
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk
inoremap <Home> <C-o>g<Home>
inoremap <End>  <C-o>g<End>

这可行,但有一个小问题。我的状态行中有一些代码可以在输入模式和正常模式之间更改颜色,如下所示:

if version >= 700
  highlight statusLine cterm=bold ctermfg=black ctermbg=red
  au InsertLeave * highlight StatusLine cterm=bold ctermfg=black ctermbg=red gui=bold guifg=black guibg=red
  au InsertEnter * highlight StatusLine cterm=bold ctermfg=black ctermbg=green   gui=bold guifg=black guibg=green
endif

...我现在注意到(在一台比我家里的机器慢的机器上),每次我按下其中一个箭头时,临时模式开关<ctrl>o(至少我认为)会使状态行快速闪烁红色,然后又变绿了。

是否可以重新定义按键以避免临时跳转到正常模式?

答案1

我有两个想法,但都很复杂:

  1. 自行使用:inoremap <expr>并执行光标重新定位:call cursor()。缺点是您必须计算哪个换行列直接位于光标上方/下方。
  2. 用于将命令:inoremap <expr>包装<C-o>gj:set eventignore+=InsertLeave,InsertEnter之前并在之后选择恢复,如下所示:
function! IgnoreOn( motion )
    set eventignore+=InsertLeave,InsertEnter
    return "\<C-o>" . a:motion
endfunction
function! IgnoreOff()
    set eventignore-=InsertLeave,InsertEnter
    return "\<Left>\<Right>" | " Workaround for missing screen update.
endfunction
inoremap <expr> <SID>IgnoreOff IgnoreOff()
inoremap <expr> <SID>IgnoredDown IgnoreOn('gj')
inoremap <script> <Down> <SID>IgnoredDown<SID>IgnoreOff

答案2

我的解决方案基于Igno的建议,但不需要过多的鼠标移动。

autocmd! InsertEnter * set eventignore-=InsertLeave
function! s:UpDown(keys)
  set eventignore+=InsertLeave
  return "\<C-O>".a:keys
endfunction
inoremap <expr> <DOWN> <SID>UpDown('gj')
inoremap <expr> <Up> <SID>UpDown('gk')

相关内容