Skip to content

Commit 8b1862a

Browse files
committed
patch 7.4.1435
Problem: It is confusing that ch_sendexpr() and ch_sendraw() wait for a response. Solution: Add ch_evalexpr() and ch_evalraw().
1 parent b6ff811 commit 8b1862a

5 files changed

Lines changed: 179 additions & 69 deletions

File tree

runtime/doc/channel.txt

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*channel.txt* For Vim version 7.4. Last change: 2016 Feb 23
1+
*channel.txt* For Vim version 7.4. Last change: 2016 Feb 27
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -74,7 +74,7 @@ In T1 you should see:
7474
=== socket opened === ~
7575

7676
You can now send a message to the server: >
77-
echo ch_sendexpr(channel, 'hello!')
77+
echo ch_evalexpr(channel, 'hello!')
7878
7979
The message is received in T1 and a response is sent back to Vim.
8080
You can see the raw messages in T1. What Vim sends is:
@@ -101,7 +101,7 @@ Instead of giving a callback with every send call, it can also be specified
101101
when opening the channel: >
102102
call ch_close(channel)
103103
let channel = ch_open('localhost:8765', {'callback': "MyHandler"})
104-
call ch_sendexpr(channel, 'hello!', {'callback': 0})
104+
call ch_sendexpr(channel, 'hello!')
105105
106106
==============================================================================
107107
3. Opening a channel *channel-open*
@@ -171,7 +171,7 @@ Use |ch_status()| to see if the channel could be opened.
171171
msec at least.
172172

