mg yank/undo fix

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

mg yank/undo fix

Kjell-5
The following diff fixes an error where undoing a yank
operation actually doubles the text in the yank buffer.

to reproduce, do a C-K, C-Y, M-x undo, C-Y in a buffer with some text.

Please have a close look at this one, as it changes the semantics of
the KFORW/KBACK flags into, well, flags.

Index: def.h
===================================================================
RCS file: /usr/local/cvs/src/usr.bin/mg/def.h,v
retrieving revision 1.72
diff -u -r1.72 def.h
--- def.h 7 Nov 2005 23:32:20 -0000 1.72
+++ def.h 16 Nov 2005 18:40:46 -0000
@@ -108,9 +108,10 @@
 /*
  * Flags for "ldelete"/"kinsert"
  */
-#define KNONE 0
-#define KFORW 1
-#define KBACK 2
+#define KNONE 0x0001
+#define KFORW 0x0002
+#define KBACK 0x0004
+#define KUNDO 0x0008
 
 
 /*
@@ -357,6 +358,7 @@
 void kdelete(void);
 int kinsert(int, int);
 int kremove(int);
+int kchunk(char *, RSIZE, int);
 
 /* window.c X */
 MGWIN *new_window(BUFFER *);
Index: line.c
===================================================================
RCS file: /usr/local/cvs/src/usr.bin/mg/line.c,v
retrieving revision 1.25
diff -u -r1.25 line.c
--- line.c 13 Oct 2005 20:28:49 -0000 1.25
+++ line.c 16 Nov 2005 18:42:45 -0000
@@ -427,13 +427,6 @@
 
  undo_add_delete(curwp->w_dotp, curwp->w_doto, n);
 
- /*
- * HACK - doesn't matter, and fixes back-over-nl bug for empty
- * kill buffers.
- */
- if (kused == kstart)
- kflag = KFORW;
-
  while (n != 0) {
  dotp = curwp->w_dotp;
  doto = curwp->w_doto;
@@ -452,7 +445,7 @@
  return (FALSE);
  lchange(WFHARD);
  if (ldelnewline() == FALSE ||
-    (kflag != KNONE && kinsert('\n', kflag) == FALSE))
+    kinsert('\n', kflag) == FALSE)
  return (FALSE);
  --n;
  continue;
@@ -460,20 +453,8 @@
  lchange(WFEDIT);
  /* Scrunch text */
  cp1 = &dotp->l_text[doto];
- if (kflag == KFORW) {
- while (ksize - kused < chunk)
- if (kgrow(FALSE) == FALSE)
- return (FALSE);
- bcopy(cp1, &(kbufp[kused]), (int)chunk);
- kused += chunk;
- } else if (kflag == KBACK) {
- while (kstart < chunk)
- if (kgrow(TRUE) == FALSE)
- return (FALSE);
- bcopy(cp1, &(kbufp[kstart - chunk]), (int)chunk);
- kstart -= chunk;
- } else if (kflag != KNONE)
- panic("broken ldelete call");
+ if (kchunk(cp1, chunk, kflag) != TRUE)
+ return (FALSE);
  for (cp2 = cp1 + chunk; cp2 < &dotp->l_text[dotp->l_used];
     cp2++)
  *cp1++ = *cp2;
@@ -622,17 +603,20 @@
  * that if you put something in the kill buffer you are going to put more
  * stuff there too later. Return TRUE if all is well, and FALSE on errors.
  * Print a message on errors.  Dir says whether to put it at back or front.
+ * This call is ignored if KUNDO or KNONE is set.
  */
 int
-kinsert(int c, int dir)
+kinsert(int c, int kflag)
 {
- if (kused == ksize && dir == KFORW && kgrow(FALSE) == FALSE)
+ if (kflag & (KUNDO | KNONE))
+ return (TRUE);
+ if (kused == ksize && (kflag & KFORW) && kgrow(FALSE) == FALSE)
  return (FALSE);
- if (kstart == 0 && dir == KBACK && kgrow(TRUE) == FALSE)
+ if (kstart == 0 && (kflag & KBACK) && kgrow(TRUE) == FALSE)
  return (FALSE);
- if (dir == KFORW)
+ if (kflag & KFORW)
  kbufp[kused++] = c;
- else if (dir == KBACK)
+ else if (kflag & KBACK)
  kbufp[--kstart] = c;
  else
  panic("broken kinsert call"); /* Oh shit! */
@@ -640,7 +624,7 @@
 }
 
 /*
- * kgrow - just get more kill buffer for the callee. back is true if
+ * kgrow - just get more kill buffer for the callee. If back is TRUE,
  * we are trying to get space at the beginning of the kill buffer.
  */
 static int
@@ -680,4 +664,37 @@
  if (n < 0 || n + kstart >= kused)
  return (-1);
  return (CHARMASK(kbufp[n + kstart]));
+}
+
+/*
+ * copy a string into the kill buffer. kflag gives direction.
+ * if KUNDO set, do nothing.
+ */
+int
+kchunk(char *cp1, RSIZE chunk, int kflag)
+{
+ /*
+ * HACK - doesn't matter, and fixes back-over-nl bug for empty
+ * kill buffers.
+ */
+ if (kused == kstart)
+ kflag |= KFORW;
+ if (kflag & KUNDO) {
+ return (TRUE);
+ } else if (kflag & KFORW) {
+ while (ksize - kused < chunk)
+ if (kgrow(FALSE) == FALSE)
+ return (FALSE);
+ bcopy(cp1, &(kbufp[kused]), (int)chunk);
+ kused += chunk;
+ } else if (kflag & KBACK) {
+ while (kstart < chunk)
+ if (kgrow(TRUE) == FALSE)
+ return (FALSE);
+ bcopy(cp1, &(kbufp[kstart - chunk]), (int)chunk);
+ kstart -= chunk;
+ } else if (!(kflag & KNONE))
+ panic("broken kchunk call");
+
+ return (TRUE);
 }
Index: undo.c
===================================================================
RCS file: /usr/local/cvs/src/usr.bin/mg/undo.c,v
retrieving revision 1.33
diff -u -r1.33 undo.c
--- undo.c 12 Nov 2005 18:48:08 -0000 1.33
+++ undo.c 16 Nov 2005 18:33:01 -0000
@@ -506,7 +506,7 @@
  */
  switch (ptr->type) {
  case INSERT:
- ldelete(ptr->region.r_size, KFORW);
+ ldelete(ptr->region.r_size, KFORW | KUNDO);
  break;
  case DELETE:
  region_put_data(ptr->content,