]> granicus.if.org Git - vim/commitdiff
patch 7.4.2298 v7.4.2298
authorBram Moolenaar <Bram@vim.org>
Thu, 1 Sep 2016 13:11:51 +0000 (15:11 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 1 Sep 2016 13:11:51 +0000 (15:11 +0200)
Problem:    It is not possible to close the "in" part of a channel.
Solution:   Add ch_close_in().

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

index c5189727cdca6f5d65ed6e9ffb00b1b549641c87..1f23042aefc21a821d3cc13822618ce8ac06e672 100644 (file)
@@ -1,4 +1,4 @@
-*channel.txt*      For Vim version 7.4.  Last change: 2016 Aug 31
+*channel.txt*      For Vim version 7.4.  Last change: 2016 Sep 01
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -501,6 +501,10 @@ A special mode is when "in_top" is set to zero and "in_bot" is not set: Every
 time a line is added to the buffer, the last-but-one line will be send to the
 job stdin.  This allows for editing the last line and sending it when pressing
 Enter.
+                                                       *channel-close-in*
+When not using the special mode the pipe or socket will be closed after the
+last line has been written.  This signals the reading end that the input
+finished.  You can also use |ch_close_in()| to close it sooner.
 
 NUL bytes in the text will be passed to the job (internally Vim stores these
 as NL bytes).
index bd495041b6ebede8e956cd9c0fde663a6101fd60..88585621e684a6cd9f4d58d31a0ce67fee0c48a1 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 7.4.  Last change: 2016 Aug 31
+*eval.txt*     For Vim version 7.4.  Last change: 2016 Sep 01
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -2009,6 +2009,7 @@ call({func}, {arglist} [, {dict}])
                                any     call {func} with arguments {arglist}
 ceil({expr})                   Float   round {expr} up
 ch_close({handle})             none    close {handle}
+ch_close_in({handle})          none    close in part of {handle}
 ch_evalexpr({handle}, {expr} [, {options}])
                                any     evaluate {expr} on JSON {handle}
 ch_evalraw({handle}, {string} [, {options}])
@@ -2980,6 +2981,14 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
 ch_close({handle})                                             *ch_close()*
                Close {handle}.  See |channel-close|.
                {handle} can be Channel or a Job that has a Channel.
+               A close callback is not invoked.
+
+               {only available when compiled with the |+channel| feature}
+
+ch_close_in({handle})                                          *ch_close_in()*
+               Close the "in" part of {handle}.  See |channel-close-in|.
+               {handle} can be Channel or a Job that has a Channel.
+               A close callback is not invoked.
 
                {only available when compiled with the |+channel| feature}
 
index dbed65932996525763ee924f1449b0862641c976..bbe98be1b22daca6e518c8a6213c5bb0d5c38c23 100644 (file)
@@ -2735,6 +2735,15 @@ channel_close(channel_T *channel, int invoke_close_cb)
     channel->ch_nb_close_cb = NULL;
 }
 
+/*
+ * Close the "in" part channel "channel".
+ */
+    void
+channel_close_in(channel_T *channel)
+{
+    may_close_part(&channel->CH_IN_FD);
+}
+
 /*
  * Clear the read buffer on "channel"/"part".
  */
index 578f0f58237c6bebbe59adff7127672be9b749ba..9d94694d82eca1c011caec0172cb6e02a458a681 100644 (file)
@@ -77,6 +77,7 @@ static void f_ceil(typval_T *argvars, typval_T *rettv);
 #endif
 #ifdef FEAT_JOB_CHANNEL
 static void f_ch_close(typval_T *argvars, typval_T *rettv);
+static void f_ch_close_in(typval_T *argvars, typval_T *rettv);
 static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
 static void f_ch_evalraw(typval_T *argvars, typval_T *rettv);
 static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv);
@@ -499,6 +500,7 @@ static struct fst
 #endif
 #ifdef FEAT_JOB_CHANNEL
     {"ch_close",       1, 1, f_ch_close},
