Skip to content

Commit e15221b

Browse files
authored
Merge pull request #16 from vim-denops/stream
💥 Support Web Streams API and simplify the features
2 parents 91c919b + 1442ef4 commit e15221b

20 files changed

+1204
-948
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,8 @@ jobs:
3838
run: |
3939
deno task test
4040
timeout-minutes: 5
41+
- run: |
42+
deno coverage --unstable .coverage --lcov > coverage.lcov
43+
- uses: codecov/codecov-action@v1
44+
with:
45+
file: ./coverage.lcov

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
deno.lock
2+
.coverage

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
[![deno land](http://img.shields.io/badge/available%20on-deno.land/x-lightgrey.svg?logo=deno)](https://deno.land/x/vim_channel_command)
44
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/vim_channel_command/mod.ts)
55
[![Test](https://github.com/vim-denops/deno-vim-channel-command/workflows/Test/badge.svg)](https://github.com/vim-denops/deno-vim-channel-command/actions?query=workflow%3ATest)
6+
[![codecov](https://codecov.io/github/vim-denops/deno-vim-channel-command/branch/main/graph/badge.svg?token=FYH6RHO6UC)](https://codecov.io/github/vim-denops/deno-vim-channel-command)
67

78
[Deno][deno] module to support [Vim's Channel commands][vim's channel commands].
89

client.ts

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { Indexer } from "https://deno.land/x/[email protected]/mod.ts";
2+
import { buildMessage, Message } from "./message.ts";
3+
import {
4+
buildCallCommand,
5+
buildExCommand,
6+
buildExprCommand,
7+
buildNormalCommand,
8+
buildRedrawCommand,
9+
Command,
10+
} from "./command.ts";
11+
12+
const msgidThreshold = 2 ** 32;
13+
14+
type Session = {
15+
send: (data: Command | Message) => void;
16+
recv: (msgid: number) => Promise<Message>;
17+
};
18+
19+
/**
20+
* Client is a wrapper of Session to send commands and messages.
21+
*
22+
* @example
23+
* ```ts
24+
* import { assertNumber } from "https://deno.land/x/unknownutil/mod.ts";
25+
* import { channel } from "https://deno.land/x/streamtools/mod.ts";
26+
* import { Session, Client } from "./mod.ts";
27+
*
28+
* const input = channel<Uint8Array>();
29+
* const output = channel<Uint8Array>();
30+
* const session = new Session(input.reader, output.writer);
31+
* session.start();
32+
*
33+
* // Create a client
34+
* const client = new Client(session);
35+
*
36+
* // Send a ex command
37+
* client.ex("echo 'Hello, world!'");
38+
*
39+
* // Send a call command and wait for the result.
40+
* console.log(await client.call("abs", -1)); // 1
41+
* ```
42+
*/
43+
export class Client {
44+
#session: Session;
45+
#indexer: Indexer;
46+
47+
/**
48+
* Constructs a new client.
49+
*
50+
* Note that the indexer must be unique for each session to avoid message ID conflicts.
51+
* If multiple clients are created for a single session, specify a single indexer.
52+
*
53+
* @param {Session} session The session to communicate with.
54+
* @param {Indexer} indexer The indexer to generate message IDs.
55+
*/
56+
constructor(session: Session, indexer?: Indexer) {
57+
this.#session = session;
58+
this.#indexer = indexer ?? new Indexer(msgidThreshold);
59+
}
60+
61+
#nextMsgid(): number {
62+
// The msgid must be a negative number to avoid confusion with message that Vim sends.
63+
// https://github.com/vim/vim/blob/b848ce6b7e27f24aff47a4d63933e0f96663acfe/runtime/doc/channel.txt#L379-L381
64+
return (this.#indexer.next() + 1) * -1;
65+
}
66+
67+
async #recv(msgid: number): Promise<unknown> {
68+
const [_, response] = await this.#session.recv(msgid);
69+
return response;
70+
}
71+
72+
/**
73+
* Sends a message to Vim.
74+
*
75+
* @param {number} msgid The message ID.
76+
* @param {unknown} value The value to send.
77+
*/
78+
reply(msgid: number, value: unknown): void {
79+
const message = buildMessage(msgid, value);
80+
this.#session.send(message);
81+
}
82+
83+
/**
84+
* Sends a redraw command to Vim.
85+
*
86+
* @param {boolean} force Whether to force redraw.
87+
*/
88+
redraw(force = false): void {
89+
const command = buildRedrawCommand(force);
90+
this.#session.send(command);
91+
}
92+
93+
/**
94+
* Sends an ex command to Vim.
95+
*
96+
* @param {string} expr The expression to evaluate.
97+
*/
98+
ex(expr: string): void {
99+
const command = buildExCommand(expr);
100+
this.#session.send(command);
101+
}
102+
103+
/**
104+
* Sends a normal command to Vim.
105+
*
106+
* @param {string} expr The expression to evaluate.
107+
*/
108+
normal(expr: string): void {
109+
const command = buildNormalCommand(expr);
110+
this.#session.send(command);
111+
}
112+
113+
/**
114+
* Sends an expr command to Vim and wait for the result.
115+
*
116+
* @param {string} expr The expression to evaluate.
117+
* @returns {Promise<unknown>} The result of the expression.
118+
*/
119+
expr(expr: string): Promise<unknown> {
120+
const msgid = this.#nextMsgid();
121+
const command = buildExprCommand(expr, msgid);
122+
this.#session.send(command);
123+
return this.#recv(msgid);
124+
}
125+
126+
/**
127+
* Sends an expr command to Vim.
128+
*
129+
* @param {string} expr The expression to evaluate.
130+
*/
131+
exprNoReply(expr: string): void {
132+
const command = buildExprCommand(expr);
133+
this.#session.send(command);
134+
}
135+
136+
/**
137+
* Sends a call command to Vim and wait for the result.
138+
*
139+
* @param {string} fn The function name to call.
140+
* @param {unknown[]} args The arguments to pass to the function.
141+
* @returns {Promise<unknown>} The result of the function.
142+
*/
143+
call(fn: string, ...args: unknown[]): Promise<unknown> {
144+
const msgid = this.#nextMsgid();
145+
const command = buildCallCommand(fn, args, msgid);
146+
this.#session.send(command);
147+
return this.#recv(msgid);
148+
}
149+
150+
/**
151+
* Sends a call command to Vim.
152+
*
153+
* @param {string} fn The function name to call.
154+
* @param {unknown[]} args The arguments to pass to the function.
155+
*/
156+
callNoReply(fn: string, ...args: unknown[]): void {
157+
const command = buildCallCommand(fn, args);
158+
this.#session.send(command);
159+
}
160+
}

0 commit comments

Comments
 (0)