diff options
author | Kjell Wooding <kjell@cvs.openbsd.org> | 2008-06-14 07:38:54 +0000 |
---|---|---|
committer | Kjell Wooding <kjell@cvs.openbsd.org> | 2008-06-14 07:38:54 +0000 |
commit | 6d63c5c28d1fe760ae7cbb47f13a485d7dabe584 (patch) | |
tree | 35bdba06b275218f6089e22526c33a46b31a700e /usr.bin/mg | |
parent | 23cf02a5cde3ab70d81348bc7d0cc22727efbef6 (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.h | 3 | ||||
-rw-r--r-- | usr.bin/mg/kbd.c | 45 | ||||
-rw-r--r-- | usr.bin/mg/undo.c | 16 |
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; |