summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-01-05 00:02:57 +0100
committerBram Moolenaar <Bram@vim.org>2019-01-05 00:02:57 +0100
commit8b62d87e4243d3dc9bf4f17bfe1a8953077a70c9 (patch)
tree3d1d16641f92aedc102ebb93a341256571e0b928
parent4164bb204e97a2ff3d6c43cba779bdff9e853892 (diff)
patch 8.1.0692: if a buffer was deleted a channel can't write to itv8.1.0692
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)
-rw-r--r--src/channel.c34
-rw-r--r--src/testdir/test_channel.vim22
-rw-r--r--src/version.c2
3 files changed, 51 insertions, 7 deletions
diff --git a/src/channel.c b/src/channel.c
index cb435c8bc8..6f5bf20234 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1099,6 +1099,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);
}
}
}
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index bbc6048537..091cd4ba12 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 144c9eff03..193e3270aa 100644
--- a/src/version.c
+++ b/src/version.c
@@ -800,6 +800,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 692,
+/**/
691,
/**/
690,