summaryrefslogtreecommitdiff
path: root/usr.bin/mg/kbd.c
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/kbd.c
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/kbd.c')
-rw-r--r--usr.bin/mg/kbd.c45
1 files changed, 36 insertions, 9 deletions
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));
+}