Patch 7.4.1502
Problem: Writing last-but-one line of buffer to a channel isn't implemented
yet.
Solution: Implement it. Fix leaving a swap file behind.
Files: src/channel.c, src/structs.h, src/memline.c, src/proto/channel.pro
*** ../vim-7.4.1501/src/channel.c 2016-03-05 22:19:37.278622998 +0100
--- src/channel.c 2016-03-06 20:07:22.013564002 +0100
***************
*** 837,843 ****
ch_logs(channel, "reading from buffer '%s'",
(char *)in_part->ch_buffer->b_ffname);
if (options->jo_set & JO_IN_TOP)
! in_part->ch_buf_top = options->jo_in_top;
else
in_part->ch_buf_top = 1;
if (options->jo_set & JO_IN_BOT)
--- 837,854 ----
ch_logs(channel, "reading from buffer '%s'",
(char *)in_part->ch_buffer->b_ffname);
if (options->jo_set & JO_IN_TOP)
! {
! if (options->jo_in_top == 0 && !(options->jo_set & JO_IN_BOT))
! {
! /* Special mode: send last-but-one line when appending a line
! * to the buffer. */
! in_part->ch_buffer->b_write_to_channel = TRUE;
! in_part->ch_buf_top =
! in_part->ch_buffer->b_ml.ml_line_count + 1;
! }
! else
! in_part->ch_buf_top = options->jo_in_top;
! }
else
in_part->ch_buf_top = 1;
if (options->jo_set & JO_IN_BOT)
***************
*** 864,876 ****
NULL, (linenr_T)0, BLN_LISTED);
buf_copy_options(buf, BCO_ENTER);
#ifdef FEAT_QUICKFIX
! clear_string_option(&buf->b_p_bt);
! buf->b_p_bt = vim_strsave((char_u *)"nofile");
! clear_string_option(&buf->b_p_bh);
! buf->b_p_bh = vim_strsave((char_u *)"hide");
#endif
curbuf = buf;
! ml_open(curbuf);
ml_replace(1, (char_u *)"Reading from channel output...", TRUE);
changed_bytes(1, 0);
curbuf = save_curbuf;
--- 875,886 ----
NULL, (linenr_T)0, BLN_LISTED);
buf_copy_options(buf, BCO_ENTER);
#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
curbuf = buf;
! if (curbuf->b_ml.ml_mfp == NULL)
! ml_open(curbuf);
ml_replace(1, (char_u *)"Reading from channel output...", TRUE);
changed_bytes(1, 0);
curbuf = save_curbuf;
***************
*** 982,989 ****
}
}
/*
! * Write any lines to the in channel.
*/
void
channel_write_in(channel_T *channel)
--- 992,1016 ----
}
}
+ static void
+ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
+ {
+ char_u *line = ml_get_buf(buf, lnum, FALSE);
+ int len = STRLEN(line);
+ char_u *p;
+
+ /* TODO: check if channel can be written to, do not block on write */
+ if ((p = alloc(len + 2)) == NULL)
+ return;
+ STRCPY(p, line);
+ p[len] = NL;
+ p[len + 1] = NUL;
+ channel_send(channel, PART_IN, p, "write_buf_line()");
+ vim_free(p);
+ }
+
/*
! * Write any lines to the input channel.
*/
void
channel_write_in(channel_T *channel)
***************
*** 991,996 ****
--- 1018,1024 ----
chanpart_T *in_part = &channel->ch_part[PART_IN];
linenr_T lnum;
buf_T *buf = in_part->ch_buffer;
+ int written = 0;
if (buf == NULL)
return;
***************
*** 1007,1029 ****
for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot
&& lnum <= buf->b_ml.ml_line_count; ++lnum)
{
! char_u *line = ml_get_buf(buf, lnum, FALSE);
! int len = STRLEN(line);
! char_u *p;
!
! /* TODO: check if channel can be written to */
! if ((p = alloc(len + 2)) == NULL)
! break;
! STRCPY(p, line);
! p[len] = NL;
! p[len + 1] = NUL;
! channel_send(channel, PART_IN, p, "channel_write_in()");
! vim_free(p);
}
in_part->ch_buf_top = lnum;
}
/*
* Invoke the "callback" on channel "channel".
*/
static void
--- 1035,1095 ----
for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot
&& lnum <= buf->b_ml.ml_line_count; ++lnum)
{
! write_buf_line(buf, lnum, channel);
! ++written;
}
+
+ if (written == 1)
+ ch_logn(channel, "written line %d to channel", (int)lnum - 1);
+ else if (written > 1)
+ ch_logn(channel, "written %d lines to channel", written);
+
in_part->ch_buf_top = lnum;
}
/*
+ * Write appended lines above the last one in "buf" to the channel.
+ */
+ void
+ channel_write_new_lines(buf_T *buf)
+ {
+ channel_T *channel;
+ int found_one = FALSE;
+
+ /* There could be more than one channel for the buffer, loop over all of
+ * them. */
+ for (channel = first_channel; channel != NULL; channel = channel->ch_next)
+ {
+ chanpart_T *in_part = &channel->ch_part[PART_IN];
+ linenr_T lnum;
+ int written = 0;
+
+ if (in_part->ch_buffer == buf)
+ {
+ if (in_part->ch_fd == INVALID_FD)
+ /* pipe was closed */
+ continue;
+ found_one = TRUE;
+ for (lnum = in_part->ch_buf_bot; lnum < buf->b_ml.ml_line_count;
+ ++lnum)
+ {
+ write_buf_line(buf, lnum, channel);
+ ++written;
+ }
+
+ if (written == 1)
+ ch_logn(channel, "written line %d to channel", (int)lnum - 1);
+ else if (written > 1)
+ ch_logn(channel, "written %d lines to channel", written);
+
+ in_part->ch_buf_bot = lnum;
+ }
+ }
+ if (!found_one)
+ buf->b_write_to_channel = FALSE;
+ }
+
+ /*
* Invoke the "callback" on channel "channel".
*/
static void
***************
*** 1470,1475 ****
--- 1536,1611 ----
vim_free(item);
}
+ static void
+ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel)
+ {
+ buf_T *save_curbuf = curbuf;
+ linenr_T lnum = buffer->b_ml.ml_line_count;
+ int save_write_to = buffer->b_write_to_channel;
+
+ /* If the buffer is also used as input insert above the last
+ * line. Don't write these lines. */
+ if (save_write_to)
+ {
+ --lnum;
+ buffer->b_write_to_channel = FALSE;
+ }
+
+ /* Append to the buffer */
+ ch_logn(channel, "appending line %d to buffer", (int)lnum + 1);
+
+ curbuf = buffer;
+ u_sync(TRUE);
+ /* ignore undo failure, undo is not very useful here */
+ ignored = u_save(lnum, lnum + 1);
+
+ ml_append(lnum, msg, 0, FALSE);
+ appended_lines_mark(lnum, 1L);
+ curbuf = save_curbuf;
+
+ if (buffer->b_nwindows > 0)
+ {
+ win_T *wp;
+ win_T *save_curwin;
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_buffer == buffer
+ && (save_write_to
+ ? wp->w_cursor.lnum == lnum + 1
+ : (wp->w_cursor.lnum == lnum
+ && wp->w_cursor.col == 0)))
+ {
+ ++wp->w_cursor.lnum;
+ save_curwin = curwin;
+ curwin = wp;
+ curbuf = curwin->w_buffer;
+ scroll_cursor_bot(0, FALSE);
+ curwin = save_curwin;
+ curbuf = curwin->w_buffer;
+ }
+ }
+ redraw_buf_later(buffer, VALID);
+ channel_need_redraw = TRUE;
+ }
+
+ if (save_write_to)
+ {
+ channel_T *ch;
+
+ /* Find channels reading from this buffer and adjust their
+ * next-to-read line number. */
+ buffer->b_write_to_channel = TRUE;
+ for (ch = first_channel; ch != NULL; ch = ch->ch_next)
+ {
+ chanpart_T *in_part = &ch->ch_part[PART_IN];
+
+ if (in_part->ch_buffer == buffer)
+ in_part->ch_buf_bot = buffer->b_ml.ml_line_count;
+ }
+ }
+ }
+
/*
* Invoke a callback for "channel"/"part" if needed.
* Return TRUE when a message was handled, there might be another one.
***************
*** 1634,1679 ****
/* JSON or JS mode: re-encode the message. */
msg = json_encode(listtv, ch_mode);
if (msg != NULL)
! {
! buf_T *save_curbuf = curbuf;
! linenr_T lnum = buffer->b_ml.ml_line_count;
!
! /* Append to the buffer */
! ch_logn(channel, "appending line %d to buffer", (int)lnum + 1);
!
! curbuf = buffer;
! u_sync(TRUE);
! /* ignore undo failure, undo is not very useful here */
! ignored = u_save(lnum, lnum + 1);
!
! ml_append(lnum, msg, 0, FALSE);
! appended_lines_mark(lnum, 1L);
! curbuf = save_curbuf;
!
! if (buffer->b_nwindows > 0)
! {
! win_T *wp;
! win_T *save_curwin;
!
! FOR_ALL_WINDOWS(wp)
! {
! if (wp->w_buffer == buffer
! && wp->w_cursor.lnum == lnum
! && wp->w_cursor.col == 0)
! {
! ++wp->w_cursor.lnum;
! save_curwin = curwin;
! curwin = wp;
! curbuf = curwin->w_buffer;
! scroll_cursor_bot(0, FALSE);
! curwin = save_curwin;
! curbuf = curwin->w_buffer;
! }
! }
! redraw_buf_later(buffer, VALID);
! channel_need_redraw = TRUE;
! }
! }
}
if (callback != NULL)
--- 1770,1776 ----
/* JSON or JS mode: re-encode the message. */
msg = json_encode(listtv, ch_mode);
if (msg != NULL)
! append_to_buffer(buffer, msg, channel);
}
if (callback != NULL)
*** ../vim-7.4.1501/src/structs.h 2016-03-03 22:51:36.125809792 +0100
--- src/structs.h 2016-03-06 18:03:57.346135772 +0100
***************
*** 2051,2056 ****
--- 2051,2060 ----
int b_netbeans_file; /* TRUE when buffer is owned by
NetBeans */
int b_was_netbeans_file;/* TRUE if b_netbeans_file was once
set */
#endif
+ #ifdef FEAT_CHANNEL
+ int b_write_to_channel; /* TRUE when appended lines are
written to
+ * a channel. */
+ #endif
#ifdef FEAT_CRYPT
cryptstate_T *b_cryptstate; /* Encryption state while reading or
writing
*** ../vim-7.4.1501/src/memline.c 2016-02-23 14:52:31.885232171 +0100
--- src/memline.c 2016-03-06 18:17:40.697666562 +0100
***************
*** 3059,3064 ****
--- 3059,3069 ----
(char_u *)"\n", 1);
}
#endif
+ #ifdef FEAT_CHANNEL
+ if (buf->b_write_to_channel)
+ channel_write_new_lines(buf);
+ #endif
+
return OK;
}
*** ../vim-7.4.1501/src/proto/channel.pro 2016-03-03 22:51:36.133809707
+0100
--- src/proto/channel.pro 2016-03-06 18:21:38.671221230 +0100
***************
*** 14,19 ****
--- 14,20 ----
void channel_set_options(channel_T *channel, jobopt_T *opt);
void channel_set_req_callback(channel_T *channel, int part, char_u *callback,
int id);
void channel_write_in(channel_T *channel);
+ void channel_write_new_lines(buf_T *buf);
char_u *channel_get(channel_T *channel, int part);
int channel_collapse(channel_T *channel, int part);
int channel_can_write_to(channel_T *channel);
*** ../vim-7.4.1501/src/version.c 2016-03-06 16:38:23.123062145 +0100
--- src/version.c 2016-03-06 20:10:22.255688403 +0100
***************
*** 745,746 ****
--- 745,748 ----
{ /* Add new patch number below this line */
+ /**/
+ 1502,
/**/
--
Imagine a world without hypothetical situations.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.