Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5aa568f

Browse files
committedFeb 19, 2025·
👍 Add getbufinfo() helper function
When a funcref appears in buffer-local variables, calling getbufinfo() from denops world will fail due to the error on serializing its return value using json_encode(). To avoid this, we add a wrapper function of getbufinfo() to filter-out buffer-local variables from its return value.
1 parent 5892973 commit 5aa568f

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed
 

‎deno.jsonc

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"./helper/echo": "./helper/echo.ts",
2121
"./helper/execute": "./helper/execute.ts",
2222
"./helper/expr_string": "./helper/expr_string.ts",
23+
"./helper/getbufinfo": "./helper/getbufinfo.ts",
2324
"./helper/input": "./helper/input.ts",
2425
"./helper/keymap": "./helper/keymap.ts",
2526
"./helper/load": "./helper/load.ts",

‎helper/getbufinfo.ts

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type { Denops } from "../mod.ts";
2+
import type { BufInfo } from "../function/types.ts";
3+
import type { BufNameArg, GetBufInfoDictArg } from "../function/buffer.ts";
4+
5+
/**
6+
* Get buffer information.
7+
*
8+
* This is same as getbufinfo() function in Vim script, but filters the
9+
* 'variables' entry in order to avoid errors when returning values from Vim
10+
* script world into Deno world due to appearances of Funcrefs in buffer-local
11+
* variables.
12+
*
13+
* ```typescript
14+
* import type { Entrypoint } from "jsr:@denops/std";
15+
* import { getbufinfo } from "jsr:@denops/std/helper/getbufinfo";
16+
*
17+
* export const main: Entrypoint = async (denops) => {
18+
* console.log(
19+
* await getbufinfo(denops, await denops.call("bufnr") as number),
20+
* );
21+
* }
22+
* ```
23+
*/
24+
export function getbufinfo(
25+
denops: Denops,
26+
buf?: BufNameArg,
27+
): Promise<BufInfo[]>;
28+
export function getbufinfo(
29+
denops: Denops,
30+
dict?: GetBufInfoDictArg,
31+
): Promise<BufInfo[]>;
32+
export async function getbufinfo(
33+
denops: Denops,
34+
...args: unknown[]
35+
): Promise<BufInfo[]> {
36+
const bufinfos = await denops.eval(
37+
"map(call('getbufinfo', l:args), {_, v -> filter(v, {k -> k !=# 'variables'})})",
38+
{
39+
args: args,
40+
},
41+
) as Record<
42+
keyof BufInfo,
43+
unknown
44+
>[];
45+
return bufinfos.map((bufinfo) => ({
46+
...bufinfo,
47+
changed: !!bufinfo.changed,
48+
hidden: !!bufinfo.hidden,
49+
listed: !!bufinfo.listed,
50+
loaded: !!bufinfo.loaded,
51+
} as unknown as BufInfo));
52+
}

‎helper/getbufinfo_test.ts

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { getbufinfo } from "./getbufinfo.ts";
2+
import { assertEquals, assertFalse } from "@std/assert";
3+
import { assert, is } from "@core/unknownutil";
4+
import { test } from "@denops/test";
5+
import type { BufInfo } from "../function/types.ts";
6+
7+
test({
8+
mode: "all",
9+
name: "buffer",
10+
fn: async (denops, t) => {
11+
await t.step({
12+
name: "getbufinfo()",
13+
fn: async () => {
14+
await denops.cmd("enew!");
15+
await denops.cmd("new foo");
16+
await denops.call("setline", 1, "abcdef");
17+
await denops.cmd("new bar");
18+
await denops.cmd("hide");
19+
await denops.cmd("new baz");
20+
await denops.cmd("bunload!");
21+
22+
const actual = await getbufinfo(denops);
23+
assert(actual, is.ArrayOf((x): x is BufInfo => is.Record(x)));
24+
assertEquals(actual.length, 4);
25+
assertEquals(
26+
actual.map(({ changed, hidden, listed, loaded }) => (
27+
{ changed, hidden, listed, loaded }
28+
)),
29+
[
30+
{
31+
// [No Name]
32+
changed: false,
33+
hidden: false,
34+
listed: true,
35+
loaded: true,
36+
},
37+
{
38+
// foo
39+
changed: true,
40+
hidden: false,
41+
listed: true,
42+
loaded: true,
43+
},
44+
{
45+
// bar
46+
changed: false,
47+
hidden: true,
48+
listed: true,
49+
loaded: true,
50+
},
51+
{
52+
// baz
53+
changed: false,
54+
hidden: false,
55+
listed: true,
56+
loaded: false,
57+
},
58+
],
59+
"boolean properties are invalid.",
60+
);
61+
},
62+
});
63+
await denops.cmd("1,$bwipeout!");
64+
65+
await t.step({
66+
name: "getbufinfo() will filter buffer-local variables",
67+
fn: async () => {
68+
await denops.cmd("enew!");
69+
await denops.cmd("let b:var = 0");
70+
71+
const actual = await getbufinfo(denops);
72+
assertEquals(actual.length, 1);
73+
assertFalse("variables" in actual[0]);
74+
},
75+
});
76+
},
77+
});

‎helper/mod.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export * from "./expr_string.ts";
99
export * from "./input.ts";
1010
export * from "./keymap.ts";
1111
export * from "./load.ts";
12+
export * from "./getbufinfo.ts";

0 commit comments

Comments
 (0)
Please sign in to comment.