Skip to content

Commit d05258e

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents 1b15a71 + 0945eaf commit d05258e

File tree

9 files changed

+71
-16
lines changed

9 files changed

+71
-16
lines changed

runtime/doc/channel.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,11 @@ This uses the channel timeout. To read without a timeout, just get any
418418
message that is available: >
419419
let output = ch_read(channel, {'timeout': 0})
420420
When no message was available then the result is v:none for a JSON or JS mode
421-
channels, an empty string for a RAW or NL channel.
421+
channels, an empty string for a RAW or NL channel. You can use |ch_canread()|
422+
to check if there is something to read.
423+
424+
Note that when there is no callback message are dropped. To avoid that add a
425+
close callback to the channel.
422426

423427
To read all output from a RAW channel that is available: >
424428
let output = ch_readraw(channel)
@@ -470,6 +474,11 @@ This depends on the system (on Unix this happens because closing the write end
470474
of a pipe causes the read end to get EOF). To avoid this make the job sleep
471475
for a short while before it exits.
472476

477+
Note that if the job exits before you read the output, the output may be lost.
478+
This depends on the system (on Unix this happens because closing the write end
479+
of a pipe causes the read end to get EOF). To avoid this make the job sleep
480+
for a short while before it exits.
481+
473482
The handler defined for "out_cb" will not receive stderr. If you want to
474483
handle that separately, add an "err_cb" handler: >
475484
let job = job_start(command, {"out_cb": "MyHandler",

runtime/doc/eval.txt

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,7 @@ byteidxcomp({expr}, {nr}) Number byte index of {nr}'th char in {expr}
20092009
call({func}, {arglist} [, {dict}])
20102010
any call {func} with arguments {arglist}
20112011
ceil({expr}) Float round {expr} up
2012+
ch_canread({handle}) Number check if there is something to read
20122013
ch_close({handle}) none close {handle}
20132014
ch_close_in({handle}) none close in part of {handle}
20142015
ch_evalexpr({handle}, {expr} [, {options}])
@@ -2980,16 +2981,28 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
29802981
don't fit, a vertical layout is used anyway. For some systems
29812982
the horizontal layout is always used.
29822983

2984+
ch_canread({handle}) *ch_canread()*
2985+
Return non-zero when there is something to read from {handle}.
2986+
{handle} can be a Channel or a Job that has a Channel.
2987+
2988+
This is useful to read from a channel at a convenient time,
2989+
e.g. from a timer.
2990+
2991+
Note that messages are dropped when the channel does not have
2992+
a callback. Add a close callback to avoid that.
2993+
2994+
{only available when compiled with the |+channel| feature}
2995+
29832996
ch_close({handle}) *ch_close()*
29842997
Close {handle}. See |channel-close|.
2985-
{handle} can be Channel or a Job that has a Channel.
2998+
{handle} can be a Channel or a Job that has a Channel.
29862999
A close callback is not invoked.
29873000

29883001
{only available when compiled with the |+channel| feature}
29893002

29903003
ch_close_in({handle}) *ch_close_in()*
29913004
Close the "in" part of {handle}. See |channel-close-in|.
2992-
{handle} can be Channel or a Job that has a Channel.
3005+
{handle} can be a Channel or a Job that has a Channel.
29933006
A close callback is not invoked.
29943007

29953008
{only available when compiled with the |+channel| feature}
@@ -2998,7 +3011,7 @@ ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
29983011
Send {expr} over {handle}. The {expr} is encoded
29993012
according to the type of channel. The function cannot be used
30003013
with a raw channel. See |channel-use|.
3001-
{handle} can be Channel or a Job that has a Channel.
3014+
{handle} can be a Channel or a Job that has a Channel.
30023015
*E917*
30033016
{options} must be a Dictionary. It must not have a "callback"
30043017
entry. It can have a "timeout" entry to specify the timeout
@@ -3012,7 +3025,7 @@ ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
30123025

30133026
ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
30143027
Send {string} over {handle}.
3015-
{handle} can be Channel or a Job that has a Channel.
3028+
{handle} can be a Channel or a Job that has a Channel.
30163029

30173030
Works like |ch_evalexpr()|, but does not encode the request or
30183031
decode the response. The caller is responsible for the
@@ -3025,7 +3038,7 @@ ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
30253038

30263039
ch_getbufnr({handle}, {what}) *ch_getbufnr()*
30273040
Get the buffer number that {handle} is using for {what}.
3028-
{handle} can be Channel or a Job that has a Channel.
3041+
{handle} can be a Channel or a Job that has a Channel.
30293042
{what} can be "err" for stderr, "out" for stdout or empty for
30303043
socket output.
30313044
Returns -1 when there is no buffer.
@@ -3099,7 +3112,7 @@ ch_open({address} [, {options}]) *ch_open()*
30993112

31003113
ch_read({handle} [, {options}]) *ch_read()*
31013114
Read from {handle} and return the received message.
3102-
{handle} can be Channel or a Job that has a Channel.
3115+
{handle} can be a Channel or a Job that has a Channel.
31033116
See |channel-more|.
31043117
{only available when compiled with the |+channel| feature}
31053118

@@ -3113,7 +3126,7 @@ ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
31133126
according to the type of channel. The function cannot be used
31143127
with a raw channel.
31153128
See |channel-use|. *E912*
3116-
{handle} can be Channel or a Job that has a Channel.
3129+
{handle} can be a Channel or a Job that has a Channel.
31173130

31183131
{only available when compiled with the |+channel| feature}
31193132

@@ -3134,7 +3147,7 @@ ch_setoptions({handle}, {options}) *ch_setoptions()*
31343147
"timeout" default read timeout in msec
31353148
"mode" mode for the whole channel
31363149
See |ch_open()| for more explanation.
3137-
{handle} can be Channel or a Job that has a Channel.
3150+
{handle} can be a Channel or a Job that has a Channel.
31383151

31393152
Note that changing the mode may cause queued messages to be
31403153
lost.
@@ -3148,7 +3161,7 @@ ch_status({handle} [, {options}]) *ch_status()*
31483161
"open" channel can be used
31493162
"buffered" channel can be read, not written to
31503163
"closed" channel can not be used
3151-
{handle} can be Channel or a Job that has a Channel.
3164+
{handle} can be a Channel or a Job that has a Channel.
31523165
"buffered" is used when the channel was closed but there is
31533166
still data that can be obtained with |ch_read()|.
31543167

src/channel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2624,7 +2624,7 @@ channel_is_open(channel_T *channel)
26242624
/*
26252625
* Return TRUE if "channel" has JSON or other typeahead.
26262626
*/
2627-
static int
2627+
int
26282628
channel_has_readahead(channel_T *channel, ch_part_T part)
26292629
{
26302630
ch_mode_T ch_mode = channel->ch_part[part].ch_mode;

src/evalfunc.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static void f_call(typval_T *argvars, typval_T *rettv);
7676
static void f_ceil(typval_T *argvars, typval_T *rettv);
7777
#endif
7878
#ifdef FEAT_JOB_CHANNEL
79+
static void f_ch_canread(typval_T *argvars, typval_T *rettv);
7980
static void f_ch_close(typval_T *argvars, typval_T *rettv);
8081
static void f_ch_close_in(typval_T *argvars, typval_T *rettv);
8182
static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
@@ -499,6 +500,7 @@ static struct fst
499500
{"ceil", 1, 1, f_ceil},
500501
#endif
501502
#ifdef FEAT_JOB_CHANNEL
503+
{"ch_canread", 1, 1, f_ch_canread},
502504
{"ch_close", 1, 1, f_ch_close},
503505
{"ch_close_in", 1, 1, f_ch_close_in},
504506
{"ch_evalexpr", 2, 3, f_ch_evalexpr},
@@ -1778,6 +1780,21 @@ f_ceil(typval_T *argvars, typval_T *rettv)
17781780
#endif
17791781

17801782
#ifdef FEAT_JOB_CHANNEL
1783+
/*
1784+
* "ch_canread()" function
1785+
*/
1786+
static void
1787+
f_ch_canread(typval_T *argvars, typval_T *rettv)
1788+
{
1789+
channel_T *channel = get_channel_arg(&argvars[0], TRUE, TRUE, 0);
1790+
1791+
rettv->vval.v_number = 0;
1792+
if (channel != NULL)
1793+
rettv->vval.v_number = channel_has_readahead(channel, PART_SOCK)
1794+
|| channel_has_readahead(channel, PART_OUT)
1795+
|| channel_has_readahead(channel, PART_ERR);
1796+
}
1797+
17811798
/*
17821799
* "ch_close()" function
17831800
*/

src/option.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5972,9 +5972,11 @@ did_set_string_option(
59725972

59735973
/* Check for a "normal" directory or file name in some options. Disallow a
59745974
* path separator (slash and/or backslash), wildcards and characters that
5975-
* are often illegal in a file name. */
5975+
* are often illegal in a file name. Be more permissive if "secure" is off.
5976+
*/
59765977
else if (((options[opt_idx].flags & P_NFNAME)
5977-
&& vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL)
5978+
&& vim_strpbrk(*varp, (char_u *)(secure
5979+
? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
59785980
|| ((options[opt_idx].flags & P_NDNAME)
59795981
&& vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL))
59805982
{

src/proto/channel.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ void channel_consume(channel_T *channel, ch_part_T part, int len);
2525
int channel_collapse(channel_T *channel, ch_part_T part, int want_nl);
2626
int channel_can_write_to(channel_T *channel);
2727
int channel_is_open(channel_T *channel);
28+
int channel_has_readahead(channel_T *channel, ch_part_T part);
2829
char *channel_status(channel_T *channel, int req_part);
2930
void channel_info(channel_T *channel, dict_T *dict);
3031
void channel_close(channel_T *channel, int invoke_close_cb);

src/testdir/shared.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func RunServer(cmd, testfunc, args)
8888

8989
call call(function(a:testfunc), [port])
9090
catch
91-
call assert_false(1, "Caught exception: " . v:exception)
91+
call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
9292
finally
9393
call s:kill_server(a:cmd)
9494
endtry

src/testdir/test_channel.vim

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ func Ch_communicate(port)
5858
" string with ][ should work
5959
call assert_equal('this][that', ch_evalexpr(handle, 'echo this][that'))
6060

61+
" nothing to read now
62+
call assert_equal(0, ch_canread(handle))
63+
6164
" sending three messages quickly then reading should work
6265
for i in range(3)
6366
call ch_sendexpr(handle, 'echo hello ' . i)
@@ -368,7 +371,7 @@ func Ch_raw_one_time_callback(port)
368371
endif
369372
call ch_setoptions(handle, {'mode': 'raw'})
370373

371-
" The message are sent raw, we do our own JSON strings here.
374+
" The messages are sent raw, we do our own JSON strings here.
372375
call ch_sendraw(handle, "[1, \"hello!\"]\n", {'callback': 'Ch_handleRaw1'})
373376
call WaitFor('g:Ch_reply1 != ""')
374377
call assert_equal("[1, \"got it\"]", g:Ch_reply1)
@@ -431,7 +434,10 @@ func Test_raw_pipe()
431434
return
432435
endif
433436
call ch_log('Test_raw_pipe()')
434-
let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
437+
" Add a dummy close callback to avoid that messages are dropped when calling
438+
" ch_canread().
439+
let job = job_start(s:python . " test_channel_pipe.py",
440+
\ {'mode': 'raw', 'close_cb': {chan -> 0}})
435441
call assert_equal(v:t_job, type(job))
436442
call assert_equal("run", job_status(job))
437443

@@ -458,6 +464,9 @@ func Test_raw_pipe()
458464
call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
459465

460466
call ch_sendraw(job, "double this\n")
467+
let g:handle = job_getchannel(job)
468+
call WaitFor('ch_canread(g:handle)')
469+
unlet g:handle
461470
let msg = ch_readraw(job)
462471
call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
463472

src/version.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,10 @@ static char *(features[]) =
779779

780780
static int included_patches[] =
781781
{ /* Add new patch number below this line */
782+
/**/
783+
106,
784+
/**/
785+
105,
782786
/**/
783787
104,
784788
/**/

0 commit comments

Comments
 (0)