在 vimrc 缩写中使用通配符

using wildcards in vimrc abbreviations

我正在设置我的 .vimrc 来写一些 HTML,目前有这些行:

abb <buffer> <h1> <h1></h1><ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>
abb <buffer> <h2> <h2></h2><ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>
abb <buffer> <h3> <h3></h3><ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>
abb <buffer> <h4> <h4></h4><ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>
abb <buffer> <h5> <h5></h5><ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>
abb <buffer> <h6> <h6></h6><ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>

它会自动为我写的任何开始的 h-tag 添加一个结束标记,将光标移动到它们的中间并使用 :helpgrep Eatchar

中的函数去除空白

我的问题是,如果有更优雅的方法,告诉 vim 接受 并添加一个具有相同数字的结束标记,而不是必须具体定义每个案例? 或者就此而言,有没有一种方法可以定义添加结束标记并将光标移回函数的整个过程,然后仅指定我希望应用它的所有标记?因为在这下面我有很多行用于一堆看起来几乎相同的其他标签。

我不确定如何参数化单个缩写;我怀疑您需要为此深入研究功能。但是,您可以定义一个由尾部组成的映射:

inoremap nowsp <ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>

然后在您的缩写中使用该地图

abb <buffer> <h1> <h1></h1>nowsp
abb <buffer> <h2> <h2></h2>nowsp
" etc

:help abbreviations:help mapping 都不能在左侧使用通配符。此类问题的一种解决方案是遍历标题级别并以编程方式创建缩写:

for level in range(1, 6)
    execute "abbreviate <buffer> <h" .. level .. "> <h" .. level .. "></h" .. level .. "><ESC>?<<CR>i<C-R>=Eatchar('\m\s\<bar>/')<CR>"
endfor

它当然更聪明一点,但我想知道失去易读性是否真的值得。

我最近写了一个函数来满足我的类似需求。此功能可以在其他工具中找到,例如 VSCode.

当我输入 > 时,它会尝试回头检查 > 是否在像 <div> 这样的标签中。如果是这样,它将完成它并将光标设置在 <div>|</div>.

相比于emmet或snippets,这种方式感觉更直接。

function! CompleteTag()
  let line = getline('.')
  let end = col('.') - 1
  let begin = end - 1
  let tagname_regexp = '[a-zA-Z0-9-]'

  while begin > 0
    if line[begin] !~ tagname_regexp
      break
    endif
    let begin -= 1
  endwhile

  if line[begin] == '<'
    let tagname = line[begin+1:end-1]
    let move = MoveBack(len(tagname)+3)
    return '></'.tagname.'>'.move
  endif

  return '>'
endfunction

function! MoveBack(n)
  let move = ''
  for i in range(0, a:n-1)
    let move .= "\<Left>"
  endfor
  return move
endfunction

autocmd FileType jsx,html,vue,svelte inoremap<buffer> > <c-r>=CompleteTag()<cr>
autocmd FileType jsx,html,vue,svelte inoremap<buffer> <c-cr> <cr><esc>O