173173
"timeout" The time to wait for a request when blocking, E.g. when using
174-
ch_sendexpr(). In milliseconds. The default is 2000 (2
174+
ch_evalexpr(). In milliseconds. The default is 2000 (2
175175
seconds).
176176
*out-timeout* *err-timeout*
177177
"out-timeout" Timeout for stdout. Only when using pipes.
@@ -214,15 +214,15 @@ If there is an error reading or writing a channel it will be closed.
214214
4. Using a JSON or JS channel *channel-use*
215215

216216
If mode is JSON then a message can be sent synchronously like this: >
217-
let response = ch_sendexpr(channel, {expr})
217+
let response = ch_evalexpr(channel, {expr})
218218
This awaits a response from the other side.
219219

220220
When mode is JS this works the same, except that the messages use
221221
JavaScript encoding. See |js_encode()| for the difference.
222222

223223
To send a message, without handling a response or letting the channel callback
224224
handle the response: >
225-
call ch_sendexpr(channel, {expr}, {'callback': 0})
225+
call ch_sendexpr(channel, {expr})
226226
227227
To send a message and letting the response handled by a specific function,
228228
asynchronously: >
@@ -263,8 +263,9 @@ On read error or ch_close(), when using a socket, the string "DETACH" is sent,
263263
if still possible. The channel will then be inactive. For a JSON and JS mode
264264
channel quotes are used around DETACH, otherwise there are no quotes.
265265

266-
It is also possible to use ch_sendraw() on a JSON or JS channel. The caller
267-
is then completely responsible for correct encoding and decoding.
266+
It is also possible to use ch_sendraw() and ch_evalraw() on a JSON or JS
267+
channel. The caller is then completely responsible for correct encoding and
268+
decoding.
268269

269270
==============================================================================
270271
5. Channel commands *channel-commands*
@@ -363,7 +364,7 @@ Leave out the fourth argument if no response is to be sent:
363364
6. Using a RAW or NL channel *channel-raw*
364365

365366
If mode is RAW or NL then a message can be send like this: >
366-
let response = ch_sendraw(channel, {string})
367+
let response = ch_evalraw(channel, {string})
367368
368369
The {string} is sent as-is. The response will be what can be read from the
369370
channel right away. Since Vim doesn't know how to recognize the end of the
@@ -377,18 +378,18 @@ first NL. This can also be just the NL for an empty response.
377378
If no NL was read before the channel timeout an empty string is returned.
378379

379380
To send a message, without expecting a response: >
380-
call ch_sendraw(channel, {string}, 0)
381+
call ch_sendraw(channel, {string})
381382
The process can send back a response, the channel handler will be called with
382383
it.
383384

384385
To send a message and letting the response handled by a specific function,
385386
asynchronously: >
386-
call ch_sendraw(channel, {string}, {callback})
387+
call ch_sendraw(channel, {string}, {'callback': 'MyHandler'})
387388
388389
This {string} can also be JSON, use |json_encode()| to create it and
389390
|json_decode()| to handle a received JSON message.
390391

391-
It is not possible to use |ch_sendexpr()| on a raw channel.
392+
It is not possible to use |ch_evalexpr()| or |ch_sendexpr()| on a raw channel.
392393

393394
==============================================================================
394395
7. More channel functions *channel-more*
@@ -447,8 +448,8 @@ If you want to handle both stderr and stdout with one handler use the
447448
"callback" option: >
448449
let job = job_start(command, {"callback": "MyHandler"})
449450
450-
You can send a message to the command with ch_sendraw(). If the channel is in
451-
JSON or JS mode you can use ch_sendexpr().
451+
You can send a message to the command with ch_evalraw(). If the channel is in
452+
JSON or JS mode you can use ch_evalexpr().
452453

453454
There are several options you can use, see |job-options|.
454455
For example, to start a job and write its output in buffer "dummy": >

runtime/doc/eval.txt

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,10 @@ call( {func}, {arglist} [, {dict}])
18181818
any call {func} with arguments {arglist}
18191819
ceil( {expr}) Float round {expr} up
18201820
ch_close( {channel}) none close {channel}
1821+
ch_evalexpr( {channel}, {expr} [, {options}])
1822+
any evaluate {expr} on JSON {channel}
1823+
ch_evalraw( {channel}, {string} [, {options}])
1824+
any evaluate {string} on raw {channel}
18211825
ch_getjob( {channel}) Job get the Job of {channel}
18221826
ch_log( {msg} [, {channel}]) none write {msg} in the channel log file
18231827
ch_logfile( {fname} [, {mode}]) none start logging channel activity
@@ -2692,6 +2696,31 @@ ch_close({channel}) *ch_close()*
26922696
Close {channel}. See |channel-close|.
26932697
{only available when compiled with the |+channel| feature}
26942698

2699+
ch_evalexpr({channel}, {expr} [, {options}]) *ch_evalexpr()*
2700+
Send {expr} over {channel}. The {expr} is encoded
2701+
according to the type of channel. The function cannot be used
2702+
with a raw channel. See |channel-use|. *E912*
2703+
*E917*
2704+
{options} must be a Dictionary. It must not have a "callback"
2705+
entry.
2706+
2707+
ch_evalexpr() waits for a response and returns the decoded
2708+
expression. When there is an error or timeout it returns an
2709+
empty string.
2710+
2711+
{only available when compiled with the |+channel| feature}
2712+
2713+
ch_evalraw({channel}, {string} [, {options}]) *ch_evalraw()*
2714+
Send {string} over {channel}.
2715+
Works like |ch_evalexpr()|, but does not encode the request or
2716+
decode the response. The caller is responsible for the
2717+
correct contents. Also does not add a newline for a channel
2718+
in NL mode, the caller must do that. The NL in the response
2719+
is removed.
2720+
See |channel-use|.
2721+
2722+
{only available when compiled with the |+channel| feature}
2723+
26952724
ch_getjob({channel}) *ch_getjob()*
26962725
Get the Job associated with {channel}.
26972726
If there is no job calling |job_status()| on the returned Job
@@ -2769,16 +2798,11 @@ ch_sendexpr({channel}, {expr} [, {options}]) *ch_sendexpr()*
27692798
according to the type of channel. The function cannot be used
27702799
with a raw channel. See |channel-use|. *E912*
27712800

2772-
{options} must be a Dictionary.
2773-
When "callback" is a Funcref or the name of a function,
2774-
ch_sendexpr() returns immediately. The callback is invoked
2775-
when the response is received. See |channel-callback|.
2776-
2777-
Without "callback" ch_sendexpr() waits for a response and
2778-
returns the decoded expression. When there is an error or
2779-
timeout it returns an empty string.
2780-
2781-
When "callback" is zero no response is expected.
2801+
{options} must be a Dictionary. The "callback" item is a
2802+
Funcref or the name of a function it is invoked when the
2803+
response is received. See |channel-callback|.
2804+
Without "callback" the channel handler is invoked, otherwise
2805+
any received message is dropped.
27822806

27832807
{only available when compiled with the |+channel| feature}
27842808

@@ -7391,7 +7415,6 @@ scrollbind Compiled with 'scrollbind' support.
73917415
showcmd Compiled with 'showcmd' support.
73927416
signs Compiled with |:sign| support.
73937417
smartindent Compiled with 'smartindent' support.
7394-
sniff Compiled with SNiFF interface support.
73957418
spell Compiled with spell checking support |spell|.
73967419
startuptime Compiled with |--startuptime| support.
73977420
statusline Compiled with support for 'statusline', 'rulerformat'

src/eval.c

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,8 @@ static void f_ceil(typval_T *argvars, typval_T *rettv);
507507
#endif
508508
#ifdef FEAT_CHANNEL
509509
static void f_ch_close(typval_T *argvars, typval_T *rettv);
510+
static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
511+
static void f_ch_evalraw(typval_T *argvars, typval_T *rettv);
510512
# ifdef FEAT_JOB
511513
static void f_ch_getjob(typval_T *argvars, typval_T *rettv);
512514
# endif
@@ -8201,6 +8203,8 @@ static struct fst
82018203
#endif
82028204
#ifdef FEAT_CHANNEL
82038205
{"ch_close", 1, 1, f_ch_close},
8206+
{"ch_evalexpr", 2, 3, f_ch_evalexpr},
8207+
{"ch_evalraw", 2, 3, f_ch_evalraw},
82048208
# ifdef FEAT_JOB
82058209
{"ch_getjob", 1, 1, f_ch_getjob},
82068210
# endif
@@ -10485,7 +10489,13 @@ f_ch_readraw(typval_T *argvars, typval_T *rettv)
1048510489
* Otherwise returns NULL.
1048610490
*/
1048710491
static channel_T *
10488-
send_common(typval_T *argvars, char_u *text, int id, char *fun, int *part_read)
10492+
send_common(
10493+
typval_T *argvars,
10494+
char_u *text,
10495+
int id,
10496+
int eval,
10497+
char *fun,
10498+
int *part_read)
1048910499
{
1049010500
channel_T *channel;
1049110501
jobopt_T opt;
@@ -10502,9 +10512,17 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun, int *part_read)
1050210512
return NULL;
1050310513

1050410514
/* Set the callback. An empty callback means no callback and not reading
10505-
* the response. */
10515+
* the response. With "ch_evalexpr()" and "ch_evalraw()" a callback is not
10516+
* allowed. */
1050610517
if (opt.jo_callback != NULL && *opt.jo_callback != NUL)
10518+
{
10519+
if (eval)
10520+
{
10521+
EMSG2(_("E917: Cannot use a callback with %s()"), fun);
10522+
return NULL;
10523+
}
1050710524
channel_set_req_callback(channel, part_send, opt.jo_callback, id);
10525+
}
1050810526

1050910527
if (channel_send(channel, part_send, text, fun) == OK
1051010528
&& opt.jo_callback == NULL)
@@ -10513,10 +10531,10 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun, int *part_read)
1051310531
}
1051410532

