Skip to content

Commit 3b05c69

Browse files
committed
🐛 Fix helper/input in Vim
- Fix `helper/input` does not returns `null` if `<C-c>` pressed in Vim. - Fix `helper/input` breaks Vim mappings. Correctly restore global or buffer local mapping. - Change test mode to "all".
1 parent 38ddb1f commit 3b05c69

File tree

3 files changed

+124
-45
lines changed

3 files changed

+124
-45
lines changed

helper/input.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as fn from "../function/mod.ts";
55
import * as lambda from "../lambda/mod.ts";
66
import { execute } from "./execute.ts";
77

8-
const cacheKey = "denops_std/helper/input@1";
8+
const cacheKey = "denops_std/helper/input@2";
99

1010
async function ensurePrerequisites(denops: Denops): Promise<string> {
1111
if (typeof denops.context[cacheKey] === "string") {
@@ -67,8 +67,10 @@ async function ensurePrerequisites(denops: Denops): Promise<string> {
6767
endfunction
6868
else
6969
function! s:input_${suffix}(prompt, text, completion) abort
70-
let original = maparg('<Esc>', 'n')
70+
let originalEsc = maparg('<Esc>', 'c', 0, 1)
71+
let originalInt = maparg('<C-c>', 'c', 0, 1)
7172
execute printf('cnoremap <nowait><buffer> <Esc> <C-u>%s<CR>', s:escape_token_${suffix})
73+
execute printf('cnoremap <nowait><buffer> <C-c> <C-u>%s<CR>', s:escape_token_${suffix})
7274
try
7375
let result = a:completion is# v:null
7476
\\ ? input(a:prompt, a:text)
@@ -81,10 +83,15 @@ async function ensurePrerequisites(denops: Denops): Promise<string> {
8183
catch /^Vim:Interrupt$/
8284
return v:null
8385
finally
84-
if empty(original)
86+
if get(originalEsc, 'buffer')
87+
call mapset(originalEsc)
88+
else
8589
cunmap <buffer> <Esc>
90+
endif
91+
if get(originalInt, 'buffer')
92+
call mapset(originalInt)
8693
else
87-
execute printf('cmap <buffer> %s', original)
94+
cunmap <buffer> <C-c>
8895
endif
8996
endtry
9097
endfunction

helper/input_test.ts

Lines changed: 112 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ test({
1616
helper.define(
1717
"CmdlineEnter",
1818
"*",
19-
`call feedkeys("Hello world!\\<CR>", "t")`,
19+
`call feedkeys("Hello world!\\<CR>", "it")`,
2020
);
2121
});
2222
const result = await input(denops);
@@ -28,7 +28,7 @@ test({
2828
fn: async () => {
2929
await autocmd.group(denops, "denops_std_helper_input", (helper) => {
3030
helper.remove("*");
31-
helper.define("CmdlineEnter", "*", `call feedkeys("\\<CR>", "t")`);
31+
helper.define("CmdlineEnter", "*", `call feedkeys("\\<CR>", "it")`);
3232
});
3333
const result = await input(denops, {
3434
text: "Hello world!",
@@ -44,7 +44,7 @@ test({
4444
helper.define(
4545
"CmdlineEnter",
4646
"*",
47-
`call feedkeys("\\<Tab>\\<CR>", "t")`,
47+
`call feedkeys("\\<Tab>\\<CR>", "it")`,
4848
);
4949
});
5050
const result = await input(denops, {
@@ -61,7 +61,7 @@ test({
6161
helper.define(
6262
"CmdlineEnter",
6363
"*",
64-
`call feedkeys("\\<Tab>\\<CR>", "t")`,
64+
`call feedkeys("\\<Tab>\\<CR>", "it")`,
6565
);
6666
});
6767
const result = await input(denops, {
@@ -88,7 +88,7 @@ test({
8888
helper.define(
8989
"CmdlineEnter",
9090
"*",
91-
`call feedkeys("\\<Tab>\\<CR>", "t")`,
91+
`call feedkeys("\\<Tab>\\<CR>", "it")`,
9292
);
9393
});
9494
const result = await input(denops, {
@@ -105,7 +105,7 @@ test({
105105
helper.define(
106106
"CmdlineEnter",
107107
"*",
108-
`call feedkeys("\\<Tab>\\<CR>", "t")`,
108+
`call feedkeys("\\<Tab>\\<CR>", "it")`,
109109
);
110110
});
111111
const result = await input(denops, {
@@ -127,41 +127,113 @@ test({
127127
);
128128
},
129129
});
130-
},
131-
});
132-
133-
test({
134-
// XXX: This test does not work properly on Vim
135-
mode: "nvim",
136-
name: "returns `null` when <Esc> is pressed",
137-
fn: async (denops) => {
138-
await autocmd.group(denops, "denops_std_helper_input", (helper) => {
139-
helper.remove("*");
140-
helper.define(
141-
"CmdlineEnter",
142-
"*",
143-
`call timer_start(0, { -> feedkeys("Hello world!\\<Esc>", "t") })`,
144-
);
130+
await t.step({
131+
name: "returns `null` when <Esc> is pressed",
132+
fn: async () => {
133+
await autocmd.group(denops, "denops_std_helper_input", (helper) => {
134+
helper.remove("*");
135+
helper.define(
136+
"CmdlineEnter",
137+
"*",
138+
`call feedkeys("Hello world!\\<Esc>", "it")`,
139+
);
140+
});
141+
const result = await input(denops);
142+
assertEquals(result, null);
143+
},
145144
});
146-
const result = await input(denops);
147-
assertEquals(result, null);
148-
},
149-
});
150-
151-
test({
152-
// XXX: This test does not work properly on Vim
153-
mode: "nvim",
154-
name: "returns `null` when <C-c> is pressed",
155-
fn: async (denops) => {
156-
await autocmd.group(denops, "denops_std_helper_input", (helper) => {
157-
helper.remove("*");
158-
helper.define(
159-
"CmdlineEnter",
160-
"*",
161-
`call feedkeys("Hello world!\\<C-c>", "t")`,
162-
);
145+
await t.step({
146+
name: "returns `null` when <C-c> is pressed",
147+
fn: async () => {
148+
await autocmd.group(denops, "denops_std_helper_input", (helper) => {
149+
helper.remove("*");
150+
helper.define(
151+
"CmdlineEnter",
152+
"*",
153+
`call feedkeys("Hello world!\\<C-c>", "it")`,
154+
);
155+
});
156+
const result = await input(denops);
157+
assertEquals(result, null);
158+
},
159+
});
160+
await t.step({
161+
name: "should have global mapping restored",
162+
fn: async () => {
163+
await denops.cmd("cnoremap <Esc> foo");
164+
await denops.cmd("cmap <silent> <C-c> bar");
165+
const globalEsc = await denops.call("maparg", "<Esc>", "c", 0, 1);
166+
const globalInt = await denops.call("maparg", "<C-c>", "c", 0, 1);
167+
try {
168+
await autocmd.group(denops, "denops_std_helper_input", (helper) => {
169+
helper.remove("*");
170+
helper.define(
171+
"CmdlineEnter",
172+
"*",
173+
`call feedkeys("Hello world!\\<CR>", "it")`,
174+
);
175+
});
176+
await input(denops);
177+
assertEquals(
178+
await denops.call("maparg", "<Esc>", "c", 0, 1),
179+
globalEsc,
180+
);
181+
assertEquals(
182+
await denops.call("maparg", "<C-c>", "c", 0, 1),
183+
globalInt,
184+
);
185+
} finally {
186+
await denops.cmd("silent! cunmap <Esc>");
187+
await denops.cmd("silent! cunmap <C-c>");
188+
}
189+
},
190+
});
191+
await t.step({
192+
name: "should have buffer local mapping restored",
193+
fn: async () => {
194+
await denops.cmd("cnoremap <Esc> foo");
195+
await denops.cmd("cmap <silent> <C-c> bar");
196+
const globalEsc = await denops.call("maparg", "<Esc>", "c", 0, 1);
197+
const globalInt = await denops.call("maparg", "<C-c>", "c", 0, 1);
198+
await denops.cmd("cnoremap <expr><buffer> <Esc> eval('')");
199+
await denops.cmd("cnoremap <nowait><buffer> <C-c> baz");
200+
const bufferEsc = await denops.call("maparg", "<Esc>", "c", 0, 1);
201+
const bufferInt = await denops.call("maparg", "<C-c>", "c", 0, 1);
202+
try {
203+
await autocmd.group(denops, "denops_std_helper_input", (helper) => {
204+
helper.remove("*");
205+
helper.define(
206+
"CmdlineEnter",
207+
"*",
208+
`call feedkeys("Hello world!\\<CR>", "it")`,
209+
);
210+
});
211+
await input(denops);
212+
assertEquals(
213+
await denops.call("maparg", "<Esc>", "c", 0, 1),
214+
bufferEsc,
215+
);
216+
assertEquals(
217+
await denops.call("maparg", "<C-c>", "c", 0, 1),
218+
bufferInt,
219+
);
220+
await denops.cmd("cunmap <buffer> <Esc>");
221+
await denops.cmd("cunmap <buffer> <C-c>");
222+
assertEquals(
223+
await denops.call("maparg", "<Esc>", "c", 0, 1),
224+
globalEsc,
225+
);
226+
assertEquals(
227+
await denops.call("maparg", "<C-c>", "c", 0, 1),
228+
globalInt,
229+
);
230+
} finally {
231+
await denops.cmd("silent! cunmap <buffer> <Esc>");
232+
await denops.cmd("silent! cunmap <buffer> <C-c>");
233+
await denops.cmd("silent! cunmap <Esc>");
234+
await denops.cmd("silent! cunmap <C-c>");
235+
}
236+
},
163237
});
164-
const result = await input(denops);
165-
assertEquals(result, null);
166238
},
167239
});

helper/keymap_test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type Spec = {
1616
};
1717

1818
test({
19-
mode: "nvim",
19+
mode: "all",
2020
name: "send()",
2121
fn: async (denops, t) => {
2222
const specs: Spec[] = [

0 commit comments

Comments
 (0)