突出显示所有选择的出现

时间:2018-01-12 11:31:39

标签: vim plugins

我正在创建一个小功能,以突出显示当前在可视模式下选择的相同术语。

这是我目前的工作:

function CheckSameTerm()

    let currentmode = mode()

    " Check for (any) visual mode
    if currentmode =~? '.*v'

        exec printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))

        "this method is for selection only and not full word(but don't really work) 
        "let select = getline("'<")[getpos("'<")[2]-1:getpos("'>")[2]-1]
        "exec printf('match IncSearch /\V\<%s\>/', select)

    endif

endfunction

au CursorMoved * exec "call CheckSameTerm()"

现在我完全陷入了两个问题:

  • 代码实际检查全字&gt;转义(展开(''),'/ \'),因为我无法获得精确选定的文字。

  • 我必须找到一种方法来删除视觉假期的突出显示(但不存在任何事件)

那么你有什么想法吗?最重要的问题是:我是否继续走好路?也许我更想念一些事情。

哦,顺便说一下,这是学习vim脚本,它不是生命保护程序;)

修改

此插件已演变,请检查https://github.com/Losams/-VIM-Plugins/blob/master/checkSameTerm.vim

1 个答案:

答案 0 :(得分:2)

你是正确的方式。然而,这远远超出了微不足道的Vim定制,并且要将其转变为强大的插件,需要做更多的工作。

解决您的问题:

  • 遗憾的是,'<,'>标记只有在您离开可视模式后(显式或在对其进行操作后)才包含当前选择。您提取文本的代码很好,但标记尚未设置。相反,您可以y帮助当前选择,然后使用gv恢复它。这破坏了默认的寄存器;需要额外的代码来保存/恢复其内容。 (请参阅我的ingo#selection#Get()中的ingo-library plugin以获得强大的实施方案。)
  • 由于视觉选择不一定由关键字边界分隔,因此您需要从模式中删除\< ... \>
  • 要处理跨行的选择,需要将嵌入的换行符转换为\n原子。在转义选择中的特殊字符后,我使用substitute()执行此操作。
  • mode()为视觉模式返回vV^V。无需.*和模式匹配; ^V也是一个字符(无论如何,我们无法以良好的方式处理块状选择,因此最好忽略它。)
  • 要关闭突出显示,只需在条件中添加else块即可。但是,它需要额外的光标移动才能应用。
  • :execute中您不需要:autocmd;这里没有需要插值的变量。

这就是我所拥有的:

function! CheckSameTerm()
    let currentmode = mode()
    " Check for (any) visual mode
    if currentmode ==? 'v'
        normal! ygv
        exec printf('match IncSearch /\V%s/', substitute(escape(@", '/\'), '\n', '\\n', 'g'))
    else
        match none
    endif
endfunction
au! CursorMoved * call CheckSameTerm()

我希望这可以帮助您进一步探索Vim脚本。玩得开心!