Karsten Hopp ad8464
To: vim-dev@vim.org
Karsten Hopp ad8464
Subject: Patch 7.1.207
Karsten Hopp ad8464
Fcc: outbox
Karsten Hopp ad8464
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp ad8464
Mime-Version: 1.0
Karsten Hopp ad8464
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp ad8464
Content-Transfer-Encoding: 8bit
Karsten Hopp ad8464
------------
Karsten Hopp ad8464
Karsten Hopp ad8464
Patch 7.1.207
Karsten Hopp ad8464
Problem:    Netbeans: "remove" cannot delete one line. 
Karsten Hopp ad8464
Solution:   Remove partial lines and whole lines properly.  Avoid a memory
Karsten Hopp ad8464
	    leak.  (Xavier de Gaye)
Karsten Hopp ad8464
Files:	    src/netbeans.c
Karsten Hopp ad8464
Karsten Hopp ad8464
Karsten Hopp ad8464
*** ../vim-7.1.206/src/netbeans.c	Thu May 10 18:40:48 2007
Karsten Hopp ad8464
--- src/netbeans.c	Sat Jan  5 18:03:24 2008
Karsten Hopp ad8464
***************
Karsten Hopp ad8464
*** 1204,1209 ****
Karsten Hopp ad8464
--- 1204,1257 ----
Karsten Hopp ad8464
      return result;
Karsten Hopp ad8464
  }
Karsten Hopp ad8464
  
Karsten Hopp ad8464
+ /*
Karsten Hopp ad8464
+  * Remove from "first" byte to "last" byte (inclusive), at line "lnum" of the
Karsten Hopp ad8464
+  * current buffer.  Remove to end of line when "last" is MAXCOL.
Karsten Hopp ad8464
+  */
Karsten Hopp ad8464
+     static void
Karsten Hopp ad8464
+ nb_partialremove(linenr_T lnum, colnr_T first, colnr_T last)
Karsten Hopp ad8464
+ {
Karsten Hopp ad8464
+     char_u *oldtext, *newtext;
Karsten Hopp ad8464
+     int oldlen;
Karsten Hopp ad8464
+     int lastbyte = last;
Karsten Hopp ad8464
+ 
Karsten Hopp ad8464
+     oldtext = ml_get(lnum);
Karsten Hopp ad8464
+     oldlen = STRLEN(oldtext);
Karsten Hopp ad8464
+     if (first >= oldlen || oldlen == 0)  /* just in case */
Karsten Hopp ad8464
+ 	return;
Karsten Hopp ad8464
+     if (lastbyte >= oldlen)
Karsten Hopp ad8464
+ 	lastbyte = oldlen - 1;
Karsten Hopp ad8464
+     newtext = alloc(oldlen - (int)(lastbyte - first));
Karsten Hopp ad8464
+     if (newtext != NULL)
Karsten Hopp ad8464
+     {
Karsten Hopp ad8464
+ 	mch_memmove(newtext, oldtext, first);
Karsten Hopp ad8464
+ 	mch_memmove(newtext + first, oldtext + lastbyte + 1, STRLEN(oldtext + lastbyte + 1) + 1);
Karsten Hopp ad8464
+ 	nbdebug(("    NEW LINE %d: %s\n", lnum, newtext));
Karsten Hopp ad8464
+ 	ml_replace(lnum, newtext, FALSE);
Karsten Hopp ad8464
+     }
Karsten Hopp ad8464
+ }
Karsten Hopp ad8464
+ 
Karsten Hopp ad8464
+ /*
Karsten Hopp ad8464
+  * Replace the "first" line with the concatenation of the "first" and
Karsten Hopp ad8464
+  * the "other" line. The "other" line is not removed.
Karsten Hopp ad8464
+  */
Karsten Hopp ad8464
+     static void
Karsten Hopp ad8464
+ nb_joinlines(linenr_T first, linenr_T other)
Karsten Hopp ad8464
+ {
Karsten Hopp ad8464
+     int len_first, len_other;
Karsten Hopp ad8464
+     char_u *p;
Karsten Hopp ad8464
+ 
Karsten Hopp ad8464
+     len_first = STRLEN(ml_get(first));
Karsten Hopp ad8464
+     len_other = STRLEN(ml_get(other));
Karsten Hopp ad8464
+     p = alloc((unsigned)(len_first + len_other + 1));
Karsten Hopp ad8464
+     if (p != NULL)
Karsten Hopp ad8464
+     {
Karsten Hopp ad8464
+       mch_memmove(p, ml_get(first), len_first);
Karsten Hopp ad8464
+       mch_memmove(p + len_first, ml_get(other), len_other + 1);
Karsten Hopp ad8464
+       ml_replace(first, p, FALSE);
Karsten Hopp ad8464
+     }
Karsten Hopp ad8464
+ }
Karsten Hopp ad8464
+ 
Karsten Hopp ad8464
  #define SKIP_STOP 2
