Hi,

The kill-buffer command in mg doesn't behave quite as I would expect,
if you invoke it multiple times via C-u #, then follow with M-_ (undo)
or C-y (paste), only the last buffer killed (re)appears and not the
multiple paragraphs that I think should. This diff changes that
behaviour. 

Also, by fixing kill-paragraph I had worked out how to mark multiple
paragraphs in one go, so the mark-paragraph command was straight
forward to add in. This diff therefore is doing two things, fixing
kill-paragraph and introducing the mark-paragraph command. I can split
them out if required.  Comments/ok? 

-lum

Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mg/def.h,v
retrieving revision 1.147
diff -u -p -u -p -r1.147 def.h
--- def.h       3 Jun 2015 23:40:01 -0000       1.147
+++ def.h       17 Sep 2015 18:44:39 -0000
@@ -587,6 +587,7 @@ int          fillpara(int, int);
 int             killpara(int, int);
 int             fillword(int, int);
 int             setfillcol(int, int);
+int             markpara(int, int);
 
 /* word.c X */
 int             backword(int, int);
Index: funmap.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/funmap.c,v
retrieving revision 1.49
diff -u -p -u -p -r1.49 funmap.c
--- funmap.c    19 Mar 2015 21:22:15 -0000      1.49
+++ funmap.c    17 Sep 2015 18:44:39 -0000
@@ -132,6 +132,7 @@ static struct funmap functnames[] = {
        {localunbind, "local-unset-key",},
        {makebkfile, "make-backup-files",},
        {makedir, "make-directory",},
+       {markpara, "mark-paragraph",},
        {markbuffer, "mark-whole-buffer",},
        {do_meta, "meta-key-mode",},    /* better name, anyone? */
        {negative_argument, "negative-argument",},
Index: keymap.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/keymap.c,v
retrieving revision 1.55
diff -u -p -u -p -r1.55 keymap.c
--- keymap.c    19 Mar 2015 21:48:05 -0000      1.55
+++ keymap.c    17 Sep 2015 18:44:39 -0000
@@ -268,7 +268,9 @@ static PF metasqf[] = {
        capword,                /* c */
        delfword,               /* d */
        rescan,                 /* e */
-       forwword                /* f */
+       forwword,               /* f */
+       rescan,                 /* g */
+       markpara                /* h */
 };
 
 static PF metal[] = {
@@ -333,7 +335,7 @@ struct KEYMAPE (8) metamap = {
                        '*', '>', metami, NULL
                },
                {
-                       '[', 'f', metasqf, (KEYMAP *) &metasqlmap
+                       '[', 'h', metasqf, (KEYMAP *) &metasqlmap
                },
                {
                        'l', '}', metal, NULL
Index: mg.1
===================================================================
RCS file: /cvs/src/usr.bin/mg/mg.1,v
retrieving revision 1.91
diff -u -p -u -p -r1.91 mg.1
--- mg.1        9 Sep 2015 19:03:13 -0000       1.91
+++ mg.1        17 Sep 2015 18:44:39 -0000
@@ -292,6 +292,8 @@ capitalize-word
 kill-word
 .It M-f
 forward-word
+.It M-h
+mark-paragraph
 .It M-l
 downcase-word
 .It M-m
@@ -672,6 +674,8 @@ Unbind a key mapping in the local (topmo
 Toggle generation of backup files.
 .It make-directory
 Prompt the user for a path or directory name which is then created.
+.It mark-paragraph
+Mark the current paragraph.
 .It mark-whole-buffer
 Marks whole buffer as a region by putting dot at the beginning and mark
 at the end of buffer.
Index: paragraph.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/paragraph.c,v
retrieving revision 1.36
diff -u -p -u -p -r1.36 paragraph.c
--- paragraph.c 19 Mar 2015 21:22:15 -0000      1.36
+++ paragraph.c 17 Sep 2015 18:44:39 -0000
@@ -20,6 +20,9 @@ static int    fillcol = 70;
 
 #define MAXWORD 256
 
+static int     findpara(void);
+static int     do_gotoeop(int, int, int *);
+
 /*
  * Move to start of paragraph.
  * Move backwards by line, checking from the 1st character forwards for the
@@ -70,7 +73,15 @@ gotobop(int f, int n)
 int
 gotoeop(int f, int n)
 {
-       int col, nospace;
+       int i;
+
+       return(do_gotoeop(f, n, &i));
+}
+
+int
+do_gotoeop(int f, int n, int *i)
+{
+       int col, nospace, j = 0;
 
        /* the other way... */
        if (n < 0)
@@ -78,6 +89,7 @@ gotoeop(int f, int n)
 
        /* for each one asked for */
        while (n-- > 0) {
+               *i = ++j;
                nospace = 0;
                while (lforw(curwp->w_dotp) != curbp->b_headp) {
                        col = 0;
@@ -251,32 +263,82 @@ cleanup:
 int
 killpara(int f, int n)
 {
-       int     status, end = FALSE;    /* returned status of functions */
+       int     lineno, status;
+
+       if (findpara() == FALSE)
+               return (TRUE);
+
+       /* goto beginning of para */
+       (void)gotobop(FFRAND, 1);
 
-       /* for each paragraph to delete */
-       while (n--) {
+       /* take a note of the line number for deletions */
+       lineno = curwp->w_dotline;
 
-               /* mark out the end and beginning of the para to delete */
-               if (!gotoeop(FFRAND, 1))
-                       end = TRUE;
+       curwp->w_markp = curwp->w_dotp;
+       curwp->w_marko = curwp->w_doto;
 
-               /* set the mark here */
-               curwp->w_markp = curwp->w_dotp;
-               curwp->w_marko = curwp->w_doto;
+       (void)gotoeop(FFRAND, n);
 
-               /* go to the beginning of the paragraph */
-               (void)gotobop(FFRAND, 1);
+       if ((status = killregion(FFRAND, 1)) != TRUE)
+               return (status);
+
+       curwp->w_dotline = lineno;
+       return (TRUE);
+}
+
+/*
+ * Mark a paragraph.  Mark n paragraphs starting with the current one.
+ */
+/* ARGSUSED */
+int
+markpara(int f, int n)
+{
+       int i = 0;
 
-               /* force us to the beginning of line */
+       clearmark(FFARG, 0);
+
+       if (findpara() == FALSE)
+               return (TRUE);
+
+       (void)do_gotoeop(FFRAND, n, &i);
+
+       curwp->w_markp = curwp->w_dotp;
+       curwp->w_marko = curwp->w_doto;
+
+       (void)gotobop(FFRAND, i);
+
+       return (TRUE);
+}
+
+/*
+ * Go down the buffer until we find text.
+ */
+int
+findpara(void)
+{
+       int     col, nospace = 0;
+
+       /* we move forward to find a para to mark */
+       do {
                curwp->w_doto = 0;
+               col = 0;
 
-               /* and delete it */
-               if ((status = killregion(FFRAND, 1)) != TRUE)
-                       return (status);
+               /* check if we are on a blank line */
+               while (col < llength(curwp->w_dotp)) {
+                       if (!isspace(lgetc(curwp->w_dotp, col)))
+                               nospace = 1;
+                       col++;
+               }
+               if (nospace)
+                       break;
+
+               if (lforw(curwp->w_dotp) == curbp->b_headp)
+                       return (FALSE);
+
+               curwp->w_dotp = lforw(curwp->w_dotp);   
+               curwp->w_dotline++;
+       } while (1);
 
-               if (end)
-                       return (TRUE);
-       }
        return (TRUE);
 }

Reply via email to