1051510533
/*
10516-
* "ch_sendexpr()" function
10534+
* common for "ch_evalexpr()" and "ch_sendexpr()"
1051710535
*/
1051810536
static void
10519-
f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
10537+
ch_expr_common(typval_T *argvars, typval_T *rettv, int eval)
1052010538
{
1052110539
char_u *text;
1052210540
typval_T *listtv;
@@ -10539,7 +10557,7 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
1053910557
ch_mode = channel_get_mode(channel, part_send);
1054010558
if (ch_mode == MODE_RAW || ch_mode == MODE_NL)
1054110559
{
10542-
EMSG(_("E912: cannot use ch_sendexpr() with a raw or nl channel"));
10560+
EMSG(_("E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"));
1054310561
return;
1054410562
}
1054510563

@@ -10549,9 +10567,10 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
1054910567
if (text == NULL)
1055010568
return;
1055110569

10552-
channel = send_common(argvars, text, id, "sendexpr", &part_read);
10570+
channel = send_common(argvars, text, id, eval,
10571+
eval ? "ch_evalexpr" : "ch_sendexpr", &part_read);
1055310572
vim_free(text);
10554-
if (channel != NULL)
10573+
if (channel != NULL && eval)
1055510574
{
1055610575
/* TODO: timeout from options */
1055710576
timeout = channel_get_timeout(channel, part_read);
@@ -10570,10 +10589,28 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
1057010589
}
1057110590

1057210591
/*
10573-
* "ch_sendraw()" function
10592+
* "ch_evalexpr()" function
1057410593
*/
1057510594
static void
10576-
f_ch_sendraw(typval_T *argvars, typval_T *rettv)
10595+
f_ch_evalexpr(typval_T *argvars, typval_T *rettv)
10596+
{
10597+
ch_expr_common(argvars, rettv, TRUE);
10598+
}
10599+
10600+
/*
10601+
* "ch_sendexpr()" function
10602+
*/
10603+
static void
10604+
f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
10605+
{
10606+
ch_expr_common(argvars, rettv, FALSE);
10607+
}
10608+
10609+
/*
10610+
* common for "ch_evalraw()" and "ch_sendraw()"
10611+
*/
10612+
static void
10613+
ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
1057710614
{
1057810615
char_u buf[NUMBUFLEN];
1057910616
char_u *text;
@@ -10586,15 +10623,34 @@ f_ch_sendraw(typval_T *argvars, typval_T *rettv)
1058610623
rettv->vval.v_string = NULL;
1058710624

1058810625
text = get_tv_string_buf(&argvars[1], buf);
10589-
channel = send_common(argvars, text, 0, "sendraw", &part_read);
10590-
if (channel != NULL)
10626+
channel = send_common(argvars, text, 0, eval,
10627+
eval ? "ch_evalraw" : "ch_sendraw", &part_read);
10628+
if (channel != NULL && eval)
1059110629
{
1059210630
/* TODO: timeout from options */
1059310631
timeout = channel_get_timeout(channel, part_read);
1059410632
rettv->vval.v_string = channel_read_block(channel, part_read, timeout);
1059510633
}
1059610634
}
1059710635

10636+
/*
10637+
* "ch_evalraw()" function
10638+
*/
10639+
static void
10640+
f_ch_evalraw(typval_T *argvars, typval_T *rettv)
10641+
{
10642+
ch_raw_common(argvars, rettv, TRUE);
10643+
}
10644+
10645+
/*
10646+
* "ch_sendraw()" function
10647+
*/
10648+
static void
10649+
f_ch_sendraw(typval_T *argvars, typval_T *rettv)
10650+
{
10651+
ch_raw_common(argvars, rettv, FALSE);
10652+
}
10653+
1059810654
/*
1059910655
* "ch_setoptions()" function
1060010656
*/

0 commit comments

Comments
 (0)