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