]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1382 v7.4.1382
authorBram Moolenaar <Bram@vim.org>
Sun, 21 Feb 2016 19:10:26 +0000 (20:10 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 21 Feb 2016 19:10:26 +0000 (20:10 +0100)
Problem:    Can't get the job of a channel.
Solution:   Add ch_getjob().

runtime/doc/channel.txt
runtime/doc/eval.txt
src/eval.c
src/version.c

index aca6b087757ed8e2bcd9fc1124ff7162b5eb5145..aa31816fcb778071279c3b87b9230bd2947698a4 100644 (file)
@@ -1,4 +1,4 @@
-*channel.txt*      For Vim version 7.4.  Last change: 2016 Feb 20
+*channel.txt*      For Vim version 7.4.  Last change: 2016 Feb 21
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -93,7 +93,7 @@ To handle asynchronous communication a callback needs to be used: >
        func MyHandler(channel, msg)
          echo "from the handler: " . a:msg
        endfunc
-       call ch_sendexpr(channel, 'hello!', "MyHandler")
+       call ch_sendexpr(channel, 'hello!', {'callback': "MyHandler"})
 Vim will not wait for a response.  Now the server can send the response later
 and MyHandler will be invoked.
 
@@ -101,13 +101,15 @@ Instead of giving a callback with every send call, it can also be specified
 when opening the channel: >
        call ch_close(channel)
        let channel = ch_open('localhost:8765', {'callback': "MyHandler"})
-       call ch_sendexpr(channel, 'hello!', 0)
+       call ch_sendexpr(channel, 'hello!', {'callback': 0})
 
 ==============================================================================
 3. Opening a channel                                   *channel-open*
 
 To open a channel: >
     let channel = ch_open({address} [, {options}])
+    if ch_status(channel) == "open"
+      " use the channel
 
 Use |ch_status()| to see if the channel could be opened.
 
@@ -131,25 +133,32 @@ Use |ch_status()| to see if the channel could be opened.
                                                        *channel-callback*
 "callback"     A function that is called when a message is received that is
                not handled otherwise.  It gets two arguments: the channel
-               handle and the received message. Example: >
+               and the received message. Example: >
        func Handle(channel, msg)
          echo 'Received: ' . a:msg
        endfunc
        let channel = ch_open("localhost:8765", {"callback": "Handle"})
 <
+               When "mode" is "json" or "js" the "msg" argument is the body
+               of the received message, converted to Vim types.
+               When "mode" is "nl" the "msg" argument is one message,
+               excluding the NL.
+               When "mode" is "raw" the "msg" argument is the whole message
+               as a string.
+                                                       *out-cb*
 "out-cb"       A function like "callback" but used for stdout.  Only for when
                the channel uses pipes.  When "out-cb" wasn't set the channel
                callback is used.
-
+                                                       *err-cb*
 "err-cb"       A function like "callback" but used for stderr.  Only for when
                the channel uses pipes.  When "err-cb" wasn't set the channel
                callback is used.
 
-               TODO:
+               TODO:                                   *close-cb*
 "close-cb"     A function that is called when the channel gets closed, other
                than by calling ch_close().  It should be defined like this: >
        func MyCloseHandler(channel)
-
+<                                                      *waittime*
 "waittime"     The time to wait for the connection to be made in
                milliseconds.  The default is zero, don't wait, which is
                useful if the server is supposed to be running already.  A
@@ -158,41 +167,34 @@ Use |ch_status()| to see if the channel could be opened.
 "timeout"      The time to wait for a request when blocking, E.g. when using
                ch_sendexpr().  In milliseconds.  The default is 2000 (2
                seconds).
-
+                                               *out-timeout* *err-timeout*
 "out-timeout"  Timeout for stdout.  Only when using pipes.
 "err-timeout"  Timeout for stderr.  Only when using pipes.
                Note: when setting "timeout" the part specific mode is
                overwritten.  Therefore set "timeout" first and the part
                specific mode later.
 
-When "mode" is "json" or "js" the "msg" argument is the body of the received
-message, converted to Vim types.
-When "mode" is "raw" the "msg" argument is the whole message as a string.
-
 When "mode" is "json" or "js" the "callback" is optional.  When omitted it is
 only possible to receive a message after sending one.
 
-To change the channel options after opening it use ch_setoptions().  The
-arguments are similar to what is passed to ch_open(), but "waittime" cannot be
-given, since that only applies to opening the channel.
+To change the channel options after opening it use |ch_setoptions()|.  The
+arguments are similar to what is passed to |ch_open()|, but "waittime" cannot
+be given, since that only applies to opening the channel.
 
-The handler can be added or changed: >
+For example, the handler can be added or changed: >
     call ch_setoptions(channel, {'callback': callback})
 When "callback" is empty (zero or an empty string) the handler is removed.
 
 The timeout can be changed: >
     call ch_setoptions(channel, {'timeout': msec})
 <
-                                                         *E906*
+                                                         *channel-close* *E906*
 Once done with the channel, disconnect it like this: >
     call ch_close(channel)
 When a socket is used this will close the socket for both directions.  When
 pipes are used (stdin/stdout/stderr) they are all closed.  This might not be
 what you want!  Stopping the job with job_stop() might be better.
 
-TODO:
-Currently up to 10 channels can be in use at the same time. *E897*
-
 When the channel can't be opened you will get an error message.  There is a
 difference between MS-Windows and Unix: On Unix when the port doesn't exist
 ch_open() fails quickly.  On MS-Windows "waittime" applies.
@@ -211,12 +213,13 @@ This awaits a response from the other side.
 When mode is JS this works the same, except that the messages use
 JavaScript encoding.  See |js_encode()| for the difference.
 
-To send a message, without handling a response: >
-    call ch_sendexpr(channel, {expr}, 0)
+To send a message, without handling a response or letting the channel callback
+handle the response: >
+    call ch_sendexpr(channel, {expr}, {'callback': 0})
 
 To send a message and letting the response handled by a specific function,
 asynchronously: >
-    call ch_sendexpr(channel, {expr}, {callback})
+    call ch_sendexpr(channel, {expr}, {'callback': Handler})
 
 Vim will match the response with the request using the message ID.  Once the
 response is received the callback will be invoked.  Further responses with the
@@ -424,13 +427,18 @@ The function will be called with the channel and a message. You would define
 it like this: >
     func MyHandler(channel, msg)
 
-Without the handler you need to read the output with ch_read().
+Without the handler you need to read the output with |ch_read()| or
+|ch_readraw()|.
 
-The handler defined for "out-cb" will also receive stderr.  If you want to
+The handler defined for "out-cb" will not receive stderr.  If you want to
 handle that separately, add an "err-cb" handler: >
     let job = job_start(command, {"out-cb": "MyHandler",
            \                     "err-cb": "ErrHandler"})
 
+If you want to handle both stderr and stdout with one handler use the
+"callback" option: >
+    let job = job_start(command, {"callback": "MyHandler"}) 
+
 You can send a message to the command with ch_sendraw().  If the channel is in
 JSON or JS mode you can use ch_sendexpr().
 
@@ -481,7 +489,10 @@ This gives the job some time to make the port available.
 10. Job options                                                *job-options*
 
 The {options} argument in job_start() is a dictionary.  All entries are
-optional.  The same options can be used with job_setoptions(job, {options}).
+optional.  Some options can be used after the job has started, using
+job_setoptions(job, {options}).  Many options can be used with the channel
+related to the job, using ch_setoptions(channel, {options}).
+See |job_setoptions()| and |ch_setoptions()|.
 
                                                *job-callback*
 "callback": handler    Callback for something to read on any part of the
@@ -495,13 +506,18 @@ optional.  The same options can be used with job_setoptions(job, {options}).
 TODO:                                          *job-close-cb*
 "close-cb": handler    Callback for when the channel is closed.  Same as
                        "close-cb" on ch_open().
-TODO:                                          *job-exit-cb*
+                                               *job-exit-cb*
 "exit-cb": handler     Callback for when the job ends.  The arguments are the
                        job and the exit status.
-TODO:                                          *job-killonexit*
-"killonexit": 1                Stop the job when Vim exits.
-"killonexit": 0                Do not stop the job when Vim exits.
-                       The default is 1.
+                       Vim checks about every 10 seconds for jobs that ended.
+                       The callback can also be triggered by calling
+                       |job_status()|.
+                                               *job-stoponexit*
+"stoponexit": {signal} Send {signal} to the job when Vim exits.  See
+                       |job_stop()| for possible values.
+"stoponexit": ""       Do not stop the job when Vim exits.
+                       The default is "term".
+
 TODO:                                          *job-term*
 "term": "open"         Start a terminal and connect the job
                        stdin/stdout/stderr to it.
@@ -529,9 +545,6 @@ TODO:                                               *job-err-io*
 "err-io": "buffer"     stderr appends to a buffer
 "err-buffer": "name"   buffer to append to
 
-TODO: more options
-
-
 ==============================================================================
 11. Controlling a job                                  *job-control*
 
index f5885da14f0b5e1bed34ba20c43baf1cb4516189..022a5da7a54372b1b577310404b419669198c707 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 7.4.  Last change: 2016 Feb 19
+*eval.txt*     For Vim version 7.4.  Last change: 2016 Feb 21
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -59,11 +59,11 @@ Dictionary  An associative, unordered array: Each entry has a key and a
 Funcref                A reference to a function |Funcref|.
                Example: function("strlen")
 
-Special                v:false, v:true, v:none and v:null
+Special                |v:false|, |v:true|, |v:none| and |v:null|.  *Special*
 
-Job            Used for a job, see |job_start()|.
+Job            Used for a job, see |job_start()|. *Job*
 
-Channel                Used for a channel, see |ch_open()|.
+Channel                Used for a channel, see |ch_open()|. *Channel*
 
 The Number and String types are converted automatically, depending on how they
 are used.
@@ -1817,17 +1817,19 @@ byteidxcomp( {expr}, {nr})      Number  byte index of {nr}'th char in {expr}
 call( {func}, {arglist} [, {dict}])
                                any     call {func} with arguments {arglist}
 ceil( {expr})                  Float   round {expr} up
-ch_close( {handle})            none    close a channel
+ch_close( {channel})           none    close {channel}
+ch_getjob( {channel})          Job     get the Job of {channel}
 ch_log( {msg} [, {channel}])   none    write {msg} in the channel log file
 ch_logfile( {fname} [, {mode}])        none    start logging channel activity
 ch_open( {address} [, {options}]) Channel open a channel to {address}
-ch_readraw( {handle})          String  read from channel {handle}
-ch_sendexpr( {handle}, {expr} [, {options}])
-                               any     send {expr} over JSON channel {handle}
-ch_sendraw( {handle}, {string} [, {options}])
-                               any     send {string} over raw channel {handle}
-ch_setoptions( {handle}, {options})  none  set options for channel {handle}
-ch_status( {handle})           String  status of channel {handle}
+ch_read( {channel} [, {options}])  String  read from  {channel}
+ch_readraw( {channel} [, {options}])  String  read raw from  {channel}
+ch_sendexpr( {channel}, {expr} [, {options}])
+                               any     send {expr} over JSON {channel}
+ch_sendraw( {channel}, {string} [, {options}])
+                               any     send {string} over raw {channel}
+ch_setoptions( {channel}, {options})  none  set options for {channel}
+ch_status( {channel})          String  status of  {channel}
 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}
