Ultisnips 如何在 Vim 中即时转换文本?

How Ultisnips transforms text instantly in Vim?

SirVer/ultisnips 是一个非常高效的插件,用于在 Vim 中编写脚本。但是任何人都知道 Ultisnips 如何在 Vim 中立即转换文本,如 gif 中所示。此示例中的 Ultisnips 在输入字符后立即将文本 "This is the subtitle" 中的每个字符转换为减号。

长什么样子

据我了解,他们似乎在作弊 ;) 这里有一个提示,可以为您提供基本概念。 所以第一步,输入一些文本。 然后 yyps/./_/g 就完成了

s/./-/g

它是如何完成的(嗯,很有可能)

所以他们基本上是拦截每个符号插入。 但是怎么办?看起来他们正在为特定事件使用自动命令,即 CursorMovedI,它被触发 "after the cursor was moved in Insert mode".

如果您查看 the source code,您可以轻松找到自动命令绑定。

替代方法

VIM 是一个控制台文本编辑器,终端不广泛支持这种文本格式。不过有一些解决方法,比如使用特殊的 utf-8 字符(当然,文本应该进行相应编码)。 Here's 可用于此方法的代码片段:

" modify selected text using combining diacritics
command! -range -nargs=0 Overline        call s:CombineSelection(<line1>, <line2>, '0305')
command! -range -nargs=0 Underline       call s:CombineSelection(<line1>, <line2>, '0332')
command! -range -nargs=0 DoubleUnderline call s:CombineSelection(<line1>, <line2>, '0333')
command! -range -nargs=0 Strikethrough   call s:CombineSelection(<line1>, <line2>, '0336')

function! s:CombineSelection(line1, line2, cp)
  execute 'let char = "\u'.a:cp.'"'
  execute a:line1.','.a:line2.'s/\%V[^[:cntrl:]]/&'.char.'/ge'
endfunction

但如您所见,它并不理想:

您可以使用 ultisnips 这样的东西:

snippet ssec "Subsection" b
${1:${VISUAL:Subsection name}}
`!p snip.rv = rst_char_len(t[1])*'-'`

上面的代码适用于 rst.snippets,它有小节 "ssec" 但是您必须查看整个代码,因为函数 "rst_char_len" 在同一个文件中定义,以提供您键入的字符串的长度。允许我们执行此特技的全局定义 可以阅读 here.