patch 8.1.1912: more functions can be used as methods

Problem:    More functions can be used as methods.
Solution:   Make channel and job functions usable as a method.
This commit is contained in:
Bram Moolenaar
2019-08-22 22:55:13 +02:00
parent 64b4d73524
commit 570497ac40
4 changed files with 116 additions and 48 deletions

View File

@ -1,4 +1,4 @@
*channel.txt* For Vim version 8.1. Last change: 2019 Jul 28 *channel.txt* For Vim version 8.1. Last change: 2019 Aug 22
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -474,18 +474,25 @@ ch_canread({handle}) *ch_canread()*
Note that messages are dropped when the channel does not have Note that messages are dropped when the channel does not have
a callback. Add a close callback to avoid that. a callback. Add a close callback to avoid that.
Can also be used as a |method|: >
GetChannel()->ch_canread()
ch_close({handle}) *ch_close()* ch_close({handle}) *ch_close()*
Close {handle}. See |channel-close|. Close {handle}. See |channel-close|.
{handle} can be a Channel or a Job that has a Channel. {handle} can be a Channel or a Job that has a Channel.
A close callback is not invoked. A close callback is not invoked.
Can also be used as a |method|: >
GetChannel()->ch_close()
ch_close_in({handle}) *ch_close_in()* ch_close_in({handle}) *ch_close_in()*
Close the "in" part of {handle}. See |channel-close-in|. Close the "in" part of {handle}. See |channel-close-in|.
{handle} can be a Channel or a Job that has a Channel. {handle} can be a Channel or a Job that has a Channel.
A close callback is not invoked. A close callback is not invoked.
Can also be used as a |method|: >
GetChannel()->ch_close_in()
ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()* ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
Send {expr} over {handle}. The {expr} is encoded Send {expr} over {handle}. The {expr} is encoded
@ -501,6 +508,9 @@ ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
expression. When there is an error or timeout it returns an expression. When there is an error or timeout it returns an
empty string. empty string.
Can also be used as a |method|: >
GetChannel()->ch_evalexpr(expr)
ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()* ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
Send {string} over {handle}. Send {string} over {handle}.
@ -516,6 +526,8 @@ ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
need to use |ch_readraw()| to fetch the rest. need to use |ch_readraw()| to fetch the rest.
See |channel-use|. See |channel-use|.
Can also be used as a |method|: >
GetChannel()->ch_evalraw(rawstring)
ch_getbufnr({handle}, {what}) *ch_getbufnr()* ch_getbufnr({handle}, {what}) *ch_getbufnr()*
Get the buffer number that {handle} is using for {what}. Get the buffer number that {handle} is using for {what}.
@ -524,12 +536,17 @@ ch_getbufnr({handle}, {what}) *ch_getbufnr()*
socket output. socket output.
Returns -1 when there is no buffer. Returns -1 when there is no buffer.
Can also be used as a |method|: >
GetChannel()->ch_getbufnr(what)
ch_getjob({channel}) *ch_getjob()* ch_getjob({channel}) *ch_getjob()*
Get the Job associated with {channel}. Get the Job associated with {channel}.
If there is no job calling |job_status()| on the returned Job If there is no job calling |job_status()| on the returned Job
will result in "fail". will result in "fail".
Can also be used as a |method|: >
GetChannel()->ch_getjob()
ch_info({handle}) *ch_info()* ch_info({handle}) *ch_info()*
Returns a Dictionary with information about {handle}. The Returns a Dictionary with information about {handle}. The
@ -558,6 +575,9 @@ ch_info({handle}) *ch_info()*
"in_io" "null", "pipe", "file" or "buffer" "in_io" "null", "pipe", "file" or "buffer"
"in_timeout" timeout in msec "in_timeout" timeout in msec
Can also be used as a |method|: >
GetChannel()->ch_info()
ch_log({msg} [, {handle}]) *ch_log()* ch_log({msg} [, {handle}]) *ch_log()*
Write {msg} in the channel log file, if it was opened with Write {msg} in the channel log file, if it was opened with
@ -567,6 +587,9 @@ ch_log({msg} [, {handle}]) *ch_log()*
{handle} can be a Channel or a Job that has a Channel. The {handle} can be a Channel or a Job that has a Channel. The
Channel must be open for the channel number to be used. Channel must be open for the channel number to be used.
Can also be used as a |method|: >
'did something'->ch_log()
ch_logfile({fname} [, {mode}]) *ch_logfile()* ch_logfile({fname} [, {mode}]) *ch_logfile()*
Start logging channel activity to {fname}. Start logging channel activity to {fname}.
@ -584,6 +607,9 @@ ch_logfile({fname} [, {mode}]) *ch_logfile()*
aware that this may contain confidential and privacy sensitive aware that this may contain confidential and privacy sensitive
information, e.g. a password you type in a terminal window. information, e.g. a password you type in a terminal window.
Can also be used as a |method|: >
'logfile'->ch_logfile('w')
ch_open({address} [, {options}]) *ch_open()* ch_open({address} [, {options}]) *ch_open()*
Open a channel to {address}. See |channel|. Open a channel to {address}. See |channel|.
@ -595,6 +621,9 @@ ch_open({address} [, {options}]) *ch_open()*
If {options} is given it must be a |Dictionary|. If {options} is given it must be a |Dictionary|.
See |channel-open-options|. See |channel-open-options|.
Can also be used as a |method|: >
GetAddress()->ch_open()
ch_read({handle} [, {options}]) *ch_read()* ch_read({handle} [, {options}]) *ch_read()*
Read from {handle} and return the received message. Read from {handle} and return the received message.
@ -603,11 +632,17 @@ ch_read({handle} [, {options}]) *ch_read()*
there is nothing more to read (channel was closed). there is nothing more to read (channel was closed).
See |channel-more|. See |channel-more|.
Can also be used as a |method|: >
GetChannel()->ch_read()
ch_readblob({handle} [, {options}]) *ch_readblob()* ch_readblob({handle} [, {options}]) *ch_readblob()*
Like ch_read() but reads binary data and returns a |Blob|. Like ch_read() but reads binary data and returns a |Blob|.
See |channel-more|. See |channel-more|.
Can also be used as a |method|: >
GetChannel()->ch_readblob()
ch_readraw({handle} [, {options}]) *ch_readraw()* ch_readraw({handle} [, {options}]) *ch_readraw()*
Like ch_read() but for a JS and JSON channel does not decode Like ch_read() but for a JS and JSON channel does not decode
@ -615,6 +650,9 @@ ch_readraw({handle} [, {options}]) *ch_readraw()*
the NL to arrive, but otherwise works like ch_read(). the NL to arrive, but otherwise works like ch_read().
See |channel-more|. See |channel-more|.
Can also be used as a |method|: >
GetChannel()->ch_readraw()
ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()* ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
Send {expr} over {handle}. The {expr} is encoded Send {expr} over {handle}. The {expr} is encoded
@ -623,6 +661,9 @@ ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
See |channel-use|. *E912* See |channel-use|. *E912*
{handle} can be a Channel or a Job that has a Channel. {handle} can be a Channel or a Job that has a Channel.
Can also be used as a |method|: >
GetChannel()->ch_sendexpr(expr)
ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()* ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()*
Send |String| or |Blob| {expr} over {handle}. Send |String| or |Blob| {expr} over {handle}.
@ -633,6 +674,9 @@ ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()*
is removed. is removed.
See |channel-use|. See |channel-use|.
Can also be used as a |method|: >
GetChannel()->ch_sendraw(rawexpr)
ch_setoptions({handle}, {options}) *ch_setoptions()* ch_setoptions({handle}, {options}) *ch_setoptions()*
Set options on {handle}: Set options on {handle}:
@ -648,6 +692,9 @@ ch_setoptions({handle}, {options}) *ch_setoptions()*
These options cannot be changed: These options cannot be changed:
"waittime" only applies to |ch_open()| "waittime" only applies to |ch_open()|
Can also be used as a |method|: >
GetChannel()->ch_setoptions(options)
ch_status({handle} [, {options}]) *ch_status()* ch_status({handle} [, {options}]) *ch_status()*
Return the status of {handle}: Return the status of {handle}:
@ -664,6 +711,8 @@ ch_status({handle} [, {options}]) *ch_status()*
"err". For example, to get the error status: > "err". For example, to get the error status: >
ch_status(job, {"part": "err"}) ch_status(job, {"part": "err"})
< <
Can also be used as a |method|: >
GetChannel()->ch_status()
============================================================================== ==============================================================================
9. Starting a job with a channel *job-start* *job* 9. Starting a job with a channel *job-start* *job*
@ -792,6 +841,8 @@ job_getchannel({job}) *job_getchannel()*
To check if the job has no channel: > To check if the job has no channel: >
if string(job_getchannel()) == 'channel fail' if string(job_getchannel()) == 'channel fail'
< <
Can also be used as a |method|: >
GetJob()->job_getchannel()
job_info([{job}]) *job_info()* job_info([{job}]) *job_info()*
Returns a Dictionary with information about {job}: Returns a Dictionary with information about {job}:
@ -817,12 +868,18 @@ job_info([{job}]) *job_info()*
Without any arguments, returns a List with all Job objects. Without any arguments, returns a List with all Job objects.
Can also be used as a |method|: >
GetJob()->job_info()
job_setoptions({job}, {options}) *job_setoptions()* job_setoptions({job}, {options}) *job_setoptions()*
Change options for {job}. Supported are: Change options for {job}. Supported are:
"stoponexit" |job-stoponexit| "stoponexit" |job-stoponexit|
"exit_cb" |job-exit_cb| "exit_cb" |job-exit_cb|
Can also be used as a |method|: >
GetJob()->job_setoptions(options)
job_start({command} [, {options}]) *job_start()* job_start({command} [, {options}]) *job_start()*
Start a job and return a Job object. Unlike |system()| and Start a job and return a Job object. Unlike |system()| and
@ -881,6 +938,9 @@ job_start({command} [, {options}]) *job_start()*
{options} must be a Dictionary. It can contain many optional {options} must be a Dictionary. It can contain many optional
items, see |job-options|. items, see |job-options|.
Can also be used as a |method|: >
BuildCommand()->job_start()
job_status({job}) *job_status()* *E916* job_status({job}) *job_status()* *E916*
Returns a String with the status of {job}: Returns a String with the status of {job}:
@ -897,6 +957,9 @@ job_status({job}) *job_status()* *E916*
For more information see |job_info()|. For more information see |job_info()|.
Can also be used as a |method|: >
GetJob()->job_status()
job_stop({job} [, {how}]) *job_stop()* job_stop({job} [, {how}]) *job_stop()*
Stop the {job}. This can also be used to signal the job. Stop the {job}. This can also be used to signal the job.
@ -940,6 +1003,9 @@ job_stop({job} [, {how}]) *job_stop()*
When using "kill" Vim will assume the job will die and close When using "kill" Vim will assume the job will die and close
the channel. the channel.
Can also be used as a |method|: >
GetJob()->job_stop()
============================================================================== ==============================================================================
12. Job options *job-options* 12. Job options *job-options*

