summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/channel.c12
-rw-r--r--src/eval.c47
-rw-r--r--src/os_unix.c2
-rw-r--r--src/os_win32.c2
-rw-r--r--src/proto/channel.pro3
-rw-r--r--src/structs.h5
-rw-r--r--src/testdir/test_channel.vim20
-rw-r--r--src/version.c2
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,