Skip to content

Commit 3cf7d9c

Browse files
committed
👍 Rewrite autocmd module to provide new functional style
1 parent 9a872e4 commit 3cf7d9c

File tree

7 files changed

+578
-89
lines changed

7 files changed

+578
-89
lines changed

autocmd/common.ts

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import { Denops } from "../deps.ts";
2+
import { AutocmdEvent } from "./types.ts";
3+
4+
type CommonOptions = {
5+
group?: string;
6+
};
7+
8+
export type DefineOptions = CommonOptions & {
9+
once?: boolean;
10+
nested?: boolean;
11+
};
12+
13+
export type RemoveOptions = CommonOptions;
14+
15+
export type ListOptions = CommonOptions;
16+
17+
export type EmitOptions = CommonOptions & {
18+
nomodeline?: boolean;
19+
};
20+
21+
export async function define(
22+
denops: Denops,
23+
event: AutocmdEvent | AutocmdEvent[],
24+
pat: string | string[],
25+
cmd: string,
26+
options: DefineOptions = {},
27+
): Promise<void> {
28+
const expr = buildDefineExpr(event, pat, cmd, options);
29+
await denops.cmd(expr);
30+
}
31+
32+
export async function remove(
33+
denops: Denops,
34+
event?: "*" | AutocmdEvent | AutocmdEvent[],
35+
pat?: string | string[],
36+
options: RemoveOptions = {},
37+
): Promise<void> {
38+
const expr = buildRemoveExpr(event, pat, options);
39+
await denops.cmd(expr);
40+
}
41+
42+
export async function list(
43+
denops: Denops,
44+
event?: "*" | AutocmdEvent | AutocmdEvent[],
45+
pat?: string | string[],
46+
options: ListOptions = {},
47+
): Promise<unknown> {
48+
const terms = ["au"];
49+
if (options.group) {
50+
terms.push(options.group);
51+
}
52+
if (event) {
53+
if (Array.isArray(event)) {
54+
terms.push(event.join(","));
55+
} else {
56+
terms.push(event);
57+
}
58+
if (pat) {
59+
if (Array.isArray(pat)) {
60+
terms.push(pat.join(","));
61+
} else {
62+
terms.push(pat);
63+
}
64+
}
65+
}
66+
const expr = terms.join(" ");
67+
return await denops.call("execute", expr);
68+
}
69+
70+
export async function emit(
71+
denops: Denops,
72+
event: AutocmdEvent | AutocmdEvent[],
73+
fname?: string,
74+
options: EmitOptions = {},
75+
): Promise<unknown> {
76+
const terms = ["do"];
77+
if (options.nomodeline) {
78+
terms.push("<nomodeline>");
79+
}
80+
if (options.group) {
81+
terms.push(options.group);
82+
}
83+
if (Array.isArray(event)) {
84+
terms.push(event.join(","));
85+
} else {
86+
terms.push(event);
87+
}
88+
if (fname) {
89+
terms.push(fname);
90+
}
91+
const expr = terms.join(" ");
92+
return await denops.cmd(expr);
93+
}
94+
95+
export async function emitAll(
96+
denops: Denops,
97+
event: AutocmdEvent | AutocmdEvent[],
98+
fname?: string,
99+
options: EmitOptions = {},
100+
): Promise<unknown> {
101+
const terms = ["doautoa"];
102+
if (options.nomodeline) {
103+
terms.push("<nomodeline>");
104+
}
105+
if (options.group) {
106+
terms.push(options.group);
107+
}
108+
if (Array.isArray(event)) {
109+
terms.push(event.join(","));
110+
} else {
111+
terms.push(event);
112+
}
113+
if (fname) {
114+
terms.push(fname);
115+
}
116+
const expr = terms.join(" ");
117+
return await denops.cmd(expr);
118+
}
119+
120+
export function buildDefineExpr(
121+
event: AutocmdEvent | AutocmdEvent[],
122+
pat: string | string[],
123+
cmd: string,
124+
options: DefineOptions = {},
125+
): string {
126+
const terms = ["au"];
127+
if (options.group) {
128+
terms.push(options.group);
129+
}
130+
if (Array.isArray(event)) {
131+
terms.push(event.join(","));
132+
} else {
133+
terms.push(event);
134+
}
135+
if (Array.isArray(pat)) {
136+
terms.push(pat.join(","));
137+
} else {
138+
terms.push(pat);
139+
}
140+
if (options.once) {
141+
terms.push("++once");
142+
}
143+
if (options.nested) {
144+
terms.push("++nested");
145+
}
146+
terms.push(cmd);
147+
return terms.join(" ");
148+
}
149+
150+
export function buildRemoveExpr(
151+
event?: "*" | AutocmdEvent | AutocmdEvent[],
152+
pat?: string | string[],
153+
options: RemoveOptions = {},
154+
): string {
155+
const terms = ["au!"];
156+
if (options.group) {
157+
terms.push(options.group);
158+
}
159+
if (event) {
160+
if (Array.isArray(event)) {
161+
terms.push(event.join(","));
162+
} else {
163+
terms.push(event);
164+
}
165+
if (pat) {
166+
if (Array.isArray(pat)) {
167+
terms.push(pat.join(","));
168+
} else {
169+
terms.push(pat);
170+
}
171+
}
172+
}
173+
return terms.join(" ");
174+
}

