函数调用后将插入模式光标返回到同一位置

时间:2013-01-31 13:45:57

标签: function vim

当我插入相同的字符两次时,我一直在尝试编写一些Vimscript来调用函数,在我的特殊情况下,如果你插入两次半冒号以实际将半冒号移到最后,我想要它这条线。

command! Semi call Semi()
inoremap ; <C-O>:Semi2<CR>

function! Semi()
    let x = getpos(".")
    " If we are in the last column..
    if col(".")+1 == col("$")
        let insert_semi = getline(".") . ";"
        call setline(".", insert_semi)
        let x[2] += 1
        call setpos(".", x)
        return
    endif
    let char = getline(".")[x[2] - 2]
    if char == ";"
        " if prev char was a semicolon also, remove and append to the end
    else
        " insert semicolon normally...
    endif
endfunction

我遇到的问题是在最后一列调用此函数时,必须退出插入模式以调用此函数,光标将进入正常模式并将光标移动到最后一列。有没有办法判断光标是附加到行的末尾还是插入到最后一列之前,当函数调用完成后将它返回到同一位置?

我很清楚我可以在;;上使用插入映射但是我不喜欢这种行为,其中Vim进入等待下一个键模式并且不显示你所写的内容。这个问题不仅与我列出的问题有关,而且在第一列中也会出现一个更普遍的问题。

3 个答案:

答案 0 :(得分:1)

如果你的函数不使用插入模式附加';' - 例如通过从缓冲区粘贴 - 您可以使用gi命令返回到退出插入模式的位置。

答案 1 :(得分:1)

我建议不要使用i_CTRL-O,它会触发InsertLeaveInsertEnter个事件,这可能会影响其他插件。我会在这里使用:inoremap <expr> ;。见:help :map-expr。在该表达式(即您的函数)内,记录当前光标位置并将其与最后记录的光标位置进行比较。如果它在它旁边,则返回键以撤消插入并在末尾重做(<BS><BS><End>;),否则只返回;

答案 2 :(得分:-1)

你不需要一个功能:

inoremap ;; ;;<Esc>h"_xxm`$p``a

或清洁:

inoremap ;; <Esc>m`A;<Esc>``a