【问题标题】:cycle through characters in vimvim 中的字符循环
【发布时间】:2011-11-01 13:46:28
【问题描述】:

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

如果我输入字符“a”、“e”、“o”、“i”或“u”并按下快捷键 p.e。 F12 每次点击快捷键都要循环遍历字符

p.e.

a -> F12 -> à -> F12 -> â -> F12 -> ä -> F12 -> ä -> F12 -> 再次回到“a”
A -> F12 -> À -> F12 -> Â -> F12 -> Ä -> F12 -> Ä -> F12 -> 再次回到“A”

同样
e --> eéèêëée
E --> EÉÊÈËÉE
i --> iîïi
我 --> 我是我
o --> oôöo
O --> OÔÖO
你 --> uûùüüu
U --> UÛÙÜU

谁能帮帮我?

【问题讨论】:

  • 我认为没有简单的方法可以实现这一点。您可以在命令模式下使用 CTRL-a 来增加字符代码,但这不是您想要的。
  • 你可以调整 unicycle.vim 来处理这些,尽管我可以发誓已经有另一个插件专门用于这个。现在找不到了。

标签: vim unicode macros character


【解决方案1】:

这是一个功能,可以满足您的需求。它的工作原理是抓取光标下的 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()

【讨论】:

  • 我花了很长时间才想出一个答案,而我在完成后比这更草率了。干得好(未经测试;))
  • let @xold_paste_contents 应改为 getreg()getregtype()setreg()。这样您就不会丢失寄存器类型(矩形、线条或字符)。
  • 感谢 Benoit,我已经进行了这些更改。有用的建议。
  • @PrinceGoulash,我注意到你的函数在 utf8 编码中不起作用。你知道要改变什么才能让它工作吗?这是一个多字节问题不是吗?
【解决方案2】:

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

【讨论】:

  • 我们的想法是一样的!最困难的部分是提取光标下的 unicode 字符...... Vim 没有本地方法来做这件事似乎很奇怪。
  • @PrinceGoulash 您可能对我刚刚进行的编辑感兴趣。我想我找到了一种比以前更清晰地获得角色的方法。无论如何,都是很好的参考资料。
  • @RandyMorris,如果编码为 utf-8,您的函数也不适用于 unicode 字符
猜你喜欢
  • 2016-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多