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);
+}

Reply via email to