Skip to content

Commit 2ac1b5a

Browse files
authored
Merge pull request #266 from vim-denops/option-class
👍 implement options method with class
2 parents 016970e + 9a141c3 commit 2ac1b5a

File tree

5 files changed

+884
-12063
lines changed

5 files changed

+884
-12063
lines changed

.scripts/gen-option/format.ts

+18-117
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,12 @@
11
import type { Option, OptionScope, OptionType } from "./types.ts";
22

3-
const denops = "@denops/core";
4-
53
const translate: Record<string, string> = {
64
"default": "defaultValue",
75
"delete": "delete_",
86
"eval": "eval_",
97
"function": "function_",
108
};
119

12-
function defaultValue(type: OptionType): string {
13-
switch (type) {
14-
case "string":
15-
return `""`;
16-
case "number":
17-
return `0`;
18-
case "boolean":
19-
return `false`;
20-
default: {
21-
const unknownType: never = type;
22-
throw new Error(`Unknown type ${unknownType}`);
23-
}
24-
}
25-
}
26-
27-
function coerceValue(expr: string, type: OptionType): string {
28-
switch (type) {
29-
case "string":
30-
return `(${expr}) as string`;
31-
case "number":
32-
return `(${expr}) as number`;
33-
case "boolean":
34-
// Vim returns (0 | 1) so coerce to boolean.
35-
return `Boolean(${expr})`;
36-
default: {
37-
const unknownType: never = type;
38-
throw new Error(`Unknown type ${unknownType}`);
39-
}
40-
}
41-
}
42-
4310
export function formatDocs(docs: string): string[] {
4411
const lines = docs.replaceAll(/\*\//g, "* /").split("\n");
4512
const normalizedLines = lines.map((v) => ` * ${v}`.trimEnd());
@@ -51,13 +18,9 @@ function formatOption(option: Option): string[] {
5118
const name = translate[option.name] ?? option.name;
5219
const lines = [
5320
...formatDocs(docs),
54-
`export const ${name}: ${getOptionTypeName(scope, type)} = {`,
55-
...formatOptionBody(name, type),
56-
...(scope.includes("global") ? formatGlobalOptionBody(name, type) : []),
57-
...(scope.includes("local") ? formatLocalOptionBody(name, type) : []),
58-
...(scope.includes("local") ? formatBufferOptionBody(name, type) : []),
59-
...(scope.includes("local") ? formatWindowOptionBody(name, type) : []),
60-
`};`,
21+
`export const ${name}: ${getOptionTypeName(scope, type)} = ${
22+
getOptionConstructor(name, type)
23+
};`,
6124
"",
6225
];
6326
return lines;
@@ -73,90 +36,28 @@ function getOptionTypeName(scope: OptionScope[], type: OptionType): string {
7336
}
7437
}
7538

76-
function formatOptionBody(name: string, type: OptionType): string[] {
77-
const lines = [
78-
` async get(denops: Denops): Promise<${type}> {`,
79-
` const result = await options.get(denops, "${name}");`,
80-
` return ${coerceValue(`result ?? ${defaultValue(type)}`, type)};`,
81-
` },`,
82-
` set(denops: Denops, value: ${type}): Promise<void> {`,
83-
` return options.set(denops, "${name}", value);`,
84-
` },`,
85-
` reset(denops: Denops): Promise<void> {`,
86-
` return options.remove(denops, "${name}");`,
87-
` },`,
88-
];
89-
return lines;
90-
}
91-
92-
function formatGlobalOptionBody(name: string, type: OptionType): string[] {
93-
const lines = [
94-
` async getGlobal(denops: Denops): Promise<${type}> {`,
95-
` const result = await globalOptions.get(denops, "${name}");`,
96-
` return ${coerceValue(`result ?? ${defaultValue(type)}`, type)};`,
97-
` },`,
98-
` setGlobal(denops: Denops, value: ${type}): Promise<void> {`,
99-
` return globalOptions.set(denops, "${name}", value);`,
100-
` },`,
101-
` resetGlobal(denops: Denops): Promise<void> {`,
102-
` return globalOptions.remove(denops, "${name}");`,
103-
` },`,
104-
];
105-
return lines;
106-
}
107-
108-
function formatLocalOptionBody(name: string, type: OptionType): string[] {
109-
const lines = [
110-
` async getLocal(denops: Denops): Promise<${type}> {`,
111-
` const result = await localOptions.get(denops, "${name}");`,
112-
` return ${coerceValue(`result ?? ${defaultValue(type)}`, type)};`,
113-
` },`,
114-
` setLocal(denops: Denops, value: ${type}): Promise<void> {`,
115-
` return localOptions.set(denops, "${name}", value);`,
116-
` },`,
117-
` resetLocal(denops: Denops): Promise<void> {`,
118-
` return localOptions.remove(denops, "${name}");`,
119-
` },`,
120-
];
121-
return lines;
122-
}
123-
124-
function formatBufferOptionBody(name: string, type: OptionType): string[] {
125-
const lines = [
126-
` async getBuffer(denops: Denops, bufnr: number): Promise<${type}> {`,
127-
` const result = await getbufvar(denops, bufnr, "&${name}");`,
128-
` return ${coerceValue(`result ?? ${defaultValue(type)}`, type)};`,
129-
` },`,
130-
` setBuffer(denops: Denops, bufnr: number, value: ${type}): Promise<void> {`,
131-
` return setbufvar(denops, bufnr, "&${name}", value);`,
132-
` },`,
133-
];
134-
return lines;
135-
}
136-
137-
function formatWindowOptionBody(name: string, type: OptionType): string[] {
138-
const lines = [
139-
` async getWindow(denops: Denops, winnr: number): Promise<${type}> {`,
140-
` const result = await getwinvar(denops, winnr, "&${name}");`,
141-
` return ${coerceValue(`result ?? ${defaultValue(type)}`, type)};`,
142-
` },`,
143-
` setWindow(denops: Denops, winnr: number, value: ${type}): Promise<void> {`,
144-
` return setwinvar(denops, winnr, "&${name}", value);`,
145-
` },`,
146-
];
147-
return lines;
39+
function getOptionConstructor(name: string, type: OptionType): string {
40+
switch (type) {
41+
case "string":
42+
return `new StringOption("${name}")`;
43+
case "number":
44+
return `new NumberOption("${name}")`;
45+
case "boolean":
46+
return `new BooleanOption("${name}")`;
47+
default: {
48+
const unknownType: never = type;
49+
throw new Error(`Unknown type ${unknownType}`);
50+
}
51+
}
14852
}
14953

15054
export function format(options: Option[], root: string): string[] {
151-
const fn = `${root}/../function/mod.ts`;
152-
const variable = `${root}/../variable/mod.ts`;
15355
const types = `${root}/types.ts`;
56+
const utils = `${root}/_utils.ts`;
15457
const lines = [
15558
"// NOTE: This file is generated. Do NOT modify it manually.",
156-
`import type { Denops } from "${denops}";`,
157-
`import { getbufvar, setbufvar, getwinvar, setwinvar } from "${fn}";`,
158-
`import { globalOptions, localOptions, options } from "${variable}";`,
15959
`import type { GlobalOption, GlobalOrLocalOption, LocalOption } from "${types}";`,
60+
`import { BooleanOption, NumberOption, StringOption } from "${utils}";`,
16061
"",
16162
...options.map(formatOption),
16263
];

0 commit comments

Comments
 (0)