changeset 17831:4ab97fdf7ff7 v8.1.1912

patch 8.1.1912: more functions can be used as methods Commit: https://github.com/vim/vim/commit/570497ac409ad448574bb6210cb9c6e573483759 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Aug 22 22:55:13 2019 +0200 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.
author Bram Moolenaar <Bram@vim.org>
date Thu, 22 Aug 2019 23:00:03 +0200
parents e8805fbb60a3
children 756153721e77
files runtime/doc/channel.txt src/evalfunc.c src/testdir/test_channel.vim src/version.c
diffstat 4 files changed, 116 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/channel.txt
+++ b/runtime/doc/channel.txt
@@ -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
 		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} [, {option
 		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_ge
 		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_l
 		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_
 		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_
 		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
 		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
 		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}
 		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
 		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
 		"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_getchann
 		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}])			*jo
 		{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()* *E9
 
 		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*
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -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},
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -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_buff
   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))
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1912,
+/**/
     1911,
 /**/
     1910,