0

当我两次插入相同的字符时,我一直在尝试编写一些 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 进入等待下一个键模式并且不显示您编写的内容。此问题不仅与我列出的问题有关,而且与第一列中也出现的更普遍的问题有关。

4

3 回答 3

2

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

于 2013-01-31T14:07:17.997 回答
1

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

于 2013-01-31T14:09:44.400 回答
-1

你不需要一个函数:

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

或更清洁:

inoremap ;; <Esc>m`A;<Esc>``a
于 2013-01-31T14:19:59.580 回答