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