From 951058bb5c2b3c5d5fb2a1f1722536e5a6a10df7 Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Mon, 10 Sep 2018 17:34:33 -0500
Subject: [PATCH 1/3] justify: implement justification of marked text, modeling
 it after Pico

One major difference: Pico won't do anything if you do a full-justify
with the mark on, but this seems wrong, so nano will do the same as
for a plain justify with the mark on.
---
 src/text.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 72 insertions(+), 8 deletions(-)

diff --git a/src/text.c b/src/text.c
index 5e57a762..a8ab3211 100644
--- a/src/text.c
+++ b/src/text.c
@@ -2229,7 +2229,8 @@ void justify_paragraph(filestruct **firstline, size_t quote_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 quote_len;
@@ -2241,15 +2242,16 @@ void do_justify(bool full_justify)
 	filestruct *last_par_line = NULL;
 		/* Will be the line after the last line of the justified
 		 * paragraph(s), if any. */
-	bool filebot_inpar;
+	bool filebot_inpar = FALSE;
 		/* Whether the text at filebot is part of the current paragraph. */
-
+	size_t top_x = 0;
+		/* The top x-coordinate of the paragraph we justify. */
+	size_t bot_x = 0;
+		/* 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. */
 
@@ -2257,8 +2259,18 @@ 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;
-#endif
 
+	/* 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;
+
+	/* If the mark is on, the marked text will be our paragraph.  Don't try to
+	 * justify the entire file or check for a paragraph. */
+	if (!openfile->mark)
+#endif
+	{
 	/* If we're justifying the entire file, start at the beginning. */
 	if (full_justify) {
 		openfile->current = openfile->fileage;
@@ -2276,11 +2288,37 @@ void do_justify(bool full_justify)
 		refresh_needed = TRUE;
 		return;
 	}
+	}
 
 	/* 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 what Pico does: treat all the 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;
+
+		quote_len = quote_length(first_par_line->data);
+		par_len = last_par_line->lineno - first_par_line->lineno;
+
+		if (bot_x > 0) {
+			par_len++;
+			filebot_inpar = TRUE;
+		}
+	} else
+#endif
+	{
+		size_t jus_len;
+			/* The number of lines we're storing in the current cutbuffer. */
+
 	/* Set
 	 * first_par_line and last_par_line to the first line of the paragraph. */
 	first_par_line = openfile->current;
@@ -2304,6 +2342,10 @@ void do_justify(bool full_justify)
 		jus_len--;
 	}
 
+		if (filebot_inpar)
+			bot_x = strlen(last_par_line->data);
+	}
+
 #ifndef NANO_TINY
 	add_undo(COUPLE_BEGIN);
 	openfile->undotop->strdata = mallocstrcpy(NULL, _("justify"));
@@ -2315,8 +2357,8 @@ 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,
-					filebot_inpar ? strlen(last_par_line->data) : 0);
+	extract_buffer(&cutbuffer, &cutbottom, first_par_line, top_x,
+					last_par_line, bot_x);
 #ifndef NANO_TINY
 	update_undo(CUT);
 #endif
@@ -2327,12 +2369,17 @@ void do_justify(bool full_justify)
 	/* Justify the current paragraph. */
 	justify_paragraph(&jusline, quote_len, par_len);
 
+#ifndef NANO_TINY
+	if (!openfile->mark)
+#endif
+	{
 	/* If we're justifying the entire file, search for and justify paragraphs
 	 * until we can't anymore. */
 	if (full_justify) {
 		while (find_paragraph(&jusline, &filebot_inpar, &quote_len, &par_len))
 			justify_paragraph(&jusline, quote_len, par_len);
 	}
+	}
 
 #ifndef NANO_TINY
 	add_undo(PASTE);
@@ -2344,6 +2391,18 @@ void do_justify(bool full_justify)
 
 	add_undo(COUPLE_END);
 	openfile->undotop->strdata = mallocstrcpy(NULL, _("justify"));
+
+	/* If we justified marked text, restore the coordinates of the mark. */
+	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. */
@@ -2354,6 +2413,11 @@ void do_justify(bool full_justify)
 	edit_refresh();
 
 	/* 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
-- 
2.19.1

