]> granicus.if.org Git - vim/commitdiff
patch 8.0.0015 v8.0.0015
authorBram Moolenaar <Bram@vim.org>
Mon, 26 Sep 2016 20:36:58 +0000 (22:36 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 26 Sep 2016 20:36:58 +0000 (22:36 +0200)
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.

runtime/doc/eval.txt
src/channel.c
src/evalfunc.c
src/proto/channel.pro
src/testdir/test_channel.vim
src/version.c

index d34fa5be26e0d66313ed44c348655e0cbf721658..43d1883273b9fffadd5be945258b01a28ba598ee 100644 (file)
@@ -2031,7 +2031,8 @@ ch_sendraw({handle}, {string} [, {options}])
                                any     send {string} over raw {handle}
 ch_setoptions({handle}, {options})
                                none    set options for {handle}
-ch_status({handle})            String  status of channel {handle}
+ch_status({handle} [, {options}])
+                               String  status of channel {handle}
 changenr()                     Number  current change number
 char2nr({expr}[, {utf8}])      Number  ASCII/UTF8 value of first char in {expr}
 cindent({lnum})                        Number  C indent for line {lnum}
@@ -3042,7 +3043,8 @@ ch_info({handle})                                         *ch_info()*
                Returns a Dictionary with information about {handle}.  The
                items are:
                   "id"           number of the channel
-                  "status"       "open" (any part is open) or "closed"
+                  "status"       "open", "buffered" or "closed", like
+                                 ch_status()
                When opened with ch_open():
                   "hostname"     the hostname of the address
                   "port"         the port of the address
@@ -3051,11 +3053,11 @@ ch_info({handle})                                               *ch_info()*
                   "sock_io"      "socket"
                   "sock_timeout" timeout in msec
                When opened with job_start():
-                  "out_status"   "open" or "closed"
+                  "out_status"   "open", "buffered" or "closed"
                   "out_mode"     "NL", "RAW", "JSON" or "JS"
                   "out_io"       "null", "pipe", "file" or "buffer"
                   "out_timeout"  timeout in msec
-                  "err_status"   "open" or "closed"
+                  "err_status"   "open", "buffered" or "closed"
                   "err_mode"     "NL", "RAW", "JSON" or "JS"
                   "err_io"       "out", "null", "pipe", "file" or "buffer"
                   "err_timeout"  timeout in msec
@@ -3140,7 +3142,7 @@ ch_setoptions({handle}, {options})                        *ch_setoptions()*
                These options cannot be changed:
                        "waittime"      only applies to |ch_open()|
 
-ch_status({handle})                                            *ch_status()*
+ch_status({handle} [, {options}])                              *ch_status()*
                Return the status of {handle}:
                        "fail"          failed to open the channel
                        "open"          channel can be used
@@ -3150,6 +3152,11 @@ ch_status({handle})                                              *ch_status()*
                "buffered" is used when the channel was closed but there is
                still data that can be obtained with |ch_read()|.
 
+               If {options} is given it can contain a "part" entry to specify
+               the part of the channel to return the status for: "out" or
+               "err".  For example, to get the error status: >
+                       ch_status(job, {"part": "err"})
+<
                                                        *copy()*
 copy({expr})   Make a copy of {expr}.  For Numbers and Strings this isn't
                different from using {expr} directly.
index f4d1e95b08e4ecaf6f87b23f3355b6e9a28fdd54..0bab47a6263cd58f42a7d2bdf376dc67d542716c 100644 (file)
@@ -2590,23 +2590,41 @@ channel_has_readahead(channel_T *channel, int part)
 
 /*
  * 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 @@ channel_part_info(channel_T *channel, dict_T *dict, char *name, int part)
     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 @@ channel_part_info(channel_T *channel, dict_T *dict, char *name, int part)
     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_part_info(channel_T *channel, dict_T *dict, char *name, int part)
 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 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
                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);
index e89bc30083c647450dd1533899b7834aed018efe..84eaa8cbeb2f890081b079bc0676dfa9777ba7b3 100644 (file)
@@ -514,7 +514,7 @@ static struct fst
     {"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_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
 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
 
index 869989cc482810c0a75a5a680db56f552ed40dff..e056d5ffe0bd27d50ff45238e29d04e45b38eede 100644 (file)
@@ -24,7 +24,7 @@ void channel_consume(channel_T *channel, int part, int len);
 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);
index f8252f1a3ca611cfd16c9dc5ac8d5d64462f2dbc..eb75a0b1d20bc863d2181d18267b8bc4bf3b6bcc 100644 (file)
@@ -434,6 +434,23 @@ func Test_raw_pipe()
   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")
index cf9b1986a6166ea2d45744618029c2999e9178e2..cd1595007fae57cdb558e80317079223e5d34985 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    15,
 /**/
     14,
 /**/