Skip to content

Commit d284157

Browse files
authored
Merge pull request #50 from vim-denops/echo
πŸ‘ Add `echo` function to `helper` module
2 parents 25f2b60 + d38dfc4 commit d284157

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

β€Ždenops_std/deps.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * as fs from "https://deno.land/std@0.100.0/fs/mod.ts#^";
22
export * as hash from "https://deno.land/std@0.100.0/hash/mod.ts#^";
33
export * as path from "https://deno.land/std@0.100.0/path/mod.ts#^";
4+
export { deferred } from "https://deno.land/std@0.100.0/async/mod.ts#^";
45

56
export * from "https://deno.land/x/denops_core@v1.0.0-beta.3/mod.ts#^";

β€Ždenops_std/helper/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@
66

77
## Usage
88

9+
### echo
10+
11+
Use `echo()` to show messages on the cmdline area. It is required while Vim
12+
won't show messages reported from channel commands and it won't pause multi-line
13+
messages reported from asynchronous context (e.g. timer or job). It's same for
14+
`denops.cmd('echo "Hello\nWorld!"')` in Neovim.
15+
16+
Note that there is no similar function for `echomsg` while there is no way to
17+
properly show multi-line messages with `echomsg` from asynchronous context.
18+
19+
```typescript
20+
import { Denops } from "https://deno.land/x/denops_std/mod.ts";
21+
import { echo } from "https://deno.land/x/denops_std/helper/mod.ts";
22+
23+
export async function main(denops: Denops): Promise<void> {
24+
await echo(denops, "Hello\nWorld!");
25+
}
26+
```
27+
928
### batch
1029

1130
Use `batch()` to call multiple denops functions sequentially without overhead

β€Ždenops_std/helper/echo.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { deferred, Denops } from "../deps.ts";
2+
import * as anonymous from "../anonymous/mod.ts";
3+
import { execute } from "./execute.ts";
4+
5+
let defined = false;
6+
7+
/**
8+
* Echo message as like `echo` on Vim script.
9+
*
10+
* Vim (not Neovim) won't show message posted from a channel command
11+
* and Vim won't pause multiline message posted from timer.
12+
* This function applied some workaround to show message posted from
13+
* a channel command, and pause if the message is multiline.
14+
*
15+
* Note that it does nothing and return immediately when denops is
16+
* running as 'test' mode to avoid unwilling test failures.
17+
*/
18+
export function echo(denops: Denops, message: string): Promise<void> {
19+
if (denops.meta.mode === "test") {
20+
return Promise.resolve();
21+
} else if (denops.meta.host === "vim") {
22+
return echoVim(denops, message);
23+
} else {
24+
return denops.cmd("redraw | echo message", { message });
25+
}
26+
}
27+
28+
async function echoVim(denops: Denops, message: string): Promise<void> {
29+
const waiter = deferred<void>();
30+
const id = anonymous.once(denops, () => waiter.resolve())[0];
31+
await define(denops);
32+
await denops.cmd(
33+
`call timer_start(0, { -> s:denops_std_helper_echo(l:message, l:name, l:id) })`,
34+
{
35+
message,
36+
name: denops.name,
37+
id,
38+
},
39+
);
40+
await waiter;
41+
}
42+
43+
async function define(denops: Denops): Promise<void> {
44+
if (defined) {
45+
return;
46+
}
47+
await execute(
48+
denops,
49+
`
50+
if exists('s:loaded_denops_std_helper_echo')
51+
return
52+
endif
53+
let s:loaded_denops_std_helper_echo = 1
54+
function! s:denops_std_helper_echo(message, name, id) abort
55+
let info = {}
56+
let info.t = timer_start(0, { -> feedkeys('jk', 'n') })
57+
let info.name = a:name
58+
let info.id = a:id
59+
let info.message = a:message
60+
let info.updatetime = &updatetime
61+
let &updatetime = 1
62+
let s:denops_std_helper_echo_info = info
63+
augroup denops_std_helper_echo
64+
autocmd!
65+
autocmd CursorHold * ++once call s:denops_std_helper_echo_post()
66+
augroup END
67+
endfunction
68+
function! s:denops_std_helper_echo_post() abort
69+
let info = s:denops_std_helper_echo_info
70+
silent! unlet! s:denops_std_helper_echo_info
71+
let &updatetime = info.updatetime
72+
call timer_stop(info.t)
73+
redraw | echo info.message
74+
call denops#request(info.name, info.id, [])
75+
endfunction
76+
`,
77+
);
78+
defined = true;
79+
}

β€Ždenops_std/helper/echo_test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { test } from "../deps_test.ts";
2+
import { echo } from "./echo.ts";
3+
4+
test({
5+
mode: "all",
6+
name: "echo() shows short message",
7+
fn: async (denops) => {
8+
await echo(denops, "Hello");
9+
// No way to test if `echo` success
10+
},
11+
});
12+
13+
test({
14+
mode: "all",
15+
name: "echo() shows multiline message",
16+
fn: async (denops) => {
17+
await denops.cmd("set cmdheight=5");
18+
await echo(denops, "A\nB\nC\nD\nE");
19+
// No way to test if `echo` success
20+
},
21+
});

0 commit comments

Comments
Β (0)