+    {"ch_close_in",    1, 1, f_ch_close_in},
     {"ch_evalexpr",    2, 3, f_ch_evalexpr},
     {"ch_evalraw",     2, 3, f_ch_evalraw},
     {"ch_getbufnr",    2, 2, f_ch_getbufnr},
@@ -1791,6 +1793,18 @@ f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
     }
 }
 
+/*
+ * "ch_close()" function
+ */
+    static void
+f_ch_close_in(typval_T *argvars, typval_T *rettv UNUSED)
+{
+    channel_T *channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0);
+
+    if (channel != NULL)
+       channel_close_in(channel);
+}
+
 /*
  * "ch_getbufnr()" function
  */
index 1acae9a105e85ee0c9bad63319d03f812055fcb2..869989cc482810c0a75a5a680db56f552ed40dff 100644 (file)
@@ -27,6 +27,7 @@ int channel_is_open(channel_T *channel);
 char *channel_status(channel_T *channel);
 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);
 void channel_clear(channel_T *channel);
 void channel_free_all(void);
 char_u *channel_read_block(channel_T *channel, int part, int timeout);
index 6bea0e8b96238c120b97ffc8ac98ea0f963b411d..0121deb25a2130d65132c0be7c582fd082c1417f 100644 (file)
@@ -792,22 +792,32 @@ func Test_pipe_from_buffer_nr()
   call Run_test_pipe_from_buffer(0)
 endfunc
 
-func Run_pipe_through_sort(all)
+func Run_pipe_through_sort(all, use_buffer)
   if !executable('sort') || !has('job')
     return
   endif
-  split sortin
-  call setline(1, ['ccc', 'aaa', 'ddd', 'bbb', 'eee'])
-  let options = {'in_io': 'buffer', 'in_name': 'sortin',
-       \ 'out_io': 'buffer', 'out_name': 'sortout'}
+  let options = {'out_io': 'buffer', 'out_name': 'sortout'}
+  if a:use_buffer
+    split sortin
+    call setline(1, ['ccc', 'aaa', 'ddd', 'bbb', 'eee'])
+    let options.in_io = 'buffer'
+    let options.in_name = 'sortin'
+  endif
   if !a:all
     let options.in_top = 2
     let options.in_bot = 4
   endif
   let g:job = job_start('sort', options)
   call assert_equal("run", job_status(g:job))
+
+  if !a:use_buffer
+    call ch_sendraw(g:job, "ccc\naaa\nddd\nbbb\neee\n")
+    call ch_close_in(g:job)
+  endif
+
   call WaitFor('job_status(g:job) == "dead"')
   call assert_equal("dead", job_status(g:job))
+
   sp sortout
   call assert_equal('Reading from channel output...', getline(1))
   if a:all
@@ -818,18 +828,25 @@ func Run_pipe_through_sort(all)
 
   call job_stop(g:job)
   unlet g:job
-  bwipe! sortin
+  if a:use_buffer
+    bwipe! sortin
+  endif
   bwipe! sortout
 endfunc
 
 func Test_pipe_through_sort_all()
   call ch_log('Test_pipe_through_sort_all()')
-  call Run_pipe_through_sort(1)
+  call Run_pipe_through_sort(1, 1)
 endfunc
 
 func Test_pipe_through_sort_some()
   call ch_log('Test_pipe_through_sort_some()')
-  call Run_pipe_through_sort(0)
+  call Run_pipe_through_sort(0, 1)
+endfunc
+
+func Test_pipe_through_sort_feed()
+  call ch_log('Test_pipe_through_sort_feed()')
+  call Run_pipe_through_sort(1, 0)
 endfunc
 
 func Test_pipe_to_nameless_buffer()
index 3162f330fb42a26bf22ac442765f7325c388845b..87e401b1e469e1b95fa77ccda522e2b09b9f054e 100644 (file)
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2298,
 /**/
     2297,
 /**/