diff --git a/denops/skkeleton/context.ts b/denops/skkeleton/context.ts index 6fab4b07c..0f212e5d4 100644 --- a/denops/skkeleton/context.ts +++ b/denops/skkeleton/context.ts @@ -24,6 +24,8 @@ export class Context { word: "", candidate: "", }; + // abbrevFromDirect用: abbrevセッション完了時に呼ばれるコールバック + onAbbrevDone?: () => Promise; kakutei(str: string) { this.preEdit.doKakutei(str); diff --git a/denops/skkeleton/function/common.ts b/denops/skkeleton/function/common.ts index a74865571..16b8764a1 100644 --- a/denops/skkeleton/function/common.ts +++ b/denops/skkeleton/function/common.ts @@ -73,7 +73,7 @@ export async function newline(context: Context) { } } -export function cancel(context: Context) { +export async function cancel(context: Context) { const state = context.state; if ( state.type === "input" && @@ -83,12 +83,12 @@ export function cancel(context: Context) { context.kakutei("\x03"); } if (config.immediatelyCancel) { - initializeState(context.state); + await initializeStateWithAbbrev(context); return; } switch (state.type) { case "input": - initializeState(state); + await initializeStateWithAbbrev(context); break; case "henkan": context.state.type = "input"; diff --git a/denops/skkeleton/function/henkan.ts b/denops/skkeleton/function/henkan.ts index 3927007ca..0005924f5 100644 --- a/denops/skkeleton/function/henkan.ts +++ b/denops/skkeleton/function/henkan.ts @@ -135,8 +135,13 @@ export async function henkanInput(context: Context, key: string) { } } + const wasAbbrevSession = context.onAbbrevDone !== undefined; await kakutei(context); - await handleKey(context, keyToNotation[key] ?? key); + if (wasAbbrevSession) { + context.kakutei(key); + } else { + await handleKey(context, keyToNotation[key] ?? key); + } } export async function suffix(context: Context) { diff --git a/denops/skkeleton/main.ts b/denops/skkeleton/main.ts index 13a428175..a9e4b3017 100644 --- a/denops/skkeleton/main.ts +++ b/denops/skkeleton/main.ts @@ -144,6 +144,19 @@ async function enable(opts: unknown, vimStatus: unknown): Promise { return ""; } +async function abbrevFromDirect( + opts: unknown, + vimStatus: unknown, +): Promise { + await enable(opts, vimStatus); + const context = currentContext.get(); + context.onAbbrevDone = async () => { + await context.denops!.call("skkeleton#disable"); + }; + await modeFunctions.get()["abbrev"]?.(context, ""); + return context.preEdit.output(context.toString()); +} + async function disable(opts: unknown, vimStatus: unknown): Promise { const context = currentContext.get(); const state = currentContext.get().state; @@ -303,6 +316,8 @@ export const main: Entrypoint = async (denops) => { return buildResult(await enable(opts, vimStatus)); } else if (func === "enable") { return buildResult(await enable(opts, vimStatus)); + } else if (func === "abbrevFromDirect") { + return buildResult(await abbrevFromDirect(opts, vimStatus)); } else if (func === "disable") { return buildResult(await disable(opts, vimStatus)); } else if (func === "toggle") { @@ -374,6 +389,10 @@ export const main: Entrypoint = async (denops) => { word: midasi, candidate: word, }; + // abbrevFromDirectセッション中にddc経由で確定された場合の後処理 + if (context.onAbbrevDone && context.mode === "abbrev") { + await initializeStateWithAbbrev(context, ["converter"]); + } }, // deno-lint-ignore require-await async getConfig() { diff --git a/denops/skkeleton/mode.ts b/denops/skkeleton/mode.ts index 546f38acb..54cb3e65f 100644 --- a/denops/skkeleton/mode.ts +++ b/denops/skkeleton/mode.ts @@ -29,8 +29,18 @@ export async function initializeStateWithAbbrev( ignore: string[] = [], ) { if (context.mode === "abbrev") { - await modeChange(context, "hira"); ignore = ignore.filter((key) => key !== "converter" && key !== "table"); + initializeState(context.state, ignore); + if (context.onAbbrevDone) { + // onAbbrevDoneがある場合はmodeChange("hira")をスキップし + // コールバックに後処理を委ねる(例: disable) + const callback = context.onAbbrevDone; + context.onAbbrevDone = undefined; + await callback(); + } else { + await modeChange(context, "hira"); + } + return; } initializeState(context.state, ignore); }