繁体   English   中英

当vim进入可视模式时运行命令

[英]Run command when vim enters visual mode

我使用一个小脚本来触发插入模式,以便更改行号颜色:

function! CursorLineNrColorInsert(mode)
    " Insert mode: blue
    if a:mode == "i"
        highlight CursorLineNr ctermfg=4
        highlight CursorLineNr guifg=#268bd2

    " Replace mode: red
    elseif a:mode == "r"
        highlight CursorLineNr ctermfg=1
        highlight CursorLineNr guifg=#dc322f

    else
        highlight CursorLineNr ctermfg=0
        highlight CursorLineNr guifg=#073642

    endif
endfunction

autocmd InsertEnter * call CursorLineNrColorInsert(v:insertmode)
autocmd InsertLeave * highlight CursorLineNr ctermfg=0
autocmd InsertLeave * highlight CursorLineNr guifg=#073642

当我进入任何插入模式并在正常模式下恢复为原始颜色时,这非常正常并且会立即更改我的行号。

我想对视觉模式做同样的事情:

function! CursorLineNrColorVisual(mode)
    " Visual mode: orange
    if mode()=~#"^[vV\<C-v>]"
        highlight CursorLineNr ctermfg=9
        highlight CursorLineNr guifg=#cb4b16

    else
        highlight CursorLineNr ctermfg=0
        highlight CursorLineNr guifg=#073642

    endif
endfunction

autocmd CursorMoved * call CursorLineNrColorVisual(mode())

基本上它可以工作但不是立即,因为在CursorMoved上触发了该函数。 一旦激活任何视觉模式,我怎么能立即解雇CursorLineNrColorVisual()

花了一些时间:help我结束以下设置:

" Colorize line numbers in insert and visual modes
" ------------------------------------------------
function! SetCursorLineNrColorInsert(mode)
    " Insert mode: blue
    if a:mode == "i"
        highlight CursorLineNr ctermfg=4 guifg=#268bd2

    " Replace mode: red
    elseif a:mode == "r"
        highlight CursorLineNr ctermfg=1 guifg=#dc322f

    endif
endfunction


function! SetCursorLineNrColorVisual()
    set updatetime=0

    " Visual mode: orange
    highlight CursorLineNr cterm=none ctermfg=9 guifg=#cb4b16
endfunction


function! ResetCursorLineNrColor()
    set updatetime=4000
    highlight CursorLineNr cterm=none ctermfg=0 guifg=#073642
endfunction


vnoremap <silent> <expr> <SID>SetCursorLineNrColorVisual SetCursorLineNrColorVisual()
nnoremap <silent> <script> v v<SID>SetCursorLineNrColorVisual
nnoremap <silent> <script> V V<SID>SetCursorLineNrColorVisual
nnoremap <silent> <script> <C-v> <C-v><SID>SetCursorLineNrColorVisual


augroup CursorLineNrColorSwap
    autocmd!
    autocmd InsertEnter * call SetCursorLineNrColorInsert(v:insertmode)
    autocmd InsertLeave * call ResetCursorLineNrColor()
    autocmd CursorHold * call ResetCursorLineNrColor()
augroup END

为了在离开可视模式后恢复行号的颜色,我必须执行以下步骤:

  1. 重新映射相关的键绑定以调用“输入 - 视觉功能”
  2. 进入可视模式时,该函数为CursorHold事件设置CursorHold updatetime=0
  3. 通过autocmd CursorHold调用“leave-visual-function”
  4. 在离开可视模式时,该函数会为CursorHold事件重置CursorHold updatetime=4000

正如romainl指出的那样,没有用于进入/退出视觉模式的事件。 我这样做:

function! CursorLineNrColorVisual()
    ...
    return ''   " Return nothing to make the map-expr a no-op.
endfunction
vnoremap <expr> <SID>CursorLineNrColorVisual CursorLineNrColorVisual()
nnoremap <script> v v<SID>CursorLineNrColorVisual
nnoremap <script> V V<SID>CursorLineNrColorVisual
nnoremap <script> <C-v> <C-v><SID>CursorLineNrColorVisual

或者,您可以尝试将表达式( %{CursorLineNrColorVisual} )放入'statusline' %{CursorLineNrColorVisual} 'statusline' ; 这经常得到评估。

[编辑] Promptlines插件使用此方法:

由于每次更改模式时都会重新绘制状态行,因此每次更改模式时都可以通过在状态行中添加%{AnyName(mode())}%{AnyName(mode())}不会显示)。 然后,您可以实现一个能够过滤当前模式的AnyName函数。 举个例子:

let &stl.='%{RedrawStatuslineColors(mode())}'

function! RedrawStatuslineColors(mode)
    if a:mode == 'n'
        call NormalHighlight()
    elseif a:mode == 'i'
        call InsertHighlight()
    elseif a:mode == 'R'
        call ReplaceHighlight()
    elseif a:mode == 'v' || a:mode == 'V' || a:mode == '^V'
        call VisualHighlight()
    endif
endfunction

[编辑2] Itchyny建议在此线程上使用其他方法,以避免性能问题:建议缓存模式并立即完成功能(即RedrawStatuslineColors() )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM