@@ -4,6 +4,7 @@ import { batch } from "../batch/mod.ts";
4
4
import { generateUniqueString } from "../util.ts" ;
5
5
6
6
const cacheKey = Symbol ( "denops_std/helper/echo" ) ;
7
+ const cacheKeySilent = Symbol ( "denops_std/helper/echo/silent" ) ;
7
8
const suffix = generateUniqueString ( ) ;
8
9
9
10
async function ensurePrerequisites ( denops : Denops ) : Promise < string > {
@@ -13,9 +14,11 @@ async function ensurePrerequisites(denops: Denops): Promise<string> {
13
14
denops . context [ cacheKey ] = true ;
14
15
const script = `
15
16
let g:loaded_denops_std_helper_echo_${ suffix } = 1
17
+ let s:denops_std_helper_echo_timer = 0
16
18
17
19
function! DenopsStdHelperEcho_${ suffix } (message) abort
18
- call timer_start(0, { -> s:DenopsStdHelperEchoInternal_${ suffix } (a:message) })
20
+ call timer_stop(s:denops_std_helper_echo_timer)
21
+ let s:denops_std_helper_echo_timer = timer_start(0, { -> s:DenopsStdHelperEchoInternal_${ suffix } (a:message) })
19
22
endfunction
20
23
21
24
function! s:DenopsStdHelperEchoInternal_${ suffix } (message) abort
@@ -26,6 +29,39 @@ async function ensurePrerequisites(denops: Denops): Promise<string> {
26
29
return suffix ;
27
30
}
28
31
32
+ export type Silent = "" | "silent" | "silent!" ;
33
+
34
+ /**
35
+ * Get global silent status
36
+ */
37
+ export function getSilent ( denops : Denops ) : Silent {
38
+ return ( denops . context [ cacheKeySilent ] ?? "" ) as Silent ;
39
+ }
40
+
41
+ /**
42
+ * Set global silent status
43
+ */
44
+ export function setSilent ( denops : Denops , silent : Silent ) : void {
45
+ denops . context [ cacheKeySilent ] = silent ;
46
+ }
47
+
48
+ /**
49
+ * Ensure global silent status during given function
50
+ */
51
+ export async function ensureSilent < T > (
52
+ denops : Denops ,
53
+ silent : Silent ,
54
+ executor : ( ) => T ,
55
+ ) : Promise < T > {
56
+ const saved = denops . context [ cacheKeySilent ] ;
57
+ denops . context [ cacheKeySilent ] = silent ;
58
+ try {
59
+ return await executor ( ) ;
60
+ } finally {
61
+ denops . context [ cacheKeySilent ] = saved ;
62
+ }
63
+ }
64
+
29
65
/**
30
66
* Echo message as like `echo` on Vim script.
31
67
*
@@ -36,29 +72,68 @@ async function ensurePrerequisites(denops: Denops): Promise<string> {
36
72
*
37
73
* Note that it does nothing and return immediately when denops is
38
74
* running as 'test' mode to avoid unwilling test failures.
75
+ *
76
+ * WARNING:
77
+ * In order to make the behavior of Vim and Neovim consistent,
78
+ * `timer_start()` is used internally not only in Vim but also in
79
+ * Neovim. Note that this means that you cannot control the message
80
+ * by prepending `silent` when calling it from the Vim script.
81
+ * If you want to control the message, use the `setSilent` function
82
+ * to change the silent state to `'silent'` or `'silent!'` in
83
+ * advance, or use the `ensureSilent` function to fix the silent state
84
+ * to `'silent'` or `'silent!'` during execution of any function.
39
85
*/
40
- export function echo ( denops : Denops , message : string ) : Promise < void > {
86
+ export function echo (
87
+ denops : Denops ,
88
+ message : string ,
89
+ ) : Promise < void > {
90
+ const silent = getSilent ( denops ) ;
91
+ switch ( silent ) {
92
+ case "silent" :
93
+ case "silent!" :
94
+ return Promise . resolve ( ) ;
95
+ }
41
96
if ( denops . meta . mode === "test" ) {
42
97
return Promise . resolve ( ) ;
43
- } else if ( denops . meta . host === "vim" ) {
44
- return echoVim ( denops , message ) ;
45
98
} else {
46
- return denops . cmd ( "redraw | echo message" , { message } ) ;
99
+ return echoInternal ( denops , message ) ;
47
100
}
48
101
}
49
102
50
103
/**
51
104
* Echo message as an error message.
52
105
*
53
- * Note that this function just use ErrorMsg highlight and is not equivalent
54
- * to `echoerr` command in Vim/Neovim.
106
+ * Note that this function just use ErrorMsg highlight and is not
107
+ * equivalent to `echoerr` command in Vim/Neovim.
108
+ *
109
+ * WARNING:
110
+ * In order to make the behavior of Vim and Neovim consistent,
111
+ * `timer_start()` is used internally not only in Vim but also in
112
+ * Neovim. Note that this means that you cannot control the message
113
+ * by prepending `silent` when calling it from the Vim script.
114
+ * If you want to control the message, use the `setSilent` function
115
+ * to change the silent state to `'silent!'` in advance, or use the
116
+ * `ensureSilent` function to fix the silent state to `'silent!'`
117
+ * during execution of any function.
55
118
*/
56
- export async function echoerr ( denops : Denops , message : string ) : Promise < void > {
57
- await batch ( denops , async ( denops ) => {
58
- await denops . cmd ( "echohl ErrorMsg" ) ;
59
- await echo ( denops , message ) ;
60
- await denops . cmd ( "echohl None" ) ;
61
- } ) ;
119
+ export async function echoerr (
120
+ denops : Denops ,
121
+ message : string ,
122
+ ) : Promise < void > {
123
+ const silent = getSilent ( denops ) ;
124
+ switch ( silent ) {
125
+ case "silent!" :
126
+ return Promise . resolve ( ) ;
127
+ }
128
+ if ( denops . meta . mode === "test" ) {
129
+ return Promise . resolve ( ) ;
130
+ } else {
131
+ await batch ( denops , async ( denops ) => {
132
+ await denops . cmd ( "echohl ErrorMsg" ) ;
133
+ await echoInternal ( denops , message ) ;
134
+ await denops . cmd ( "echohl None" ) ;
135
+ } ) ;
136
+ }
62
137
}
63
138
64
139
/**
@@ -85,7 +160,7 @@ export async function friendlyCall(
85
160
}
86
161
}
87
162
88
- async function echoVim ( denops : Denops , message : string ) : Promise < void > {
163
+ async function echoInternal ( denops : Denops , message : string ) : Promise < void > {
89
164
const suffix = await ensurePrerequisites ( denops ) ;
90
165
await denops . call ( `DenopsStdHelperEcho_${ suffix } ` , message ) ;
91
166
}
0 commit comments