我想创建一个vim宏来做下一步:
如果我输入字符“a”,“e”,“o”,“i”或“u”并按下shorctut键p.e. F12 每次单击快捷键
时,它都必须遍历字符体育课。
a - > F12 - > à - > F12 - > â> F12 - > ä - > F12 - > ä - > F12 - >再次回到“a” A - > F12 - > À - > F12 - > Â - > F12 - > Ä - > F12 - > Ä - > F12 - >再次回到“A”
同样的
e - > EEEEEEE
E - > EEEEEEE
我 - > IIII
我 - > IIII
o - >呜
O - >呜
你 - > UUUUUU
U - > UÛÙÜU
任何人都可以帮助我吗?
答案 0 :(得分:4)
这是一个能够做你想要的功能。它的工作原理是抓取光标下的unicode字符,查看它是否存在于其中一个字符列表中,如果是,则将其推进到该列表中的下一个字符。我通过复制它,从寄存器中提取它,然后在函数末尾恢复寄存器的原始内容,以一种丑陋的方式抓取光标下的字符。必须有一个更优雅的方式!
function! CycleThroughChars()
let x_contents = getreg("x")
let x_type = getregtype("x")
let lists = [ ["a","à","â","ä","a"],
\ ["A","À","Â","Ä","A"],
\ ["e","é","è","ê","ë","e"],
\ ["E","É","Ê","È","Ë","E"],
\ ["i","î","ï","i"],
\ ["I","Î","Ï","I"],
\ ["o","ô","ö","o"],
\ ["O","Ô","Ö","O"],
\ ["u","û","ù","ü","u"],
\ ["U","Û","Ù","Ü","U"] ]
sil exe 'normal! "xyl'
let c_char = @x
for this_list in lists
let c_index = index(this_list,c_char)
if c_index != -1
sil exe "normal! r" . this_list[c_index+1]
break
endif
endfor
call setreg("x",x_contents,x_type)
startinsert
endfunction
inoremap <silent> <F12> <ESC>:call CycleThroughChars()<CR><right>
希望这有帮助。
修改强>
我意识到第二个for循环是多余的,所以我已将其从函数中删除。该功能不受影响,但每个列表只需要进行一次index()
次呼叫。
答案 1 :(得分:0)
编辑:我能够通过调用matchstr()替换补充函数。现在比现在更干净了。
为了完整起见,这就是我想出来的。
let g:unicode_list = [
\ [ 'a', 'à', 'â', 'ä' ],
\ [ 'A', 'À', 'Â', 'Ä' ],
\ [ 'e', 'é', 'è', 'ê', 'ë' ],
\ [ 'E', 'É', 'Ê', 'È', 'Ë' ],
\ [ 'i', 'î' ],
\ [ 'I', 'Î', 'Ï' ],
\ [ 'o', 'ô', 'ö' ],
\ [ 'O', 'Ô', 'Ö' ],
\ [ 'u', 'û', 'ù', 'ü' ],
\ [ 'U', 'Û', 'Ù', 'Ü' ],
\]
function! CycleUnicode(mode)
let char = matchstr(getline('.'), '.', col('.')-1)
for sublist in g:unicode_list
let idx = index(sublist, char)
if idx >= 0
try
let char = sublist[idx+1]
catch /E684/
let char = sublist[0]
endtry
execute "normal! r" . char
break
endif
endfor
if a:mode == 'i'
startinsert
endif
endfunction
inoremap <f12> <esc>:call CycleUnicode('i')<enter><right>
nnoremap <f12> :call CycleUnicode('n')<enter>