View File

@ -474,24 +474,24 @@ static funcentry_T global_functions[] =
{"ceil", 1, 1, FEARG_1, f_ceil}, {"ceil", 1, 1, FEARG_1, f_ceil},
#endif #endif
#ifdef FEAT_JOB_CHANNEL #ifdef FEAT_JOB_CHANNEL
{"ch_canread", 1, 1, 0, f_ch_canread}, {"ch_canread", 1, 1, FEARG_1, f_ch_canread},
{"ch_close", 1, 1, 0, f_ch_close}, {"ch_close", 1, 1, FEARG_1, f_ch_close},
{"ch_close_in", 1, 1, 0, f_ch_close_in}, {"ch_close_in", 1, 1, FEARG_1, f_ch_close_in},
{"ch_evalexpr", 2, 3, 0, f_ch_evalexpr}, {"ch_evalexpr", 2, 3, FEARG_1, f_ch_evalexpr},
{"ch_evalraw", 2, 3, 0, f_ch_evalraw}, {"ch_evalraw", 2, 3, FEARG_1, f_ch_evalraw},
{"ch_getbufnr", 2, 2, 0, f_ch_getbufnr}, {"ch_getbufnr", 2, 2, FEARG_1, f_ch_getbufnr},
{"ch_getjob", 1, 1, 0, f_ch_getjob}, {"ch_getjob", 1, 1, FEARG_1, f_ch_getjob},
{"ch_info", 1, 1, 0, f_ch_info}, {"ch_info", 1, 1, FEARG_1, f_ch_info},
{"ch_log", 1, 2, 0, f_ch_log}, {"ch_log", 1, 2, FEARG_1, f_ch_log},
{"ch_logfile", 1, 2, 0, f_ch_logfile}, {"ch_logfile", 1, 2, FEARG_1, f_ch_logfile},
{"ch_open", 1, 2, 0, f_ch_open}, {"ch_open", 1, 2, FEARG_1, f_ch_open},
{"ch_read", 1, 2, 0, f_ch_read}, {"ch_read", 1, 2, FEARG_1, f_ch_read},
{"ch_readblob", 1, 2, 0, f_ch_readblob}, {"ch_readblob", 1, 2, FEARG_1, f_ch_readblob},
{"ch_readraw", 1, 2, 0, f_ch_readraw}, {"ch_readraw", 1, 2, FEARG_1, f_ch_readraw},
{"ch_sendexpr", 2, 3, 0, f_ch_sendexpr}, {"ch_sendexpr", 2, 3, FEARG_1, f_ch_sendexpr},
{"ch_sendraw", 2, 3, 0, f_ch_sendraw}, {"ch_sendraw", 2, 3, FEARG_1, f_ch_sendraw},
{"ch_setoptions", 2, 2, 0, f_ch_setoptions}, {"ch_setoptions", 2, 2, FEARG_1, f_ch_setoptions},
{"ch_status", 1, 2, 0, f_ch_status}, {"ch_status", 1, 2, FEARG_1, f_ch_status},
#endif #endif
{"changenr", 0, 0, 0, f_changenr}, {"changenr", 0, 0, 0, f_changenr},
{"char2nr", 1, 2, 0, f_char2nr}, {"char2nr", 1, 2, 0, f_char2nr},
@ -635,12 +635,12 @@ static funcentry_T global_functions[] =
#endif #endif
{"items", 1, 1, FEARG_1, f_items}, {"items", 1, 1, FEARG_1, f_items},
#ifdef FEAT_JOB_CHANNEL #ifdef FEAT_JOB_CHANNEL
{"job_getchannel", 1, 1, 0, f_job_getchannel}, {"job_getchannel", 1, 1, FEARG_1, f_job_getchannel},
{"job_info", 0, 1, 0, f_job_info}, {"job_info", 0, 1, FEARG_1, f_job_info},
{"job_setoptions", 2, 2, 0, f_job_setoptions}, {"job_setoptions", 2, 2, FEARG_1, f_job_setoptions},
{"job_start", 1, 2, 0, f_job_start}, {"job_start", 1, 2, FEARG_1, f_job_start},
{"job_status", 1, 1, 0, f_job_status}, {"job_status", 1, 1, FEARG_1, f_job_status},
{"job_stop", 1, 2, 0, f_job_stop}, {"job_stop", 1, 2, FEARG_1, f_job_stop},
#endif #endif
{"join", 1, 2, FEARG_1, f_join}, {"join", 1, 2, FEARG_1, f_join},
{"js_decode", 1, 1, 0, f_js_decode}, {"js_decode", 1, 1, 0, f_js_decode},