autocmd/common_test.ts

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
import { assertEquals, test } from "../deps_test.ts";
2+
import { globals } from "../variable/mod.ts";
3+
import { define, emit, emitAll, list, remove } from "./common.ts";
4+
5+
test({
6+
mode: "any",
7+
name: "define() defines an autocmd",
8+
fn: async (denops) => {
9+
await globals.set(denops, "denops_autocmd_test", 0);
10+
await define(
11+
denops,
12+
"User",
13+
"DenopsTest",
14+
"let g:denops_autocmd_test += 1",
15+
);
16+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
17+
await denops.cmd("doautocmd User DenopsTest");
18+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
19+
await denops.cmd("doautocmd User DenopsTest");
20+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
21+
},
22+
});
23+
test({
24+
mode: "any",
25+
name: "define() defines an autocmd (once)",
26+
fn: async (denops) => {
27+
await globals.set(denops, "denops_autocmd_test", 0);
28+
await define(
29+
denops,
30+
"User",
31+
"DenopsTest",
32+
"let g:denops_autocmd_test += 1",
33+
{
34+
once: true,
35+
},
36+
);
37+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
38+
await denops.cmd("doautocmd User DenopsTest");
39+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
40+
await denops.cmd("doautocmd User DenopsTest");
41+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
42+
},
43+
});
44+
test({
45+
mode: "any",
46+
name: "define() defines an autocmd (nested)",
47+
fn: async (denops) => {
48+
await globals.set(denops, "denops_autocmd_test", 0);
49+
await define(denops, "BufNew", "*", "let g:denops_autocmd_test += 1");
50+
await define(denops, "User", "DenopsTest", "new", {
51+
nested: true,
52+
});
53+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
54+
await denops.cmd("doautocmd User DenopsTest");
55+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
56+
await denops.cmd("doautocmd User DenopsTest");
57+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
58+
},
59+
});
60+
test({
61+
mode: "any",
62+
name: "define() defines an autocmd (group)",
63+
fn: async (denops) => {
64+
await globals.set(denops, "denops_autocmd_test", 0);
65+
await denops.cmd("augroup MyDenopsTestGroup1 | augroup END");
66+
await denops.cmd("augroup MyDenopsTestGroup2 | augroup END");
67+
await define(
68+
denops,
69+
"User",
70+
"DenopsTest",
71+
"let g:denops_autocmd_test += 1",
72+
{
73+
group: "MyDenopsTestGroup1",
74+
},
75+
);
76+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
77+
await denops.cmd("doautocmd User DenopsTest");
78+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
79+
await denops.cmd("doautocmd MyDenopsTestGroup1 User DenopsTest");
80+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
81+
await denops.cmd("doautocmd MyDenopsTestGroup2 User DenopsTest");
82+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
83+
},
84+
});
85+
86+
test({
87+
mode: "any",
88+
name: "remove() removes an autocmd",
89+
fn: async (denops) => {
90+
await globals.set(denops, "denops_autocmd_test", 0);
91+
await define(
92+
denops,
93+
"User",
94+
"DenopsTest",
95+
"let g:denops_autocmd_test += 1",
96+
);
97+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
98+
await denops.cmd("doautocmd User DenopsTest");
99+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
100+
await remove(denops, "User", "DenopsTest");
101+
await denops.cmd("doautocmd User DenopsTest");
102+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
103+
},
104+
});
105+
test({
106+
mode: "any",
107+
name: "remove() removes an autocmd (ALL for {event})",
108+
fn: async (denops) => {
109+
await globals.set(denops, "denops_autocmd_test", 0);
110+
await define(
111+
denops,
112+
"User",
113+
"DenopsTest1",
114+
"let g:denops_autocmd_test += 1",
115+
);
116+
await define(
117+
denops,
118+
"User",
119+
"DenopsTest2",
120+
"let g:denops_autocmd_test += 1",
121+
);
122+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
123+
await denops.cmd("doautocmd User DenopsTest1");
124+
await denops.cmd("doautocmd User DenopsTest2");
125+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
126+
await remove(denops, "User");
127+
await denops.cmd("doautocmd User DenopsTest1");
128+
await denops.cmd("doautocmd User DenopsTest2");
129+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
130+
},
131+
});
132+
test({
133+
mode: "any",
134+
name: "remove() removes an autocmd (ALL)",
135+
fn: async (denops) => {
136+
await globals.set(denops, "denops_autocmd_test", 0);
137+
await define(
138+
denops,
139+
"User",
140+
"DenopsTest1",
141+
"let g:denops_autocmd_test += 1",
142+
);
143+
await define(
144+
denops,
145+
"User",
146+
"DenopsTest2",
147+
"let g:denops_autocmd_test += 1",
148+
);
149+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
150+
await denops.cmd("doautocmd User DenopsTest1");
151+
await denops.cmd("doautocmd User DenopsTest2");
152+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
153+
await remove(denops);
154+
await denops.cmd("doautocmd User DenopsTest1");
155+
await denops.cmd("doautocmd User DenopsTest2");
156+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
157+
},
158+
});
159+
160+
test({
161+
mode: "any",
162+
name: "list() lists autocmds",
163+
fn: async (denops) => {
164+
await define(denops, "User", "DenopsTest", "echo '1'");
165+
await define(denops, "User", "DenopsTest", "echo '2'");
166+
await define(denops, "User", "DenopsTest", "echo '3'");
167+
assertEquals(
168+
await list(denops, "User", "DenopsTest"),
169+
[
170+
"",
171+
"--- Autocommands ---",
172+
"User",
173+
" DenopsTest",
174+
" echo '1'",
175+
" echo '2'",
176+
" echo '3'",
177+
].join("\n"),
178+
);
179+
},
180+
});
181+
182+
test({
183+
mode: "any",
184+
name: "emit() emits an autocmd",
185+
fn: async (denops) => {
186+
await globals.set(denops, "denops_autocmd_test", 0);
187+
await define(
188+
denops,
189+
"User",
190+
"DenopsTest",
191+
"let g:denops_autocmd_test += 1",
192+
);
193+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
194+
await emit(denops, "User", "DenopsTest");
195+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
196+
await emit(denops, "User", "DenopsTest");
197+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
198+
},
199+
});
200+
201+
test({
202+
mode: "any",
203+
name: "emitAll() emits an autocmd",
204+
fn: async (denops) => {
205+
await globals.set(denops, "denops_autocmd_test", 0);
206+
await define(
207+
denops,
208+
"User",
209+
"DenopsTest",
210+
"let g:denops_autocmd_test += 1",
211+
);
212+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 0);
213+
await emitAll(denops, "User", "DenopsTest");
214+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 1);
215+
await emitAll(denops, "User", "DenopsTest");
216+
assertEquals(await globals.get(denops, "denops_autocmd_test"), 2);
217+
},
218+
});

0 commit comments

Comments
 (0)