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:
@@ -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.
|
||||
* 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);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
buf_copy_options(buf, BCO_ENTER);
|
||||
prepare_buffer(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)
|
||||
ml_replace(1, (char_u *)(err ? "Reading from channel error..."
|
||||
: "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'",
|
||||
(char *)buf->b_ffname);
|
||||
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'",
|
||||
(char *)buf->b_ffname);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1645,6 +1645,28 @@ func Test_collapse_buffers()
|
||||
bwipe!
|
||||
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()
|
||||
if !has('unix')
|
||||
return
|
||||
|
@@ -799,6 +799,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
692,
|
||||
/**/
|
||||
691,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user