diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/channel.c | 12 | ||||
-rw-r--r-- | src/eval.c | 47 | ||||
-rw-r--r-- | src/os_unix.c | 2 | ||||
-rw-r--r-- | src/os_win32.c | 2 | ||||
-rw-r--r-- | src/proto/channel.pro | 3 | ||||
-rw-r--r-- | src/structs.h | 5 | ||||
-rw-r--r-- | src/testdir/test_channel.vim | 20 | ||||
-rw-r--r-- | src/version.c | 2 |
8 files changed, 62 insertions, 31 deletions
diff --git a/src/channel.c b/src/channel.c index 3cfe1bea3..d4663d86e 100644 --- a/src/channel.c +++ b/src/channel.c @@ -697,6 +697,18 @@ channel_set_callback(channel_T *channel, char_u *callback) } /* + * Set various properties from an "options" argument. + */ + void +channel_set_options(channel_T *channel, jobopt_T *options) +{ + channel_set_mode(channel, options->jo_mode); + + if (options->jo_callback != NULL && *options->jo_callback != NUL) + channel_set_callback(channel, options->jo_callback); +} + +/* * Set the callback for channel "channel" for the response with "id". */ void diff --git a/src/eval.c b/src/eval.c index 8e4e5400a..f47b09609 100644 --- a/src/eval.c +++ b/src/eval.c @@ -9930,15 +9930,18 @@ f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED) } /* - * Get the "mode" entry from "dict", if it exists, and parse the mode name. - * If the mode is invalide return FAIL. + * Get the option entries from "dict", and parse them. + * If an option value is invalid return FAIL. */ static int -get_mode_arg(dict_T *dict, jobopt_T *opt) +get_job_options(dict_T *dict, jobopt_T *opt) { dictitem_T *item; char_u *mode; + if (dict == NULL) + return OK; + if ((item = dict_find(dict, (char_u *)"mode", -1)) != NULL) { mode = get_tv_string(&item->di_tv); @@ -9956,6 +9959,17 @@ get_mode_arg(dict_T *dict, jobopt_T *opt) return FAIL; } } + + if ((item = dict_find(dict, (char_u *)"callback", -1)) != NULL) + { + opt->jo_callback = get_callback(&item->di_tv); + if (opt->jo_callback == NULL) + { + EMSG2(_(e_invarg2), "callback"); + return FAIL; + } + } + return OK; } @@ -9966,7 +9980,6 @@ get_mode_arg(dict_T *dict, jobopt_T *opt) f_ch_open(typval_T *argvars, typval_T *rettv) { char_u *address; - char_u *callback = NULL; char_u *p; char *rest; int port; @@ -10004,20 +10017,19 @@ f_ch_open(typval_T *argvars, typval_T *rettv) } options.jo_mode = MODE_JSON; + options.jo_callback = NULL; if (argvars[1].v_type == VAR_DICT) { dict_T *dict = argvars[1].vval.v_dict; dictitem_T *item; /* parse argdict */ - if (get_mode_arg(dict, &options) == FAIL) + if (get_job_options(dict, &options) == FAIL) return; if ((item = dict_find(dict, (char_u *)"waittime", -1)) != NULL) waittime = get_tv_number(&item->di_tv); if ((item = dict_find(dict, (char_u *)"timeout", -1)) != NULL) timeout = get_tv_number(&item->di_tv); - if ((item = dict_find(dict, (char_u *)"callback", -1)) != NULL) - callback = get_callback(&item->di_tv); } if (waittime < 0 || timeout < 0) { @@ -10029,10 +10041,8 @@ f_ch_open(typval_T *argvars, typval_T *rettv) if (channel != NULL) { rettv->vval.v_channel = channel; - channel_set_mode(channel, options.jo_mode); + channel_set_options(channel, &options); channel_set_timeout(channel, timeout); - if (callback != NULL && *callback != NUL) - channel_set_callback(channel, callback); } } @@ -10082,6 +10092,7 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun) { channel_T *channel; char_u *callback = NULL; + jobopt_T options; channel = get_channel_arg(&argvars[0]); if (channel == NULL) @@ -10089,9 +10100,15 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun) if (argvars[2].v_type != VAR_UNKNOWN) { - callback = get_callback(&argvars[2]); - if (callback == NULL) + if (argvars[2].v_type != VAR_DICT) + { + EMSG(_(e_invarg)); + return NULL; + } + options.jo_callback = NULL; + if (get_job_options(argvars[2].vval.v_dict, &options) == FAIL) return NULL; + callback = options.jo_callback; } /* Set the callback. An empty callback means no callback and not reading * the response. */ @@ -14511,17 +14528,15 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv) /* Default mode is NL. */ options.jo_mode = MODE_NL; + options.jo_callback = NULL; if (argvars[1].v_type != VAR_UNKNOWN) { - dict_T *dict; - if (argvars[1].v_type != VAR_DICT) { EMSG(_(e_invarg)); return; } - dict = argvars[1].vval.v_dict; - if (get_mode_arg(dict, &options) == FAIL) + if (get_job_options(argvars[1].vval.v_dict, &options) == FAIL) return; } diff --git a/src/os_unix.c b/src/os_unix.c index 0059c9eee..1f0f2c804 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5127,7 +5127,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options) # ifdef FEAT_CHANNEL channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]); channel_set_job(channel, job); - channel_set_mode(channel, options->jo_mode); + channel_set_options(channel, options); # ifdef FEAT_GUI channel_gui_register(channel); # endif diff --git a/src/os_win32.c b/src/os_win32.c index eaa8ba5f5..63d7d60cb 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -5125,7 +5125,7 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options) job->jv_channel = channel; channel_set_pipes(channel, (sock_T)ifd[1], (sock_T)ofd[0], (sock_T)efd[0]); channel_set_job(channel, job); - channel_set_mode(channel, options->jo_mode); + channel_set_options(channel, options); # ifdef FEAT_GUI channel_gui_register(channel); diff --git a/src/proto/channel.pro b/src/proto/channel.pro index e1c88627f..a4acfe6d1 100644 --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -7,9 +7,10 @@ void channel_gui_register_all(void); channel_T *channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)); void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err); void channel_set_job(channel_T *channel, job_T *job); -void channel_set_mode(channel_T *channel, ch_mode_T ch_mode); +void channel_set_mode(channel_T *channel, ch_mode_T mode); void channel_set_timeout(channel_T *channel, int timeout); void channel_set_callback(channel_T *channel, char_u *callback); +void channel_set_options(channel_T *channel, jobopt_T *options); void channel_set_req_callback(channel_T *channel, char_u *callback, int id); char_u *channel_get(channel_T *channel); int channel_collapse(channel_T *channel); diff --git a/src/structs.h b/src/structs.h index eb72f90f2..802180bb7 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1373,11 +1373,12 @@ struct channel_S { }; /* - * Options for job commands. + * Options for job and channel commands. */ typedef struct { - ch_mode_T jo_mode; + ch_mode_T jo_mode; /* "mode" */ + char_u *jo_callback; /* "callback", not allocated! */ } jobopt_T; diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index e9c2a98e7..7cd32c81b 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -117,7 +117,7 @@ func s:communicate(port) call assert_equal('added more', getline('$')) " Send a request with a specific handler. - call ch_sendexpr(handle, 'hello!', 's:RequestHandler') + call ch_sendexpr(handle, 'hello!', {'callback': 's:RequestHandler'}) sleep 10m if !exists('s:responseHandle') call assert_false(1, 's:responseHandle was not set') @@ -128,7 +128,7 @@ func s:communicate(port) unlet s:responseHandle let s:responseMsg = '' - call ch_sendexpr(handle, 'hello!', function('s:RequestHandler')) + call ch_sendexpr(handle, 'hello!', {'callback': function('s:RequestHandler')}) sleep 10m if !exists('s:responseHandle') call assert_false(1, 's:responseHandle was not set') @@ -171,7 +171,7 @@ func s:communicate(port) call assert_equal('ok', ch_sendexpr(handle, 'empty-request')) " make the server quit, can't check if this works, should not hang. - call ch_sendexpr(handle, '!quit!', 0) + call ch_sendexpr(handle, '!quit!', {'callback': 0}) endfunc func Test_communicate() @@ -242,7 +242,7 @@ func s:channel_handler(port) call assert_equal('we called you', s:reply) " Test that it works while not waiting on a numbered message. - call ch_sendexpr(handle, 'call me again', 0) + call ch_sendexpr(handle, 'call me again', {'callback': 0}) sleep 10m call assert_equal('we did call you', s:reply) endfunc @@ -292,11 +292,11 @@ func Test_raw_pipe() call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) - call ch_sendraw(handle, "echo something\n", 0) + call ch_sendraw(handle, "echo something\n", {'callback': 0}) let msg = ch_readraw(handle) call assert_equal("something\n", substitute(msg, "\r", "", 'g')) - call ch_sendraw(handle, "double this\n", 0) + call ch_sendraw(handle, "double this\n", {'callback': 0}) let msg = ch_readraw(handle) call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g')) @@ -315,10 +315,10 @@ func Test_nl_pipe() call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) - call ch_sendraw(handle, "echo something\n", 0) + call ch_sendraw(handle, "echo something\n", {'callback': 0}) call assert_equal("something", ch_readraw(handle)) - call ch_sendraw(handle, "double this\n", 0) + call ch_sendraw(handle, "double this\n", {'callback': 0}) call assert_equal("this", ch_readraw(handle)) call assert_equal("AND this", ch_readraw(handle)) @@ -340,7 +340,7 @@ endfunc " Test that "unlet handle" in a handler doesn't crash Vim. func s:unlet_handle(port) let s:channelfd = ch_open('localhost:' . a:port, s:chopt) - call ch_sendexpr(s:channelfd, "test", function('s:UnletHandler')) + call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')}) sleep 10m call assert_equal('what?', s:unletResponse) endfunc @@ -360,7 +360,7 @@ endfunc " Test that "unlet handle" in a handler doesn't crash Vim. func s:close_handle(port) let s:channelfd = ch_open('localhost:' . a:port, s:chopt) - call ch_sendexpr(s:channelfd, "test", function('s:CloseHandler')) + call ch_sendexpr(s:channelfd, "test", {'callback': function('s:CloseHandler')}) sleep 10m call assert_equal('what?', s:unletResponse) endfunc diff --git a/src/version.c b/src/version.c index 9821bdfc9..f7c008ce2 100644 --- a/src/version.c +++ b/src/version.c @@ -748,6 +748,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1341, +/**/ 1340, /**/ 1339, |