|
| 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 | +} |
0 commit comments