summaryrefslogtreecommitdiff
path: root/usr.bin/mg
diff options
context:
space:
mode:
authorKjell Wooding <kjell@cvs.openbsd.org>2008-06-14 07:38:54 +0000
committerKjell Wooding <kjell@cvs.openbsd.org>2008-06-14 07:38:54 +0000
commit6d63c5c28d1fe760ae7cbb47f13a485d7dabe584 (patch)
tree35bdba06b275218f6089e22526c33a46b31a700e /usr.bin/mg
parent23cf02a5cde3ab70d81348bc7d0cc22727efbef6 (diff)
unf*ck undo.
No seriously. Reposition the cursor to the start of the redo position, like emacs. This gets us halfway to being emacs-finger-friendly. For the rest, introduce a rptcount variable to count successive invocations of the same function. This means undo will abort properly on C-g, and other such interruptions. This is a lot of diff for a simple-seeming problem. Emacs undo is hard.
Diffstat (limited to 'usr.bin/mg')
-rw-r--r--usr.bin/mg/def.h3
-rw-r--r--usr.bin/mg/kbd.c45
-rw-r--r--usr.bin/mg/undo.c16
3 files changed, 50 insertions, 14 deletions
diff --git a/usr.bin/mg/def.h b/usr.bin/mg/def.h
index bd3b8ce677f..451d792829f 100644
--- a/usr.bin/mg/def.h
+++ b/usr.bin/mg/def.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: def.h,v 1.104 2008/06/13 19:10:17 kjell Exp $ */
+/* $OpenBSD: def.h,v 1.105 2008/06/14 07:38:53 kjell Exp $ */
/* This file is in the public domain. */
@@ -668,3 +668,4 @@ extern char prompt[];
int tceeol;
int tcinsl;
int tcdell;
+int rptcount; /* successive invocation count */
diff --git a/usr.bin/mg/kbd.c b/usr.bin/mg/kbd.c
index 0d75c1c68b5..c0bd9e836aa 100644
--- a/usr.bin/mg/kbd.c
+++ b/usr.bin/mg/kbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kbd.c,v 1.23 2006/12/21 18:06:02 kjell Exp $ */
+/* $OpenBSD: kbd.c,v 1.24 2008/06/14 07:38:53 kjell Exp $ */
/* This file is in the public domain. */
@@ -23,6 +23,8 @@
char prompt[PROMPTL] = "", *promptp = prompt;
#endif /* !NO_DPROMPT */
+static int mgwrap(PF, int, int);
+
static int use_metakey = TRUE;
static int pushed = FALSE;
static int pushedc;
@@ -162,7 +164,7 @@ doin(void)
if (macrodef && macrocount < MAXMACRO)
macro[macrocount++].m_funct = funct;
#endif /* !NO_MACRO */
- return ((*funct)(0, 1));
+ return (mgwrap(funct, 0, 1));
}
int
@@ -179,8 +181,8 @@ rescan(int f, int n)
c = TOLOWER(key.k_chars[key.k_count - 1]);
curmap = curbp->b_modes[md]->p_map;
for (i = 0; i < key.k_count - 1; i++) {
- if ((fp = doscan(curmap, (key.k_chars[i]), &curmap))
- != NULL)
+ if ((fp = doscan(curmap, (key.k_chars[i]),
+ &curmap)) != NULL)
break;
}
if (fp == NULL) {
@@ -195,7 +197,8 @@ rescan(int f, int n)
macro[macrocount - 1].m_funct
= fp;
#endif /* !NO_MACRO */
- return ((*fp)(f, n));
+
+ return (mgwrap(fp, f, n));
}
}
}
@@ -218,7 +221,7 @@ rescan(int f, int n)
if (macrodef && macrocount <= MAXMACRO)
macro[macrocount - 1].m_funct = fp;
#endif /* !NO_MACRO */
- return ((*fp)(f, n));
+ return (mgwrap(fp, f, n));
}
}
}
@@ -252,7 +255,7 @@ universal_argument(int f, int n)
macro[macrocount++].m_funct = funct;
}
#endif /* !NO_MACRO */
- return ((*funct)(FFUNIV, nn));
+ return (mgwrap(funct, FFUNIV, nn));
}
nn <<= 2;
}
@@ -290,7 +293,7 @@ digit_argument(int f, int n)
macro[macrocount++].m_funct = funct;
}
#endif /* !NO_MACRO */
- return ((*funct)(FFOTHARG, nn));
+ return (mgwrap(funct, FFOTHARG, nn));
}
int
@@ -328,7 +331,7 @@ negative_argument(int f, int n)
macro[macrocount++].m_funct = funct;
}
#endif /* !NO_MACRO */
- return ((*funct)(FFNEGARG, nn));
+ return (mgwrap(funct, FFNEGARG, nn));
}
/*
@@ -424,3 +427,27 @@ quote(int f, int n)
}
return (selfinsert(f, n));
}
+
+/*
+ * Wraper function to count invocation repeats.
+ * We ignore any function whose sole purpose is to get us
+ * to the intended function.
+ */
+static int
+mgwrap(PF funct, int f, int n)
+{
+ static PF ofp;
+
+ if (funct != rescan &&
+ funct != negative_argument &&
+ funct != digit_argument &&
+ funct != universal_argument) {
+ if (funct == ofp)
+ rptcount++;
+ else
+ rptcount = 0;
+ ofp = funct;
+ }
+
+ return ((*funct)(f, n));
+}
diff --git a/usr.bin/mg/undo.c b/usr.bin/mg/undo.c
index 4b8d1a25fbd..f4206a86a74 100644
--- a/usr.bin/mg/undo.c
+++ b/usr.bin/mg/undo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: undo.c,v 1.45 2008/06/11 17:07:37 kjell Exp $ */
+/* $OpenBSD: undo.c,v 1.46 2008/06/14 07:38:53 kjell Exp $ */
/*
* This file is in the public domain
*/
@@ -173,7 +173,8 @@ undo_enable(int on)
/*
* If undo is enabled, then:
- * undo_boundary_enable(FALS) stops recording undo boundaries between actions.
+ * undo_boundary_enable(FALSE) stops recording undo boundaries
+ * between actions.
* undo_boundary_enable(TRUE) enables undo boundaries.
* If undo is disabled, this function has no effect.
*/
@@ -443,12 +444,15 @@ undo(int f, int n)
static int nulled = FALSE;
int lineno;
+ if (n < 0)
+ return (FALSE);
+
dot = find_dot(curwp->w_dotp, curwp->w_doto);
ptr = curbp->b_undoptr;
- /* if we moved, make ptr point back to the top of the list */
- if ((ptr == NULL && nulled == TRUE) || curbp->b_undopos != dot) {
+ /* first invocation, make ptr point back to the top of the list */
+ if ((ptr == NULL && nulled == TRUE) || rptcount == 0) {
ptr = LIST_FIRST(&curbp->b_undo);
nulled = TRUE;
}
@@ -515,8 +519,12 @@ undo(int f, int n)
ldelete(ptr->region.r_size, KNONE);
break;
case DELETE:
+ lp = curwp->w_dotp;
+ offset = curwp->w_doto;
region_put_data(ptr->content,
ptr->region.r_size);
+ curwp->w_dotp = lp;
+ curwp->w_doto = offset;
break;
case BOUNDARY:
done = 1;