Karsten Hopp ad8464
  #define streq(a,b) (strcmp(a,b) == 0)
Karsten Hopp ad8464
  static int needupdate = 0;
Karsten Hopp ad8464
***************
Karsten Hopp ad8464
*** 1371,1376 ****
Karsten Hopp ad8464
--- 1419,1426 ----
Karsten Hopp ad8464
  	    long count;
Karsten Hopp ad8464
  	    pos_T first, last;
Karsten Hopp ad8464
  	    pos_T *pos;
Karsten Hopp ad8464
+ 	    pos_T *next;
Karsten Hopp ad8464
+ 	    linenr_T del_from_lnum, del_to_lnum;  /* lines to be deleted as a whole */
Karsten Hopp ad8464
  	    int oldFire = netbeansFireChanges;
Karsten Hopp ad8464
  	    int oldSuppress = netbeansSuppressNoLines;
Karsten Hopp ad8464
  	    int wasChanged;
Karsten Hopp ad8464
***************
Karsten Hopp ad8464
*** 1420,1444 ****
Karsten Hopp ad8464
  		}
Karsten Hopp ad8464
  		last = *pos;
Karsten Hopp ad8464
  		nbdebug(("    LAST POS: line %d, col %d\n", last.lnum, last.col));
Karsten Hopp ad8464
! 		curwin->w_cursor = first;
Karsten Hopp ad8464
  		doupdate = 1;
Karsten Hopp ad8464
  
Karsten Hopp ad8464
! 		/* keep part of first line */
Karsten Hopp ad8464
! 		if (first.lnum == last.lnum && first.col != last.col)
Karsten Hopp ad8464
  		{
Karsten Hopp ad8464
! 		    /* deletion is within one line */
Karsten Hopp ad8464
! 		    char_u *p = ml_get(first.lnum);
Karsten Hopp ad8464
! 		    mch_memmove(p + first.col, p + last.col + 1, STRLEN(p + last.col) + 1);
Karsten Hopp ad8464
! 		    nbdebug(("    NEW LINE %d: %s\n", first.lnum, p));
Karsten Hopp ad8464
! 		    ml_replace(first.lnum, p, TRUE);
Karsten Hopp ad8464
  		}
Karsten Hopp ad8464
  
