To: vim_dev@googlegroups.com Subject: Patch 7.4.1438 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1438 Problem: Can't get buffer number of a channel. Solution: Add ch_getbufnr(). Files: src/eval.c, src/channel.c, src/testdir/test_channel.vim, runtime/doc/channel.txt, runtime/doc/eval.txt *** ../vim-7.4.1437/src/eval.c 2016-02-27 20:14:09.920546700 +0100 --- src/eval.c 2016-02-27 20:35:15.419261164 +0100 *************** *** 499,504 **** --- 499,505 ---- 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); + static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv); # ifdef FEAT_JOB static void f_ch_getjob(typval_T *argvars, typval_T *rettv); # endif *************** *** 8195,8200 **** --- 8196,8202 ---- {"ch_close", 1, 1, f_ch_close}, {"ch_evalexpr", 2, 3, f_ch_evalexpr}, {"ch_evalraw", 2, 3, f_ch_evalraw}, + {"ch_getbufnr", 2, 2, f_ch_getbufnr}, # ifdef FEAT_JOB {"ch_getjob", 1, 1, f_ch_getjob}, # endif *************** *** 10227,10239 **** return FAIL; } - for (part = PART_OUT; part <= PART_IN; ++part) - if (opt->jo_io[part] == JIO_BUFFER && opt->jo_io_name[part] == NULL) - { - EMSG(_("E915: Missing name for buffer")); - return FAIL; - } - return OK; } #endif --- 10229,10234 ---- *************** *** 10278,10283 **** --- 10273,10305 ---- } } + /* + * "ch_getbufnr()" function + */ + static void + f_ch_getbufnr(typval_T *argvars, typval_T *rettv) + { + channel_T *channel = get_channel_arg(&argvars[0]); + + rettv->vval.v_number = -1; + if (channel != NULL) + { + char_u *what = get_tv_string(&argvars[1]); + int part; + + if (STRCMP(what, "err") == 0) + part = PART_ERR; + else if (STRCMP(what, "out") == 0) + part = PART_OUT; + else if (STRCMP(what, "in") == 0) + part = PART_IN; + else + part = PART_SOCK; + if (channel->ch_part[part].ch_buffer != NULL) + rettv->vval.v_number = channel->ch_part[part].ch_buffer->b_fnum; + } + } + # ifdef FEAT_JOB /* * "ch_getjob()" function *** ../vim-7.4.1437/src/channel.c 2016-02-27 14:44:21.331585379 +0100 --- src/channel.c 2016-02-27 20:50:21.973745670 +0100 *************** *** 787,798 **** static buf_T * find_buffer(char_u *name) { ! buf_T *buf = buflist_findname(name); buf_T *save_curbuf = curbuf; if (buf == NULL) { ! buf = buflist_new(name, NULL, (linenr_T)0, BLN_LISTED); buf_copy_options(buf, BCO_ENTER); #ifdef FEAT_QUICKFIX clear_string_option(&buf->b_p_bt); --- 787,801 ---- static buf_T * find_buffer(char_u *name) { ! buf_T *buf = NULL; buf_T *save_curbuf = curbuf; + if (name != NULL && *name != NUL) + buf = buflist_findname(name); if (buf == NULL) { ! buf = buflist_new(name == NULL ? (char_u *)"" : name, ! NULL, (linenr_T)0, BLN_LISTED); buf_copy_options(buf, BCO_ENTER); #ifdef FEAT_QUICKFIX clear_string_option(&buf->b_p_bt); *************** *** 880,886 **** channel->ch_part[PART_OUT].ch_mode = MODE_NL; channel->ch_part[PART_OUT].ch_buffer = find_buffer(opt->jo_io_name[PART_OUT]); ! ch_logs(channel, "writing to buffer %s", (char *)channel->ch_part[PART_OUT].ch_buffer->b_ffname); } } --- 883,889 ---- channel->ch_part[PART_OUT].ch_mode = MODE_NL; channel->ch_part[PART_OUT].ch_buffer = find_buffer(opt->jo_io_name[PART_OUT]); ! ch_logs(channel, "writing to buffer '%s'", (char *)channel->ch_part[PART_OUT].ch_buffer->b_ffname); } } *************** *** 1357,1363 **** --- 1360,1373 ---- callback = channel->ch_part[part].ch_callback; else callback = channel->ch_callback; + buffer = channel->ch_part[part].ch_buffer; + if (buffer != NULL && !buf_valid(buffer)) + { + /* buffer was wiped out */ + channel->ch_part[part].ch_buffer = NULL; + buffer = NULL; + } if (ch_mode == MODE_JSON || ch_mode == MODE_JS) { *** ../vim-7.4.1437/src/testdir/test_channel.vim 2016-02-27 19:20:58.781967198 +0100 --- src/testdir/test_channel.vim 2016-02-27 20:40:36.799887357 +0100 *************** *** 400,405 **** --- 400,431 ---- endtry endfunc + func Test_pipe_to_nameless_buffer() + if !has('job') + return + endif + call ch_log('Test_pipe_to_nameless_buffer()') + let job = job_start(s:python . " test_channel_pipe.py", + \ {'out-io': 'buffer'}) + 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") + exe ch_getbufnr(handle, "out") . 'sbuf' + for i in range(100) + sleep 10m + if line('$') >= 3 + break + endif + endfor + call assert_equal(['Reading from channel output...', 'line one', 'line two'], getline(1, '$')) + bwipe! + finally + call job_stop(job) + endtry + endfunc + """""""""" let s:unletResponse = '' *** ../vim-7.4.1437/runtime/doc/channel.txt 2016-02-27 19:20:58.781967198 +0100 --- runtime/doc/channel.txt 2016-02-27 20:26:04.721043726 +0100 *************** *** 561,571 **** When the IO mode is "buffer" and there is a callback, the text is appended to the buffer before invoking the callback. ! *E915* The name of the buffer is compared the full name of existing buffers. If ! there is a match that buffer is used. Otherwise a new buffer is created, ! where 'buftype' is set to "nofile" and 'bufhidden' to "hide". If you prefer ! other settings, create the buffer first and pass the buffer number. When the buffer written to is displayed in a window and the cursor is in the first column of the last line, the cursor will be moved to the newly added --- 561,574 ---- When the IO mode is "buffer" and there is a callback, the text is appended to the buffer before invoking the callback. ! The name of the buffer is compared the full name of existing buffers. If ! there is a match that buffer is used. Otherwise a new buffer is created. ! Use an empty name to always create a new buffer. |ch_getbufnr()| can then be ! used to get the buffer number. ! ! For a new buffer 'buftype' is set to "nofile" and 'bufhidden' to "hide". If ! you prefer other settings, create the buffer first and pass the buffer number. When the buffer written to is displayed in a window and the cursor is in the first column of the last line, the cursor will be moved to the newly added *** ../vim-7.4.1437/runtime/doc/eval.txt 2016-02-27 19:20:58.781967198 +0100 --- runtime/doc/eval.txt 2016-02-27 20:22:57.507009992 +0100 *************** *** 1812,1817 **** --- 1822,1828 ---- any evaluate {expr} on JSON {channel} ch_evalraw( {channel}, {string} [, {options}]) any evaluate {string} on raw {channel} + ch_getbufnr( {channel}, {what}) Number get buffer number for {channel}/{what} ch_getjob( {channel}) Job get the Job of {channel} ch_log( {msg} [, {channel}]) none write {msg} in the channel log file ch_logfile( {fname} [, {mode}]) none start logging channel activity *************** *** 2707,2712 **** --- 2722,2734 ---- {only available when compiled with the |+channel| feature} + ch_getbufnr({channel}, {what}) *ch_getbufnr()* + Get the buffer number that {channel} is using for {what}. + {what} can be "err" for stderr, "out" for stdout or empty for + socket output. + Returns -1 when there is no buffer. + {only available when compiled with the |+channel| feature} + ch_getjob({channel}) *ch_getjob()* Get the Job associated with {channel}. If there is no job calling |job_status()| on the returned Job *** ../vim-7.4.1437/src/version.c 2016-02-27 20:14:09.924546658 +0100 --- src/version.c 2016-02-27 20:36:11.006677575 +0100 *************** *** 745,746 **** --- 745,748 ---- { /* Add new patch number below this line */ + /**/ + 1438, /**/ -- "Software is like sex... it's better when it's free." -- Linus Torvalds, initiator of the free Linux OS Makes me wonder what FSF stands for...? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///