循环浏览vim中的字符

时间:2011-11-01 13:46:29

标签: vim unicode macros character

我想创建一个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

任何人都可以帮助我吗?

2 个答案:

答案 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>