Karsten Hopp ad8464
! 		if (first.lnum < last.lnum)
Karsten Hopp ad8464
  		{
Karsten Hopp ad8464
  		    int i;
Karsten Hopp ad8464
  
Karsten Hopp ad8464
  		    /* delete signs from the lines being deleted */
Karsten Hopp ad8464
! 		    for (i = first.lnum; i <= last.lnum; i++)
Karsten Hopp ad8464
  		    {
Karsten Hopp ad8464
  			int id = buf_findsign_id(buf->bufp, (linenr_T)i);
Karsten Hopp ad8464
  			if (id > 0)
Karsten Hopp ad8464
--- 1470,1544 ----
Karsten Hopp ad8464
  		}
Karsten Hopp ad8464
  		last = *pos;
Karsten Hopp ad8464
  		nbdebug(("    LAST POS: line %d, col %d\n", last.lnum, last.col));
Karsten Hopp ad8464
! 		del_from_lnum = first.lnum;
Karsten Hopp ad8464
! 		del_to_lnum = last.lnum;
Karsten Hopp ad8464
  		doupdate = 1;
Karsten Hopp ad8464
  
Karsten Hopp ad8464
! 		/* Get the position of the first byte after the deleted
Karsten Hopp ad8464
! 		 * section.  "next" is NULL when deleting to the end of the
Karsten Hopp ad8464
! 		 * file. */
Karsten Hopp ad8464
! 		next = off2pos(buf->bufp, off + count);
Karsten Hopp ad8464
! 
Karsten Hopp ad8464
! 		/* Remove part of the first line. */
Karsten Hopp ad8464
! 		if (first.col != 0 || (next != NULL && first.lnum == next->lnum))
Karsten Hopp ad8464
  		{
Karsten Hopp ad8464
! 		    if (first.lnum != last.lnum
Karsten Hopp ad8464
! 			    || (next != NULL && first.lnum != next->lnum))
Karsten Hopp ad8464
! 		    {
Karsten Hopp ad8464
! 			/* remove to the end of the first line */
Karsten Hopp ad8464
! 			nb_partialremove(first.lnum, first.col,
Karsten Hopp ad8464
! 							     (colnr_T)MAXCOL);
Karsten Hopp ad8464
! 			if (first.lnum == last.lnum)
Karsten Hopp ad8464
! 			{
Karsten Hopp ad8464
! 			    /* Partial line to remove includes the end of
Karsten Hopp ad8464
! 			     * line.  Join the line with the next one, have
Karsten Hopp ad8464
! 			     * the next line deleted below. */
Karsten Hopp ad8464
! 			    nb_joinlines(first.lnum, next->lnum);
Karsten Hopp ad8464
! 			    del_to_lnum = next->lnum;
Karsten Hopp ad8464
! 			}
Karsten Hopp ad8464
! 		    }
Karsten Hopp ad8464
! 		    else
Karsten Hopp ad8464
! 		    {
Karsten Hopp ad8464
! 			/* remove within one line */
Karsten Hopp ad8464
! 			nb_partialremove(first.lnum, first.col, last.col);
Karsten Hopp ad8464
! 		    }
Karsten Hopp ad8464
! 		    ++del_from_lnum;  /* don't delete the first line */
Karsten Hopp ad8464
! 		}
Karsten Hopp ad8464
! 
Karsten Hopp ad8464
! 		/* Remove part of the last line. */
Karsten Hopp ad8464
! 		if (first.lnum != last.lnum && next != NULL
Karsten Hopp ad8464
! 			&& next->col != 0 && last.lnum == next->lnum)
Karsten Hopp ad8464
! 		{
Karsten Hopp ad8464
! 		    nb_partialremove(last.lnum, 0, last.col);
Karsten Hopp ad8464
! 		    if (del_from_lnum > first.lnum)
Karsten Hopp ad8464
! 		    {
Karsten Hopp ad8464
! 			/* Join end of last line to start of first line; last
Karsten Hopp ad8464
! 			 * line is deleted below. */
Karsten Hopp ad8464
! 			nb_joinlines(first.lnum, last.lnum);
Karsten Hopp ad8464
! 		    }
Karsten Hopp ad8464
! 		    else
Karsten Hopp ad8464
! 			/* First line is deleted as a whole, keep the last
Karsten Hopp ad8464
! 			 * line. */
Karsten Hopp ad8464
! 			--del_to_lnum;
Karsten Hopp ad8464
  		}
Karsten Hopp ad8464
  
Karsten Hopp ad8464
! 		/* First is partial line; last line to remove includes
Karsten Hopp ad8464
! 		 * the end of line; join first line to line following last
Karsten Hopp ad8464
! 		 * line; line following last line is deleted below. */
Karsten Hopp ad8464
! 		if (first.lnum != last.lnum && del_from_lnum > first.lnum
Karsten Hopp ad8464
! 			&& next != NULL && last.lnum != next->lnum)
Karsten Hopp ad8464
! 		{
Karsten Hopp ad8464
! 		    nb_joinlines(first.lnum, next->lnum);
Karsten Hopp ad8464
! 		    del_to_lnum = next->lnum;
Karsten Hopp ad8464
! 		}
Karsten Hopp ad8464
! 
Karsten Hopp ad8464
! 		/* Delete whole lines if there are any. */
Karsten Hopp ad8464
! 		if (del_to_lnum >= del_from_lnum)
Karsten Hopp ad8464
  		{
Karsten Hopp ad8464
  		    int i;
Karsten Hopp ad8464
  
Karsten Hopp ad8464
  		    /* delete signs from the lines being deleted */
Karsten Hopp ad8464
! 		    for (i = del_from_lnum; i <= del_to_lnum; i++)
Karsten Hopp ad8464
  		    {
Karsten Hopp ad8464
  			int id = buf_findsign_id(buf->bufp, (linenr_T)i);
Karsten Hopp ad8464
  			if (id > 0)
Karsten Hopp ad8464
***************
Karsten Hopp ad8464
*** 1450,1459 ****
Karsten Hopp ad8464
  			    nbdebug(("    No sign on line %d\n", i));
Karsten Hopp ad8464
  		    }
Karsten Hopp ad8464
  
Karsten Hopp ad8464
! 		    /* delete whole lines */
Karsten Hopp ad8464
! 		    nbdebug(("    Deleting lines %d through %d\n", first.lnum, last.lnum));
Karsten Hopp ad8464
! 		    del_lines(last.lnum - first.lnum + 1, FALSE);
Karsten Hopp ad8464
  		}
Karsten Hopp ad8464
  		buf->bufp->b_changed = wasChanged; /* logically unchanged */
Karsten Hopp ad8464
  		netbeansFireChanges = oldFire;
Karsten Hopp ad8464
  		netbeansSuppressNoLines = oldSuppress;
Karsten Hopp ad8464
--- 1550,1564 ----
Karsten Hopp ad8464
  			    nbdebug(("    No sign on line %d\n", i));
Karsten Hopp ad8464
  		    }
