Re: mg:join-line
Yeah, nice catch on the twiddle bug. This looks pretty good. Anyone else try it? -kj On Mon, Jan 17, 2011 at 10:10 AM, Henri Kemppainen ducl...@guu.fi wrote: Looks pretty good. I might add an undo boundary around the whole thing (I note emacs doesn't do this properly, at least on the version I have here)... I like it. If undo is a concern, then it might be a good idea to check the other functions while we're here. I found at least the following offenders in random.c: twiddle() might return early, leaving the boundaries disabled; openline() can open many at once, but each gets its own boundary; justone() makes two changes but doesn't set the boundary; lfindent() and newline() have the same problem as openline(). There's also indent() which makes two changes, but it's not bound to a key and is only called via cmode, where the undo boundaries are in place already. I'm afraid simply adding the the undo boundary around newline() will break yank(), which sets its own boundary and calls newline() among other changes. If we want this undo stuff, then we probably should add checks such that none of these functions set boundaries if they were disabled (by some other function) to start with. What do you think? The following diff fixes twiddle() and adds boundaries for openline(), justone(), and lfindent(). I leave newline() intact for now. --- src/usr.bin/mg.old/random.c Mon Jan 17 15:16:09 2011 +++ src/usr.bin/mg/random.c Mon Jan 17 16:25:21 2011 @@ -119,7 +119,6 @@ twiddle(int f, int n) dotp = curwp-w_dotp; doto = curwp-w_doto; - undo_boundary_enable(FFRAND, 0); if (doto == llength(dotp)) { if (--doto = 0) return (FALSE); @@ -129,6 +128,7 @@ twiddle(int f, int n) if (doto == 0) return (FALSE); } + undo_boundary_enable(FFRAND, 0); cr = lgetc(dotp, doto - 1); (void)backdel(FFRAND, 1); (void)forwchar(FFRAND, 1); @@ -158,6 +158,7 @@ openline(int f, int n) return (TRUE); /* insert newlines */ + undo_boundary_enable(FFRAND, 0); i = n; do { s = lnewline(); @@ -166,6 +167,7 @@ openline(int f, int n) /* then go back up overtop of them all */ if (s == TRUE) s = backchar(f | FFRAND, n); + undo_boundary_enable(FFRAND, 1); return (s); } @@ -223,8 +225,11 @@ deblank(int f, int n) int justone(int f, int n) { + undo_boundary_enable(FFRAND, 0); (void)delwhite(f, n); - return (linsert(1, ' ')); + linsert(1, ' '); + undo_boundary_enable(FFRAND, 1); + return (TRUE); } /* @@ -318,10 +323,12 @@ int lfindent(int f, int n) { int c, i, nicol; + int s = TRUE; if (n 0) return (FALSE); + undo_boundary_enable(FFRAND, 0); while (n--) { nicol = 0; for (i = 0; i llength(curwp-w_dotp); ++i) { @@ -337,10 +344,13 @@ lfindent(int f, int n) curbp-b_flag BFNOTAB) ? linsert(nicol, ' ') == FALSE : ( #endif /* NOTAB */ ((i = nicol / 8) != 0 linsert(i, '\t') == FALSE) || - ((i = nicol % 8) != 0 linsert(i, ' ') == FALSE - return (FALSE); + ((i = nicol % 8) != 0 linsert(i, ' ') == FALSE { + s = FALSE; + break; + } } - return (TRUE); + undo_boundary_enable(FFRAND, 1); + return (s); } /*
Re: mg:join-line
Kjell Wooding wrote: I might add an undo boundary around the whole thing (I note emacs doesn't do this properly, at least on the version I have here)... Undoing join-line works fine with the emacs version I am using here. Built 2 days ago, from git. ~% emacs --version GNU Emacs 24.0.50.1 # Han
Re: mg:join-line
Good grief. Who builds emacs? Half of the point of mg is to avoid doing exactly that! ;) (The version I have here is 22.1.1.) By the way,if anyone looking for free commits, there are a bunch more missing undo boundaries in mg. I haven't yet had a chance to chase them all down properly... -kj On Mon, Jan 17, 2011 at 9:52 AM, Han Boetes h...@mijncomputer.nl wrote: Kjell Wooding wrote: I might add an undo boundary around the whole thing (I note emacs doesn't do this properly, at least on the version I have here)... Undoing join-line works fine with the emacs version I am using here. Built 2 days ago, from git. ~% emacs --version GNU Emacs 24.0.50.1 # Han
Re: mg:join-line
Looks pretty good. I might add an undo boundary around the whole thing (I note emacs doesn't do this properly, at least on the version I have here)... I like it. If undo is a concern, then it might be a good idea to check the other functions while we're here. I found at least the following offenders in random.c: twiddle() might return early, leaving the boundaries disabled; openline() can open many at once, but each gets its own boundary; justone() makes two changes but doesn't set the boundary; lfindent() and newline() have the same problem as openline(). There's also indent() which makes two changes, but it's not bound to a key and is only called via cmode, where the undo boundaries are in place already. I'm afraid simply adding the the undo boundary around newline() will break yank(), which sets its own boundary and calls newline() among other changes. If we want this undo stuff, then we probably should add checks such that none of these functions set boundaries if they were disabled (by some other function) to start with. What do you think? The following diff fixes twiddle() and adds boundaries for openline(), justone(), and lfindent(). I leave newline() intact for now. --- src/usr.bin/mg.old/random.c Mon Jan 17 15:16:09 2011 +++ src/usr.bin/mg/random.c Mon Jan 17 16:25:21 2011 @@ -119,7 +119,6 @@ twiddle(int f, int n) dotp = curwp-w_dotp; doto = curwp-w_doto; - undo_boundary_enable(FFRAND, 0); if (doto == llength(dotp)) { if (--doto = 0) return (FALSE); @@ -129,6 +128,7 @@ twiddle(int f, int n) if (doto == 0) return (FALSE); } + undo_boundary_enable(FFRAND, 0); cr = lgetc(dotp, doto - 1); (void)backdel(FFRAND, 1); (void)forwchar(FFRAND, 1); @@ -158,6 +158,7 @@ openline(int f, int n) return (TRUE); /* insert newlines */ + undo_boundary_enable(FFRAND, 0); i = n; do { s = lnewline(); @@ -166,6 +167,7 @@ openline(int f, int n) /* then go back up overtop of them all */ if (s == TRUE) s = backchar(f | FFRAND, n); + undo_boundary_enable(FFRAND, 1); return (s); } @@ -223,8 +225,11 @@ deblank(int f, int n) int justone(int f, int n) { + undo_boundary_enable(FFRAND, 0); (void)delwhite(f, n); - return (linsert(1, ' ')); + linsert(1, ' '); + undo_boundary_enable(FFRAND, 1); + return (TRUE); } /* @@ -318,10 +323,12 @@ int lfindent(int f, int n) { int c, i, nicol; + int s = TRUE; if (n 0) return (FALSE); + undo_boundary_enable(FFRAND, 0); while (n--) { nicol = 0; for (i = 0; i llength(curwp-w_dotp); ++i) { @@ -337,10 +344,13 @@ lfindent(int f, int n) curbp-b_flag BFNOTAB) ? linsert(nicol, ' ') == FALSE : ( #endif /* NOTAB */ ((i = nicol / 8) != 0 linsert(i, '\t') == FALSE) || - ((i = nicol % 8) != 0 linsert(i, ' ') == FALSE - return (FALSE); + ((i = nicol % 8) != 0 linsert(i, ' ') == FALSE { + s = FALSE; + break; + } } - return (TRUE); + undo_boundary_enable(FFRAND, 1); + return (s); } /*
Re: mg:join-line
I'm afraid simply adding the the undo boundary around newline() will break yank(), which sets its own boundary and calls newline() among other changes. If we want this undo stuff, then we probably should add checks such that none of these functions set boundaries if they were disabled (by some other function) to start with. What do you think? Hmm. You are right. I considered this problem once before (and could swear I remember solving it). Let me scour my drive for notes. A disable refcount might do the trick, ignoring re-enables until all nested boundary calls are done. will look at the rest of the diff shortly. thanks! -kj
mg:join-line
Looks pretty good. I might add an undo boundary around the whole thing (I note emacs doesn't do this properly, at least on the version I have here)... like so: Index: def.h === RCS file: /cvs/src/usr.bin/mg/def.h,v retrieving revision 1.114 diff -u -r1.114 def.h --- def.h 17 Jan 2011 03:12:06 - 1.114 +++ def.h 17 Jan 2011 03:33:32 - @@ -512,6 +512,7 @@ int backdel(int, int); int space_to_tabstop(int, int); int backtoindent(int, int); +int joinline(int, int); /* extend.c X */ int insert(int, int); Index: funmap.c === RCS file: /cvs/src/usr.bin/mg/funmap.c,v retrieving revision 1.33 diff -u -r1.33 funmap.c --- funmap.c17 Jan 2011 03:12:06 - 1.33 +++ funmap.c17 Jan 2011 03:33:32 - @@ -103,6 +103,7 @@ {fillword, insert-with-wrap,}, {backisearch, isearch-backward,}, {forwisearch, isearch-forward,}, + {joinline, join-line,}, {justone, just-one-space,}, {ctrlg, keyboard-quit,}, {killbuffer_cmd, kill-buffer,}, Index: keymap.c === RCS file: /cvs/src/usr.bin/mg/keymap.c,v retrieving revision 1.44 diff -u -r1.44 keymap.c --- keymap.c17 Jan 2011 03:12:06 - 1.44 +++ keymap.c17 Jan 2011 03:33:32 - @@ -228,7 +228,7 @@ NULL, /* [ */ delwhite, /* \ */ rescan, /* ] */ - rescan, /* ^ */ + joinline, /* ^ */ rescan, /* _ */ rescan, /* ` */ rescan, /* a */ Index: mg.1 === RCS file: /cvs/src/usr.bin/mg/mg.1,v retrieving revision 1.48 diff -u -r1.48 mg.1 --- mg.117 Jan 2011 03:12:06 - 1.48 +++ mg.117 Jan 2011 03:33:33 - @@ -220,6 +220,8 @@ end-of-buffer .It M-\e delete-horizontal-space +.It M-^ +join-line .It M-b backward-word .It M-c @@ -510,6 +512,9 @@ isearch ignores any explicit arguments. If invoked during macro definition or evaluation, the non-incremental search-forward is invoked instead. +.It join-line +Join the current line to the previous. If called with an argument, +join the next line to the current one. .It just-one-space Delete any whitespace around dot, then insert a space. .It keyboard-quit Index: random.c === RCS file: /cvs/src/usr.bin/mg/random.c,v retrieving revision 1.27 diff -u -r1.27 random.c --- random.c17 Jan 2011 03:12:06 - 1.27 +++ random.c17 Jan 2011 03:33:33 - @@ -453,3 +453,33 @@ ++curwp-w_doto; return (TRUE); } + +/* + * Join the current line to the previous, or with arg, the next line + * to the current one. If the former line is not empty, leave exactly + * one space at the joint. Otherwise, leave no whitespace. + */ +int +joinline(int f, int n) +{ + int doto; + + undo_boundary_enable(FFRAND, 0); + if (f FFARG) { + gotoeol(FFRAND, 1); + forwdel(FFRAND, 1); + } else { + gotobol(FFRAND, 1); + backdel(FFRAND, 1); + } + + delwhite(FFRAND, 1); + + if ((doto = curwp-w_doto) 0) { + linsert(1, ' '); + curwp-w_doto = doto; + } + undo_boundary_enable(FFRAND, 1); + + return (TRUE); +}