Skip to content

Commit 3343e1c

Browse files
committed
👍 Bypass operations to internal denops outside of batch block
1 parent 1f4af69 commit 3343e1c

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

denops_std/batch/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,33 @@ export async function main(denops: Denops): Promise<void> {
6767
}
6868
```
6969

70+
The `denops` instance passed to the `batch` block is available even outside of
71+
the block. It works like a real `denops` instance, mean that you can write code
72+
like:
73+
74+
```typescript
75+
import { Denops } from "https://deno.land/x/denops_std/mod.ts";
76+
import { batch } from "https://deno.land/x/denops_std/batch/mod.ts";
77+
import * as anonymous from "https://deno.land/x/denops_std/anonymous/mod.ts";
78+
79+
export async function main(denops: Denops): Promise<void> {
80+
await batch(denops, async (denops) => {
81+
const [id] = anonymous.add(denops, () => {
82+
// This code is called outside of 'batch' block
83+
// thus the 'denops' instance works like a real one.
84+
// That's why you can write code like below
85+
if (await denops.eval("&verbose")) {
86+
await denops.cmd("echomsg 'VERBOSE'");
87+
}
88+
await denops.cmd("echomsg 'Hello world'");
89+
});
90+
await denops.cmd(
91+
`command! Test call denops#request('${denops.name}', '${id}', [])`,
92+
);
93+
});
94+
}
95+
```
96+
7097
### gather
7198

7299
Use `gather()` to call multiple denops functions sequentially without overhead

denops_std/batch/batch.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@ import { Context, Denops, Dispatcher, Meta } from "../deps.ts";
33
class BatchHelper implements Denops {
44
#denops: Denops;
55
#calls: [string, ...unknown[]][];
6+
#closed: boolean;
67

78
constructor(denops: Denops) {
89
this.#denops = denops;
910
this.#calls = [];
11+
this.#closed = false;
1012
}
1113

1214
static getCalls(helper: BatchHelper): [string, ...unknown[]][] {
1315
return helper.#calls;
1416
}
1517

18+
static close(helper: BatchHelper): void {
19+
helper.#closed = true;
20+
}
21+
1622
get name(): string {
1723
return this.#denops.name;
1824
}
@@ -30,21 +36,33 @@ class BatchHelper implements Denops {
3036
}
3137

3238
call(fn: string, ...args: unknown[]): Promise<unknown> {
39+
if (this.#closed) {
40+
return this.#denops.call(fn, ...args);
41+
}
3342
this.#calls.push([fn, ...args]);
3443
return Promise.resolve();
3544
}
3645

3746
batch(...calls: [string, ...unknown[]][]): Promise<unknown[]> {
47+
if (this.#closed) {
48+
return this.#denops.batch(...calls);
49+
}
3850
this.#calls.push(...calls);
3951
return Promise.resolve([]);
4052
}
4153

4254
cmd(cmd: string, ctx: Context = {}): Promise<void> {
55+
if (this.#closed) {
56+
return this.#denops.cmd(cmd, ctx);
57+
}
4358
this.call("denops#api#cmd", cmd, ctx);
4459
return Promise.resolve();
4560
}
4661

4762
eval(expr: string, ctx: Context = {}): Promise<unknown> {
63+
if (this.#closed) {
64+
return this.#denops.eval(expr, ctx);
65+
}
4866
this.call("denops#api#eval", expr, ctx);
4967
return Promise.resolve();
5068
}
@@ -62,7 +80,11 @@ export async function batch(
6280
main: (helper: BatchHelper) => Promise<void>,
6381
): Promise<void> {
6482
const helper = new BatchHelper(denops);
65-
await main(helper);
83+
try {
84+
await main(helper);
85+
} finally {
86+
BatchHelper.close(helper);
87+
}
6688
const calls = BatchHelper.getCalls(helper);
6789
await denops.batch(...calls);
6890
}

denops_std/batch/batch_test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { assertEquals, test } from "../deps_test.ts";
2-
import { batch } from "./batch.ts";
2+
import { batch, BatchHelper } from "./batch.ts";
33

44
test({
55
mode: "any",
@@ -130,3 +130,33 @@ test({
130130
]);
131131
},
132132
});
133+
test({
134+
mode: "any",
135+
name:
136+
"The 'helper' instance passed in batch block is available outside of the block",
137+
fn: async (denops) => {
138+
await denops.cmd("let g:denops_batch_test = []");
139+
await denops.cmd(
140+
"command! -nargs=1 DenopsBatchTest let g:denops_batch_test += [<f-args>]",
141+
);
142+
143+
let helper: BatchHelper;
144+
await batch(denops, (denops) => {
145+
helper = denops;
146+
return Promise.resolve();
147+
});
148+
await helper!.call("execute", "DenopsBatchTest 1");
149+
await helper!.batch(["execute", "DenopsBatchTest 1"]);
150+
await helper!.cmd("DenopsBatchTest 1");
151+
assertEquals(
152+
await helper!.eval("add(g:denops_batch_test, string(1))"),
153+
["1", "1", "1", "1"],
154+
);
155+
assertEquals(await denops.eval("g:denops_batch_test") as string[], [
156+
"1",
157+
"1",
158+
"1",
159+
"1",
160+
]);
161+
},
162+
});

0 commit comments

Comments
 (0)