Skip to content

続きを打った後でも確定アンドゥ出来るようにする - #260

Merged
Shougo merged 1 commit into
vim-skk:mainfrom
delphinus:feat/kakutei-undo-after-more-input
Sep 22, 2026
Merged

Shougo merged 1 commit into
vim-skk:mainfrom
delphinus:feat/kakutei-undo-after-more-input

Conversation

@delphinus

Copy link
Copy Markdown
Contributor

#257 で相談していた「後続入力があっても、消さずにそのまま取り消せる」を実装しました。

問題

確定した文字列がカーソルの直前に残っている場合しか動きません。

  1. <C-z>kakuteiUndo を割り当てます。
  2. 「確定する」と入力しようとして Kakutei<Space> を「各停」で確定し、気付かずに suru まで打ちます。
  3. ここで <C-z> を押しても何も起きません。<C-h> を 2 回押して「する」を消して初めて動きます。

誤変換に気付くのは続きを打った後であることが多いので、これは煩わしいです。

直し方

確定アンドゥは、カーソルの直前から <BS> 相当を確定した文字数ぶん送って消しています。カーソルがそこに無いと消せないのはこのためです。

そこで、消す処理はそのままに、カーソルの方を確定した文字列の末尾まで動かしてから <BS> を送るようにしました。skkeleton#locate_kakutei() を足し、確定した文字列が書かれた場所にまだ在ることを確かめてからカーソルを移します。後ろに続く文字はカーソルより後ろに残るので、送った <BS> には巻き込まれません。

消して良いか確かめる方法は s:remove_marker_henkan() が補完のマーカーに対して既にやっているものと同様、記録したバイト位置に同じ文字列がまだ在るかを見ています。

ddskk と揃えなかった点

ddskk の skk-henkan-start-point / skk-henkan-end-point は Emacs のマーカーなので編集に追従し、確定した文字列より前を編集していても取り消せます。今回の実装は記録したバイト位置なので、それ以前を編集されると位置がずれてしまいます。その場合は何もしません。

同じことをするなら extmarks / text property が要ります。Neovim と Vim で別実装になるうえ、マーカーの後始末も要ります。一方で「確定アンドゥしたいが、その前に確定した文字列より前を編集した」という場面は多くありません。効果の割に複雑になるので今回は実装を省きました。

もう一つ、ddskk の skk-undo-kakutei-subr内容を確かめずにマーカーの範囲を delete-region します。今回の実装では記録した位置に同じ文字列が在ることを確かめてから消します。ずれた位置のまま消してしまうより良いと考えたからです。

挿入モードのみ

コマンドラインモードと端末モードでは、今までどおり、カーソルの直前に残っている場合のみ確定アンドゥできます。

コマンドラインモードでも実現は可能でしょうが、方法はかなり異なると思いますので今回は実装しませんでした。端末バッファは skkeleton が書き換えて良いものではないのでそもそも対象外です。

アンドゥ単位について

#257 で「挿入モードでのカーソル移動が絡んでアンドゥ単位の切れ方が変わる」と書きましたが、変わりませんでした。Vim 9.1 と Neovim 0.13 の双方で確かめました。

動作確認

  • deno task fmt-check / lint 指摘なし、deno check 通ります。
  • DENOPS_TEST_DENOPS_PATH を設定して全テストを実行し、変更前 115 passed / 0 failed → 変更後 118 passed / 0 failed。追加した 3 件ぶんちょうど増えて、失敗は増えていません。
  • 追加した実バッファ (Neovim) のテストは「テスト を確定 → する を入力 → <C-u>▼テストする → 別候補で確定 → 手酢戸する」を通しで見ます。

doc/skkeleton-functions.jax の制約の記述を書き換えています。

🤖 Generated with Claude Code

kakuteiUndo has been giving up as soon as anything followed the confirmed
string: it deletes by feeding backspaces, so it needed the cursor to still
sit right after the kakutei. A mis-conversion is usually noticed after
typing the rest of the word, which left "delete what you typed, undo, type
it again" as the way to use it.

Let it walk back instead. skkeleton#locate_kakutei() checks that the
confirmed string is still where it was written and puts the cursor at its
end, and the existing backspace path takes it from there, leaving what
follows alone.

The check is the one s:remove_marker_henkan() already does for the
completion marker: the recorded byte offset has to still hold the same
text. This is not a marker and does not follow edits, so an edit in front
of the kakutei on the same line puts it out of reach -- the undo then does
nothing, as it does today. ddskk trusts its markers and deletes the region
unconditionally; verifying is worth more here than matching that, since a
stale offset would otherwise delete text the undo does not own.

Insert mode only. The command line has no line to walk back into and a
terminal buffer is not ours to edit, so both keep the old rule of the
cursor having to be right after the kakutei.

Note: moving the cursor this way does not break the undo block the insert
is building up -- measured in Neovim, with and without undojoin, the whole
insertion still goes back with a single u. undojoin would not help if it
did: the deletion is fed back as keys after skkeleton#handle() returns,
past the command undojoin would apply to.

確認:
  deno task fmt-check / lint  指摘なし
  deno check main.ts  通る
  DENOPS_TEST_DENOPS_PATH を設定して全テスト
    変更前 115 passed / 0 failed
    変更後 118 passed / 0 failed  (追加した 3 件ぶん)
  doc/skkeleton-functions.jax  追加分は表示幅 78 桁以内

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Shougo

Shougo commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

手元で試したところ問題なさそうです。

@Shougo
Shougo merged commit 80485e9 into vim-skk:main Sep 22, 2026
2 checks passed
@delphinus
delphinus deleted the feat/kakutei-undo-after-more-input branch September 22, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants