# HG changeset patch # User Christian Brabandt # Date 1457561705 -3600 # Node ID c08c6d19db4df86a2398c8e505c39b1d6ca89a9c # Parent 81ddc32fa49295736e342becd781c31f0031a5f6 commit https://github.com/vim/vim/commit/29fd03878c41526a586d77b3f3cd7938d26297af Author: Bram Moolenaar Date: Wed Mar 9 23:14:07 2016 +0100 patch 7.4.1529 Problem: Specifying buffer number for channel not implemented yet. Solution: Implement passing a buffer number. diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -987,7 +987,11 @@ channel_set_options(channel_T *channel, /* writing output to a buffer. Default mode is NL. */ if (!(opt->jo_set & JO_OUT_MODE)) channel->ch_part[PART_OUT].ch_mode = MODE_NL; - channel->ch_part[PART_OUT].ch_buffer = + if (opt->jo_set & JO_OUT_BUF) + channel->ch_part[PART_OUT].ch_buffer = + buflist_findnr(opt->jo_io_buf[PART_OUT]); + else + channel->ch_part[PART_OUT].ch_buffer = find_buffer(opt->jo_io_name[PART_OUT], FALSE); ch_logs(channel, "writing out to buffer '%s'", (char *)channel->ch_part[PART_OUT].ch_buffer->b_ffname); @@ -1003,6 +1007,9 @@ channel_set_options(channel_T *channel, if (opt->jo_io[PART_ERR] == JIO_OUT) channel->ch_part[PART_ERR].ch_buffer = channel->ch_part[PART_OUT].ch_buffer; + else if (opt->jo_set & JO_ERR_BUF) + channel->ch_part[PART_ERR].ch_buffer = + buflist_findnr(opt->jo_io_buf[PART_ERR]); else channel->ch_part[PART_ERR].ch_buffer = find_buffer(opt->jo_io_name[PART_ERR], TRUE); diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -10119,6 +10119,27 @@ get_job_options(typval_T *tv, jobopt_T * opt->jo_io_name[part] = get_tv_string_buf_chk(item, opt->jo_io_name_buf[part]); } + else if (STRCMP(hi->hi_key, "in-buf") == 0 + || STRCMP(hi->hi_key, "out-buf") == 0 + || STRCMP(hi->hi_key, "err-buf") == 0) + { + part = part_from_char(*hi->hi_key); + + if (!(supported & JO_OUT_IO)) + break; + opt->jo_set |= JO_OUT_BUF << (part - PART_OUT); + opt->jo_io_buf[part] = get_tv_number(item); + if (opt->jo_io_buf[part] <= 0) + { + EMSG2(_(e_invarg2), get_tv_string(item)); + return FAIL; + } + if (buflist_findnr(opt->jo_io_buf[part]) == NULL) + { + EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[part]); + return FAIL; + } + } else if (STRCMP(hi->hi_key, "in-top") == 0 || STRCMP(hi->hi_key, "in-bot") == 0) { @@ -15156,21 +15177,36 @@ f_job_start(typval_T *argvars, typval_T if ((opt.jo_set & JO_IN_IO) && opt.jo_io[PART_IN] == JIO_BUFFER) { - buf_T *buf; + buf_T *buf = NULL; /* check that we can find the buffer before starting the job */ - if (!(opt.jo_set & JO_IN_NAME)) - { - EMSG(_("E915: in-io buffer requires in-name to be set")); - return; - } - buf = buflist_find_by_name(opt.jo_io_name[PART_IN], FALSE); + if (opt.jo_set & JO_IN_BUF) + { + buf = buflist_findnr(opt.jo_io_buf[PART_IN]); + if (buf == NULL) + EMSGN(_(e_nobufnr), (long)opt.jo_io_buf[PART_IN]); + } + else if (!(opt.jo_set & JO_IN_NAME)) + { + EMSG(_("E915: in-io buffer requires in-buf or in-name to be set")); + } + else + buf = buflist_find_by_name(opt.jo_io_name[PART_IN], FALSE); if (buf == NULL) return; if (buf->b_ml.ml_mfp == NULL) { - EMSG2(_("E918: buffer must be loaded: %s"), - opt.jo_io_name[PART_IN]); + char_u buf[NUMBUFLEN]; + char_u *s; + + if (opt.jo_set & JO_IN_BUF) + { + sprintf((char *)buf, "%d", opt.jo_io_buf[PART_IN]); + s = buf; + } + else + s = opt.jo_io_name[PART_IN]; + EMSG2(_("E918: buffer must be loaded: %s"), s); return; } job->jv_in_buf = buf; diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1409,7 +1409,10 @@ struct channel_S { #define JO_IN_NAME 0x200000 /* "in-name" (JO_OUT_NAME << 2) */ #define JO_IN_TOP 0x400000 /* "in-top" */ #define JO_IN_BOT 0x800000 /* "in-bot" */ -#define JO_ALL 0xffffff +#define JO_OUT_BUF 0x1000000 /* "out-buf" */ +#define JO_ERR_BUF 0x2000000 /* "err-buf" (JO_OUT_BUF << 1) */ +#define JO_IN_BUF 0x4000000 /* "in-buf" (JO_OUT_BUF << 2) */ +#define JO_ALL 0xfffffff #define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE) #define JO_CB_ALL \ @@ -1439,6 +1442,7 @@ typedef struct job_io_T jo_io[4]; /* PART_OUT, PART_ERR, PART_IN */ char_u jo_io_name_buf[4][NUMBUFLEN]; char_u *jo_io_name[4]; /* not allocated! */ + int jo_io_buf[4]; linenr_T jo_in_top; linenr_T jo_in_bot; diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -610,13 +610,22 @@ func Test_nl_write_both_file() endtry endfunc -func Test_pipe_to_buffer() +func Run_test_pipe_to_buffer(use_name) 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'}) + let options = {'out-io': 'buffer'} + if a:use_name + let options['out-name'] = 'pipe-output' + let firstline = 'Reading from channel output...' + else + sp pipe-output + let options['out-buf'] = bufnr('%') + quit + let firstline = '' + endif + let job = job_start(s:python . " test_channel_pipe.py", options) call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) @@ -626,20 +635,37 @@ func Test_pipe_to_buffer() call ch_sendraw(handle, "quit\n") sp pipe-output call s:waitFor('line("$") >= 6') - call assert_equal(['Reading from channel output...', 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$')) + call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$')) bwipe! finally call job_stop(job) endtry endfunc -func Test_pipe_err_to_buffer() +func Test_pipe_to_buffer_name() + call Run_test_pipe_to_buffer(1) +endfunc + +func Test_pipe_to_buffer_nr() + call Run_test_pipe_to_buffer(0) +endfunc + +func Run_test_pipe_err_to_buffer(use_name) if !has('job') return endif call ch_log('Test_pipe_err_to_buffer()') - let job = job_start(s:python . " test_channel_pipe.py", - \ {'err-io': 'buffer', 'err-name': 'pipe-err'}) + let options = {'err-io': 'buffer'} + if a:use_name + let options['err-name'] = 'pipe-err' + let firstline = 'Reading from channel error...' + else + sp pipe-err + let options['err-buf'] = bufnr('%') + quit + let firstline = '' + endif + let job = job_start(s:python . " test_channel_pipe.py", options) call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) @@ -649,13 +675,21 @@ func Test_pipe_err_to_buffer() call ch_sendraw(handle, "quit\n") sp pipe-err call s:waitFor('line("$") >= 5') - call assert_equal(['Reading from channel error...', 'line one', 'line two', 'this', 'AND this'], getline(1, '$')) + call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$')) bwipe! finally call job_stop(job) endtry endfunc +func Test_pipe_err_to_buffer_name() + call Run_test_pipe_err_to_buffer(1) +endfunc + +func Test_pipe_err_to_buffer_nr() + call Run_test_pipe_err_to_buffer(0) +endfunc + func Test_pipe_both_to_buffer() if !has('job') return @@ -680,7 +714,7 @@ func Test_pipe_both_to_buffer() endtry endfunc -func Test_pipe_from_buffer() +func Run_test_pipe_from_buffer(use_name) if !has('job') return endif @@ -688,9 +722,14 @@ func Test_pipe_from_buffer() sp pipe-input call setline(1, ['echo one', 'echo two', 'echo three']) + let options = {'in-io': 'buffer'} + if a:use_name + let options['in-name'] = 'pipe-input' + else + let options['in-buf'] = bufnr('%') + endif - let job = job_start(s:python . " test_channel_pipe.py", - \ {'in-io': 'buffer', 'in-name': 'pipe-input'}) + let job = job_start(s:python . " test_channel_pipe.py", options) call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) @@ -703,6 +742,14 @@ func Test_pipe_from_buffer() endtry endfunc +func Test_pipe_from_buffer_name() + call Run_test_pipe_from_buffer(1) +endfunc + +func Test_pipe_from_buffer_nr() + call Run_test_pipe_from_buffer(0) +endfunc + func Test_pipe_to_nameless_buffer() if !has('job') return diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 1529, +/**/ 1528, /**/ 1527,