On 10/13/07, Xavier de Gaye wrote:
> algorithm:
>   next is position of first byte (if exists) after deleted section
>   partial 1st line if:
>     first->col != 0 or (next != NULL and first->lnum == next->lnum)
>   partial last line if:
>     first->lnum != last->lnum and next != NULL and last->lnum  == next->lnum
>   delete full lines:
>     if partial 1st line: from = first + 1 else first
>     if partial last line: to = last - 1 else last
>     if to >= from:
>        move cursor to from
>        delete to:from


Hello Bram,

The following patch fixes the problem.

I have run the tests with the following setup:
vim:
    Makefile: CFLAGS = -DNBDEBUG
    nbdebug.h: #define nbdebug(a) nbdbg a
clewn:
    export SPRO_GVIM_DEBUG=netbeans.log
    export SPRO_GVIM_DLEVEL=0xffffffff
    tail -f netbeans.log
    clewn -d -vc /path/to/patched/vim71/src/vim
        edit a file and use the following command to remove a
        section of the file:
            (gdb) # <bufID> remove <off> <length>

I have tested all the cases on a file with fileformat=unix, including
the cases when the section ends on the terminating newline byte.

Xavier


=====================================================================
*** netbeans.c.orig     2007-10-12 21:18:54.000000000 +0200
--- netbeans.c  2007-10-15 20:19:28.000000000 +0200
***************
*** 83,88 ****
--- 83,89 ----
  static void messageFromNetbeans __ARGS((gpointer, gint, GdkInputCondition));
  #endif
  static void nb_parse_cmd __ARGS((char_u *));
+ static void nb_partialremove __ARGS((linenr_T lnum, colnr_T first,
colnr_T last, int eol));
  static int  nb_do_cmd __ARGS((int, char_u *, int, int, char_u *));
  static void nb_send __ARGS((char *buf, char *fun));

***************
*** 1204,1209 ****
--- 1205,1230 ----
      return result;
  }

+ /*
+  * Remove from first byte to last byte included, at line lnum
+  * of the current buffer. Remove to end of line when eol is TRUE.
+  */
+     static void
+ nb_partialremove(linenr_T lnum, colnr_T first, colnr_T last, int eol)
+ {
+     int len;
+     char_u *ptr;
+
+     ptr = vim_strsave(ml_get(lnum));
+     len = STRLEN(ptr);
+     if(eol || last >= len)
+       last = len - 1;
+
+     mch_memmove(ptr + first, ptr + last + 1, STRLEN(ptr + last + 1) + 1);
+     nbdebug(("    NEW LINE %d: %s\n", lnum, ptr));
+     ml_replace(lnum, ptr, TRUE);
+ }
+
  #define SKIP_STOP 2
  #define streq(a,b) (strcmp(a,b) == 0)
  static int needupdate = 0;