View File

@ -62,7 +62,7 @@ func Ch_communicate(port)
" check that getjob without a job is handled correctly " check that getjob without a job is handled correctly
call assert_equal('no process', string(ch_getjob(handle))) call assert_equal('no process', string(ch_getjob(handle)))
let dict = ch_info(handle) let dict = handle->ch_info()
call assert_true(dict.id != 0) call assert_true(dict.id != 0)
call assert_equal('open', dict.status) call assert_equal('open', dict.status)
call assert_equal(a:port, string(dict.port)) call assert_equal(a:port, string(dict.port))
@ -148,7 +148,7 @@ func Ch_communicate(port)
call test_garbagecollect_now() call test_garbagecollect_now()
" check setting options (without testing the effect) " check setting options (without testing the effect)
call ch_setoptions(handle, {'callback': 's:NotUsed'}) eval handle->ch_setoptions({'callback': 's:NotUsed'})
call ch_setoptions(handle, {'timeout': 1111}) call ch_setoptions(handle, {'timeout': 1111})
call ch_setoptions(handle, {'mode': 'json'}) call ch_setoptions(handle, {'mode': 'json'})
call assert_fails("call ch_setoptions(handle, {'waittime': 111})", "E475") call assert_fails("call ch_setoptions(handle, {'waittime': 111})", "E475")
@ -227,7 +227,7 @@ endfunc
func Ch_two_channels(port) func Ch_two_channels(port)
let handle = ch_open('localhost:' . a:port, s:chopt) let handle = ch_open('localhost:' . a:port, s:chopt)
call assert_equal(v:t_channel, type(handle)) call assert_equal(v:t_channel, type(handle))
if ch_status(handle) == "fail" if handle->ch_status() == "fail"
call assert_report("Can't open channel") call assert_report("Can't open channel")
return return
endif endif
@ -249,7 +249,7 @@ func Ch_two_channels(port)
endfunc endfunc
func Test_two_channels() func Test_two_channels()
call ch_log('Test_two_channels()') eval 'Test_two_channels()'->ch_log()
call s:run_server('Ch_two_channels') call s:run_server('Ch_two_channels')
endfunc endfunc
@ -321,7 +321,7 @@ func Ch_oneHandler(chan, msg)
endfunc endfunc
func Ch_channel_zero(port) func Ch_channel_zero(port)
let handle = ch_open('localhost:' . a:port, s:chopt) let handle = ('localhost:' .. a:port)->ch_open(s:chopt)
if ch_status(handle) == "fail" if ch_status(handle) == "fail"
call assert_report("Can't open channel") call assert_report("Can't open channel")
return return
@ -478,8 +478,8 @@ func Test_raw_pipe()
call assert_equal("something\n", substitute(msg, "\r", "", 'g')) call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
call ch_sendraw(job, "double this\n") call ch_sendraw(job, "double this\n")
let g:handle = job_getchannel(job) let g:handle = job->job_getchannel()
call WaitFor('ch_canread(g:handle)') call WaitFor('g:handle->ch_canread()')
unlet g:handle unlet g:handle
let msg = ch_readraw(job) let msg = ch_readraw(job)
call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g')) call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
@ -488,7 +488,7 @@ func Test_raw_pipe()
call ch_sendraw(job, "double this\n", {'callback': 'Ch_handler'}) call ch_sendraw(job, "double this\n", {'callback': 'Ch_handler'})
call WaitForAssert({-> assert_equal("this\nAND this\n", substitute(g:Ch_reply, "\r", "", 'g'))}) call WaitForAssert({-> assert_equal("this\nAND this\n", substitute(g:Ch_reply, "\r", "", 'g'))})
let reply = ch_evalraw(job, "quit\n", {'timeout': 100}) let reply = job->ch_evalraw("quit\n", {'timeout': 100})
call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g')) call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g'))
finally finally
call job_stop(job) call job_stop(job)
@ -496,7 +496,7 @@ func Test_raw_pipe()
let g:Ch_job = job let g:Ch_job = job
call WaitForAssert({-> assert_equal("dead", job_status(g:Ch_job))}) call WaitForAssert({-> assert_equal("dead", job_status(g:Ch_job))})
let info = job_info(job) let info = job->job_info()
call assert_equal("dead", info.status) call assert_equal("dead", info.status)
call assert_equal("term", info.stoponexit) call assert_equal("term", info.stoponexit)
call assert_equal(2, len(info.cmd)) call assert_equal(2, len(info.cmd))
@ -534,7 +534,7 @@ func Test_raw_pipe_blob()
call ch_sendraw(job, blob) call ch_sendraw(job, blob)
" Read a blob with the reply. " Read a blob with the reply.
let msg = ch_readblob(job) let msg = job->ch_readblob()
let expected = 'something' let expected = 'something'
for i in range(0, len(expected) - 1) for i in range(0, len(expected) - 1)
call assert_equal(char2nr(expected[i]), msg[i]) call assert_equal(char2nr(expected[i]), msg[i])
@ -558,7 +558,7 @@ func Test_nl_pipe()
try try
let handle = job_getchannel(job) let handle = job_getchannel(job)
call ch_sendraw(handle, "echo something\n") call ch_sendraw(handle, "echo something\n")
call assert_equal("something", ch_readraw(handle)) call assert_equal("something", handle->ch_readraw())
call ch_sendraw(handle, "echoerr wrong\n") call ch_sendraw(handle, "echoerr wrong\n")
call assert_equal("wrong", ch_readraw(handle, {'part': 'err'})) call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
@ -568,7 +568,7 @@ func Test_nl_pipe()
call assert_equal("AND this", ch_readraw(handle)) call assert_equal("AND this", ch_readraw(handle))
call ch_sendraw(handle, "split this line\n") call ch_sendraw(handle, "split this line\n")
call assert_equal("this linethis linethis line", ch_read(handle)) call assert_equal("this linethis linethis line", handle->ch_read())
let reply = ch_evalraw(handle, "quit\n") let reply = ch_evalraw(handle, "quit\n")
call assert_equal("Goodbye!", reply) call assert_equal("Goodbye!", reply)
@ -873,7 +873,7 @@ func Run_pipe_through_sort(all, use_buffer)
if !a:use_buffer if !a:use_buffer
call assert_equal("run", job_status(job)) call assert_equal("run", job_status(job))
call ch_sendraw(job, "ccc\naaa\nddd\nbbb\neee\n") call ch_sendraw(job, "ccc\naaa\nddd\nbbb\neee\n")
call ch_close_in(job) eval job->ch_close_in()
endif endif
call WaitForAssert({-> assert_equal("dead", job_status(job))}) call WaitForAssert({-> assert_equal("dead", job_status(job))})
@ -917,7 +917,7 @@ func Test_pipe_to_nameless_buffer()
let handle = job_getchannel(job) let handle = job_getchannel(job)
call ch_sendraw(handle, "echo line one\n") call ch_sendraw(handle, "echo line one\n")
call ch_sendraw(handle, "echo line two\n") call ch_sendraw(handle, "echo line two\n")
exe ch_getbufnr(handle, "out") . 'sbuf' exe handle->ch_getbufnr("out") .. 'sbuf'
call WaitFor('line("$") >= 3') call WaitFor('line("$") >= 3')
call assert_equal(['Reading from channel output...', 'line one', 'line two'], getline(1, '$')) call assert_equal(['Reading from channel output...', 'line one', 'line two'], getline(1, '$'))
bwipe! bwipe!
@ -1249,7 +1249,7 @@ endfunc
func Test_close_and_exit_cb() func Test_close_and_exit_cb()
let g:retdict = {'ret': {}} let g:retdict = {'ret': {}}
func g:retdict.close_cb(ch) dict func g:retdict.close_cb(ch) dict
let self.ret['close_cb'] = job_status(ch_getjob(a:ch)) let self.ret['close_cb'] = a:ch->ch_getjob()->job_status()
endfunc endfunc
func g:retdict.exit_cb(job, status) dict func g:retdict.exit_cb(job, status) dict
let self.ret['exit_cb'] = job_status(a:job) let self.ret['exit_cb'] = job_status(a:job)
@ -1306,7 +1306,7 @@ endfunc
" Test that "unlet handle" in a handler doesn't crash Vim. " Test that "unlet handle" in a handler doesn't crash Vim.
func Ch_unlet_handle(port) func Ch_unlet_handle(port)
let s:channelfd = ch_open('localhost:' . a:port, s:chopt) let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')}) eval s:channelfd->ch_sendexpr("test", {'callback': function('s:UnletHandler')})
call WaitForAssert({-> assert_equal('what?', g:Ch_unletResponse)}) call WaitForAssert({-> assert_equal('what?', g:Ch_unletResponse)})
endfunc endfunc
@ -1320,7 +1320,7 @@ endfunc
let g:Ch_unletResponse = '' let g:Ch_unletResponse = ''
func Ch_CloseHandler(handle, msg) func Ch_CloseHandler(handle, msg)
let g:Ch_unletResponse = a:msg let g:Ch_unletResponse = a:msg
call ch_close(s:channelfd) eval s:channelfd->ch_close()
endfunc endfunc
" Test that "unlet handle" in a handler doesn't crash Vim. " Test that "unlet handle" in a handler doesn't crash Vim.
@ -1355,7 +1355,7 @@ func Ch_open_delay(port)
call assert_report("Can't open channel") call assert_report("Can't open channel")
return return
endif endif
call assert_equal('got it', ch_evalexpr(channel, 'hello!')) call assert_equal('got it', channel->ch_evalexpr('hello!'))
call ch_close(channel) call ch_close(channel)
endfunc endfunc
@ -1396,7 +1396,7 @@ function MyExitCb(job, status)
endfunc endfunc
function Ch_test_exit_callback(port) function Ch_test_exit_callback(port)
call job_setoptions(g:currentJob, {'exit_cb': 'MyExitCb'}) eval g:currentJob->job_setoptions({'exit_cb': 'MyExitCb'})
let g:Ch_exit_job = g:currentJob let g:Ch_exit_job = g:currentJob
call assert_equal('MyExitCb', job_info(g:currentJob)['exit_cb']) call assert_equal('MyExitCb', job_info(g:currentJob)['exit_cb'])
endfunc endfunc
@ -1428,7 +1428,7 @@ endfunction
func Test_exit_callback_interval() func Test_exit_callback_interval()
let g:exit_cb_val = {'start': reltime(), 'end': 0, 'process': 0} let g:exit_cb_val = {'start': reltime(), 'end': 0, 'process': 0}
let job = job_start([s:python, '-c', 'import time;time.sleep(0.5)'], {'exit_cb': 'MyExitTimeCb'}) let job = [s:python, '-c', 'import time;time.sleep(0.5)']->job_start({'exit_cb': 'MyExitTimeCb'})
let g:exit_cb_val.process = job_info(job).process let g:exit_cb_val.process = job_info(job).process
call WaitFor('type(g:exit_cb_val.end) != v:t_number || g:exit_cb_val.end != 0') call WaitFor('type(g:exit_cb_val.end) != v:t_number || g:exit_cb_val.end != 0')
let elapsed = reltimefloat(g:exit_cb_val.end) let elapsed = reltimefloat(g:exit_cb_val.end)
@ -1507,7 +1507,7 @@ endfunc
func Test_job_stop_immediately() func Test_job_stop_immediately()
let g:job = job_start([s:python, '-c', 'import time;time.sleep(10)']) let g:job = job_start([s:python, '-c', 'import time;time.sleep(10)'])
try try
call job_stop(g:job) eval g:job->job_stop()
call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
finally finally
call job_stop(g:job, 'kill') call job_stop(g:job, 'kill')
@ -1821,7 +1821,7 @@ func Test_raw_large_data()
let outlen = 79999 let outlen = 79999
let want = repeat('X', outlen) . "\n" let want = repeat('X', outlen) . "\n"
call ch_sendraw(job, want) eval job->ch_sendraw(want)
call WaitFor({-> len(g:out) >= outlen}, 10000) call WaitFor({-> len(g:out) >= outlen}, 10000)
call WaitForAssert({-> assert_equal("dead", job_status(job))}) call WaitForAssert({-> assert_equal("dead", job_status(job))})
call assert_equal(want, substitute(g:out, '\r', '', 'g')) call assert_equal(want, substitute(g:out, '\r', '', 'g'))
@ -1919,7 +1919,7 @@ endfunc
" Do this last, it stops any channel log. " Do this last, it stops any channel log.
func Test_zz_nl_err_to_out_pipe() func Test_zz_nl_err_to_out_pipe()
call ch_logfile('Xlog') eval 'Xlog'->ch_logfile()
call ch_log('Test_zz_nl_err_to_out_pipe()') call ch_log('Test_zz_nl_err_to_out_pipe()')
let job = job_start(s:python . " test_channel_pipe.py", {'err_io': 'out'}) let job = job_start(s:python . " test_channel_pipe.py", {'err_io': 'out'})
call assert_equal("run", job_status(job)) call assert_equal("run", job_status(job))

View File

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