1
0
forked from aniani/vim

patch 8.1.0692: if a buffer was deleted a channel can't write to it

Problem:    If a buffer was deleted a channel can't write to it.
Solution:   When the buffer exists but was unloaded, prepare it for writing.
            (closes #3764)
This commit is contained in:
Bram Moolenaar
2019-01-05 00:02:57 +01:00
parent 4164bb204e
commit 8b62d87e42
3 changed files with 51 additions and 7 deletions

View File

@@ -1098,6 +1098,25 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options)
} }
} }
/*
* Prepare buffer "buf" for writing channel output to.
*/
static void
prepare_buffer(buf_T *buf)
{
buf_T *save_curbuf = curbuf;
buf_copy_options(buf, BCO_ENTER);
curbuf = buf;
#ifdef FEAT_QUICKFIX
set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
#endif
if (curbuf->b_ml.ml_mfp == NULL)
ml_open(curbuf);
curbuf = save_curbuf;
}
/* /*
* Find a buffer matching "name" or create a new one. * Find a buffer matching "name" or create a new one.
* Returns NULL if there is something very wrong (error already reported). * Returns NULL if there is something very wrong (error already reported).
@@ -1120,14 +1139,9 @@ find_buffer(char_u *name, int err, int msg)
NULL, (linenr_T)0, BLN_LISTED | BLN_NEW); NULL, (linenr_T)0, BLN_LISTED | BLN_NEW);
if (buf == NULL) if (buf == NULL)
return NULL; return NULL;
buf_copy_options(buf, BCO_ENTER); prepare_buffer(buf);
curbuf = buf; curbuf = buf;
#ifdef FEAT_QUICKFIX
set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
#endif
if (curbuf->b_ml.ml_mfp == NULL)
ml_open(curbuf);
if (msg) if (msg)
ml_replace(1, (char_u *)(err ? "Reading from channel error..." ml_replace(1, (char_u *)(err ? "Reading from channel error..."
: "Reading from channel output..."), TRUE); : "Reading from channel output..."), TRUE);
@@ -1244,6 +1258,9 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
ch_log(channel, "writing out to buffer '%s'", ch_log(channel, "writing out to buffer '%s'",
(char *)buf->b_ffname); (char *)buf->b_ffname);
set_bufref(&channel->ch_part[PART_OUT].ch_bufref, buf); set_bufref(&channel->ch_part[PART_OUT].ch_bufref, buf);
// if the buffer was deleted or unloaded resurrect it
if (buf->b_ml.ml_mfp == NULL)
prepare_buffer(buf);
} }
} }
} }
@@ -1287,6 +1304,9 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
ch_log(channel, "writing err to buffer '%s'", ch_log(channel, "writing err to buffer '%s'",
(char *)buf->b_ffname); (char *)buf->b_ffname);
set_bufref(&channel->ch_part[PART_ERR].ch_bufref, buf); set_bufref(&channel->ch_part[PART_ERR].ch_bufref, buf);
// if the buffer was deleted or unloaded resurrect it
if (buf->b_ml.ml_mfp == NULL)
prepare_buffer(buf);
} }
} }
} }

View File

@@ -1645,6 +1645,28 @@ func Test_collapse_buffers()
bwipe! bwipe!
endfunc endfunc
func Test_write_to_deleted_buffer()
if !executable('echo') || !has('job')
return
endif
let job = job_start('echo hello', {'out_io': 'buffer', 'out_name': 'test_buffer', 'out_msg': 0})
call WaitForAssert({-> assert_equal("dead", job_status(job))})
let bufnr = bufnr('test_buffer')
call assert_equal(['hello'], getbufline(bufnr, 1, '$'))
call assert_equal('nofile', getbufvar(bufnr, '&buftype'))
call assert_equal('hide', getbufvar(bufnr, '&bufhidden'))
bdel test_buffer
call assert_equal([], getbufline(bufnr, 1, '$'))
let job = job_start('echo hello', {'out_io': 'buffer', 'out_name': 'test_buffer', 'out_msg': 0})
call WaitForAssert({-> assert_equal("dead", job_status(job))})
call assert_equal(['hello'], getbufline(bufnr, 1, '$'))
call assert_equal('nofile', getbufvar(bufnr, '&buftype'))
call assert_equal('hide', getbufvar(bufnr, '&bufhidden'))
bwipe! test_buffer
endfunc
func Test_cmd_parsing() func Test_cmd_parsing()
if !has('unix') if !has('unix')
return return

View File

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