Skip to content

Commit d6eba67

Browse files
authored
Merge pull request #1 from vim-denops/first
Initial impl
2 parents c384e6a + 964f449 commit d6eba67

File tree

6 files changed

+362
-0
lines changed

6 files changed

+362
-0
lines changed

autocmd.ts

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import { Denops } from "./deps.ts";
2+
import { execute } from "./execute.ts";
3+
4+
export async function autocmd(
5+
denops: Denops,
6+
group: string,
7+
main: (helper: AutocmdHelper) => void,
8+
): Promise<void> {
9+
const commands: string[] = [];
10+
const helper = new AutocmdHelper(commands);
11+
main(helper);
12+
if (group) {
13+
commands.unshift(`aug ${group}`);
14+
commands.push("aug END");
15+
}
16+
await execute(denops, commands);
17+
}
18+
19+
export class AutocmdHelper {
20+
#commands: string[];
21+
22+
constructor(commands: string[]) {
23+
this.#commands = commands;
24+
}
25+
26+
define(
27+
event: AutocmdEvent | AutocmdEvent[],
28+
pat: string | string[],
29+
cmd: string,
30+
options: AutocmdOptions = {},
31+
): void {
32+
const terms = ["au"];
33+
if (Array.isArray(event)) {
34+
terms.push(event.join(","));
35+
} else {
36+
terms.push(event);
37+
}
38+
if (Array.isArray(pat)) {
39+
terms.push(pat.join(","));
40+
} else {
41+
terms.push(pat);
42+
}
43+
if (options.once) {
44+
terms.push("++once");
45+
}
46+
if (options.nested) {
47+
terms.push("++nested");
48+
}
49+
terms.push(cmd);
50+
this.#commands.push(terms.join(" "));
51+
}
52+
53+
remove(
54+
event?: AutocmdEvent | AutocmdEvent[],
55+
pat?: string | string[],
56+
options: AutocmdOptions = {},
57+
): void {
58+
const terms = ["au!"];
59+
if (event) {
60+
if (Array.isArray(event)) {
61+
terms.push(event.join(","));
62+
} else {
63+
terms.push(event);
64+
}
65+
if (pat) {
66+
if (Array.isArray(pat)) {
67+
terms.push(pat.join(","));
68+
} else {
69+
terms.push(pat);
70+
}
71+
if (options.once) {
72+
terms.push("++once");
73+
}
74+
if (options.nested) {
75+
terms.push("++nested");
76+
}
77+
}
78+
}
79+
this.#commands.push(terms.join(" "));
80+
}
81+
}
82+
83+
export interface AutocmdOptions {
84+
once?: boolean;
85+
nested?: boolean;
86+
}
87+
88+
export type AutocmdEvent =
89+
| "*"
90+
| "BufAdd"
91+
| "BufDelete"
92+
| "BufEnter"
93+
| "BufFilePost"
94+
| "BufFilePre"
95+
| "BufHidden"
96+
| "BufLeave"
97+
| "BufModifiedSet"
98+
| "BufNew"
99+
| "BufNewFile"
100+
| "BufRead"
101+
| "BufReadPost"
102+
| "BufReadCmd"
103+
| "BufReadPre"
104+
| "BufUnload"
105+
| "BufWinEnter"
106+
| "BufWinLeave"
107+
| "BufWipeout"
108+
| "BufWrite"
109+
| "BufWritePre"
110+
| "BufWriteCmd"
111+
| "BufWritePost"
112+
| "ChanInfo"
113+
| "ChanOpen"
114+
| "CmdUndefined"
115+
| "CmdlineChanged"
116+
| "CmdlineEnter"
117+
| "CmdlineLeave"
118+
| "CmdwinEnter"
119+
| "CmdwinLeave"
120+
| "ColorScheme"
121+
| "ColorSchemePre"
122+
| "CompleteChanged"
123+
| "CompleteDonePre"
124+
| "CompleteDone"
125+
| "CursorHold"
126+
| "CursorHoldI"
127+
| "CursorMoved"
128+
| "CursorMovedI"
129+
| "DiffUpdated"
130+
| "DirChanged"
131+
| "FileAppendCmd"
132+
| "FileAppendPost"
133+
| "FileAppendPre"
134+
| "FileChangedRO"
135+
| "ExitPre"
136+
| "FileChangedShell"
137+
| "FileChangedShellPost"
138+
| "FileReadCmd"
139+
| "FileReadPost"
140+
| "FileReadPre"
141+
| "FileType"
142+
| "FileWriteCmd"
143+
| "FileWritePost"
144+
| "FileWritePre"
145+
| "FilterReadPost"
146+
| "FilterReadPre"
147+
| "FilterWritePost"
148+
| "FilterWritePre"
149+
| "FocusGained"
150+
| "FocusLost"
151+
| "FuncUndefined"
152+
| "UIEnter"
153+
| "UILeave"
154+
| "InsertChange"
155+
| "InsertCharPre"
156+
| "TextYankPost"
157+
| "InsertEnter"
158+
| "InsertLeavePre"
159+
| "InsertLeave"
160+
| "MenuPopup"
161+
| "OptionSet"
162+
| "QuickFixCmdPre"
163+
| "QuickFixCmdPost"
164+
| "QuitPre"
165+
| "RemoteReply"
166+
| "SessionLoadPost"
167+
| "ShellCmdPost"
168+
| "Signal"
169+
| "ShellFilterPost"
170+
| "SourcePre"
171+
| "SourcePost"
172+
| "SourceCmd"
173+
| "SpellFileMissing"
174+
| "StdinReadPost"
175+
| "StdinReadPre"
176+
| "SwapExists"
177+
| "Syntax"
178+
| "TabEnter"
179+
| "TabLeave"
180+
| "TabNew"
181+
| "TabNewEntered"
182+
| "TabClosed"
183+
| "TermOpen"
184+
| "TermEnter"
185+
| "TermLeave"
186+
| "TermClose"
187+
| "TermResponse"
188+
| "TextChanged"
189+
| "TextChangedI"
190+
| "TextChangedP"
191+
| "User"
192+
| "UserGettingBored"
193+
| "VimEnter"
194+
| "VimLeave"
195+
| "VimLeavePre"
196+
| "VimResized"
197+
| "VimResume"
198+
| "VimSuspend"
199+
| "WinClosed"
200+
| "WinEnter"
201+
| "WinLeave"
202+
| "WinNew"
203+
| "WinScrolled";

