1
0
forked from aniani/vim

patch 7.4.1382

Problem:    Can't get the job of a channel.
Solution:   Add ch_getjob().
This commit is contained in:
Bram Moolenaar 2016-02-21 20:10:26 +01:00
parent eab089d22f
commit 02e83b438e
4 changed files with 151 additions and 72 deletions

View 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*

View 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)

View 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
*/

View File

@ -747,6 +747,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1382,
/**/
1381,
/**/