在 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
我正在设置我的 .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