0

同じ文字を 2 回挿入したときに関数を呼び出すための Vimscript を少し書き込もうとしましたが、私の特定のケースでは、セミコロンを 2 回挿入して実際にセミコロンを行末に移動する必要がありました。 .

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トリガーInsertLeaveとイベントを使用しないことをお勧めします。InsertEnter私ならここを使い: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 に答える