patch 8.0.0015
Problem: Can't tell which part of a channel has "buffered" status.
Solution: Add an optional argument to ch_status(). Let ch_info() also
return "buffered" for out_status and err_status.
diff --git a/src/channel.c b/src/channel.c
index f4d1e95..0bab47a 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2590,23 +2590,41 @@
/*
* Return a string indicating the status of the channel.
+ * If "req_part" is not negative check that part.
*/
char *
-channel_status(channel_T *channel)
+channel_status(channel_T *channel, int req_part)
{
int part;
int has_readahead = FALSE;
if (channel == NULL)
return "fail";
- if (channel_is_open(channel))
- return "open";
- for (part = PART_SOCK; part <= PART_ERR; ++part)
- if (channel_has_readahead(channel, part))
- {
+ if (req_part == PART_OUT)
+ {
+ if (channel->CH_OUT_FD != INVALID_FD)
+ return "open";
+ if (channel_has_readahead(channel, PART_OUT))
has_readahead = TRUE;
- break;
- }
+ }
+ else if (req_part == PART_ERR)
+ {
+ if (channel->CH_ERR_FD != INVALID_FD)
+ return "open";
+ if (channel_has_readahead(channel, PART_ERR))
+ has_readahead = TRUE;
+ }
+ else
+ {
+ if (channel_is_open(channel))
+ return "open";
+ for (part = PART_SOCK; part <= PART_ERR; ++part)
+ if (channel_has_readahead(channel, part))
+ {
+ has_readahead = TRUE;
+ break;
+ }
+ }
if (has_readahead)
return "buffered";
@@ -2619,6 +2637,7 @@
chanpart_T *chanpart = &channel->ch_part[part];
char namebuf[20]; /* longest is "sock_timeout" */
size_t tail;
+ char *status;
char *s = "";
vim_strncpy((char_u *)namebuf, (char_u *)name, 4);
@@ -2626,8 +2645,13 @@
tail = STRLEN(namebuf);
STRCPY(namebuf + tail, "status");
- dict_add_nr_str(dict, namebuf, 0,
- (char_u *)(chanpart->ch_fd == INVALID_FD ? "closed" : "open"));
+ if (chanpart->ch_fd != INVALID_FD)
+ status = "open";
+ else if (channel_has_readahead(channel, part))
+ status = "buffered";
+ else
+ status = "closed";
+ dict_add_nr_str(dict, namebuf, 0, (char_u *)status);
STRCPY(namebuf + tail, "mode");
switch (chanpart->ch_mode)
@@ -2660,7 +2684,7 @@
channel_info(channel_T *channel, dict_T *dict)
{
dict_add_nr_str(dict, "id", channel->ch_id, NULL);
- dict_add_nr_str(dict, "status", 0, (char_u *)channel_status(channel));
+ dict_add_nr_str(dict, "status", 0, (char_u *)channel_status(channel, -1));
if (channel->ch_hostname != NULL)
{
@@ -4244,6 +4268,8 @@
val = get_tv_string(item);
if (STRCMP(val, "err") == 0)
opt->jo_part = PART_ERR;
+ else if (STRCMP(val, "out") == 0)
+ opt->jo_part = PART_OUT;
else
{
EMSG2(_(e_invarg2), val);
diff --git a/src/evalfunc.c b/src/evalfunc.c
index e89bc30..84eaa8c 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -514,7 +514,7 @@
{"ch_sendexpr", 2, 3, f_ch_sendexpr},
{"ch_sendraw", 2, 3, f_ch_sendraw},
{"ch_setoptions", 2, 2, f_ch_setoptions},
- {"ch_status", 1, 1, f_ch_status},
+ {"ch_status", 1, 2, f_ch_status},
#endif
{"changenr", 0, 0, f_changenr},
{"char2nr", 1, 2, f_char2nr},
@@ -1985,13 +1985,24 @@
f_ch_status(typval_T *argvars, typval_T *rettv)
{
channel_T *channel;
+ jobopt_T opt;
+ int part = -1;
/* return an empty string by default */
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0);
- rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel));
+
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ {
+ clear_job_options(&opt);
+ if (get_job_options(&argvars[1], &opt, JO_PART) == OK
+ && (opt.jo_set & JO_PART))
+ part = opt.jo_part;
+ }
+
+ rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel, part));
}
#endif
diff --git a/src/proto/channel.pro b/src/proto/channel.pro
index 869989c..e056d5f 100644
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -24,7 +24,7 @@
int channel_collapse(channel_T *channel, int part, int want_nl);
int channel_can_write_to(channel_T *channel);
int channel_is_open(channel_T *channel);
-char *channel_status(channel_T *channel);
+char *channel_status(channel_T *channel, int req_part);
void channel_info(channel_T *channel, dict_T *dict);
void channel_close(channel_T *channel, int invoke_close_cb);
void channel_close_in(channel_T *channel);
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index f8252f1..eb75a0b 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -434,6 +434,23 @@
let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
call assert_equal(v:t_job, type(job))
call assert_equal("run", job_status(job))
+
+ call assert_equal("open", ch_status(job))
+ call assert_equal("open", ch_status(job), {"part": "out"})
+ call assert_equal("open", ch_status(job), {"part": "err"})
+ call assert_fails('call ch_status(job, {"in_mode": "raw"})', 'E475:')
+ call assert_fails('call ch_status(job, {"part": "in"})', 'E475:')
+
+ let dict = ch_info(job)
+ call assert_true(dict.id != 0)
+ call assert_equal('open', dict.status)
+ call assert_equal('open', dict.out_status)
+ call assert_equal('RAW', dict.out_mode)
+ call assert_equal('pipe', dict.out_io)
+ call assert_equal('open', dict.err_status)
+ call assert_equal('RAW', dict.err_mode)
+ call assert_equal('pipe', dict.err_io)
+
try
" For a change use the job where a channel is expected.
call ch_sendraw(job, "echo something\n")
diff --git a/src/version.c b/src/version.c
index cf9b198..cd15950 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 15,
+/**/
14,
/**/
13,