]> granicus.if.org Git - vim/commitdiff
patch 8.1.0692: if a buffer was deleted a channel can't write to it v8.1.0692
authorBram Moolenaar <Bram@vim.org>
Fri, 4 Jan 2019 23:02:57 +0000 (00:02 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 4 Jan 2019 23:02:57 +0000 (00:02 +0100)
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)

src/channel.c
src/testdir/test_channel.vim
src/version.c

index cb435c8bc8c8ceb8c0a912e5c3e69d114916d950..6f5bf20234e608fd50f5f338464292161c2b20ec 100644 (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.
  * 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);
            }
        }
     }
index bbc60485377588c92ace0690491bfe6748fd566c..091cd4ba123cd737489c86c18462f066cce34a3c 100644 (file)
@@ -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
index 144c9eff03772406be0ec472e5657aad88024a4f..193e3270aa5b0fb8f447a77b36a755cddd1b2138 100644 (file)
@@ -799,6 +799,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    692,
 /**/
     691,
 /**/