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
@ -474,18 +474,25 @@ ch_canread({handle}) *ch_canread()*
Note that messages are dropped when the channel does not have
a callback. Add a close callback to avoid that.
Can also be used as a |method|: >
GetChannel()->ch_canread()
ch_close({handle}) *ch_close()*
Close {handle}. See |channel-close|.
{handle} can be a Channel or a Job that has a Channel.
A close callback is not invoked.
Can also be used as a |method|: >
GetChannel()->ch_close()
ch_close_in({handle}) *ch_close_in()*
Close the "in" part of {handle}. See |channel-close-in|.
{handle} can be a Channel or a Job that has a Channel.
A close callback is not invoked.
Can also be used as a |method|: >
GetChannel()->ch_close_in()
ch_evalexpr({handle}, {expr} [, {options}]) *ch_evalexpr()*
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
empty string.
Can also be used as a |method|: >
GetChannel()->ch_evalexpr(expr)
ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
Send {string} over {handle}.
@ -516,6 +526,8 @@ ch_evalraw({handle}, {string} [, {options}]) *ch_evalraw()*
need to use |ch_readraw()| to fetch the rest.
See |channel-use|.
Can also be used as a |method|: >
GetChannel()->ch_evalraw(rawstring)
ch_getbufnr({handle}, {what}) *ch_getbufnr()*
Get the buffer number that {handle} is using for {what}.
@ -524,12 +536,17 @@ ch_getbufnr({handle}, {what}) *ch_getbufnr()*
socket output.
Returns -1 when there is no buffer.
Can also be used as a |method|: >
GetChannel()->ch_getbufnr(what)
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".
Can also be used as a |method|: >
GetChannel()->ch_getjob()
ch_info({handle}) *ch_info()*
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_timeout" timeout in msec
Can also be used as a |method|: >
GetChannel()->ch_info()
ch_log({msg} [, {handle}]) *ch_log()*
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
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()*
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
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()*
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|.
See |channel-open-options|.
Can also be used as a |method|: >
GetAddress()->ch_open()
ch_read({handle} [, {options}]) *ch_read()*
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).
See |channel-more|.
Can also be used as a |method|: >
GetChannel()->ch_read()
ch_readblob({handle} [, {options}]) *ch_readblob()*
Like ch_read() but reads binary data and returns a |Blob|.
See |channel-more|.
Can also be used as a |method|: >
GetChannel()->ch_readblob()
ch_readraw({handle} [, {options}]) *ch_readraw()*
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().
See |channel-more|.
Can also be used as a |method|: >
GetChannel()->ch_readraw()
ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
Send {expr} over {handle}. The {expr} is encoded
@ -623,6 +661,9 @@ ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
See |channel-use|. *E912*
{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()*
Send |String| or |Blob| {expr} over {handle}.
@ -633,6 +674,9 @@ ch_sendraw({handle}, {expr} [, {options}]) *ch_sendraw()*
is removed.
See |channel-use|.
Can also be used as a |method|: >
GetChannel()->ch_sendraw(rawexpr)
ch_setoptions({handle}, {options}) *ch_setoptions()*
Set options on {handle}:
@ -648,6 +692,9 @@ ch_setoptions({handle}, {options}) *ch_setoptions()*
These options cannot be changed:
"waittime" only applies to |ch_open()|
Can also be used as a |method|: >
GetChannel()->ch_setoptions(options)
ch_status({handle} [, {options}]) *ch_status()*
Return the status of {handle}:
@ -664,6 +711,8 @@ ch_status({handle} [, {options}]) *ch_status()*
"err". For example, to get the error status: >
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*
@ -792,6 +841,8 @@ job_getchannel({job}) *job_getchannel()*
To check if the job has no channel: >
if string(job_getchannel()) == 'channel fail'
<
Can also be used as a |method|: >
GetJob()->job_getchannel()
job_info([{job}]) *job_info()*
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.
Can also be used as a |method|: >
GetJob()->job_info()
job_setoptions({job}, {options}) *job_setoptions()*
Change options for {job}. Supported are:
"stoponexit" |job-stoponexit|
"exit_cb" |job-exit_cb|
Can also be used as a |method|: >
GetJob()->job_setoptions(options)
job_start({command} [, {options}]) *job_start()*
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
items, see |job-options|.
Can also be used as a |method|: >
BuildCommand()->job_start()
job_status({job}) *job_status()* *E916*
Returns a String with the status of {job}:
@ -897,6 +957,9 @@ job_status({job}) *job_status()* *E916*
For more information see |job_info()|.
Can also be used as a |method|: >
GetJob()->job_status()
job_stop({job} [, {how}]) *job_stop()*
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
the channel.
Can also be used as a |method|: >
GetJob()->job_stop()
==============================================================================
12. Job options *job-options*

View File

@ -474,24 +474,24 @@ static funcentry_T global_functions[] =
{"ceil", 1, 1, FEARG_1, f_ceil},
#endif
#ifdef FEAT_JOB_CHANNEL
{"ch_canread", 1, 1, 0, f_ch_canread},
{"ch_close", 1, 1, 0, f_ch_close},
{"ch_close_in", 1, 1, 0, f_ch_close_in},
{"ch_evalexpr", 2, 3, 0, f_ch_evalexpr},
{"ch_evalraw", 2, 3, 0, f_ch_evalraw},
{"ch_getbufnr", 2, 2, 0, f_ch_getbufnr},
{"ch_getjob", 1, 1, 0, f_ch_getjob},
{"ch_info", 1, 1, 0, f_ch_info},
{"ch_log", 1, 2, 0, f_ch_log},
{"ch_logfile", 1, 2, 0, f_ch_logfile},
{"ch_open", 1, 2, 0, f_ch_open},
{"ch_read", 1, 2, 0, f_ch_read},
{"ch_readblob", 1, 2, 0, f_ch_readblob},
{"ch_readraw", 1, 2, 0, f_ch_readraw},
{"ch_sendexpr", 2, 3, 0, f_ch_sendexpr},
{"ch_sendraw", 2, 3, 0, f_ch_sendraw},
{"ch_setoptions", 2, 2, 0, f_ch_setoptions},
{"ch_status", 1, 2, 0, f_ch_status},
{"ch_canread", 1, 1, FEARG_1, f_ch_canread},
{"ch_close", 1, 1, FEARG_1, f_ch_close},
{"ch_close_in", 1, 1, FEARG_1, f_ch_close_in},
{"ch_evalexpr", 2, 3, FEARG_1, f_ch_evalexpr},
{"ch_evalraw", 2, 3, FEARG_1, f_ch_evalraw},
{"ch_getbufnr", 2, 2, FEARG_1, f_ch_getbufnr},
{"ch_getjob", 1, 1, FEARG_1, f_ch_getjob},
{"ch_info", 1, 1, FEARG_1, f_ch_info},
{"ch_log", 1, 2, FEARG_1, f_ch_log},
{"ch_logfile", 1, 2, FEARG_1, f_ch_logfile},
{"ch_open", 1, 2, FEARG_1, f_ch_open},
{"ch_read", 1, 2, FEARG_1, f_ch_read},
{"ch_readblob", 1, 2, FEARG_1, f_ch_readblob},
{"ch_readraw", 1, 2, FEARG_1, f_ch_readraw},
{"ch_sendexpr", 2, 3, FEARG_1, f_ch_sendexpr},
{"ch_sendraw", 2, 3, FEARG_1, f_ch_sendraw},
{"ch_setoptions", 2, 2, FEARG_1, f_ch_setoptions},
{"ch_status", 1, 2, FEARG_1, f_ch_status},
#endif
{"changenr", 0, 0, 0, f_changenr},
{"char2nr", 1, 2, 0, f_char2nr},
@ -635,12 +635,12 @@ static funcentry_T global_functions[] =
#endif
{"items", 1, 1, FEARG_1, f_items},
#ifdef FEAT_JOB_CHANNEL
{"job_getchannel", 1, 1, 0, f_job_getchannel},
{"job_info", 0, 1, 0, f_job_info},
{"job_setoptions", 2, 2, 0, f_job_setoptions},
{"job_start", 1, 2, 0, f_job_start},
{"job_status", 1, 1, 0, f_job_status},
{"job_stop", 1, 2, 0, f_job_stop},
{"job_getchannel", 1, 1, FEARG_1, f_job_getchannel},
{"job_info", 0, 1, FEARG_1, f_job_info},
{"job_setoptions", 2, 2, FEARG_1, f_job_setoptions},
{"job_start", 1, 2, FEARG_1, f_job_start},
{"job_status", 1, 1, FEARG_1, f_job_status},
{"job_stop", 1, 2, FEARG_1, f_job_stop},
#endif
{"join", 1, 2, FEARG_1, f_join},
{"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
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_equal('open', dict.status)
call assert_equal(a:port, string(dict.port))
@ -148,7 +148,7 @@ func Ch_communicate(port)
call test_garbagecollect_now()
" 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, {'mode': 'json'})
call assert_fails("call ch_setoptions(handle, {'waittime': 111})", "E475")
@ -227,7 +227,7 @@ endfunc
func Ch_two_channels(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
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")
return
endif
@ -249,7 +249,7 @@ func Ch_two_channels(port)
endfunc
func Test_two_channels()
call ch_log('Test_two_channels()')
eval 'Test_two_channels()'->ch_log()
call s:run_server('Ch_two_channels')
endfunc
@ -321,7 +321,7 @@ func Ch_oneHandler(chan, msg)
endfunc
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"
call assert_report("Can't open channel")
return
@ -478,8 +478,8 @@ func Test_raw_pipe()
call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
call ch_sendraw(job, "double this\n")
let g:handle = job_getchannel(job)
call WaitFor('ch_canread(g:handle)')
let g:handle = job->job_getchannel()
call WaitFor('g:handle->ch_canread()')
unlet g:handle
let msg = ch_readraw(job)
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 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'))
finally
call job_stop(job)
@ -496,7 +496,7 @@ func Test_raw_pipe()
let g:Ch_job = 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("term", info.stoponexit)
call assert_equal(2, len(info.cmd))
@ -534,7 +534,7 @@ func Test_raw_pipe_blob()
call ch_sendraw(job, blob)
" Read a blob with the reply.
let msg = ch_readblob(job)
let msg = job->ch_readblob()
let expected = 'something'
for i in range(0, len(expected) - 1)
call assert_equal(char2nr(expected[i]), msg[i])
@ -558,7 +558,7 @@ func Test_nl_pipe()
try
let handle = job_getchannel(job)
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 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 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")
call assert_equal("Goodbye!", reply)
@ -873,7 +873,7 @@ func Run_pipe_through_sort(all, use_buffer)
if !a:use_buffer
call assert_equal("run", job_status(job))
call ch_sendraw(job, "ccc\naaa\nddd\nbbb\neee\n")
call ch_close_in(job)
eval job->ch_close_in()
endif
call WaitForAssert({-> assert_equal("dead", job_status(job))})
@ -917,7 +917,7 @@ func Test_pipe_to_nameless_buffer()
let handle = job_getchannel(job)
call ch_sendraw(handle, "echo line one\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 assert_equal(['Reading from channel output...', 'line one', 'line two'], getline(1, '$'))
bwipe!
@ -1249,7 +1249,7 @@ endfunc
func Test_close_and_exit_cb()
let g:retdict = {'ret': {}}
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
func g:retdict.exit_cb(job, status) dict
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.
func Ch_unlet_handle(port)
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)})
endfunc
@ -1320,7 +1320,7 @@ endfunc
let g:Ch_unletResponse = ''
func Ch_CloseHandler(handle, msg)
let g:Ch_unletResponse = a:msg
call ch_close(s:channelfd)
eval s:channelfd->ch_close()
endfunc
" 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")
return
endif
call assert_equal('got it', ch_evalexpr(channel, 'hello!'))
call assert_equal('got it', channel->ch_evalexpr('hello!'))
call ch_close(channel)
endfunc
@ -1396,7 +1396,7 @@ function MyExitCb(job, status)
endfunc
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
call assert_equal('MyExitCb', job_info(g:currentJob)['exit_cb'])
endfunc
@ -1428,7 +1428,7 @@ endfunction
func Test_exit_callback_interval()
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
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)
@ -1507,7 +1507,7 @@ endfunc
func Test_job_stop_immediately()
let g:job = job_start([s:python, '-c', 'import time;time.sleep(10)'])
try
call job_stop(g:job)
eval g:job->job_stop()
call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
finally
call job_stop(g:job, 'kill')
@ -1821,7 +1821,7 @@ func Test_raw_large_data()
let outlen = 79999
let want = repeat('X', outlen) . "\n"
call ch_sendraw(job, want)
eval job->ch_sendraw(want)
call WaitFor({-> len(g:out) >= outlen}, 10000)
call WaitForAssert({-> assert_equal("dead", job_status(job))})
call assert_equal(want, substitute(g:out, '\r', '', 'g'))
@ -1919,7 +1919,7 @@ endfunc
" Do this last, it stops any channel log.
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()')
let job = job_start(s:python . " test_channel_pipe.py", {'err_io': 'out'})
call assert_equal("run", job_status(job))

View File

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