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.

Raspunde prin e-mail lui