Skip to content

Commit c5a5945

Browse files
authored
Merge pull request #38 from vim-denops/batch
Add `batch` module to perform batch process
2 parents f5bd7ce + 415f4f7 commit c5a5945

File tree

7 files changed

+196
-4
lines changed

7 files changed

+196
-4
lines changed

denops_std/helper/batch.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import {
2+
Context,
3+
Denops,
4+
Dispatcher,
5+
Meta,
6+
} from "../vendor/https/deno.land/x/denops_core/mod.ts";
7+
8+
class BatchHelper implements Denops {
9+
#denops: Denops;
10+
#calls: [string, ...unknown[]][];
11+
12+
constructor(denops: Denops) {
13+
this.#denops = denops;
14+
this.#calls = [];
15+
}
16+
17+
static getCalls(helper: BatchHelper): [string, ...unknown[]][] {
18+
return helper.#calls;
19+
}
20+
21+
get name(): string {
22+
return this.#denops.name;
23+
}
24+
25+
get meta(): Meta {
26+
return this.#denops.meta;
27+
}
28+
29+
get dispatcher(): Dispatcher {
30+
return this.#denops.dispatcher;
31+
}
32+
33+
set dispatcher(dispatcher: Dispatcher) {
34+
this.#denops.dispatcher = dispatcher;
35+
}
36+
37+
call(fn: string, ...args: unknown[]): Promise<unknown> {
38+
this.#calls.push([fn, ...args]);
39+
return Promise.resolve();
40+
}
41+
42+
batch(..._calls: [string, ...unknown[]][]): Promise<unknown[]> {
43+
throw new Error(
44+
"The 'batch' method is not available on BatchDenops instance.",
45+
);
46+
}
47+
48+
cmd(cmd: string, ctx: Context = {}): Promise<void> {
49+
this.call("denops#api#cmd", cmd, ctx);
50+
return Promise.resolve();
51+
}
52+
53+
eval(expr: string, ctx: Context = {}): Promise<unknown> {
54+
this.call("denops#api#eval", expr, ctx);
55+
return Promise.resolve();
56+
}
57+
58+
dispatch(name: string, fn: string, ...args: unknown[]): Promise<unknown> {
59+
return this.#denops.dispatch(name, fn, ...args);
60+
}
61+
}
62+
63+
/**
64+
* Call denops functions sequentially without redraw and return the results.
65+
*
66+
* It is a wrapper function of `denops.batch()` to allow users to use `function`
67+
* modules, `denops.cmd()`, `denops.eval()`, or whatever things which assume a
68+
* `denops` instance.
69+
*/
70+
export async function batch(
71+
denops: Denops,
72+
main: (helper: BatchHelper) => Promise<void> | void,
73+
): Promise<unknown[]> {
74+
const helper = new BatchHelper(denops);
75+
await main(helper);
76+
const calls = BatchHelper.getCalls(helper);
77+
return await denops.batch(...calls);
78+
}

