vim 中循环字符

发布于 2024-12-13 03:18:35 字数 456 浏览 2 评论 0原文

我想创建一个 vim 宏来执行下一步:

如果我键入字符“a”、“e”、“o”、“i”或“u”并按快捷键 pe F12 时,它​​都必须循环显示字符

每次我单击快捷键p.e

。一个-> F12-> à-> F12-> ➡️ F12-> ä -> F12-> ä -> F12->再次回到“a”
A-> F12-> À-> F12-> �-> F12-> Ρ-> F12-> Ρ-> F12->再次回到“A”,

同样
e--> eéèêëée
E--> EÉÊÈËÉE
我——>哎哎哎
我——>伊伊伊
哦——>哦哦
哦——> OÔÖO
你——>呜呜
你——> UÛÙÜU

谁能帮助我?

I would like to create a vim macro to do next:

if I type the character "a", "e", "o", "i" or "u" and press a shorctut key p.e. F12
it has to cycle through characters every time I click the shortcut key

p.e.

a -> F12 -> à -> F12 -> â -> F12 -> ä -> F12 -> ä -> F12 -> back to "a" again
A -> F12 -> À -> F12 -> Â -> F12 -> Ä -> F12 -> Ä -> F12 -> back to "A" again

same for
e --> eéèêëée
E --> EÉÊÈËÉE
i --> iîïi
I --> IÎÏI
o --> oôöo
O --> OÔÖO
u --> uûùüüu
U --> UÛÙÜU

Can anyone help me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

惜醉颜 2024-12-20 03:18:35

这是一个可以完成您想要的功能的函数。它的工作原理是抓取光标下的 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()

Here is a function which does what you want. It works by grabbing the unicode character under the cursor, seeing if it exists in a one of the lists of characters, and if so advancing it to the next character in that list. I grab the character under the cursor in an ugly way by copying it, extracting it from the register, and then restoring the register's original contents at the end of the function. There must be a more elegant way!

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>

Hope this helps.

EDIT

I realised the second for loop was redundant, so I have removed it from the function. The functionality is unaffected, but only one index() call is necessary per list.

水染的天色ゝ 2024-12-20 03:18:35

编辑:我能够通过调用 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>

Edit: I was able to replace the supplemental function with a call to matchstr(). This is a little cleaner now than it was.

For completeness, here was what I came up with.

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文