@@ -1960,10 +1962,11 @@ invert( {expr})                 Number  bitwise invert
 isdirectory( {directory})      Number  TRUE if {directory} is a directory
 islocked( {expr})              Number  TRUE if {expr} is locked
 items( {dict})                 List    key-value pairs in {dict}
-job_getchannel( {job})         Number  get the channel handle for {job}
-job_start( {command} [, {options}]) Job        start a job     
-job_status( {job})             String  get the status of a job
-job_stop( {job} [, {how}])     Number  stop a job
+job_getchannel( {job})         Channel get the channel handle for {job}
+job_setoptions( {job}, {options}) none set options for {job}
+job_start( {command} [, {options}]) Job         start a job
+job_status( {job})             String  get the status of {job}
+job_stop( {job} [, {how}])     Number  stop {job}
 join( {list} [, {sep}])                String  join {list} items into one String
 js_decode( {string})           any     decode JS style JSON
 js_encode( {expr})             String  encode JS style JSON
@@ -2684,10 +2687,18 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
                don't fit, a vertical layout is used anyway.  For some systems
                the horizontal layout is always used.
 
-ch_close({handle})                                             *ch_close()*
-               Close channel {handle}.  See |channel|.
+ch_close({channel})                                            *ch_close()*
+               Close {channel}.  See |channel-close|.
                {only available when compiled with the |+channel| feature}
 
