diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-02-27 19:21:24 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-02-27 19:21:24 +0100 |
commit | 8b1862a31639becadcbbca5dc2eaa92db73e8e5f (patch) | |
tree | 32ce5d730c990033e18518441cf654fca6a9a673 /src | |
parent | b6ff81188d27fae774d9ad2dfb498f596d697d4b (diff) | |
download | vim-git-8b1862a31639becadcbbca5dc2eaa92db73e8e5f.tar.gz |
patch 7.4.1435v7.4.1435
Problem: It is confusing that ch_sendexpr() and ch_sendraw() wait for a
response.
Solution: Add ch_evalexpr() and ch_evalraw().
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 78 | ||||
-rw-r--r-- | src/testdir/test_channel.vim | 94 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 130 insertions, 44 deletions
diff --git a/src/eval.c b/src/eval.c index f69e81431..323caf1e5 100644 --- a/src/eval.c +++ b/src/eval.c @@ -507,6 +507,8 @@ static void f_ceil(typval_T *argvars, typval_T *rettv); #endif #ifdef FEAT_CHANNEL static void f_ch_close(typval_T *argvars, typval_T *rettv); +static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv); +static void f_ch_evalraw(typval_T *argvars, typval_T *rettv); # ifdef FEAT_JOB static void f_ch_getjob(typval_T *argvars, typval_T *rettv); # endif @@ -8201,6 +8203,8 @@ static struct fst #endif #ifdef FEAT_CHANNEL {"ch_close", 1, 1, f_ch_close}, + {"ch_evalexpr", 2, 3, f_ch_evalexpr}, + {"ch_evalraw", 2, 3, f_ch_evalraw}, # ifdef FEAT_JOB {"ch_getjob", 1, 1, f_ch_getjob}, # endif @@ -10485,7 +10489,13 @@ f_ch_readraw(typval_T *argvars, typval_T *rettv) * Otherwise returns NULL. */ static channel_T * -send_common(typval_T *argvars, char_u *text, int id, char *fun, int *part_read) +send_common( + typval_T *argvars, + char_u *text, + int id, + int eval, + char *fun, + int *part_read) { channel_T *channel; jobopt_T opt; @@ -10502,9 +10512,17 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun, int *part_read) return NULL; /* Set the callback. An empty callback means no callback and not reading - * the response. */ + * the response. With "ch_evalexpr()" and "ch_evalraw()" a callback is not + * allowed. */ if (opt.jo_callback != NULL && *opt.jo_callback != NUL) + { + if (eval) + { + EMSG2(_("E917: Cannot use a callback with %s()"), fun); + return NULL; + } channel_set_req_callback(channel, part_send, opt.jo_callback, id); + } if (channel_send(channel, part_send, text, fun) == OK && opt.jo_callback == NULL) @@ -10513,10 +10531,10 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun, int *part_read) } /* - * "ch_sendexpr()" function + * common for "ch_evalexpr()" and "ch_sendexpr()" */ static void -f_ch_sendexpr(typval_T *argvars, typval_T *rettv) +ch_expr_common(typval_T *argvars, typval_T *rettv, int eval) { char_u *text; typval_T *listtv; @@ -10539,7 +10557,7 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv) ch_mode = channel_get_mode(channel, part_send); if (ch_mode == MODE_RAW || ch_mode == MODE_NL) { - EMSG(_("E912: cannot use ch_sendexpr() with a raw or nl channel")); + EMSG(_("E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel")); return; } @@ -10549,9 +10567,10 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv) if (text == NULL) return; - channel = send_common(argvars, text, id, "sendexpr", &part_read); + channel = send_common(argvars, text, id, eval, + eval ? "ch_evalexpr" : "ch_sendexpr", &part_read); vim_free(text); - if (channel != NULL) + if (channel != NULL && eval) { /* TODO: timeout from options */ timeout = channel_get_timeout(channel, part_read); @@ -10570,10 +10589,28 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv) } /* - * "ch_sendraw()" function + * "ch_evalexpr()" function */ static void -f_ch_sendraw(typval_T *argvars, typval_T *rettv) +f_ch_evalexpr(typval_T *argvars, typval_T *rettv) +{ + ch_expr_common(argvars, rettv, TRUE); +} + +/* + * "ch_sendexpr()" function + */ + static void +f_ch_sendexpr(typval_T *argvars, typval_T *rettv) +{ + ch_expr_common(argvars, rettv, FALSE); +} + +/* + * common for "ch_evalraw()" and "ch_sendraw()" + */ + static void +ch_raw_common(typval_T *argvars, typval_T *rettv, int eval) { char_u buf[NUMBUFLEN]; char_u *text; @@ -10586,8 +10623,9 @@ f_ch_sendraw(typval_T *argvars, typval_T *rettv) rettv->vval.v_string = NULL; text = get_tv_string_buf(&argvars[1], buf); - channel = send_common(argvars, text, 0, "sendraw", &part_read); - if (channel != NULL) + channel = send_common(argvars, text, 0, eval, + eval ? "ch_evalraw" : "ch_sendraw", &part_read); + if (channel != NULL && eval) { /* TODO: timeout from options */ timeout = channel_get_timeout(channel, part_read); @@ -10596,6 +10634,24 @@ f_ch_sendraw(typval_T *argvars, typval_T *rettv) } /* + * "ch_evalraw()" function + */ + static void +f_ch_evalraw(typval_T *argvars, typval_T *rettv) +{ + ch_raw_common(argvars, rettv, TRUE); +} + +/* + * "ch_sendraw()" function + */ + static void +f_ch_sendraw(typval_T *argvars, typval_T *rettv) +{ + ch_raw_common(argvars, rettv, FALSE); +} + +/* * "ch_setoptions()" function */ static void diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 69922b140..a3955e16a 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -110,17 +110,17 @@ func s:communicate(port) endif " Simple string request and reply. - call assert_equal('got it', ch_sendexpr(handle, 'hello!')) + call assert_equal('got it', ch_evalexpr(handle, 'hello!')) " Request that triggers sending two ex commands. These will usually be " handled before getting the response, but it's not guaranteed, thus wait a " tiny bit for the commands to get executed. - call assert_equal('ok', ch_sendexpr(handle, 'make change')) + call assert_equal('ok', ch_evalexpr(handle, 'make change')) sleep 10m call assert_equal('added1', getline(line('$') - 1)) call assert_equal('added2', getline('$')) - call assert_equal('ok', ch_sendexpr(handle, 'do normal')) + call assert_equal('ok', ch_evalexpr(handle, 'do normal')) sleep 10m call assert_equal('added more', getline('$')) @@ -154,37 +154,37 @@ func s:communicate(port) call ch_setoptions(handle, {'callback': ''}) " Send an eval request that works. - call assert_equal('ok', ch_sendexpr(handle, 'eval-works')) + call assert_equal('ok', ch_evalexpr(handle, 'eval-works')) sleep 10m - call assert_equal([-1, 'foo123'], ch_sendexpr(handle, 'eval-result')) + call assert_equal([-1, 'foo123'], ch_evalexpr(handle, 'eval-result')) " Send an eval request that fails. - call assert_equal('ok', ch_sendexpr(handle, 'eval-fails')) + call assert_equal('ok', ch_evalexpr(handle, 'eval-fails')) sleep 10m - call assert_equal([-2, 'ERROR'], ch_sendexpr(handle, 'eval-result')) + call assert_equal([-2, 'ERROR'], ch_evalexpr(handle, 'eval-result')) " Send an eval request that works but can't be encoded. - call assert_equal('ok', ch_sendexpr(handle, 'eval-error')) + call assert_equal('ok', ch_evalexpr(handle, 'eval-error')) sleep 10m - call assert_equal([-3, 'ERROR'], ch_sendexpr(handle, 'eval-result')) + call assert_equal([-3, 'ERROR'], ch_evalexpr(handle, 'eval-result')) " Send a bad eval request. There will be no response. - call assert_equal('ok', ch_sendexpr(handle, 'eval-bad')) + call assert_equal('ok', ch_evalexpr(handle, 'eval-bad')) sleep 10m - call assert_equal([-3, 'ERROR'], ch_sendexpr(handle, 'eval-result')) + call assert_equal([-3, 'ERROR'], ch_evalexpr(handle, 'eval-result')) " Send an expr request - call assert_equal('ok', ch_sendexpr(handle, 'an expr')) + call assert_equal('ok', ch_evalexpr(handle, 'an expr')) sleep 10m call assert_equal('one', getline(line('$') - 2)) call assert_equal('two', getline(line('$') - 1)) call assert_equal('three', getline('$')) " Request a redraw, we don't check for the effect. - call assert_equal('ok', ch_sendexpr(handle, 'redraw')) - call assert_equal('ok', ch_sendexpr(handle, 'redraw!')) + call assert_equal('ok', ch_evalexpr(handle, 'redraw')) + call assert_equal('ok', ch_evalexpr(handle, 'redraw!')) - call assert_equal('ok', ch_sendexpr(handle, 'empty-request')) + call assert_equal('ok', ch_evalexpr(handle, 'empty-request')) " Reading while there is nothing available. call assert_equal(v:none, ch_read(handle, {'timeout': 0})) @@ -195,14 +195,14 @@ func s:communicate(port) call assert_true(reltimefloat(elapsed) < 0.6) " Send without waiting for a response, then wait for a response. - call ch_sendexpr(handle, 'wait a bit', {'callback': 0}) + call ch_sendexpr(handle, 'wait a bit') let resp = ch_read(handle) call assert_equal(type([]), type(resp)) call assert_equal(type(11), type(resp[0])) call assert_equal('waited', resp[1]) " make the server quit, can't check if this works, should not hang. - call ch_sendexpr(handle, '!quit!', {'callback': 0}) + call ch_sendexpr(handle, '!quit!') endfunc func Test_communicate() @@ -218,18 +218,18 @@ func s:two_channels(port) return endif - call assert_equal('got it', ch_sendexpr(handle, 'hello!')) + call assert_equal('got it', ch_evalexpr(handle, 'hello!')) let newhandle = ch_open('localhost:' . a:port, s:chopt) if ch_status(newhandle) == "fail" call assert_false(1, "Can't open second channel") return endif - call assert_equal('got it', ch_sendexpr(newhandle, 'hello!')) - call assert_equal('got it', ch_sendexpr(handle, 'hello!')) + call assert_equal('got it', ch_evalexpr(newhandle, 'hello!')) + call assert_equal('got it', ch_evalexpr(handle, 'hello!')) call ch_close(handle) - call assert_equal('got it', ch_sendexpr(newhandle, 'hello!')) + call assert_equal('got it', ch_evalexpr(newhandle, 'hello!')) call ch_close(newhandle) endfunc @@ -247,7 +247,7 @@ func s:server_crash(port) return endif - call ch_sendexpr(handle, '!crash!') + call ch_evalexpr(handle, '!crash!') sleep 10m endfunc @@ -271,12 +271,12 @@ func s:channel_handler(port) endif " Test that it works while waiting on a numbered message. - call assert_equal('ok', ch_sendexpr(handle, 'call me')) + call assert_equal('ok', ch_evalexpr(handle, 'call me')) sleep 10m 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', {'callback': 0}) + call ch_sendexpr(handle, 'call me again') sleep 10m call assert_equal('we did call you', s:reply) endfunc @@ -334,15 +334,15 @@ func Test_raw_pipe() call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) - call ch_sendraw(handle, "echo something\n", {'callback': 0}) + call ch_sendraw(handle, "echo something\n") let msg = ch_readraw(handle) call assert_equal("something\n", substitute(msg, "\r", "", 'g')) - call ch_sendraw(handle, "double this\n", {'callback': 0}) + call ch_sendraw(handle, "double this\n") let msg = ch_readraw(handle) call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g')) - let reply = ch_sendraw(handle, "quit\n") + let reply = ch_evalraw(handle, "quit\n") call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g')) finally call job_stop(job) @@ -358,20 +358,48 @@ func Test_nl_pipe() call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) - call ch_sendraw(handle, "echo something\n", {'callback': 0}) + call ch_sendraw(handle, "echo something\n") call assert_equal("something", ch_readraw(handle)) - call ch_sendraw(handle, "double this\n", {'callback': 0}) + call ch_sendraw(handle, "double this\n") call assert_equal("this", ch_readraw(handle)) call assert_equal("AND this", ch_readraw(handle)) - let reply = ch_sendraw(handle, "quit\n") + let reply = ch_evalraw(handle, "quit\n") call assert_equal("Goodbye!", reply) finally call job_stop(job) endtry endfunc +func Test_pipe_to_buffer() + if !has('job') + return + endif + call ch_log('Test_pipe_to_buffer()') + let job = job_start(s:python . " test_channel_pipe.py", + \ {'out-io': 'buffer', 'out-name': 'pipe-output'}) + call assert_equal("run", job_status(job)) + try + let handle = job_getchannel(job) + call ch_sendraw(handle, "echo line one\n") + call ch_sendraw(handle, "echo line two\n") + call ch_sendraw(handle, "double this\n") + call ch_sendraw(handle, "quit\n") + sp pipe-output + for i in range(100) + sleep 10m + if line('$') >= 6 + break + endif + endfor + call assert_equal(['Reading from channel output...', 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$')) + bwipe! + finally + call job_stop(job) + endtry +endfunc + """""""""" let s:unletResponse = '' @@ -434,7 +462,7 @@ func s:open_delay(port) call assert_false(1, "Can't open channel") return endif - call assert_equal('got it', ch_sendexpr(channel, 'hello!')) + call assert_equal('got it', ch_evalexpr(channel, 'hello!')) call ch_close(channel) endfunc @@ -457,7 +485,7 @@ function s:test_call(port) return endif - call assert_equal('ok', ch_sendexpr(handle, 'call-func')) + call assert_equal('ok', ch_evalexpr(handle, 'call-func')) sleep 20m call assert_equal([1, 2, 3], s:call_ret) endfunc @@ -507,7 +535,7 @@ function s:test_close_callback(port) endif call ch_setoptions(handle, {'close-cb': 'MyCloseCb'}) - call assert_equal('', ch_sendexpr(handle, 'close me')) + call assert_equal('', ch_evalexpr(handle, 'close me')) sleep 20m call assert_equal('closed', s:ch_close_ret) endfunc diff --git a/src/version.c b/src/version.c index afa926f42..7384998f5 100644 --- a/src/version.c +++ b/src/version.c @@ -744,6 +744,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1435, +/**/ 1434, /**/ 1433, |