denops_std/helper/batch_test.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { test } from "../vendor/https/deno.land/x/denops_core/test/mod.ts";
2+
import { assertEquals } from "../vendor/https/deno.land/std/testing/asserts.ts";
3+
import * as fn from "../function/mod.ts";
4+
import { batch } from "./batch.ts";
5+
6+
test({
7+
mode: "any",
8+
name: "batch() sequentially execute 'helper.call()' as batch process.",
9+
fn: async (denops) => {
10+
const results = await batch(denops, (helper) => {
11+
helper.call("range", 0);
12+
helper.call("range", 1);
13+
helper.call("range", 2);
14+
});
15+
assertEquals(results, [[], [0], [0, 1]]);
16+
},
17+
});
18+
test({
19+
mode: "any",
20+
name: "batch() sequentially execute 'helper.cmd()' as batch process.",
21+
fn: async (denops) => {
22+
await denops.cmd("let g:denops_batch_test = 0");
23+
await denops.cmd("command! DenopsBatchTest let g:denops_batch_test += 1");
24+
const results = await batch(denops, (helper) => {
25+
helper.cmd("DenopsBatchTest");
26+
helper.cmd("DenopsBatchTest");
27+
helper.cmd("DenopsBatchTest");
28+
});
29+
assertEquals(results, [0, 0, 0]);
30+
assertEquals(await denops.eval("g:denops_batch_test") as number, 3);
31+
},
32+
});
33+
test({
34+
mode: "any",
35+
name: "batch() sequentially execute 'helper.eval()' as batch process.",
36+
fn: async (denops) => {
37+
await denops.cmd("let g:denops_batch_test = 10");
38+
const results = await batch(denops, (helper) => {
39+
helper.eval("g:denops_batch_test + 1");
40+
helper.eval("g:denops_batch_test - 1");
41+
helper.eval("g:denops_batch_test * 10");
42+
});
43+
assertEquals(results, [11, 9, 100]);
44+
},
45+
});
46+
test({
47+
mode: "any",
48+
name: "batch() sequentially execute 'fn.XXX(helper, ...)' as batch process.",
49+
fn: async (denops) => {
50+
const results = await batch(denops, (helper) => {
51+
fn.range(helper, 0);
52+
fn.range(helper, 1);
53+
fn.range(helper, 2);
54+
});
55+
assertEquals(results, [[], [0], [0, 1]]);
56+
},
57+
});
58+
59+
test({
60+
mode: "any",
61+
name:
62+
"batch() sequentially execute 'helper.call()' as batch process (async).",
63+
fn: async (denops) => {
64+
const results = await batch(denops, async (helper) => {
65+
assertEquals(await helper.call("range", 0), undefined);
66+
assertEquals(await helper.call("range", 1), undefined);
67+
assertEquals(await helper.call("range", 2), undefined);
68+
});
69+
assertEquals(results, [[], [0], [0, 1]]);
70+
},
71+
});
72+
test({
73+
mode: "any",
74+
name: "batch() sequentially execute 'helper.cmd()' as batch process (async).",
75+
fn: async (denops) => {
76+
await denops.cmd("let g:denops_batch_test = 0");
77+
await denops.cmd("command! DenopsBatchTest let g:denops_batch_test += 1");
78+
const results = await batch(denops, async (helper) => {
79+
assertEquals(await helper.cmd("DenopsBatchTest"), undefined);
80+
assertEquals(await helper.cmd("DenopsBatchTest"), undefined);
81+
assertEquals(await helper.cmd("DenopsBatchTest"), undefined);
82+
});
83+
assertEquals(results, [0, 0, 0]);
84+
assertEquals(await denops.eval("g:denops_batch_test") as number, 3);
85+
},
86+
});
87+
test({
88+
mode: "any",
89+
name:
90+
"batch() sequentially execute 'helper.eval()' as batch process (async).",
91+
fn: async (denops) => {
92+
await denops.cmd("let g:denops_batch_test = 10");
93+
const results = await batch(denops, async (helper) => {
94+
assertEquals(await helper.eval("g:denops_batch_test + 1"), undefined);
95+
assertEquals(await helper.eval("g:denops_batch_test - 1"), undefined);
96+
assertEquals(await helper.eval("g:denops_batch_test * 10"), undefined);
97+
});
98+
assertEquals(results, [11, 9, 100]);
99+
},
100+
});
101+
test({
102+
mode: "any",
103+
name:
104+
"batch() sequentially execute 'fn.XXX(helper, ...)' as batch process (async).",
105+
fn: async (denops) => {
106+
const results = await batch(denops, async (helper) => {
107+
assertEquals(await fn.range(helper, 0), undefined);
108+
assertEquals(await fn.range(helper, 1), undefined);
109+
assertEquals(await fn.range(helper, 2), undefined);
110+
});
111+
assertEquals(results, [[], [0], [0, 1]]);
112+
},
113+
});

denops_std/helper/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * from "./batch.ts";
12
export * from "./execute.ts";
23
export * from "./load.ts";

denops_std/modules-lock.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
]
1010
},
1111
"https://deno.land/x/denops_core": {
12-
"version": "@v1.0.0-alpha.11",
12+
"version": "@v1.0.0-alpha.12",
1313
"modules": [
1414
"/mod.ts",
1515
"/test/mod.ts"

denops_std/modules.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
]
1010
},
1111
"https://deno.land/x/denops_core": {
12-
"version": "@v1.0.0-alpha.11",
12+
"version": "@v1.0.0-alpha.12",
1313
"modules": ["/mod.ts", "/test/mod.ts"]
1414
},
1515
"https://deno.land/x/unknownutil": {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from "https://deno.land/x/denops_core@v1.0.0-alpha.11/mod.ts";
1+
export * from "https://deno.land/x/denops_core@v1.0.0-alpha.12/mod.ts";
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from "https://deno.land/x/denops_core@v1.0.0-alpha.11/test/mod.ts";
1+
export * from "https://deno.land/x/denops_core@v1.0.0-alpha.12/test/mod.ts";

0 commit comments

Comments
 (0)