0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 7.4.1438

Problem:    Can't get buffer number of a channel.
Solution:   Add ch_getbufnr().
This commit is contained in:
Bram Moolenaar 2016-02-27 21:10:09 +01:00
parent 136f29a91d
commit c7f0ebc6d1
6 changed files with 85 additions and 14 deletions

View File

@ -561,11 +561,14 @@ TODO: *job-term*
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.
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

View File

@ -1822,6 +1822,7 @@ ch_evalexpr( {channel}, {expr} [, {options}])
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
@ -2721,6 +2722,13 @@ ch_evalraw({channel}, {string} [, {options}]) *ch_evalraw()*
{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

View File

@ -787,12 +787,15 @@ channel_set_job(channel_T *channel, job_T *job)
static buf_T *
find_buffer(char_u *name)
{
buf_T *buf = buflist_findname(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, (linenr_T)0, BLN_LISTED);
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,7 +883,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
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",
ch_logs(channel, "writing to buffer '%s'",
(char *)channel->ch_part[PART_OUT].ch_buffer->b_ffname);
}
}
@ -1357,7 +1360,14 @@ may_invoke_callback(channel_T *channel, int part)
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)
{

View File

@ -499,6 +499,7 @@ static void f_ceil(typval_T *argvars, typval_T *rettv);
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,6 +8196,7 @@ static struct fst
{"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,13 +10229,6 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
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
@ -10278,6 +10273,33 @@ f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
}
}
/*
* "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

View File

@ -400,6 +400,32 @@ func Test_pipe_to_buffer()
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 = ''

View File

@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1438,
/**/
1437,
/**/