On 2022/10/13 13:35:18 +0200, Florian Obser <flor...@openbsd.org> wrote: > On 2022-10-13 12:16 +02, Omar Polo <o...@omarpolo.com> wrote: > > small quality-of-life addition. GNU Emacs has zap-to-char bound by to > > M-z and zap-up-to-char unbound; i'm unsure how closely we want to > > follow emacs here, IMHO zap-up-to-char is way more useful than > > zap-to-char and so i opted to bound M-z to zap-up-to-char by default. > > I always tried to stay as close to emacs as possible. I'd consider it a > bug otherwise. So I think you should bind zap-to-char per default and > override it in your startup file.
agreed, i can carry an extra global-set-key in my ~/.mg :) > emacs also has this: "Goes backward if ARG is negative" > > Could you implement that, or at least check that n is not negative? Arrggg, right, I forgot that the prefix argument can be negative or zero. Here's another attempt that handles it too. The only difference I can spot with emacs now is that zap-to-char alters `pat' so C-s C-s (resuming isearch) uses the character set by zap. thanks! diff 40c942665e2a6e73653062386b61f09373477e3d 768e3c8d03fa68b2a6a27077e22e96a41f8a57b6 commit - 40c942665e2a6e73653062386b61f09373477e3d commit + 768e3c8d03fa68b2a6a27077e22e96a41f8a57b6 blob - d546dba15dd5b45503679454fbe55673640ea74e blob + 87704c129ee172c2f504741d534df826cf77131d --- usr.bin/mg/def.h +++ usr.bin/mg/def.h @@ -651,6 +651,9 @@ int readpattern(char *); int forwsrch(void); int backsrch(void); int readpattern(char *); +int zapuptochar(int, int); +int zaptochar(int, int); +int zap(int, int); /* spawn.c X */ int spawncli(int, int); blob - 36a88e4573d47eae4d321ee899f71e52ef77a8c9 blob + d9cb10a264955db8e6e77b8b8aa6352ed8db9bfd --- usr.bin/mg/funmap.c +++ usr.bin/mg/funmap.c @@ -138,6 +138,8 @@ static struct funmap functnames[] = { {killbuffer_cmd, "kill-buffer", 1}, {killline, "kill-line", 1}, {killpara, "kill-paragraph", 1}, + {zaptochar, "zap-to-char", 1}, + {zapuptochar, "zap-up-to-char", 1}, {killregion, "kill-region", 0}, {delfword, "kill-word", 1}, {toggleleavetmp, "leave-tmpdir-backups", 0}, blob - 32a9267d30fbbbc2f4fcc126133313cbc6799201 blob + 8cc8ac482f1ca345a0a6455649e4728d7946db93 --- usr.bin/mg/keymap.c +++ usr.bin/mg/keymap.c @@ -290,7 +290,7 @@ static PF metal[] = { copyregion, /* w */ extend, /* x */ rescan, /* y */ - rescan, /* z */ + zaptochar, /* z */ gotobop, /* { */ piperegion, /* | */ gotoeop /* } */ blob - a335c89e4d5329776a85c473c716b5e9e2597f19 blob + 6a910b7b1861aeeacab728e4139d5963d9ecaabd --- usr.bin/mg/mg.1 +++ usr.bin/mg/mg.1 @@ -331,6 +331,8 @@ execute-extended-command copy-region-as-kill .It M-x execute-extended-command +.It M-z +zap-to-char .It M-{ backward-paragraph .It M-| @@ -986,6 +988,11 @@ It is not a ring. kill buffer consists only of the most recent kill. It is not a ring. +.It zap-to-char +Ask for a character and delete text from the current cursor position +until the next instance of that character, including it. +.It zap-up-to-char +Like zap-to-char but doesn't delete the target character. .El .Sh MG DIRED KEY BINDINGS Specific key bindings are available in dired mode. blob - fa12b4094aae01385711ca7b01c7eba964571e65 blob + 06cddf62221237bd4abe7c1772f0e6031bdb49ab --- usr.bin/mg/search.c +++ usr.bin/mg/search.c @@ -853,3 +853,74 @@ readpattern(char *r_prompt) retval = FALSE; return (retval); } + +/* + * Prompt for a character and kill until a it (including). Mark is + * cleared afterwards. + */ +int +zaptochar(int f, int n) +{ + return (zap(TRUE, n)); +} + +/* Like zaptochar but stops before the character. */ +int +zapuptochar(int f, int n) +{ + return (zap(FALSE, n)); +} + +/* + * Prompt for a charcter and deletes from the point up to, optionally + * including, the first instance of that charcters. Marks is cleared + * afterwards. + */ +int +zap(int including, int n) +{ + int s, backward; + + backward = n < 0; + if (backward) + n = -n; + + if (including) + ewprintf("Zap to char: "); + else + ewprintf("Zap up to char: "); + + s = getkey(FALSE); + eerase(); + if (s == ABORT || s == CCHR('G')) + return (FALSE); + + if (n == 0) + return (TRUE); + + pat[0] = (char)s; + pat[1] = '\0'; + + isetmark(); + while (n--) { + s = backward ? backsrch() : forwsrch(); + if (s != TRUE) { + dobeep(); + ewprintf("Search failed: \"%s\"", pat); + swapmark(FFARG, 0); + clearmark(FFARG, 0); + return (s); + } + } + + if (!including) { + if (backward) + forwchar(FFARG, 1); + else + backchar(FFARG, 1); + } + + killregion(FFARG, 0); + clearmark(FFARG, 0); + return (TRUE); +}