Unix Technical Forum

mg yank/undo fix

This is a discussion on mg yank/undo fix within the mailing.openbsd.tech forums, part of the OpenBSD category; --> The following diff fixes an error where undoing a yank operation actually doubles the text in the yank buffer. ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 08:11 AM
kjell@pintday.org
 
Posts: n/a
Default mg yank/undo fix

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,

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 05:50 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com