Repository navigation
Conversation
External completion integrations need SKK candidates and learning without copying builtin UI internals. Expose candidate generation, acceptance, explicit document transports and UI adapters while retaining native presentation. Preserve automatic cmp and pum confirmation regardless of completion.enabled, with explicit adapters taking priority. Read only the selected pum item to avoid copying the entire menu on the input path. Keep builtin lifecycle operations separate from external clients, including teardown after configuration changes and reuse after stopping. Acknowledge cancelled requests without invoking obsolete UI callbacks.
Let completion integrations reuse one UI-independent client across buffers. Resolve named request documents and the unnamed current buffer without requiring consumer-specific routing in skkelua. Keep custom document resolution on new_server and provide explicit insertion metadata for candidate consumers. Exclude stopped clients from lookup and reuse so integrations can restart immediately, before a scheduled exit callback removes the old client.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
解決する問題
skkelua の候補を ddc.vim などの外部補完 UI で使うとき、既存の辞書検索・学習 API だけでは、組み込み補完と同じ候補をそのまま受け取れません。利用側で注釈を表示用テキストから分離し、候補順や pre-edit の置換範囲を組み立て、確定時には元の辞書情報を学習処理へ戻す必要があります。LSP source を使う場合は、その結果を返す transport も必要です。
これらを補完プラグインごとに実装すると、SKK の候補生成や確定処理の変更をそれぞれで追従することになります。この PR は、組み込み補完で使う処理を UI に依存しない Lua API として公開し、外部 UI でも同じ処理を利用できるようにします。候補生成・確定 API は直接呼び出せるため、LSP クライアントやサーバーの起動は不要です。 LSP 経由の接続も、その API を利用する方法の一つとして提供します。
変更内容と責務
候補生成・確定処理を共通の Lua API にまとめ、その上に任意で利用できる LSP 接続を用意します。
completion.get(context)completion.accept(item)lsp.start()で接続し、補完要求を送るcompletion.accept(item)completion.get(context)は明示的な入力位置から候補・置換範囲・確定に必要な metadata を返し、completion.accept(item)は確定した候補の学習や辞書登録を処理します。lsp.start(bufnr)を提供します。補完 UI を有効化せず、外部補完用クライアントをバッファ間で共有します。独自の文書表現にはlsp.new_server(get_context)と、ロード済みバッファを読むlsp.get_context()を使えます。completion.set_adapter()を使えます。既存の cmp / pum.vim との連携は自動検出を維持します。直接呼び出す場合も、返り値には LSP の
CompletionList/CompletionItemのデータ形式を使います。これは候補・置換範囲・metadata を表す形式であり、LSP 通信やクライアントのライフサイクルを要求するものではありません。独自の補完 source でも、この値を UI の候補に変換して利用できます。候補の表示・絞り込み・キー設定、確定時のテキスト置換、および入力位置が現在の SKK 入力に対応するかの判定は利用側が管理します。
completion.accept()はテキストを挿入する API ではなく、確定後の学習や辞書登録を担当します。UI への変換後も元の CompletionItem を保持し、確定イベントから渡します。completion.set_adapter()による UI 連携も LSP なしで利用できます。skkelua に ddc 固有の source や設定は追加しません。
既存の組み込み補完を維持し、
completion.enabledは引き続き組み込み補完を制御します。外部 API と cmp / pum.vim の確定キー連携はこの設定に依存しません。外部・組み込みクライアントの併用に合わせて、後始末の対象を区別し、設定変更後の detach、停止済みクライアントの再利用防止、キャンセル時の古い UI コールバック抑止も含めています。ddc + LSP の比較例で確認できること
以下は、2つの利用方法のうち 既存の
ddc-source-nvim-lspを使う経路の例です。ddc をこの source 経由で接続するため LSP を使いますが、本 PR の補完 API を利用するための必須条件ではありません。Lua API を直接呼べる補完 UI / source では、LSP transport を用意せずに同じ候補生成・確定処理を利用できます。以下は、同じ ddc/pum の表示・キー操作で補完を成立させるために、利用側がどこまで実装する必要があるかを示す最小再現例です。PR 前後で UI と辞書を揃え、skkelua への接続部分を比較します。
lsp.start()で接続するcomplete_callback()に渡すcompletion.accept()に渡すこの比較で示したい効果は、外部 UI の利用者が保守する SKK 固有の処理を減らし、組み込み補完との候補生成・確定処理の共通化を進められることです。変更前の例は送りなし入力だけを実装しますが、変更後は skkelua 側が提供する辞書登録項目も受け取れます。
再現範囲
空行の先頭、または
#のような空白で区切った位置で、Kanji→ 候補選択 → 確定・学習を確認します。両方の例で簡単なkeywordPatternを使います。既存のひらがなに続く入力の補完開始位置、送りあり、abbrev、キャンセル操作、コマンドラインはこの再現例では検証しません。候補生成 API 自体は送りあり・abbrev にも対応しています。共通設定:同じ ddc/pum・辞書・キー操作で比較する
Neovim 0.11 以上、Deno 2、Git が必要です。確認環境は Neovim
v0.13.0-nightly+338ce77/ Deno2.9.6。初回は Denops の依存ダウンロードが完了するまで待ってください。以下は新しい一時ディレクトリで実行し、普段の設定・辞書は使いません。このディレクトリに以下を
common.luaとして保存します。両方の例で同じ ddc source、pum UI、キー設定を使います。辞書はかんじ /漢字/感じ/の1項目だけを作成します。<C-j>で SKK を有効化し、<Tab>/<S-Tab>で候補を選択、<C-y>で確定します。候補がまだ出ていなければ<C-Space>で再要求できます。PR 前:外部 UI へ候補を渡すために、SKK の補完処理を設定側で組み立てる
同じディレクトリに
before.luaとして保存します。既存のget_completion_result()/get_ranks()/complete_callback()を使い、送りなし入力を ddc に接続する例です。注釈の分離、候補の重複排除・順位付け、pre-edit を置換する範囲、学習に渡す元の候補情報を設定側で組み立てます。さらに、これをddc-source-nvim-lspへ渡すための最小の LSP transport を用意します。この例が実装するのは送りなし入力だけです。送りありや辞書登録項目まで外部 UI で扱うには、対応する処理も利用側で追加する必要があります。
空のバッファで
i→#→<C-j>→Kanjiと入力します。# かんじに対して「漢字」「感じ」が表示されます。<Tab>を2回押して「感じ」を選択し、<C-y>で確定すると、行は# 感じになります。PR 後:SKK の補完処理を共有し、設定側には接続と確定イベントの配線を残す
同じディレクトリに
after.luaとして保存します。common.luaはそのまま使い、SKK 有効化時にlsp.start()を呼び、pum の確定イベントからcompletion.accept()に元の CompletionItem を渡します。候補整形・置換範囲・学習用 metadata と LSP transport は skkelua が提供するため、設定側の実装から取り除けます。この例の UI は引き続き ddc/pum が所有します。pum の選択状態と確定キーは自動検出されるため、明示的な
set_adapter()は不要です。変更前の Neovim は
:qa!で終了し、ファイルを保存せずに切り替えます。同じ操作で# 感じが確定します。PR 後は、共通の候補生成に由来する[辞書登録]項目も表示されます(この例では選択しません)。検証
# かんじから2番目の「感じ」を確定すると# 感じとなり、確定後のlastCandidateは{ type = "okurinasi", word = "かんじ", candidate = "感じ" }になります。env -u NVIM_LISTEN_ADDRESS nvim --clean --headless -l tests/run.luaが成功しています。git diff --checkが成功しています。Invalid 'start_col': out of rangeエラー出力が残っています。変更前のコミットでも再現することを確認しています。