commit f7f5514eef3a19ea5d860eaeb6bb74019225f3e0
parent afa0097ceb602c5ef09eb21936e920d44fb3776d
Author: David Lawrence Ramsey <pooka109@gmail.com>
Date: Mon, 10 Sep 2018 17:34:33 -0500
new feature: marked text gets justified into a single, new paragraph
This is modelled after Pico's behavior. However, Pico won't do anything
if you do a full-justify while the mark is on. But this is unnecessarily
limiting, so, when the mark is on, nano will handle a full-justify and a
plain justify the same.
This currently does not handle the lead (quoting + indentation) in
justified selections, does not put mid-line justified selections onto
separate lines, and does not strip whitespace after the lead in justified
selections, the latter two of which Pico does. These behaviors are
forthcoming.
Diffstat:
M | src/text.c | | | 78 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- |
1 file changed, 68 insertions(+), 10 deletions(-)
diff --git a/src/text.c b/src/text.c
@@ -1991,7 +1991,8 @@ void justify_paragraph(filestruct **line, size_t par_len)
}
/* Justify the current paragraph, and justify the entire file when
- * full_justify is TRUE. */
+ * full_justify is TRUE. If the mark is on, justify only the marked
+ * text instead. */
void do_justify(bool full_justify)
{
size_t par_len;
@@ -2001,15 +2002,14 @@ void do_justify(bool full_justify)
filestruct *last_par_line;
/* Will be the line after the last line of the justified
* paragraph(s), if any. */
+ size_t top_x;
+ /* The top x-coordinate of the paragraph we justify. */
size_t bot_x;
/* The bottom x-coordinate of the paragraph we justify. */
-
filestruct *was_cutbuffer = cutbuffer;
/* The old cutbuffer, so we can justify in the current cutbuffer. */
filestruct *was_cutbottom = cutbottom;
/* The old cutbottom, so we can justify in the current cutbuffer. */
- size_t jus_len;
- /* The number of lines we're storing in the current cutbuffer. */
filestruct *jusline;
/* The line that we're justifying in the current cutbuffer. */
@@ -2017,8 +2017,19 @@ void do_justify(bool full_justify)
/* Stash the cursor position, to be stored in the undo item. */
ssize_t was_lineno = openfile->current->lineno;
size_t was_current_x = openfile->current_x;
+
+ /* We need these to restore the coordinates of the mark after justifying
+ * marked text. */
+ ssize_t was_top_lineno = 0;
+ size_t was_top_x = 0;
+ bool right_side_up = FALSE;
#endif
+#ifndef NANO_TINY
+ /* Do normal justification only when the mark is off. */
+ if (!openfile->mark)
+#endif
+ {
/* When justifying the entire buffer, start at the top. Otherwise, when
* in a paragraph but not at its beginning, move back to its first line. */
if (full_justify)
@@ -2034,14 +2045,31 @@ void do_justify(bool full_justify)
refresh_needed = TRUE;
return;
}
-
- /* We cannot (yet) justify a marked region, so turn the mark off. */
- openfile->mark = NULL;
+ }
/* Prepare to put the text we want to justify in the cutbuffer. */
cutbuffer = NULL;
cutbottom = NULL;
+#ifndef NANO_TINY
+ /* If the mark is on, do as Pico: treat all marked text as one paragraph. */
+ if (openfile->mark) {
+ mark_order((const filestruct **)&first_par_line, &top_x,
+ (const filestruct **)&last_par_line, &bot_x,
+ &right_side_up);
+
+ /* Save the coordinates of the mark. */
+ was_top_lineno = first_par_line->lineno;
+ was_top_x = top_x;
+
+ par_len = last_par_line->lineno - first_par_line->lineno +
+ (bot_x > 0 ? 1 : 0);
+ } else
+#endif
+ {
+ size_t jus_len;
+ /* The number of lines we're storing in the current cutbuffer. */
+
/* Start out at the first line of the paragraph. */
first_par_line = openfile->current;
last_par_line = openfile->current;
@@ -2062,6 +2090,7 @@ void do_justify(bool full_justify)
bot_x = 0;
} else
bot_x = strlen(last_par_line->data);
+ }
#ifndef NANO_TINY
add_undo(COUPLE_BEGIN);
@@ -2074,12 +2103,22 @@ void do_justify(bool full_justify)
add_undo(CUT);
#endif
/* Do the equivalent of a marked cut. */
- extract_buffer(&cutbuffer, &cutbottom, first_par_line, 0, last_par_line,
- bot_x);
+ extract_buffer(&cutbuffer, &cutbottom, first_par_line, top_x,
+ last_par_line, bot_x);
#ifndef NANO_TINY
update_undo(CUT);
-#endif
+ if (openfile->mark) {
+ filestruct *line;
+
+ /* Manually justify the marked region. */
+ concat_paragraph(&cutbuffer, par_len);
+ justify_format(cutbuffer, 0);
+ line = cutbuffer;
+ rewrap_paragraph(&line, "", 0);
+ } else
+#endif
+ {
/* Prepare to justify the text we just put in the cutbuffer. */
jusline = cutbuffer;
@@ -2095,6 +2134,7 @@ void do_justify(bool full_justify)
break;
}
}
+ }
#ifndef NANO_TINY
add_undo(PASTE);
@@ -2106,6 +2146,18 @@ void do_justify(bool full_justify)
add_undo(COUPLE_END);
openfile->undotop->strdata = mallocstrcpy(NULL, _("justification"));
+
+ /* If we justified marked text, restore mark or cursor position. */
+ if (openfile->mark) {
+ if (right_side_up) {
+ openfile->mark = fsfromline(was_top_lineno);
+ openfile->mark_x = was_top_x;
+ } else {
+ openfile->current = fsfromline(was_top_lineno);
+ openfile->current_x = was_top_x;
+ }
+ update_undo(COUPLE_END);
+ }
#endif
/* We're done justifying. Restore the old cutbuffer. */
@@ -2113,6 +2165,11 @@ void do_justify(bool full_justify)
cutbottom = was_cutbottom;
/* Show what we justified on the status bar. */
+#ifndef NANO_TINY
+ if (openfile->mark)
+ statusbar(_("Justified selection"));
+ else
+#endif
if (full_justify)
statusbar(_("Justified file"));
else
@@ -2123,6 +2180,7 @@ void do_justify(bool full_justify)
set_modified();
refresh_needed = TRUE;
+ shift_held = TRUE;
}
/* Justify the current paragraph. */