From 3b05c69a513e5eb61641ede7c771e6789303052e Mon Sep 17 00:00:00 2001 From: Milly Date: Mon, 13 May 2024 09:02:06 +0900 Subject: [PATCH] :bug: Fix `helper/input` in Vim - Fix `helper/input` does not returns `null` if `` pressed in Vim. - Fix `helper/input` breaks Vim mappings. Correctly restore global or buffer local mapping. - Change test mode to "all". --- helper/input.ts | 15 +++-- helper/input_test.ts | 152 +++++++++++++++++++++++++++++++----------- helper/keymap_test.ts | 2 +- 3 files changed, 124 insertions(+), 45 deletions(-) diff --git a/helper/input.ts b/helper/input.ts index 99c7aa39..364afdbb 100644 --- a/helper/input.ts +++ b/helper/input.ts @@ -5,7 +5,7 @@ import * as fn from "../function/mod.ts"; import * as lambda from "../lambda/mod.ts"; import { execute } from "./execute.ts"; -const cacheKey = "denops_std/helper/input@1"; +const cacheKey = "denops_std/helper/input@2"; async function ensurePrerequisites(denops: Denops): Promise { if (typeof denops.context[cacheKey] === "string") { @@ -67,8 +67,10 @@ async function ensurePrerequisites(denops: Denops): Promise { endfunction else function! s:input_${suffix}(prompt, text, completion) abort - let original = maparg('', 'n') + let originalEsc = maparg('', 'c', 0, 1) + let originalInt = maparg('', 'c', 0, 1) execute printf('cnoremap %s', s:escape_token_${suffix}) + execute printf('cnoremap %s', s:escape_token_${suffix}) try let result = a:completion is# v:null \\ ? input(a:prompt, a:text) @@ -81,10 +83,15 @@ async function ensurePrerequisites(denops: Denops): Promise { catch /^Vim:Interrupt$/ return v:null finally - if empty(original) + if get(originalEsc, 'buffer') + call mapset(originalEsc) + else cunmap + endif + if get(originalInt, 'buffer') + call mapset(originalInt) else - execute printf('cmap %s', original) + cunmap endif endtry endfunction diff --git a/helper/input_test.ts b/helper/input_test.ts index 72c841f8..42ffcfb1 100644 --- a/helper/input_test.ts +++ b/helper/input_test.ts @@ -16,7 +16,7 @@ test({ helper.define( "CmdlineEnter", "*", - `call feedkeys("Hello world!\\", "t")`, + `call feedkeys("Hello world!\\", "it")`, ); }); const result = await input(denops); @@ -28,7 +28,7 @@ test({ fn: async () => { await autocmd.group(denops, "denops_std_helper_input", (helper) => { helper.remove("*"); - helper.define("CmdlineEnter", "*", `call feedkeys("\\", "t")`); + helper.define("CmdlineEnter", "*", `call feedkeys("\\", "it")`); }); const result = await input(denops, { text: "Hello world!", @@ -44,7 +44,7 @@ test({ helper.define( "CmdlineEnter", "*", - `call feedkeys("\\\\", "t")`, + `call feedkeys("\\\\", "it")`, ); }); const result = await input(denops, { @@ -61,7 +61,7 @@ test({ helper.define( "CmdlineEnter", "*", - `call feedkeys("\\\\", "t")`, + `call feedkeys("\\\\", "it")`, ); }); const result = await input(denops, { @@ -88,7 +88,7 @@ test({ helper.define( "CmdlineEnter", "*", - `call feedkeys("\\\\", "t")`, + `call feedkeys("\\\\", "it")`, ); }); const result = await input(denops, { @@ -105,7 +105,7 @@ test({ helper.define( "CmdlineEnter", "*", - `call feedkeys("\\\\", "t")`, + `call feedkeys("\\\\", "it")`, ); }); const result = await input(denops, { @@ -127,41 +127,113 @@ test({ ); }, }); - }, -}); - -test({ - // XXX: This test does not work properly on Vim - mode: "nvim", - name: "returns `null` when is pressed", - fn: async (denops) => { - await autocmd.group(denops, "denops_std_helper_input", (helper) => { - helper.remove("*"); - helper.define( - "CmdlineEnter", - "*", - `call timer_start(0, { -> feedkeys("Hello world!\\", "t") })`, - ); + await t.step({ + name: "returns `null` when is pressed", + fn: async () => { + await autocmd.group(denops, "denops_std_helper_input", (helper) => { + helper.remove("*"); + helper.define( + "CmdlineEnter", + "*", + `call feedkeys("Hello world!\\", "it")`, + ); + }); + const result = await input(denops); + assertEquals(result, null); + }, }); - const result = await input(denops); - assertEquals(result, null); - }, -}); - -test({ - // XXX: This test does not work properly on Vim - mode: "nvim", - name: "returns `null` when is pressed", - fn: async (denops) => { - await autocmd.group(denops, "denops_std_helper_input", (helper) => { - helper.remove("*"); - helper.define( - "CmdlineEnter", - "*", - `call feedkeys("Hello world!\\", "t")`, - ); + await t.step({ + name: "returns `null` when is pressed", + fn: async () => { + await autocmd.group(denops, "denops_std_helper_input", (helper) => { + helper.remove("*"); + helper.define( + "CmdlineEnter", + "*", + `call feedkeys("Hello world!\\", "it")`, + ); + }); + const result = await input(denops); + assertEquals(result, null); + }, + }); + await t.step({ + name: "should have global mapping restored", + fn: async () => { + await denops.cmd("cnoremap foo"); + await denops.cmd("cmap bar"); + const globalEsc = await denops.call("maparg", "", "c", 0, 1); + const globalInt = await denops.call("maparg", "", "c", 0, 1); + try { + await autocmd.group(denops, "denops_std_helper_input", (helper) => { + helper.remove("*"); + helper.define( + "CmdlineEnter", + "*", + `call feedkeys("Hello world!\\", "it")`, + ); + }); + await input(denops); + assertEquals( + await denops.call("maparg", "", "c", 0, 1), + globalEsc, + ); + assertEquals( + await denops.call("maparg", "", "c", 0, 1), + globalInt, + ); + } finally { + await denops.cmd("silent! cunmap "); + await denops.cmd("silent! cunmap "); + } + }, + }); + await t.step({ + name: "should have buffer local mapping restored", + fn: async () => { + await denops.cmd("cnoremap foo"); + await denops.cmd("cmap bar"); + const globalEsc = await denops.call("maparg", "", "c", 0, 1); + const globalInt = await denops.call("maparg", "", "c", 0, 1); + await denops.cmd("cnoremap eval('')"); + await denops.cmd("cnoremap baz"); + const bufferEsc = await denops.call("maparg", "", "c", 0, 1); + const bufferInt = await denops.call("maparg", "", "c", 0, 1); + try { + await autocmd.group(denops, "denops_std_helper_input", (helper) => { + helper.remove("*"); + helper.define( + "CmdlineEnter", + "*", + `call feedkeys("Hello world!\\", "it")`, + ); + }); + await input(denops); + assertEquals( + await denops.call("maparg", "", "c", 0, 1), + bufferEsc, + ); + assertEquals( + await denops.call("maparg", "", "c", 0, 1), + bufferInt, + ); + await denops.cmd("cunmap "); + await denops.cmd("cunmap "); + assertEquals( + await denops.call("maparg", "", "c", 0, 1), + globalEsc, + ); + assertEquals( + await denops.call("maparg", "", "c", 0, 1), + globalInt, + ); + } finally { + await denops.cmd("silent! cunmap "); + await denops.cmd("silent! cunmap "); + await denops.cmd("silent! cunmap "); + await denops.cmd("silent! cunmap "); + } + }, }); - const result = await input(denops); - assertEquals(result, null); }, }); diff --git a/helper/keymap_test.ts b/helper/keymap_test.ts index df258f1c..dd8c6e5e 100644 --- a/helper/keymap_test.ts +++ b/helper/keymap_test.ts @@ -16,7 +16,7 @@ type Spec = { }; test({ - mode: "nvim", + mode: "all", name: "send()", fn: async (denops, t) => { const specs: Spec[] = [