deps.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export type {
2+
Context,
3+
Dispatcher,
4+
} from "https://deno.land/x/denops@v0.7/mod.ts";
5+
export { Denops } from "https://deno.land/x/denops@v0.7/mod.ts";

execute.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Denops } from "./deps.ts";
2+
3+
/**
4+
* Execute Vim script directly
5+
*/
6+
export async function execute(
7+
denops: Denops,
8+
command: string | string[],
9+
): Promise<void> {
10+
if (Array.isArray(command)) {
11+
await denops.cmd("call execute(l:command, '')", {
12+
command: command
13+
.map((x) => x.replace(/^\s+|\s+$/g, ""))
14+
.filter((x) => !!x),
15+
});
16+
return;
17+
}
18+
command = command.replace(/\r?\n\s*\\/g, "");
19+
await execute(denops, command.split(/\r?\n/g));
20+
}

mod.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from "./autocmd.ts";
2+
export * from "./execute.ts";
3+
export * from "./variable.ts";
4+
export * from "./vim.ts";

variable.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Denops } from "./deps.ts";
2+
3+
/**
4+
* Vim variable groups
5+
*
6+
* g - Global variables
7+
* b - Buffer local variables
8+
* w - Window local variables
9+
* t - Tab page local variables
10+
* v - Vim's variables
11+
* env - Environment variables
12+
*
13+
*/
14+
export type VariableGroups = "g" | "b" | "w" | "t" | "v" | "env";
15+
16+
export async function getVar<T = unknown>(
17+
denops: Denops,
18+
group: VariableGroups,
19+
prop: string,
20+
): Promise<T> {
21+
const name = group === "env" ? `\$${prop}` : `${group}:${prop}`;
22+
// deno-lint-ignore no-explicit-any
23+
return (await denops.eval(name)) as any;
24+
}
25+
26+
export async function setVar<T = unknown>(
27+
denops: Denops,
28+
group: VariableGroups,
29+
prop: string,
30+
value: T,
31+
): Promise<void> {
32+
const name = group === "env" ? `\$${prop}` : `${group}:${prop}`;
33+
await denops.cmd(`let ${name} = value`, {
34+
value,
35+
});
36+
}
37+
38+
export async function removeVar(
39+
denops: Denops,
40+
group: VariableGroups,
41+
prop: string,
42+
): Promise<void> {
43+
const name = group === "env" ? `\$${prop}` : `${group}:${prop}`;
44+
await denops.cmd(`unlet ${name}`);
45+
}
46+
47+
export class VariableHelper {
48+
#denops: Denops;
49+
#group: VariableGroups;
50+
51+
constructor(denops: Denops, group: VariableGroups) {
52+
this.#denops = denops;
53+
this.#group = group;
54+
}
55+
56+
async get<T = unknown>(prop: string): Promise<T> {
57+
return await getVar(this.#denops, this.#group, prop);
58+
}
59+
60+
async set<T = unknown>(prop: string, value: T): Promise<void> {
61+
await setVar(this.#denops, this.#group, prop, value);
62+
}
63+
64+
async remove(prop: string): Promise<void> {
65+
await removeVar(this.#denops, this.#group, prop);
66+
}
67+
}

vim.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Context, Denops, Dispatcher } from "./deps.ts";
2+
import { execute } from "./execute.ts";
3+
import { autocmd, AutocmdHelper } from "./autocmd.ts";
4+
import { VariableHelper } from "./variable.ts";
5+
6+
export class Vim {
7+
#denops: Denops;
8+
9+
readonly g: VariableHelper;
10+
readonly b: VariableHelper;
11+
readonly w: VariableHelper;
12+
readonly t: VariableHelper;
13+
readonly v: VariableHelper;
14+
readonly env: VariableHelper;
15+
16+
constructor(denops: Denops) {
17+
this.#denops = denops;
18+
this.g = new VariableHelper(denops, "g");
19+
this.b = new VariableHelper(denops, "b");
20+
this.w = new VariableHelper(denops, "w");
21+
this.t = new VariableHelper(denops, "t");
22+
this.v = new VariableHelper(denops, "v");
23+
this.env = new VariableHelper(denops, "env");
24+
}
25+
26+
get name(): string {
27+
return this.#denops.name;
28+
}
29+
30+
async call(func: string, ...args: unknown[]): Promise<unknown> {
31+
return await this.#denops.call(func, ...args);
32+
}
33+
34+
async cmd(cmd: string, context: Context = {}): Promise<void> {
35+
await this.#denops.cmd(cmd, context);
36+
}
37+
38+
async eval(expr: string, context: Context = {}): Promise<void> {
39+
await this.#denops.eval(expr, context);
40+
}
41+
42+
async execute(command: string | string[]): Promise<void> {
43+
await execute(this.#denops, command);
44+
}
45+
46+
async autocmd(
47+
group: string,
48+
main: (helper: AutocmdHelper) => void,
49+
): Promise<void> {
50+
await autocmd(this.#denops, group, main);
51+
}
52+
53+
register(dispatcher: Dispatcher): void {
54+
this.#denops.extendDispatcher(dispatcher);
55+
}
56+
}
57+
58+
export function start(main: (vim: Vim) => Promise<void>) {
59+
Denops.start(async (denops) => {
60+
const vim = new Vim(denops);
61+
await main(vim);
62+
});
63+
}

0 commit comments

Comments
 (0)