***************
*** 1369,1376 ****
        else if (streq((char *)cmd, "remove"))
        {
            long count;
!           pos_T first, last;
!           pos_T *pos;
            int oldFire = netbeansFireChanges;
            int oldSuppress = netbeansSuppressNoLines;
            int wasChanged;
--- 1390,1397 ----
        else if (streq((char *)cmd, "remove"))
        {
            long count;
!           pos_T *pos, first, last, *next;
!           pos_T to, from;
            int oldFire = netbeansFireChanges;
            int oldSuppress = netbeansSuppressNoLines;
            int wasChanged;
***************
*** 1392,1404 ****
            {
                netbeansFireChanges = FALSE;
                netbeansSuppressNoLines = TRUE;
-
                nb_set_curbuf(buf->bufp);
                wasChanged = buf->bufp->b_changed;
                cp = (char *)args;
                off = strtol(cp, &cp, 10);
                count = strtol(cp, &cp, 10);
                args = (char_u *)cp;
                /* delete "count" chars, starting at "off" */
                pos = off2pos(buf->bufp, off);
                if (!pos)
--- 1413,1425 ----
            {
                netbeansFireChanges = FALSE;
                netbeansSuppressNoLines = TRUE;
                nb_set_curbuf(buf->bufp);
                wasChanged = buf->bufp->b_changed;
                cp = (char *)args;
                off = strtol(cp, &cp, 10);
                count = strtol(cp, &cp, 10);
                args = (char_u *)cp;
+
                /* delete "count" chars, starting at "off" */
                pos = off2pos(buf->bufp, off);
                if (!pos)
***************
*** 1410,1415 ****
--- 1431,1437 ----
                }
                first = *pos;
                nbdebug(("    FIRST POS: line %d, col %d\n", first.lnum, 
first.col));
+
                pos = off2pos(buf->bufp, off+count-1);
                if (!pos)
                {
***************
*** 1420,1444 ****
                }
                last = *pos;
                nbdebug(("    LAST POS: line %d, col %d\n", last.lnum, 
last.col));
!               curwin->w_cursor = first;
                doupdate = 1;

!               /* keep part of first line */
!               if (first.lnum == last.lnum && first.col != last.col)
                {
!                   /* deletion is within one line */
!                   char_u *p = ml_get(first.lnum);
!                   mch_memmove(p + first.col, p + last.col + 1, STRLEN(p + 
last.col) + 1);
!                   nbdebug(("    NEW LINE %d: %s\n", first.lnum, p));
!                   ml_replace(first.lnum, p, TRUE);
                }

!               if (first.lnum < last.lnum)
                {
                    int i;

                    /* delete signs from the lines being deleted */
!                   for (i = first.lnum; i <= last.lnum; i++)
                    {
                        int id = buf_findsign_id(buf->bufp, (linenr_T)i);
                        if (id > 0)
--- 1442,1481 ----
                }
                last = *pos;
                nbdebug(("    LAST POS: line %d, col %d\n", last.lnum, 
last.col));
!               from = first;
!               to = last;
                doupdate = 1;

!               /* get the position of the first byte after the deleted section 
*/
!               next = off2pos(buf->bufp, off+count);
!
!               /* remove part of the first line */
!               if (first.col != 0 || (next != NULL && first.lnum == 
next->lnum))
!               {
!                   /* remove to the end of the line */
!                   if (first.lnum != last.lnum
!                           || (next != NULL && first.lnum != next->lnum))
!                       nb_partialremove(first.lnum, first.col, 0, TRUE);
!                   else
!                       nb_partialremove(first.lnum, first.col, last.col, 
FALSE);
!
!                   from.lnum += 1;
!               }
!
!               /* remove part of the last line */
!               if (first.lnum != last.lnum && next != NULL
!                       && next->col != 0 && last.lnum == next->lnum)
                {
!                   nb_partialremove(last.lnum, 0, last.col, FALSE);
!                   to.lnum -= 1;
                }

!               if (to.lnum >= from.lnum)
                {
                    int i;

                    /* delete signs from the lines being deleted */
!                   for (i = from.lnum; i <= to.lnum; i++)
                    {
                        int id = buf_findsign_id(buf->bufp, (linenr_T)i);
                        if (id > 0)
***************
*** 1451,1458 ****
                    }

                    /* delete whole lines */
!                   nbdebug(("    Deleting lines %d through %d\n", first.lnum, 
last.lnum));
!                   del_lines(last.lnum - first.lnum + 1, FALSE);
                }
                buf->bufp->b_changed = wasChanged; /* logically unchanged */
                netbeansFireChanges = oldFire;
--- 1488,1496 ----
                    }

                    /* delete whole lines */
!                   nbdebug(("    Deleting lines %d through %d\n", from.lnum, 
to.lnum));
!                   curwin->w_cursor = from;
!                   del_lines(to.lnum - from.lnum + 1, FALSE);
                }
                buf->bufp->b_changed = wasChanged; /* logically unchanged */
                netbeansFireChanges = oldFire;
=====================================================================

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui