mg(1) searches case insensitve and puts the replace string verbatime in place. The One True Editor considers the case (capitalised or all uppercase) and adjusts the replacement string accordingly. This only happens when the replacement string is all lowercase.
The following diff implements this for mg. EXAMPLE ---------- foo Foo FOO ---------- M-% foo bar results in: ---------- bar Bar BAR ---------- while without it it does this: ---------- bar bar bar ---------- This comes up surprisingly often while I'm coding. OK? diff --git line.c line.c index ae5d4a7e3bb..dc4e5cf32bc 100644 --- line.c +++ line.c @@ -18,6 +18,7 @@ */ #include <sys/queue.h> +#include <ctype.h> #include <limits.h> #include <signal.h> #include <stdio.h> @@ -511,7 +512,10 @@ int lreplace(RSIZE plen, char *st) { RSIZE rlen; /* replacement length */ - int s; + struct line *lp; + RSIZE n; + int s, doto, is_capitalised = 0, is_allcaps = 0, is_alllower = 0; + char *repl; if ((s = checkdirty(curbp)) != TRUE) return (s); @@ -520,16 +524,57 @@ lreplace(RSIZE plen, char *st) ewprintf("Buffer is read only"); return (FALSE); } + + if ((repl = strdup(st)) == NULL) { + dobeep(); + ewprintf("out of memory"); + return (FALSE); + } + undo_boundary_enable(FFRAND, 0); (void)backchar(FFARG | FFRAND, (int)plen); + + lp = curwp->w_dotp; + doto = curwp->w_doto; + n = plen; + + is_capitalised = isupper((unsigned char)lgetc(lp, doto)); + + if (is_capitalised) { + for (n = 0, is_allcaps = 1; n < plen && is_allcaps; n++) { + is_allcaps = !isalpha((unsigned char)lgetc(lp, doto)) || + isupper((unsigned char)lgetc(lp, doto)); + doto++; + if (doto == llength(lp)) { + doto = 0; + lp = lforw(lp); + n++; /* \n is implicit in the buffer */ + } + } + } + (void)ldelete(plen, KNONE); - rlen = strlen(st); - region_put_data(st, rlen); + rlen = strlen(repl); + for (n = 0, is_alllower = 1; n < rlen && is_alllower; n++) + is_alllower = !isupper((unsigned char)repl[n]); + + if (is_alllower) { + if (is_allcaps) { + for (n = 0; n < rlen; n++) + repl[n] = toupper((unsigned char)repl[n]); + } else if (is_capitalised) { + repl[0] = toupper((unsigned char)repl[0]); + } + } + + region_put_data(repl, rlen); lchange(WFFULL); undo_boundary_enable(FFRAND, 1); + + free(repl); return (TRUE); } -- I'm not entirely sure you are real.