+ch_getjob({channel})                                           *ch_getjob()*
+               Get the Job associated with {channel}.
+               If there is no job calling |job_status()| on the returned Job
+               will result in "fail".
+
+               {only available when compiled with the |+channel| and
+               |+job| features}
+
 ch_log({msg} [, {channel}])                                    *ch_log()*
                Write {msg} in the channel log file, if it was opened with
                |ch_logfile()|.
@@ -2706,8 +2717,8 @@ ch_logfile({fname} [, {mode}])                                    *ch_logfile()*
 
 ch_open({address} [, {options}])                               *ch_open()*
                Open a channel to {address}.  See |channel|.
-               Returns the channel handle on success.  Returns a negative
-               number for failure.
+               Returns a Channel.  Use |ch_status()| to check for
+               failure.
 
                {address} has the form "hostname:port", e.g.,
                "localhost:8765".
@@ -2722,19 +2733,38 @@ ch_open({address} [, {options}])                                *ch_open()*
                        waittime    Specify connect timeout as milliseconds.
                                    Negative means forever.
                                    Default: 0 (don't wait)
-                       timeout     Specify response read timeout value as
+                       timeout     Specify response read timeout value in
                                    milliseconds. 
                                    Default: 2000.
                {only available when compiled with the |+channel| feature}
 
-ch_readraw({handle})                                           *ch_readraw()*
-               Read from channel {handle} and return the received message.
-               This uses the channel timeout.  When there is nothing to read
-               within that time an empty string is returned.
-               TODO: depends on channel mode.
+ch_read({channel} [, {options}])                               *ch_read()*
+               Read from {channel} and return the received message.
 
-ch_sendexpr({handle}, {expr} [, {options}])                    *ch_sendexpr()*
-               Send {expr} over channel {handle}.  The {expr} is encoded
+               This uses the channel timeout.  When there is nothing to read
+               within that time an empty string is returned.  To specify a
+               different timeout in msec use the "timeout" option:
+                       {"timeout": 123} ~
+               To read from the error output use the "part" option:
+                       {"part": "err"} ~
+               To read a message with a specific ID, on a JS or JSON channel:
+                       {"id": 99} ~
+               When no ID is specified or the ID is -1, the first message is
+               returned. This overrules any callback waiting for this
+               message.
+
+               For a RAW channel this returns whatever is available, since
+               Vim does not know where a message ends.
+               For a NL channel this returns one message.
+               For a JS or JSON channel this returns one decoded message.
+               This includes any sequence number.
+
+ch_readraw({channel} [, {options}])                    *ch_readraw()*
+               Like ch_read() but for a JS and JSON channel does not decode
+               the message.
+
+ch_sendexpr({channel}, {expr} [, {options}])                   *ch_sendexpr()*
+               Send {expr} over {channel}.  The {expr} is encoded
                according to the type of channel.  The function cannot be used
                with a raw channel.  See |channel-use|.  *E912*
 
@@ -2751,8 +2781,8 @@ ch_sendexpr({handle}, {expr} [, {options}])                       *ch_sendexpr()*
 
                {only available when compiled with the |+channel| feature}
 
-ch_sendraw({handle}, {string} [, {options}])           *ch_sendraw()*
-               Send {string} over channel {handle}.
+ch_sendraw({channel}, {string} [, {options}])          *ch_sendraw()*
+               Send {string} over {channel}.
                Works like |ch_sendexpr()|, but does not encode the request or
                decode the response.  The caller is responsible for the
                correct contents.  Also does not add a newline for a channel
@@ -2762,18 +2792,21 @@ ch_sendraw({handle}, {string} [, {options}])            *ch_sendraw()*
 
                {only available when compiled with the |+channel| feature}
 
-ch_setoptions({handle}, {options})                     *ch_setoptions()*
-               Set options on channel {handle}:
+ch_setoptions({channel}, {options})                    *ch_setoptions()*
+               Set options on {channel}:
                        "callback"      the channel callback
                        "timeout"       default read timeout in msec
+                       "mode"          mode for the whole channel
                See |ch_open()| for more explanation.
 
+               Note that changing the mode may cause queued messages to be
+               lost.
+
                These options cannot be changed:
-                       "mode"          cannot be changed once channel is open
                        "waittime"      only applies to "ch_open()|
 
-ch_status({handle})                                            *ch_status()*
-               Return the status of channel {handle}:
+ch_status({channel})                                           *ch_status()*
+               Return the status of {channel}:
                        "fail"          failed to open the channel
                        "open"          channel can be used
                        "closed"        channel can not be used
@@ -4370,11 +4403,15 @@ items({dict})                                           *items()*
                entry and the value of this entry.  The |List| is in arbitrary
                order.
 
-
 job_getchannel({job})                                   *job_getchannel()*
                Get the channel handle that {job} is using.
                {only available when compiled with the |+job| feature}
 
+job_setoptions({job}, {options})                       *job_setoptions()*
+               Change options for {job}.  Supported are:
+                       "stoponexit"    |job-stoponexit|
+                       "exit-cb"       |job-exit-cb|
+
 job_start({command} [, {options}])                     *job_start()*
                Start a job and return a Job object.  Unlike |system()| and
                |:!cmd| this does not wait for the job to finish.
@@ -4415,11 +4452,14 @@ job_start({command} [, {options}])                      *job_start()*
 
                {only available when compiled with the |+job| feature}
 
-job_status({job})                                              *job_status()*
+job_status({job})                                      *job_status()* *E916*
                Returns a String with the status of {job}:
                        "run"   job is running
                        "fail"  job failed to start
                        "dead"  job died or was stopped after running
+               
+               If an exit callback was set with the "exit-cb" option and the
+               job is now detected to be "dead" the callback will be invoked.
 
                {only available when compiled with the |+job| feature}
 
@@ -7375,7 +7415,6 @@ vms                       VMS version of Vim.
 vreplace               Compiled with |gR| and |gr| commands.
 wildignore             Compiled with 'wildignore' option.
 wildmenu               Compiled with 'wildmenu' option.
-win16                  Win16 version of Vim (MS-Windows 3.1).
 win32                  Win32 version of Vim (MS-Windows 95 and later, 32 or
                        64 bits)
 win32unix              Win32 version of Vim, using Unix files (Cygwin)
index cc7b9455f2b59cf683d511622309bcabc3032674..bb9a4c5694985fb8e3b66c4f66e67e2407b9da1b 100644 (file)
@@ -501,6 +501,9 @@ static void f_ceil(typval_T *argvars, typval_T *rettv);
 #endif
 #ifdef FEAT_CHANNEL
 static void f_ch_close(typval_T *argvars, typval_T *rettv);
+# ifdef FEAT_JOB
+static void f_ch_getjob(typval_T *argvars, typval_T *rettv);
+# endif
 static void f_ch_log(typval_T *argvars, typval_T *rettv);
 static void f_ch_logfile(typval_T *argvars, typval_T *rettv);
 static void f_ch_open(typval_T *argvars, typval_T *rettv);
@@ -8186,6 +8189,9 @@ static struct fst
 #endif
 #ifdef FEAT_CHANNEL
     {"ch_close",       1, 1, f_ch_close},
+# ifdef FEAT_JOB
+    {"ch_getjob",      1, 1, f_ch_getjob},
+# endif
     {"ch_log",         1, 2, f_ch_log},
     {"ch_logfile",     1, 2, f_ch_logfile},
     {"ch_open",                1, 2, f_ch_open},
@@ -10186,6 +10192,25 @@ f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
        channel_close(channel);
 }
 
+# ifdef FEAT_JOB
+/*
+ * "ch_getjob()" function
+ */
+    static void
+f_ch_getjob(typval_T *argvars, typval_T *rettv)
+{
+    channel_T *channel = get_channel_arg(&argvars[0]);
+
+    if (channel != NULL)
+    {
+       rettv->v_type = VAR_JOB;
+       rettv->vval.v_job = channel->ch_job;
+       if (channel->ch_job != NULL)
+           ++channel->ch_job->jv_refcount;
+    }
+}
+# endif
+
 /*
  * "ch_log()" function
  */
index 144dc18b78c67b7b32557ccbe886734383ff9ab9..5e6878f2fc1dd55d58646513d7ef38cf9a953c14 100644 (file)
@@ -747,6 +747,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1382,
 /**/
     1381,
 /**/