Permalink
Browse files

patch 7.4.2344

Problem:    The "Reading from channel output..." message can be unwanted.
            Appending to a buffer leaves an empty first line behind.
Solution:   Add the "out_msg" and "err_msg" options. Writing the first line
            overwrites the first, empty line.
  • Loading branch information...
1 parent 53f1673 commit 169ebb080454357279ad5ad21ac532deaec605e8 @brammool brammool committed Sep 7, 2016
Showing with 95 additions and 26 deletions.
  1. +14 −2 runtime/doc/channel.txt
  2. +35 −6 src/channel.c
  3. +6 −0 src/structs.h
  4. +38 −18 src/testdir/test_channel.vim
  5. +2 −0 src/version.c
@@ -1,4 +1,4 @@
-*channel.txt* For Vim version 7.4. Last change: 2016 Sep 01
+*channel.txt* For Vim version 7.4. Last change: 2016 Sep 07
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -646,6 +646,8 @@ See |job_setoptions()| and |ch_setoptions()|.
"out_buf": number the number of the buffer to write to
"out_modifiable": 0 when writing to a buffer, 'modifiable' will be off
(see below)
+"out_msg": 0 when writing to a new buffer, the first line will be
+ set to "Reading from channel output..."
*job-err_io* *err_name* *err_buf*
"err_io": "out" stderr messages to go to stdout
@@ -657,6 +659,8 @@ See |job_setoptions()| and |ch_setoptions()|.
"err_buf": number the number of the buffer to write to
"err_modifiable": 0 when writing to a buffer, 'modifiable' will be off
(see below)
+"err_msg": 0 when writing to a new buffer, the first line will be
+ set to "Reading from channel error..."
"block_write": number only for testing: pretend every other write to stdin
will block
@@ -686,11 +690,19 @@ 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.
-
+ *out_modifiable* *err_modifiable*
The "out_modifiable" and "err_modifiable" options can be used to set the
'modifiable' option off, or write to a buffer that has 'modifiable' off. That
means that lines will be appended to the buffer, but the user can't easily
change the buffer.
+ *out_msg* *err_msg*
+The "out_msg" option can be used to specify whether a new buffer will have the
+first line set to "Reading from channel output...". The default is to add the
+message. "err_msg" does the same for channel error.
+
+'modifiable' option off, or write to a buffer that has 'modifiable' off. That
+means that lines will be appended to the buffer, but the user can't easily
+change the buffer.
When an existing buffer is to be written where 'modifiable' is off and the
"out_modifiable" or "err_modifiable" options is not zero, an error is given
View
@@ -1079,7 +1079,7 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options)
* Returns NULL if there is something very wrong (error already reported).
*/
static buf_T *
-find_buffer(char_u *name, int err)
+find_buffer(char_u *name, int err, int msg)
{
buf_T *buf = NULL;
buf_T *save_curbuf = curbuf;
@@ -1104,7 +1104,8 @@ find_buffer(char_u *name, int err)
#endif
if (curbuf->b_ml.ml_mfp == NULL)
ml_open(curbuf);
- ml_replace(1, (char_u *)(err ? "Reading from channel error..."
+ if (msg)
+ ml_replace(1, (char_u *)(err ? "Reading from channel error..."
: "Reading from channel output..."), TRUE);
changed_bytes(1, 0);
curbuf = save_curbuf;
@@ -1196,7 +1197,11 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
}
else
{
- buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE);
+ int msg = TRUE;
+
+ if (opt->jo_set2 & JO2_OUT_MSG)
+ msg = opt->jo_message[PART_OUT];
+ buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE, msg);
}
if (buf != NULL)
{
@@ -1235,7 +1240,13 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[PART_ERR]);
}
else
- buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE);
+ {
+ int msg = TRUE;
+
+ if (opt->jo_set2 & JO2_ERR_MSG)
+ msg = opt->jo_message[PART_ERR];
+ buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE, msg);
+ }
if (buf != NULL)
{
if (opt->jo_set & JO_ERR_MODIFIABLE)
@@ -2227,6 +2238,7 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, int part)
int save_write_to = buffer->b_write_to_channel;
chanpart_T *ch_part = &channel->ch_part[part];
int save_p_ma = buffer->b_p_ma;
+ int empty = (buffer->b_ml.ml_flags & ML_EMPTY);
if (!buffer->b_p_ma && !ch_part->ch_nomodifiable)
{
@@ -2253,9 +2265,16 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, int part)
curbuf = buffer;
u_sync(TRUE);
/* ignore undo failure, undo is not very useful here */
- ignored = u_save(lnum, lnum + 1);
+ ignored = u_save(lnum, lnum + 1 + (empty ? 1 : 0));
- ml_append(lnum, msg, 0, FALSE);
+ if (empty)
+ {
+ /* The buffer is empty, replace the first (dummy) line. */
+ ml_replace(lnum, msg, TRUE);
+ lnum = 0;
+ }
+ else
+ ml_append(lnum, msg, 0, FALSE);
appended_lines_mark(lnum, 1L);
curbuf = save_curbuf;
if (ch_part->ch_nomodifiable)
@@ -4083,6 +4102,16 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
opt->jo_set |= JO_OUT_MODIFIABLE << (part - PART_OUT);
opt->jo_modifiable[part] = get_tv_number(item);
}
+ else if (STRCMP(hi->hi_key, "out_msg") == 0
+ || STRCMP(hi->hi_key, "err_msg") == 0)
+ {
+ part = part_from_char(*hi->hi_key);
+
+ if (!(supported & JO_OUT_IO))
+ break;
+ opt->jo_set2 |= JO2_OUT_MSG << (part - PART_OUT);
+ opt->jo_message[part] = get_tv_number(item);
+ }
else if (STRCMP(hi->hi_key, "in_top") == 0
|| STRCMP(hi->hi_key, "in_bot") == 0)
{
View
@@ -1634,6 +1634,10 @@ struct channel_S {
#define JO_ERR_MODIFIABLE 0x40000000 /* "err_modifiable" (JO_OUT_ << 1) */
#define JO_ALL 0x7fffffff
+#define JO2_OUT_MSG 0x0001 /* "out_msg" */
+#define JO2_ERR_MSG 0x0002 /* "err_msg" (JO_OUT_ << 1) */
+#define JO2_ALL 0x0003
+
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
#define JO_CB_ALL \
(JO_CALLBACK + JO_OUT_CALLBACK + JO_ERR_CALLBACK + JO_CLOSE_CALLBACK)
@@ -1645,6 +1649,7 @@ struct channel_S {
typedef struct
{
int jo_set; /* JO_ bits for values that were set */
+ int jo_set2; /* JO2_ bits for values that were set */
ch_mode_T jo_mode;
ch_mode_T jo_in_mode;
@@ -1656,6 +1661,7 @@ typedef struct
char_u *jo_io_name[4]; /* not allocated! */
int jo_io_buf[4];
int jo_modifiable[4];
+ int jo_message[4];
channel_T *jo_channel;
linenr_T jo_in_top;
@@ -638,21 +638,27 @@ func BufCloseCb(ch)
let g:Ch_bufClosed = 'yes'
endfunc
-func Run_test_pipe_to_buffer(use_name, nomod)
+func Run_test_pipe_to_buffer(use_name, nomod, do_msg)
if !has('job')
return
endif
call ch_log('Test_pipe_to_buffer()')
let g:Ch_bufClosed = 'no'
let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'}
+ let expected = ['', 'line one', 'line two', 'this', 'AND this', 'Goodbye!']
if a:use_name
let options['out_name'] = 'pipe-output'
- let firstline = 'Reading from channel output...'
+ if a:do_msg
+ let expected[0] = 'Reading from channel output...'
+ else
+ let options['out_msg'] = 0
+ call remove(expected, 0)
+ endif
else
sp pipe-output
let options['out_buf'] = bufnr('%')
quit
- let firstline = ''
+ call remove(expected, 0)
endif
if a:nomod
let options['out_modifiable'] = 0
@@ -667,7 +673,7 @@ func Run_test_pipe_to_buffer(use_name, nomod)
call ch_sendraw(handle, "quit\n")
sp pipe-output
call WaitFor('line("$") >= 6 && g:Ch_bufClosed == "yes"')
- call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$'))
+ call assert_equal(expected, getline(1, '$'))
if a:nomod
call assert_equal(0, &modifiable)
else
@@ -681,31 +687,41 @@ func Run_test_pipe_to_buffer(use_name, nomod)
endfunc
func Test_pipe_to_buffer_name()
- call Run_test_pipe_to_buffer(1, 0)
+ call Run_test_pipe_to_buffer(1, 0, 1)
endfunc
func Test_pipe_to_buffer_nr()
- call Run_test_pipe_to_buffer(0, 0)
+ call Run_test_pipe_to_buffer(0, 0, 1)
endfunc
func Test_pipe_to_buffer_name_nomod()
- call Run_test_pipe_to_buffer(1, 1)
+ call Run_test_pipe_to_buffer(1, 1, 1)
+endfunc
+
+func Test_pipe_to_buffer_name_nomsg()
+ call Run_test_pipe_to_buffer(1, 0, 1)
endfunc
-func Run_test_pipe_err_to_buffer(use_name, nomod)
+func Run_test_pipe_err_to_buffer(use_name, nomod, do_msg)
if !has('job')
return
endif
call ch_log('Test_pipe_err_to_buffer()')
let options = {'err_io': 'buffer'}
+ let expected = ['', 'line one', 'line two', 'this', 'AND this']
if a:use_name
let options['err_name'] = 'pipe-err'
- let firstline = 'Reading from channel error...'
+ if a:do_msg
+ let expected[0] = 'Reading from channel error...'
+ else
+ let options['err_msg'] = 0
+ call remove(expected, 0)
+ endif
else
sp pipe-err
let options['err_buf'] = bufnr('%')
quit
- let firstline = ''
+ call remove(expected, 0)
endif
if a:nomod
let options['err_modifiable'] = 0
@@ -720,7 +736,7 @@ func Run_test_pipe_err_to_buffer(use_name, nomod)
call ch_sendraw(handle, "quit\n")
sp pipe-err
call WaitFor('line("$") >= 5')
- call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$'))
+ call assert_equal(expected, getline(1, '$'))
if a:nomod
call assert_equal(0, &modifiable)
else
@@ -733,15 +749,19 @@ func Run_test_pipe_err_to_buffer(use_name, nomod)
endfunc
func Test_pipe_err_to_buffer_name()
- call Run_test_pipe_err_to_buffer(1, 0)
+ call Run_test_pipe_err_to_buffer(1, 0, 1)
endfunc
func Test_pipe_err_to_buffer_nr()
- call Run_test_pipe_err_to_buffer(0, 0)
+ call Run_test_pipe_err_to_buffer(0, 0, 1)
endfunc
func Test_pipe_err_to_buffer_name_nomod()
- call Run_test_pipe_err_to_buffer(1, 1)
+ call Run_test_pipe_err_to_buffer(1, 1, 1)
+endfunc
+
+func Test_pipe_err_to_buffer_name_nomsg()
+ call Run_test_pipe_err_to_buffer(1, 0, 0)
endfunc
func Test_pipe_both_to_buffer()
@@ -1407,7 +1427,7 @@ func Test_collapse_buffers()
1,$delete
call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'})
call WaitFor('line("$") > g:linecount')
- call assert_inrange(g:linecount + 1, g:linecount + 2, line('$'))
+ call assert_inrange(g:linecount, g:linecount + 1, line('$'))
bwipe!
endfunc
@@ -1425,9 +1445,9 @@ func Test_raw_passes_nul()
1,$delete
call job_start('cat Xtestread', {'out_io': 'buffer', 'out_name': 'testout'})
call WaitFor('line("$") > 2')
- call assert_equal("asdf\nasdf", getline(2))
- call assert_equal("xxx\n", getline(3))
- call assert_equal("\nyyy", getline(4))
+ call assert_equal("asdf\nasdf", getline(1))
+ call assert_equal("xxx\n", getline(2))
+ call assert_equal("\nyyy", getline(3))
call delete('Xtestread')
bwipe!
View
@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2344,
+/**/
2343,
/**/
2342,

0 comments on commit 169ebb0

Please sign in to comment.