Karsten Hopp ad8464
  
Karsten Hopp ad8464
! 		    nbdebug(("    Deleting lines %d through %d\n", del_from_lnum, del_to_lnum));
Karsten Hopp ad8464
! 		    curwin->w_cursor.lnum = del_from_lnum;
Karsten Hopp ad8464
! 		    curwin->w_cursor.col = 0;
Karsten Hopp ad8464
! 		    del_lines(del_to_lnum - del_from_lnum + 1, FALSE);
Karsten Hopp ad8464
  		}
Karsten Hopp ad8464
+ 
Karsten Hopp ad8464
+ 		/* Leave cursor at first deleted byte. */
Karsten Hopp ad8464
+ 		curwin->w_cursor = first;
Karsten Hopp ad8464
+ 		check_cursor_lnum();
Karsten Hopp ad8464
  		buf->bufp->b_changed = wasChanged; /* logically unchanged */
Karsten Hopp ad8464
  		netbeansFireChanges = oldFire;
Karsten Hopp ad8464
  		netbeansSuppressNoLines = oldSuppress;
Karsten Hopp ad8464
***************
Karsten Hopp ad8464
*** 2374,2381 ****
Karsten Hopp ad8464
   * the current buffer as "buf".
Karsten Hopp ad8464
   */
Karsten Hopp ad8464
      static void
Karsten Hopp ad8464
! nb_set_curbuf(buf)
Karsten Hopp ad8464
!     buf_T *buf;
Karsten Hopp ad8464
  {
Karsten Hopp ad8464
      if (curbuf != buf && buf_jump_open_win(buf) == NULL)
Karsten Hopp ad8464
  	set_curbuf(buf, DOBUF_GOTO);
Karsten Hopp ad8464
--- 2479,2485 ----
Karsten Hopp ad8464
   * the current buffer as "buf".
Karsten Hopp ad8464
   */
Karsten Hopp ad8464
      static void
Karsten Hopp ad8464
! nb_set_curbuf(buf_T *buf)
Karsten Hopp ad8464
  {
Karsten Hopp ad8464
      if (curbuf != buf && buf_jump_open_win(buf) == NULL)
Karsten Hopp ad8464
  	set_curbuf(buf, DOBUF_GOTO);
Karsten Hopp ad8464
*** ../vim-7.1.206/src/version.c	Sat Jan  5 13:58:48 2008
Karsten Hopp ad8464
--- src/version.c	Sat Jan  5 18:06:04 2008
Karsten Hopp ad8464
***************
Karsten Hopp ad8464
*** 668,669 ****
Karsten Hopp ad8464
--- 668,671 ----
Karsten Hopp ad8464
  {   /* Add new patch number below this line */
Karsten Hopp ad8464
+ /**/
Karsten Hopp ad8464
+     207,
Karsten Hopp ad8464
  /**/
Karsten Hopp ad8464
Karsten Hopp ad8464
-- 
Karsten Hopp ad8464
Q:   How many hardware engineers does it take to change a lightbulb?
Karsten Hopp ad8464
A:   None.  We'll fix it in software.
Karsten Hopp ad8464
Karsten Hopp ad8464
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp ad8464
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp ad8464
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp ad8464
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///