[prev in list] [next in list] [prev in thread] [next in thread] 

List:       nano-devel
Subject:    Re: [Nano-devel] wrap and justification
From:       Mark Majeres <mark () engine12 ! com>
Date:       2014-07-01 20:25:23
Message-ID: CAG40++G7EZFGHosQ6fiKx8MszVi5f-8nu2FwACbhKOmGFxT9gg () mail ! gmail ! com
[Download RAW message or body]

>> On 6/29/14, Benno Schulenberg <bensberg@justemail.net> wrote:
> Yes, that would be nice.  It's beautiful to have a separate patch
> that "rewrites" all of the justification code as just a few calls
> to the wrapping code.
>
>> And like you mention, the removed
>> spaces will be missing in future wraps, or justification.
>
> But justification will will leave trailing spaces at all the ends
> of the justified lines, and double trailing spaces if a sentence
> ends there (and the original contains a double space).  So it
> will never lose a double space, it just will not create any.

Benno,

Three patches are attached.  One of the three is the combination of
the remaining two.

The wrap patch works on it's own, but the justify patch will not even
compile without the wrap patch.

The justification is now considering a quote string.

I'm not understanding if you prefer the tabs and multiple spaces
converted into single spaces or if you prefer the way it is being done
in my patch.

--Mark Majeres

["justify.5049.patch" (text/x-patch)]

Index: src/nano.h
===================================================================
--- src/nano.h	(revision 5049)
+++ src/nano.h	(working copy)
@@ -191,6 +191,9 @@
 #ifndef DISABLE_WRAPPING
     SPLIT_BEGIN, SPLIT_END,
 #endif
+#ifndef DISABLE_JUSTIFY
+    JUSTIFY_BEGIN, JUSTIFY_END,
+#endif
     JOIN, PASTE, INSERT, ENTER, OTHER
 } undo_type;
 
Index: src/proto.h
===================================================================
--- src/proto.h	(revision 5049)
+++ src/proto.h	(working copy)
@@ -664,7 +664,6 @@
 size_t indent_length(const char *line);
 #endif
 #ifndef DISABLE_JUSTIFY
-void justify_format(filestruct *paragraph, size_t skip);
 size_t quote_length(const char *line);
 bool quotes_match(const char *a_line, size_t a_quote, const char
 	*b_line);
@@ -672,8 +671,7 @@
 	*b_line, size_t b_indent);
 bool begpar(const filestruct *const foo);
 bool inpar(const filestruct *const foo);
-void backup_lines(filestruct *first_line, size_t par_len);
-bool find_paragraph(size_t *const quote, size_t *const par);
+bool find_paragraph(size_t *const quote, filestruct **const last_par_line);
 void do_justify(bool full_justify);
 void do_justify_void(void);
 void do_full_justify(void);
Index: src/text.c
===================================================================
--- src/text.c	(revision 5049)
+++ src/text.c	(working copy)
@@ -40,10 +40,6 @@
 static bool prepend_wrap = FALSE;
 	/* Should we prepend wrapped text to the next line? */
 #endif
-#ifndef DISABLE_JUSTIFY
-static filestruct *jusbottom = NULL;
-	/* Pointer to the end of the justify buffer. */
-#endif
 
 #ifndef NANO_TINY
 /* Toggle the mark. */
@@ -465,6 +461,19 @@
 	f->data = data;
 	goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_END:
+	undidmsg = _("text justify");
+	goto_line_posx(u->lineno, u->begin);
+	openfile->current_undo = openfile->current_undo->next;
+	openfile->last_action = OTHER;
+	while (openfile->current_undo->type != JUSTIFY_BEGIN)
+	    do_undo();
+	u = openfile->current_undo;
+	f = openfile->current;
+	goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
+    break;
+#endif       
 #ifndef DISABLE_WRAPPING
     case SPLIT_END:
 	undidmsg = _("line wrap");
@@ -609,6 +618,18 @@
 	goto_line_posx(u->lineno, u->begin);
 	do_enter(TRUE);
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_BEGIN:
+	redidmsg = _("text justify");
+	goto_line_posx(u->lineno, u->begin);
+	openfile->current_undo = u;
+	openfile->last_action = OTHER;
+	while (openfile->current_undo->type != JUSTIFY_END)
+	    do_redo();
+	u = openfile->current_undo;
+	goto_line_posx(u->lineno, u->begin);
+    break;
+#endif /*DISABLE_JUSTIFY*/
 #ifndef DISABLE_WRAPPING
     case SPLIT_BEGIN:
 	redidmsg = _("line wrap");
@@ -916,6 +937,11 @@
 	}
 	current_action = u->type = JOIN;
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_BEGIN:
+    case JUSTIFY_END:
+    break;
+#endif    
 #ifndef DISABLE_WRAPPING
     case SPLIT_BEGIN:
 	current_action = fs->undotop->type;
@@ -1082,6 +1108,11 @@
     case ENTER:
 	u->mark_begin_x = fs->current_x;
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_BEGIN:
+    case JUSTIFY_END:
+    break;
+#endif
 #ifndef DISABLE_WRAPPING
     case SPLIT_BEGIN:
     case SPLIT_END:
@@ -1391,160 +1422,6 @@
 #endif /* !NANO_TINY || !DISABLE_JUSTIFY */
 
 #ifndef DISABLE_JUSTIFY
-/* justify_format() replaces blanks with spaces and multiple spaces by 1
- * (except it maintains up to 2 after a character in punct optionally
- * followed by a character in brackets, and removes all from the end).
- *
- * justify_format() might make paragraph->data shorter, and change the
- * actual pointer with null_at().
- *
- * justify_format() will not look at the first skip characters of
- * paragraph.  skip should be at most strlen(paragraph->data).  The
- * character at paragraph[skip + 1] must not be blank. */
-void justify_format(filestruct *paragraph, size_t skip)
-{
-    char *end, *new_end, *new_paragraph_data;
-    size_t shift = 0;
-#ifndef NANO_TINY
-    size_t mark_shift = 0;
-#endif
-
-    /* These four asserts are assumptions about the input data. */
-    assert(paragraph != NULL);
-    assert(paragraph->data != NULL);
-    assert(skip < strlen(paragraph->data));
-    assert(!is_blank_mbchar(paragraph->data + skip));
-
-    end = paragraph->data + skip;
-    new_paragraph_data = charalloc(strlen(paragraph->data) + 1);
-    strncpy(new_paragraph_data, paragraph->data, skip);
-    new_end = new_paragraph_data + skip;
-
-    while (*end != '\0') {
-	int end_len;
-
-	/* If this character is blank, change it to a space if
-	 * necessary, and skip over all blanks after it. */
-	if (is_blank_mbchar(end)) {
-	    end_len = parse_mbchar(end, NULL, NULL);
-
-	    *new_end = ' ';
-	    new_end++;
-	    end += end_len;
-
-	    while (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		end += end_len;
-		shift += end_len;
-
-#ifndef NANO_TINY
-		/* Keep track of the change in the current line. */
-		if (openfile->mark_set && openfile->mark_begin ==
-			paragraph && openfile->mark_begin_x >= end -
-			paragraph->data)
-		    mark_shift += end_len;
-#endif
-	    }
-	/* If this character is punctuation optionally followed by a
-	 * bracket and then followed by blanks, change no more than two
-	 * of the blanks to spaces if necessary, and skip over all
-	 * blanks after them. */
-	} else if (mbstrchr(punct, end) != NULL) {
-	    end_len = parse_mbchar(end, NULL, NULL);
-
-	    while (end_len > 0) {
-		*new_end = *end;
-		new_end++;
-		end++;
-		end_len--;
-	    }
-
-	    if (*end != '\0' && mbstrchr(brackets, end) != NULL) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		while (end_len > 0) {
-		    *new_end = *end;
-		    new_end++;
-		    end++;
-		    end_len--;
-		}
-	    }
-
-	    if (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		*new_end = ' ';
-		new_end++;
-		end += end_len;
-	    }
-
-	    if (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		*new_end = ' ';
-		new_end++;
-		end += end_len;
-	    }
-
-	    while (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		end += end_len;
-		shift += end_len;
-
-#ifndef NANO_TINY
-		/* Keep track of the change in the current line. */
-		if (openfile->mark_set && openfile->mark_begin ==
-			paragraph && openfile->mark_begin_x >= end -
-			paragraph->data)
-		    mark_shift += end_len;
-#endif
-	    }
-	/* If this character is neither blank nor punctuation, leave it
-	 * unchanged. */
-	} else {
-	    end_len = parse_mbchar(end, NULL, NULL);
-
-	    while (end_len > 0) {
-		*new_end = *end;
-		new_end++;
-		end++;
-		end_len--;
-	    }
-	}
-    }
-
-    assert(*end == '\0');
-
-    *new_end = *end;
-
-    /* If there are spaces at the end of the line, remove them. */
-    while (new_end > new_paragraph_data + skip &&
-	*(new_end - 1) == ' ') {
-	new_end--;
-	shift++;
-    }
-
-    if (shift > 0) {
-	openfile->totsize -= shift;
-	null_at(&new_paragraph_data, new_end - new_paragraph_data);
-	free(paragraph->data);
-	paragraph->data = new_paragraph_data;
-
-#ifndef NANO_TINY
-	/* Adjust the mark coordinates to compensate for the change in
-	 * the current line. */
-	if (openfile->mark_set && openfile->mark_begin == paragraph) {
-	    openfile->mark_begin_x -= mark_shift;
-	    if (openfile->mark_begin_x > new_end - new_paragraph_data)
-		openfile->mark_begin_x = new_end - new_paragraph_data;
-	}
-#endif
-    } else
-	free(new_paragraph_data);
-}
-
 /* The "quote part" of a line is the largest initial substring matching
  * the quote string.  This function returns the length of the quote part
  * of the given line.
@@ -1671,112 +1548,24 @@
 	quote_len)] != '\0');
 }
 
-/* Move the next par_len lines, starting with first_line, into the
- * justify buffer, leaving copies of those lines in place.  Assume that
- * par_len is greater than zero, and that there are enough lines after
- * first_line. */
-void backup_lines(filestruct *first_line, size_t par_len)
-{
-    filestruct *top = first_line;
-	/* The top of the paragraph we're backing up. */
-    filestruct *bot = first_line;
-	/* The bottom of the paragraph we're backing up. */
-    size_t i;
-	/* Generic loop variable. */
-    size_t current_x_save = openfile->current_x;
-    ssize_t fl_lineno_save = first_line->lineno;
-    ssize_t edittop_lineno_save = openfile->edittop->lineno;
-    ssize_t current_lineno_save = openfile->current->lineno;
-#ifndef NANO_TINY
-    bool old_mark_set = openfile->mark_set;
-    ssize_t mb_lineno_save = 0;
-    size_t mark_begin_x_save = 0;
-
-    if (old_mark_set) {
-	mb_lineno_save = openfile->mark_begin->lineno;
-	mark_begin_x_save = openfile->mark_begin_x;
-    }
-#endif
-
-    /* par_len will be one greater than the number of lines between
-     * current and filebot if filebot is the last line in the
-     * paragraph. */
-    assert(par_len > 0 && openfile->current->lineno + par_len <=
-	openfile->filebot->lineno + 1);
-
-    /* Move bot down par_len lines to the line after the last line of
-     * the paragraph, if there is one. */
-    for (i = par_len; i > 0 && bot != openfile->filebot; i--)
-	bot = bot->next;
-
-    /* Move the paragraph from the current buffer's filestruct to the
-     * justify buffer. */
-    move_to_filestruct(&jusbuffer, &jusbottom, top, 0, bot,
-	(i == 1 && bot == openfile->filebot) ? strlen(bot->data) : 0);
-
-    /* Copy the paragraph back to the current buffer's filestruct from
-     * the justify buffer. */
-    copy_from_filestruct(jusbuffer);
-
-    /* Move upward from the last line of the paragraph to the first
-     * line, putting first_line, edittop, current, and mark_begin at the
-     * same lines in the copied paragraph that they had in the original
-     * paragraph. */
-    if (openfile->current != openfile->fileage) {
-	top = openfile->current->prev;
-#ifndef NANO_TINY
-	if (old_mark_set &&
-		openfile->current->lineno == mb_lineno_save) {
-	    openfile->mark_begin = openfile->current;
-	    openfile->mark_begin_x = mark_begin_x_save;
-	}
-#endif
-    } else
-	top = openfile->current;
-    for (i = par_len; i > 0 && top != NULL; i--) {
-	if (top->lineno == fl_lineno_save)
-	    first_line = top;
-	if (top->lineno == edittop_lineno_save)
-	    openfile->edittop = top;
-	if (top->lineno == current_lineno_save)
-	    openfile->current = top;
-#ifndef NANO_TINY
-	if (old_mark_set && top->lineno == mb_lineno_save) {
-	    openfile->mark_begin = top;
-	    openfile->mark_begin_x = mark_begin_x_save;
-	}
-#endif
-	top = top->prev;
-    }
-
-    /* Put current_x at the same place in the copied paragraph that it
-     * had in the original paragraph. */
-    openfile->current_x = current_x_save;
-
-    set_modified();
-}
-
 /* Find the beginning of the current paragraph if we're in one, or the
  * beginning of the next paragraph if we're not.  Afterwards, save the
- * quote length and paragraph length in *quote and *par.  Return TRUE if
- * we found a paragraph, and FALSE if there was an error or we didn't
- * find a paragraph.
+ * quote length and the last line of the paragraph in *quote and 
+ * *last_par_line.  Return TRUE if we found a paragraph, and FALSE if 
+ * there was an error or we didn't find a paragraph.
  *
  * See the comment at begpar() for more about when a line is the
  * beginning of a paragraph. */
-bool find_paragraph(size_t *const quote, size_t *const par)
+bool find_paragraph(size_t *const quote, filestruct **const last_par_line)
 {
-    size_t quote_len;
-	/* Length of the initial quotation of the paragraph we search
-	 * for. */
-    size_t par_len;
-	/* Number of lines in the paragraph we search for. */
     filestruct *current_save;
 	/* The line at the beginning of the paragraph we search for. */
     ssize_t current_y_save;
 	/* The y-coordinate at the beginning of the paragraph we search
 	 * for. */
 
+    assert(quote != NULL && last_par_line != NULL);
+    
 #ifdef HAVE_REGEX_H
     if (quoterc != 0) {
 	statusbar(_("Bad quote string %s: %s"), quotestr, quoteerr);
@@ -1822,27 +1611,21 @@
     /* Now current is the first line of the paragraph.  Set quote_len to
      * the quotation length of that line, and set par_len to the number
      * of lines in this paragraph. */
-    quote_len = quote_length(openfile->current->data);
+    *quote = quote_length(openfile->current->data);
     current_save = openfile->current;
     current_y_save = openfile->current_y;
     do_para_end(FALSE);
-    par_len = openfile->current->lineno - current_save->lineno;
 
     /* If we end up past the beginning of the line, it means that we're
      * at the end of the last line of the file, and the line isn't
      * blank, in which case the last line of the file is part of the
      * paragraph. */
-    if (openfile->current_x > 0)
-	par_len++;
+    *last_par_line = (openfile->current_x > 0)?
+    openfile->current : openfile->current->prev;
+
     openfile->current = current_save;
     openfile->current_y = current_y_save;
 
-    /* Save the values of quote_len and par_len. */
-    assert(quote != NULL && par != NULL);
-
-    *quote = quote_len;
-    *par = par_len;
-
     return TRUE;
 }
 
@@ -1850,32 +1633,16 @@
  * the current paragraph. */
 void do_justify(bool full_justify)
 {
-    filestruct *first_par_line = NULL;
-	/* Will be the first line of the justified paragraph(s), if any.
-	 * For restoring after unjustify. */
-    filestruct *last_par_line = NULL;
-	/* Will be the line after the last line of the justified
-	 * paragraph(s), if any.  Also for restoring after unjustify. */
-    bool filebot_inpar = FALSE;
-	/* Whether the text at filebot is part of the current
+    filestruct *curr_last_par_line = NULL;
+	    /* The last line of the current paragraph. */        
+	size_t quote_len;
+	    /* Length of the initial quotation of the current
 	 * paragraph. */
+    filestruct *line_after_par = NULL;
+	    /* The next line after the end of the current paragraph. */        
 
-    /* We save these variables to be restored if the user
-     * unjustifies. */
-    filestruct *edittop_save = openfile->edittop;
-    filestruct *current_save = openfile->current;
-    size_t current_x_save = openfile->current_x;
-    size_t pww_save = openfile->placewewant;
-    size_t totsize_save = openfile->totsize;
-#ifndef NANO_TINY
-    filestruct *mark_begin_save = openfile->mark_begin;
-    size_t mark_begin_x_save = openfile->mark_begin_x;
-#endif
-    bool modified_save = openfile->modified;
+    add_undo(JUSTIFY_BEGIN);
 
-    int kbinput;
-    const sc *s;
-
     /* Move to the beginning of the current line, so that justifying at
      * the end of the last line of the file, if that line isn't blank,
      * will work the first time through. */
@@ -1885,386 +1652,31 @@
     if (full_justify)
 	openfile->current = openfile->fileage;
 
-#ifndef NANO_TINY
-    allow_pending_sigwinch(FALSE);
-#endif
-
     while (TRUE) {
-	size_t i;
-	    /* Generic loop variable. */
-	filestruct *curr_first_par_line;
-	    /* The first line of the current paragraph. */
-	size_t quote_len;
-	    /* Length of the initial quotation of the current
-	     * paragraph. */
-	size_t indent_len;
-	    /* Length of the initial indentation of the current
-	     * paragraph. */
-	size_t par_len;
-	    /* Number of lines in the current paragraph. */
-	ssize_t break_pos;
-	    /* Where we will break lines. */
-	char *indent_string;
-	    /* The first indentation that doesn't match the initial
-	     * indentation of the current paragraph.  This is put at the
-	     * beginning of every line broken off the first justified
-	     * line of the paragraph.  Note that this works because a
-	     * paragraph can only contain two indentations at most: the
-	     * initial one, and a different one starting on a line after
-	     * the first.  See the comment at begpar() for more about
-	     * when a line is part of a paragraph. */
 
-	/* Find the first line of the paragraph to be justified.  That
-	 * is the start of this paragraph if we're in one, or the start
-	 * of the next otherwise.  Save the quote length and paragraph
-	 * length (number of lines).  Don't refresh the screen yet,
-	 * since we'll do that after we justify.
-	 *
-	 * If the search failed, we do one of two things.  If we're
-	 * justifying the whole file, and we've found at least one
-	 * paragraph, it means that we should justify all the way to the
-	 * last line of the file, so set the last line of the text to be
-	 * justified to the last line of the file and break out of the
-	 * loop.  Otherwise, it means that there are no paragraph(s) to
-	 * justify, so refresh the screen and get out. */
-	if (!find_paragraph(&quote_len, &par_len)) {
-	    if (full_justify && first_par_line != NULL) {
-		last_par_line = openfile->filebot;
+	if (!find_paragraph(&quote_len, &curr_last_par_line) ) 
 		break;
-	    } else {
-		edit_refresh_needed = TRUE;
-		return;
-	    }
-	}
+    line_after_par = (curr_last_par_line == openfile->filebot)?
+    curr_last_par_line : curr_last_par_line->next;
+	/* openfile->current will have been set to the first line
+     * of the current paragraph */
+    do_wrap(openfile->current, curr_last_par_line->lineno, quote_len, TRUE);
 
-	/* par_len will be one greater than the number of lines between
-	 * current and filebot if filebot is the last line in the
-	 * paragraph.  Set filebot_inpar to TRUE if this is the case. */
-	filebot_inpar = (openfile->current->lineno + par_len ==
-		openfile->filebot->lineno + 1);
-
-	/* If we haven't already done it, move the original paragraph(s)
-	 * to the justify buffer, splice a copy of the original
-	 * paragraph(s) into the file in the same place, and set
-	 * first_par_line to the first line of the copy. */
-	if (first_par_line == NULL) {
-	    backup_lines(openfile->current, full_justify ?
-		openfile->filebot->lineno - openfile->current->lineno +
-		((openfile->filebot->data[0] != '\0') ? 1 : 0) :
-		par_len);
-	    first_par_line = openfile->current;
-	}
-
-	/* Set curr_first_par_line to the first line of the current
-	 * paragraph. */
-	curr_first_par_line = openfile->current;
-
-	/* Initialize indent_string to a blank string. */
-	indent_string = mallocstrcpy(NULL, "");
-
-	/* Find the first indentation in the paragraph that doesn't
-	 * match the indentation of the first line, and save it in
-	 * indent_string.  If all the indentations are the same, save
-	 * the indentation of the first line in indent_string. */
-	{
-	    const filestruct *indent_line = openfile->current;
-	    bool past_first_line = FALSE;
-
-	    for (i = 0; i < par_len; i++) {
-		indent_len = quote_len +
-			indent_length(indent_line->data + quote_len);
-
-		if (indent_len != strlen(indent_string)) {
-		    indent_string = mallocstrncpy(indent_string,
-			indent_line->data, indent_len + 1);
-		    indent_string[indent_len] = '\0';
-
-		    if (past_first_line)
-			break;
-		}
-
-		if (indent_line == openfile->current)
-		    past_first_line = TRUE;
-
-		indent_line = indent_line->next;
-	    }
-	}
-
-	/* Now tack all the lines of the paragraph together, skipping
-	 * the quoting and indentation on all lines after the first. */
-	for (i = 0; i < par_len - 1; i++) {
-	    filestruct *next_line = openfile->current->next;
-	    size_t line_len = strlen(openfile->current->data);
-	    size_t next_line_len =
-		strlen(openfile->current->next->data);
-
-	    indent_len = quote_len +
-		indent_length(openfile->current->next->data +
-		quote_len);
-
-	    next_line_len -= indent_len;
-	    openfile->totsize -= indent_len;
-
-	    /* We're just about to tack the next line onto this one.  If
-	     * this line isn't empty, make sure it ends in a space. */
-	    if (line_len > 0 &&
-		openfile->current->data[line_len - 1] != ' ') {
-		line_len++;
-		openfile->current->data =
-			charealloc(openfile->current->data,
-			line_len + 1);
-		openfile->current->data[line_len - 1] = ' ';
-		openfile->current->data[line_len] = '\0';
-		openfile->totsize++;
-	    }
-
-	    openfile->current->data =
-		charealloc(openfile->current->data, line_len +
-		next_line_len + 1);
-	    strcat(openfile->current->data, next_line->data +
-		indent_len);
-
-	    /* Don't destroy edittop or filebot! */
-	    if (next_line == openfile->edittop)
-		openfile->edittop = openfile->current;
-	    if (next_line == openfile->filebot)
-		openfile->filebot = openfile->current;
-
-#ifndef NANO_TINY
-	    /* Adjust the mark coordinates to compensate for the change
-	     * in the next line. */
-	    if (openfile->mark_set && openfile->mark_begin ==
-		next_line) {
-		openfile->mark_begin = openfile->current;
-		openfile->mark_begin_x += line_len - indent_len;
-	    }
-#endif
-
-	    unlink_node(next_line);
-	    delete_node(next_line);
-
-	    /* If we've removed the next line, we need to go through
-	     * this line again. */
-	    i--;
-
-	    par_len--;
-	    openfile->totsize--;
-	}
-
-	/* Call justify_format() on the paragraph, which will remove
-	 * excess spaces from it and change all blank characters to
-	 * spaces. */
-	justify_format(openfile->current, quote_len +
-		indent_length(openfile->current->data + quote_len));
-
-	while (par_len > 0 && strlenpt(openfile->current->data) >
-		fill) {
-	    size_t line_len = strlen(openfile->current->data);
-
-	    indent_len = strlen(indent_string);
-
-	    /* If this line is too long, try to wrap it to the next line
-	     * to make it short enough. */
-	    break_pos = break_line(openfile->current->data + indent_len,
-		fill - strnlenpt(openfile->current->data, indent_len)
-#ifndef DISABLE_HELP
-		, FALSE
-#endif
-		);
-
-	    /* We can't break the line, or don't need to, so get out. */
-	    if (break_pos == -1 || break_pos + indent_len == line_len)
-		break;
-
-	    /* Move forward to the character after the indentation and
-	     * just after the space. */
-	    break_pos += indent_len + 1;
-
-	    assert(break_pos <= line_len);
-
-	    /* Make a new line, and copy the text after where we're
-	     * going to break this line to the beginning of the new
-	     * line. */
-	    splice_node(openfile->current,
-		make_new_node(openfile->current),
-		openfile->current->next);
-
-	    /* If this paragraph is non-quoted, and autoindent isn't
-	     * turned on, set the indentation length to zero so that the
-	     * indentation is treated as part of the line. */
-	    if (quote_len == 0
-#ifndef NANO_TINY
-		&& !ISSET(AUTOINDENT)
-#endif
-		)
-		indent_len = 0;
-
-	    /* Copy the text after where we're going to break the
-	     * current line to the next line. */
-	    openfile->current->next->data = charalloc(indent_len + 1 +
-		line_len - break_pos);
-	    strncpy(openfile->current->next->data, indent_string,
-		indent_len);
-	    strcpy(openfile->current->next->data + indent_len,
-		openfile->current->data + break_pos);
-
-	    par_len++;
-	    openfile->totsize += indent_len + 1;
-
-#ifndef NANO_TINY
-	    /* Adjust the mark coordinates to compensate for the change
-	     * in the current line. */
-	    if (openfile->mark_set && openfile->mark_begin ==
-		openfile->current && openfile->mark_begin_x >
-		break_pos) {
-		openfile->mark_begin = openfile->current->next;
-		openfile->mark_begin_x -= break_pos - indent_len;
-	    }
-#endif
-
-	    /* Break the current line. */
-	    null_at(&openfile->current->data, break_pos);
-
-	    /* If the current line is the last line of the file, move
-	     * the last line of the file down to the next line. */
-	    if (openfile->filebot == openfile->current)
-		openfile->filebot = openfile->filebot->next;
-
-	    /* Go to the next line. */
-	    par_len--;
-	    openfile->current_y++;
-	    openfile->current = openfile->current->next;
-	}
-
-	/* We're done breaking lines, so we don't need indent_string
-	 * anymore. */
-	free(indent_string);
-
 	/* Go to the next line, if possible.  If there is no next line,
 	 * move to the end of the current line. */
-	if (openfile->current != openfile->filebot) {
-	    openfile->current_y++;
-	    openfile->current = openfile->current->next;
-	} else
-	    openfile->current_x = strlen(openfile->current->data);
+    openfile->current = line_after_par;
+    openfile->current_x = (openfile->current == openfile->filebot)?
+    strlen(openfile->current->data) : 0;
 
-	/* Renumber the lines of the now-justified current paragraph,
-	 * since both find_paragraph() and edit_refresh() need the line
-	 * numbers to be right. */
-	renumber(curr_first_par_line);
-
-	/* We've just finished justifying the paragraph.  If we're not
-	 * justifying the entire file, break out of the loop.
-	 * Otherwise, continue the loop so that we justify all the
-	 * paragraphs in the file. */
-	if (!full_justify)
+    /* if the filebot is found, break,  the current line will be empty */
+	if (!full_justify || openfile->current == openfile->filebot)
 	    break;
     }
 
-    /* We are now done justifying the paragraph or the file, so clean
-     * up.  current_y and totsize have been maintained above.  If we
-     * actually justified something, set last_par_line to the new end of
-     * the paragraph. */
-    if (first_par_line != NULL)
-	last_par_line = openfile->current;
-
+    add_undo(JUSTIFY_END);
     edit_refresh();
-
-#ifndef NANO_TINY
-    /* We're going to set jump_buf so that we return here after a
-     * SIGWINCH instead of to main().  Indicate this. */
-    jump_buf_main = FALSE;
-
-    /* Return here after a SIGWINCH. */
-    sigsetjmp(jump_buf, 1);
-#endif
-
-    statusbar(_("Can now UnJustify!"));
-
-    /* If constant cursor position display is on, make sure the current
-     * cursor position will be properly displayed on the statusbar. */
-    if (ISSET(CONST_UPDATE))
-	do_cursorpos(TRUE);
-
-    /* Display the shortcut list with UnJustify. */
-    uncutfunc->desc = unjust_tag;
-    currmenu = MMAIN;
-    display_main_list();
-
-    /* Now get a keystroke and see if it's unjustify.  If not, put back
-     * the keystroke and return. */
-    kbinput = do_input(FALSE);
-    s = get_shortcut(&kbinput);
-
-    if (s && s->scfunc == do_uncut_text) {
-	/* Splice the justify buffer back into the file, but only if we
-	 * actually justified something. */
-	if (first_par_line != NULL) {
-	    filestruct *top_save;
-
-	    /* Partition the filestruct so that it contains only the
-	     * text of the justified paragraph. */
-	    filepart = partition_filestruct(first_par_line, 0,
-		last_par_line, filebot_inpar ?
-		strlen(last_par_line->data) : 0);
-
-	    /* Remove the text of the justified paragraph, and
-	     * replace it with the text in the justify buffer. */
-	    free_filestruct(openfile->fileage);
-	    openfile->fileage = jusbuffer;
-	    openfile->filebot = jusbottom;
-
-	    top_save = openfile->fileage;
-
-	    /* Unpartition the filestruct so that it contains all the
-	     * text again.  Note that the justified paragraph has been
-	     * replaced with the unjustified paragraph. */
-	    unpartition_filestruct(&filepart);
-
-	     /* Renumber starting with the beginning line of the old
-	      * partition. */
-	    renumber(top_save);
-
-	    /* Restore the justify we just did (ungrateful user!). */
-	    openfile->edittop = edittop_save;
-	    openfile->current = current_save;
-	    openfile->current_x = current_x_save;
-	    openfile->placewewant = pww_save;
-	    openfile->totsize = totsize_save;
-#ifndef NANO_TINY
-	    if (openfile->mark_set) {
-		openfile->mark_begin = mark_begin_save;
-		openfile->mark_begin_x = mark_begin_x_save;
 	    }
-#endif
-	    openfile->modified = modified_save;
 
-	    /* Clear the justify buffer. */
-	    jusbuffer = NULL;
-
-	    if (!openfile->modified)
-		titlebar(NULL);
-	    edit_refresh_needed = TRUE;
-	}
-    } else {
-	unget_kbinput(kbinput, meta_key, func_key);
-
-	/* Blow away the text in the justify buffer. */
-	free_filestruct(jusbuffer);
-	jusbuffer = NULL;
-    }
-
-    blank_statusbar();
-
-    /* Display the shortcut list with UnCut. */
-    uncutfunc->desc = uncut_tag;
-    display_main_list();
-
-#ifndef NANO_TINY
-    allow_pending_sigwinch(TRUE);
-#endif
-}
-
 /* Justify the current paragraph. */
 void do_justify_void(void)
 {

["wrap.5049.patch" (text/x-patch)]

Index: src/cut.c
===================================================================
--- src/cut.c	(revision 5049)
+++ src/cut.c	(working copy)
@@ -275,8 +275,10 @@
 }
 #endif /* !NANO_TINY */
 
+
+
 /* Copy text from the cutbuffer into the current filestruct. */
-void do_uncut_text(void)
+void paste_text(void)
 {
     assert(openfile->current != NULL && openfile->current->data != NULL);
 
@@ -314,3 +316,40 @@
     dump_filestruct_reverse();
 #endif
 }
+
+/* Copy text from the cutbuffer into the current filestruct
+ * If needed, wrap the pasted text */
+void do_uncut_text(void)
+{
+    /* If the cutbuffer is empty, get out. */
+    if (cutbuffer == NULL)
+	return;
+    
+#ifndef DISABLE_WRAPPING
+    ssize_t startline = openfile->current->lineno;
+#endif
+    
+    paste_text();   
+
+#ifndef DISABLE_WRAPPING
+    if (!ISSET(NO_WRAP)){
+
+#ifndef NANO_TINY
+        add_undo(SPLIT_BEGIN);
+#endif
+
+        if(xplustabs() == 0){
+        openfile->current = openfile->current->prev;
+        join_currentline(NULL);
+        }
+        
+        do_wrap( fsfromline(startline), openfile->current->lineno, 0, FALSE);
+ 
+        openfile->placewewant = xplustabs();
+       
+#ifndef NANO_TINY
+        add_undo(SPLIT_END);
+#endif
+    }
+#endif    
+}
Index: src/nano.c
===================================================================
--- src/nano.c	(revision 5049)
+++ src/nano.c	(working copy)
@@ -1657,12 +1657,6 @@
 	 * empty.  Note that it should be empty if we're in view
 	 * mode. */
 	if (have_shortcut || get_key_buffer_len() == 0) {
-#ifndef DISABLE_WRAPPING
-	    /* If we got a shortcut or toggle, and it's not the shortcut
-	     * for verbatim input, turn off prepending of wrapped text. */
-	    if (have_shortcut && s->scfunc != do_verbatim_input)
-		wrap_reset();
-#endif
 
 	    if (kbinput != NULL) {
 		/* Display all the characters in the input buffer at
@@ -2004,7 +1998,7 @@
 		output[i] = '\n';
 	    /* Newline to Enter, if needed. */
 	    else if (output[i] == '\n') {
-		do_enter(FALSE);
+		do_enter_void();
 		i++;
 		continue;
 	    }
@@ -2062,8 +2056,7 @@
 #ifndef DISABLE_WRAPPING
 	/* If we're wrapping text, we need to call edit_refresh(). */
 	if (!ISSET(NO_WRAP))
-	    if (do_wrap(openfile->current))
-		edit_refresh_needed = TRUE;
+	    do_wrap_void();
 #endif
 
 #ifndef DISABLE_COLOR
Index: src/proto.h
===================================================================
--- src/proto.h	(revision 5049)
+++ src/proto.h	(working copy)
@@ -270,6 +270,7 @@
 void do_cut_till_eof(void);
 #endif
 void do_uncut_text(void);
+void paste_text(void);
 
 /* All functions in files.c. */
 void make_new_buffer(void);
@@ -643,15 +644,17 @@
 void do_undo(void);
 void do_redo(void);
 #endif
-void do_enter(bool undoing);
+size_t do_enter(bool undoing, bool indent_newline, ssize_t const indent_len);
 void do_enter_void(void);
+void add_break(bool undoing, ssize_t const indent_len);
 #ifndef NANO_TINY
 RETSIGTYPE cancel_command(int signal);
 bool execute_command(const char *command);
 #endif
 #ifndef DISABLE_WRAPPING
-void wrap_reset(void);
-bool do_wrap(filestruct *line);
+void do_wrap_void(void);
+void do_wrap(filestruct *line, ssize_t until_lineno, const size_t quote_len, bool \
justify_paragraph); +void join_currentline(size_t *old_x);
 #endif
 #if !defined(DISABLE_HELP) || !defined(DISABLE_WRAPJUSTIFY)
 ssize_t break_line(const char *line, ssize_t goal
@@ -662,6 +665,7 @@
 #endif
 #if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
 size_t indent_length(const char *line);
+bool is_empty(filestruct *line);
 #endif
 #ifndef DISABLE_JUSTIFY
 void justify_format(filestruct *paragraph, size_t skip);
Index: src/text.c
===================================================================
--- src/text.c	(revision 5049)
+++ src/text.c	(working copy)
@@ -36,10 +36,7 @@
 	/* The PID of the forked process in execute_command(), for use
 	 * with the cancel_command() signal handler. */
 #endif
-#ifndef DISABLE_WRAPPING
-static bool prepend_wrap = FALSE;
-	/* Should we prepend wrapped text to the next line? */
-#endif
+
 #ifndef DISABLE_JUSTIFY
 static filestruct *jusbottom = NULL;
 	/* Pointer to the end of the justify buffer. */
@@ -607,7 +604,7 @@
     case ENTER:
 	redidmsg = _("line break");
 	goto_line_posx(u->lineno, u->begin);
-	do_enter(TRUE);
+	add_break(TRUE, u->mark_begin_x);
 	break;
 #ifndef DISABLE_WRAPPING
     case SPLIT_BEGIN:
@@ -672,7 +669,7 @@
 #endif /* !NANO_TINY */
 
 /* Someone hits Enter *gasp!* */
-void do_enter(bool undoing)
+size_t do_enter(bool undoing, bool indent_newline, ssize_t const indent_len)
 {
     filestruct *newnode = make_new_node(openfile->current);
     size_t extra = 0;
@@ -684,11 +681,11 @@
 	add_undo(ENTER);
 
     /* Do auto-indenting, like the neolithic Turbo Pascal editor. */
-    if (ISSET(AUTOINDENT)) {
+    if (indent_newline) {
 	/* If we are breaking the line in the indentation, the new
 	 * indentation should have only current_x characters, and
 	 * current_x should not change. */
-	extra = indent_length(openfile->current->data);
+	extra = (indent_len == -1)? indent_length(openfile->current->data) : indent_len;
 	if (extra > openfile->current_x)
 	    extra = openfile->current_x;
     }
@@ -698,7 +695,7 @@
     strcpy(&newnode->data[extra], openfile->current->data +
 	openfile->current_x);
 #ifndef NANO_TINY
-    if (ISSET(AUTOINDENT)) {
+    if (indent_newline) {
 	strncpy(newnode->data, openfile->current->data, extra);
 	openfile->totsize += extra;
     }
@@ -733,12 +730,21 @@
 #endif
 
     edit_refresh_needed = TRUE;
+    
+    return indent_newline? extra : indent_len; 
 }
 
+/* add a break to the current line at current_x and 
+    and prepend the new line with current->data[indent_len]  */
+inline void add_break(bool undoing, ssize_t const indent_len)
+{
+    do_enter(undoing, TRUE, indent_len);
+}
+
 /* Need this again... */
-void do_enter_void(void)
+inline void do_enter_void(void)
 {
-    do_enter(FALSE);
+    do_enter(FALSE, ISSET(AUTOINDENT), -1);
 }
 
 #ifndef NANO_TINY
@@ -1099,114 +1105,70 @@
 #endif /* !NANO_TINY */
 
 #ifndef DISABLE_WRAPPING
-/* Unset the prepend_wrap flag.  We need to do this as soon as we do
- * something other than type text. */
-void wrap_reset(void)
-{
-    prepend_wrap = FALSE;
-}
 
-/* Try wrapping the given line.  Return TRUE if wrapped, FALSE otherwise. */
-bool do_wrap(filestruct *line)
+/* Return the index where the given line should be broken, or 0 if the
+ * line should not be broken. */
+ssize_t get_wrap_index(filestruct const *const line , ssize_t indent_len)
 {
-    size_t line_len;
-	/* The length of the line we wrap. */
-    ssize_t wrap_loc;
-	/* The index of line->data where we wrap. */
-#ifndef NANO_TINY
-    const char *indent_string = NULL;
-	/* Indentation to prepend to the new line. */
-    size_t indent_len = 0;
-	/* The length of indent_string. */
-#endif
-    const char *after_break;
-	/* The text after the wrap point. */
-    size_t after_break_len;
-	/* The length of after_break. */
-    const char *next_line = NULL;
-	/* The next line, minus indentation. */
-    size_t next_line_len = 0;
-	/* The length of next_line. */
+    if(indent_len < 0)
+    indent_len = 0;
 
-    /* There are three steps.  First, we decide where to wrap.  Then, we
-     * create the new wrap line.  Finally, we clean up. */
+    ssize_t wrap_loc = -1;
+    size_t leading_spaces_len = 0;
+    char const *buf = line->data + indent_len;
+    size_t line_len = strlen(line->data);
 
-    /* Step 1, finding where to wrap.  We are going to add a new line
-     * after a blank character.  In this step, we call break_line() to
-     * get the location of the last blank we can break the line at, and
-     * set wrap_loc to the location of the character after it, so that
-     * the blank is preserved at the end of the line.
-     *
-     * If there is no legal wrap point, or we reach the last character
-     * of the line while trying to find one, we should return without
-     * wrapping.  Note that if autoindent is turned on, we don't break
-     * at the end of it! */
-    assert(line != NULL && line->data != NULL);
+    assert(line_len > indent_len);    
 
-    /* Save the length of the line. */
-    line_len = strlen(line->data);
-
-    /* Find the last blank where we can break the line. */
-    wrap_loc = break_line(line->data, fill
+    /* Find the last blank where we can break the line. 
+     * but do not consider leading spaces as a location */
+    while( *buf != '\0' && (wrap_loc = break_line(buf, fill - (indent_len + \
leading_spaces_len)  #ifndef DISABLE_HELP
 	, FALSE
 #endif
-	);
+	)) == 0 ){
+    leading_spaces_len += parse_mbchar(buf, NULL, NULL);
+    buf = line->data + indent_len + leading_spaces_len;
+    }
 
-    /* If we couldn't break the line, or we've reached the end of it, we
-     * don't wrap. */
-    if (wrap_loc == -1 || line->data[wrap_loc] == '\0')
-	return FALSE;
+    /* , we don't wrap. */
+    if (wrap_loc == -1)
+	return 0;
 
+    wrap_loc += (indent_len + leading_spaces_len);
+
+    if (wrap_loc >= line_len){
+        size_t wrap_column = strnlenpt(line->data, wrap_loc);
+        if( wrap_column <= fill)
+        return 0;
+    }
+
     /* Otherwise, move forward to the character just after the blank. */
     wrap_loc += move_mbright(line->data + wrap_loc, 0);
 
-    /* If we've reached the end of the line, we don't wrap. */
-    if (line->data[wrap_loc] == '\0')
-	return FALSE;
+    /* After the move, check again.  If we've reached the end of the line,
+     * we don't wrap. */
+    if (wrap_loc >= line_len)
+	return line_len;
 
-#ifndef NANO_TINY
-    /* If autoindent is turned on, and we're on the character just after
-     * the indentation, we don't wrap. */
-    if (ISSET(AUTOINDENT)) {
-	/* Get the indentation of this line. */
-	indent_string = line->data;
-	indent_len = indent_length(indent_string);
-
-	if (wrap_loc == indent_len)
-	    return FALSE;
+    return wrap_loc;
     }
 
-    add_undo(SPLIT_BEGIN);
-#endif
+/*  join line with line->next  
+    old_x represents the x_location of line->next
+    adjusted for the new location that results from 
+    the join with line */
+void join_currentline(size_t *old_x){
+    filestruct *line = openfile->current;
+    if(line == openfile->filebot) return;
 
-    size_t old_x = openfile->current_x;
-    filestruct * oldLine = openfile->current;
-    openfile->current = line;
+    size_t line_len = strlen(line->data);
+    const char *end = line->data + move_mbleft(line->data, line_len); 
 
-    /* Step 2, making the new wrap line.  It will consist of indentation
-     * followed by the text after the wrap point, optionally followed by
-     * a space (if the text after the wrap point doesn't end in a blank)
-     * and the text of the next line, if they can fit without wrapping,
-     * the next line exists, and the prepend_wrap flag is set. */
-
-    /* after_break is the text that will be wrapped to the next line. */
-    after_break = line->data + wrap_loc;
-    after_break_len = line_len - wrap_loc;
-
-    assert(strlen(after_break) == after_break_len);
-
-    /* We prepend the wrapped text to the next line, if the prepend_wrap
-     * flag is set, there is a next line, and prepending would not make
-     * the line too long. */
-    if (prepend_wrap && line != openfile->filebot) {
-	const char *end = after_break + move_mbleft(after_break,
-		after_break_len);
-
 	/* Go to the end of the line. */
 	openfile->current_x = line_len;
 
-	/* If after_break doesn't end in a blank, make sure it ends in a
+	/* If the line doesn't end in a blank, make sure it ends in a
 	 * space. */
 	if (!is_blank_mbchar(end)) {
 #ifndef NANO_TINY
@@ -1216,8 +1178,7 @@
 	    line->data = charealloc(line->data, line_len + 1);
 	    line->data[line_len - 1] = ' ';
 	    line->data[line_len] = '\0';
-	    after_break = line->data + wrap_loc;
-	    after_break_len++;
+
 	    openfile->totsize++;
 	    openfile->current_x++;
 #ifndef NANO_TINY
@@ -1225,39 +1186,138 @@
 #endif
 	}
 
-	next_line = line->next->data;
-	next_line_len = strlen(next_line);
+    if(old_x != NULL)
+    *old_x += line_len;
 
-	if (after_break_len + next_line_len <= fill) {
 	    /* Delete the LF to join the two lines. */
 	    do_delete();
 	    /* Delete any leading blanks from the joined-on line. */
-	    while (is_blank_mbchar(&line->data[openfile->current_x]))
+    while (is_blank_mbchar(&line->data[openfile->current_x])){
+        if(old_x != NULL)
+        *old_x -= parse_mbchar(&line->data[openfile->current_x], NULL, NULL);
 		do_delete();
+    }
 	    renumber(line);
 	}
+
+        
+ssize_t copy_indent_string(filestruct *line, const size_t quote_len, bool \
cut_indent) +{
+    ssize_t indent_len = quote_len + indent_length(line->data + quote_len);
+     size_t old_x = openfile->current_x;
+    filestruct *oldline = openfile->current;
+   
+    openfile->mark_set = TRUE;
+    openfile->mark_begin =  line;
+    openfile->mark_begin_x = 0;
+    openfile->current = line;
+    openfile->current_x = indent_len;
+
+    if(cut_indent){
+    do_cut_text_void();
+    openfile->current = oldline;
+    } else
+    do_copy_text();
+    
+    openfile->current_x = old_x;
+    
+    return indent_len;
     }
 
+/* Try wrapping the given line.  Return TRUE if wrapped, FALSE otherwise. */
+void do_wrap(filestruct *line, ssize_t until_lineno, const size_t quote_len, bool \
justify_paragraph) +{
+    ssize_t wrap_loc;
+	/* The index of line->data where we wrap. */
+
+    size_t old_x = openfile->current_x;
+    filestruct *oldline = openfile->current;
+    ssize_t indent_len = -1;
+
+    bool prepend_wrap = FALSE;
+    bool next_line_inpar = TRUE;
+    
+    assert(line != NULL && line->data != NULL);    
+    
+    while (line->lineno <= until_lineno){
+    
+    openfile->current = line;
+
+    /* Find the last blank where we can break the line. */
+    wrap_loc = get_wrap_index(line, indent_len);
+    
+    if (line->lineno == until_lineno){
+        /* If we couldn't break the line, or we've reached the end of it, we
+         * don't wrap. */
+        if (wrap_loc == 0 || line->data[wrap_loc] == '\0')
+        goto Exit;
+        
+        next_line_inpar = line->next && !begpar(line->next) && \
!is_empty(line->next); +    }
+
+    if (justify_paragraph)
+    indent_len = copy_indent_string(next_line_inpar? line->next : line, quote_len, \
next_line_inpar); +
+    if (next_line_inpar){
+
+        if (oldline == line->next){
+        join_currentline(&old_x);
+        oldline = line;
+        } else
+        join_currentline(NULL);
+            
+        until_lineno--;
+    } else /* update the line we're pointing at, it may be invalid after the call to \
copy_indent_string */ +    line = openfile->current;
+    
+    if (wrap_loc == 0)
+    wrap_loc = get_wrap_index(line, indent_len);
+         
+    while (wrap_loc > indent_len) {
+        prepend_wrap = prepend_wrap || (old_x < wrap_loc && oldline == line);
     /* Go to the wrap location and split the line there. */
     openfile->current_x = wrap_loc;
-    do_enter(FALSE);
+        /* If indent_len is -1 and justify_paragraph is FALSE then indent_len will \
be determined +          in the call to do_enter and stored for subsequent iterations \
of the loop. +         If justify_paragraph is TRUE then indent_len will not be used \
or effected by do_enter */ +        indent_len = do_enter(FALSE, !justify_paragraph, \
indent_len); +        until_lineno++;
 
-    if (old_x < wrap_loc) {
-	openfile->current_x = old_x;
-	openfile->current = oldLine;
-	prepend_wrap = TRUE;
-    } else {
-	openfile->current_x += (old_x - wrap_loc);
-	prepend_wrap = FALSE;
+        /* paste the cutbuffer -- it contains the indent string */
+        if (justify_paragraph)
+        paste_text();
+        
+        if (!prepend_wrap && oldline == line){
+            old_x = openfile->current_x + old_x - wrap_loc;
+            oldline = openfile->current;
     }
 
+        line = openfile->current;
+        assert(line != NULL && line->data != NULL);
+        /* Find the last blank where we can break the line. */
+        wrap_loc = get_wrap_index(line, indent_len);
+    }
+    }
+
+Exit:
+	openfile->current = oldline;
+    openfile->current_x = old_x;
     openfile->placewewant = xplustabs();
+}
 
+void do_wrap_void(void)
+{
 #ifndef NANO_TINY
+    add_undo(SPLIT_BEGIN);
+#endif    
+
+    do_wrap(openfile->current, openfile->current->lineno, 0, FALSE);
+
+#ifndef NANO_TINY
     add_undo(SPLIT_END);
 #endif
 
-    return TRUE;
+    edit_refresh();    
 }
 #endif /* !DISABLE_WRAPPING */
 
@@ -1282,6 +1342,7 @@
 	/* Current column position in line. */
     int char_len = 0;
 	/* Length of current character, in bytes. */
+    bool non_blank_found = FALSE;
 
     assert(line != NULL);
 
@@ -1293,13 +1354,15 @@
 		|| (newln && *line == '\n')
 #endif
 		) {
+	    if(non_blank_found)
 	    blank_loc = cur_loc;
 
 #ifndef DISABLE_HELP
 	    if (newln && *line == '\n')
 		break;
 #endif
-	}
+	} else
+    non_blank_found = TRUE;
 
 	line += char_len;
 	cur_loc += char_len;
@@ -1361,35 +1424,36 @@
 }
 #endif /* !DISABLE_HELP || !DISABLE_WRAPJUSTIFY */
 
-#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
+#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY) || !defined(DISABLE_WRAPPING) \
|| !defined(DISABLE_WRAPJUSTIFY)   /* The "indentation" of a line is the whitespace \
                between the quote part
  * and the non-whitespace of the line. */
 size_t indent_length(const char *line)
 {
     size_t len = 0;
-    char *blank_mb;
     int blank_mb_len;
 
     assert(line != NULL);
 
-    blank_mb = charalloc(mb_cur_max());
-
     while (*line != '\0') {
-	blank_mb_len = parse_mbchar(line, blank_mb, NULL);
+	blank_mb_len = parse_mbchar(line, NULL, NULL);
 
-	if (!is_blank_mbchar(blank_mb))
+	if (!is_blank_mbchar(line))
 	    break;
 
 	line += blank_mb_len;
 	len += blank_mb_len;
     }
 
-    free(blank_mb);
-
     return len;
 }
-#endif /* !NANO_TINY || !DISABLE_JUSTIFY */
 
+/* Test if the line contains only blank chars */
+inline bool is_empty(filestruct *line)
+{
+    return indent_length(line->data) == strlen(line->data);
+	    }
+#endif /* !NANO_TINY || !DISABLE_JUSTIFY || !DISABLE_WRAPPING || \
!DISABLE_WRAPJUSTIFY */ +
 #ifndef DISABLE_JUSTIFY
 /* justify_format() replaces blanks with spaces and multiple spaces by 1
  * (except it maintains up to 2 after a character in punct optionally


["wrap.justify.5049.patch" (text/x-patch)]

Index: src/cut.c
===================================================================
--- src/cut.c	(revision 5049)
+++ src/cut.c	(working copy)
@@ -275,8 +275,10 @@
 }
 #endif /* !NANO_TINY */
 
+
+
 /* Copy text from the cutbuffer into the current filestruct. */
-void do_uncut_text(void)
+void paste_text(void)
 {
     assert(openfile->current != NULL && openfile->current->data != NULL);
 
@@ -314,3 +316,40 @@
     dump_filestruct_reverse();
 #endif
 }
+
+/* Copy text from the cutbuffer into the current filestruct
+ * If needed, wrap the pasted text */
+void do_uncut_text(void)
+{
+    /* If the cutbuffer is empty, get out. */
+    if (cutbuffer == NULL)
+	return;
+    
+#ifndef DISABLE_WRAPPING
+    ssize_t startline = openfile->current->lineno;
+#endif
+    
+    paste_text();   
+
+#ifndef DISABLE_WRAPPING
+    if (!ISSET(NO_WRAP)){
+
+#ifndef NANO_TINY
+        add_undo(SPLIT_BEGIN);
+#endif
+
+        if(xplustabs() == 0){
+        openfile->current = openfile->current->prev;
+        join_currentline(NULL);
+        }
+        
+        do_wrap( fsfromline(startline), openfile->current->lineno, 0, FALSE);
+ 
+        openfile->placewewant = xplustabs();
+       
+#ifndef NANO_TINY
+        add_undo(SPLIT_END);
+#endif
+    }
+#endif    
+}
Index: src/nano.c
===================================================================
--- src/nano.c	(revision 5049)
+++ src/nano.c	(working copy)
@@ -1657,12 +1657,6 @@
 	 * empty.  Note that it should be empty if we're in view
 	 * mode. */
 	if (have_shortcut || get_key_buffer_len() == 0) {
-#ifndef DISABLE_WRAPPING
-	    /* If we got a shortcut or toggle, and it's not the shortcut
-	     * for verbatim input, turn off prepending of wrapped text. */
-	    if (have_shortcut && s->scfunc != do_verbatim_input)
-		wrap_reset();
-#endif
 
 	    if (kbinput != NULL) {
 		/* Display all the characters in the input buffer at
@@ -2004,7 +1998,7 @@
 		output[i] = '\n';
 	    /* Newline to Enter, if needed. */
 	    else if (output[i] == '\n') {
-		do_enter(FALSE);
+		do_enter_void();
 		i++;
 		continue;
 	    }
@@ -2062,8 +2056,7 @@
 #ifndef DISABLE_WRAPPING
 	/* If we're wrapping text, we need to call edit_refresh(). */
 	if (!ISSET(NO_WRAP))
-	    if (do_wrap(openfile->current))
-		edit_refresh_needed = TRUE;
+	    do_wrap_void();
 #endif
 
 #ifndef DISABLE_COLOR
Index: src/nano.h
===================================================================
--- src/nano.h	(revision 5049)
+++ src/nano.h	(working copy)
@@ -191,6 +191,9 @@
 #ifndef DISABLE_WRAPPING
     SPLIT_BEGIN, SPLIT_END,
 #endif
+#ifndef DISABLE_JUSTIFY
+    JUSTIFY_BEGIN, JUSTIFY_END,
+#endif
     JOIN, PASTE, INSERT, ENTER, OTHER
 } undo_type;
 
Index: src/proto.h
===================================================================
--- src/proto.h	(revision 5049)
+++ src/proto.h	(working copy)
@@ -270,6 +270,7 @@
 void do_cut_till_eof(void);
 #endif
 void do_uncut_text(void);
+void paste_text(void);
 
 /* All functions in files.c. */
 void make_new_buffer(void);
@@ -643,15 +644,17 @@
 void do_undo(void);
 void do_redo(void);
 #endif
-void do_enter(bool undoing);
+size_t do_enter(bool undoing, bool indent_newline, ssize_t const indent_len);
 void do_enter_void(void);
+void add_break(bool undoing, ssize_t const indent_len);
 #ifndef NANO_TINY
 RETSIGTYPE cancel_command(int signal);
 bool execute_command(const char *command);
 #endif
 #ifndef DISABLE_WRAPPING
-void wrap_reset(void);
-bool do_wrap(filestruct *line);
+void do_wrap_void(void);
+void do_wrap(filestruct *line, ssize_t until_lineno, const size_t quote_len, bool \
justify_paragraph); +void join_currentline(size_t *old_x);
 #endif
 #if !defined(DISABLE_HELP) || !defined(DISABLE_WRAPJUSTIFY)
 ssize_t break_line(const char *line, ssize_t goal
@@ -662,9 +665,9 @@
 #endif
 #if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
 size_t indent_length(const char *line);
+bool is_empty(filestruct *line);
 #endif
 #ifndef DISABLE_JUSTIFY
-void justify_format(filestruct *paragraph, size_t skip);
 size_t quote_length(const char *line);
 bool quotes_match(const char *a_line, size_t a_quote, const char
 	*b_line);
@@ -672,8 +675,7 @@
 	*b_line, size_t b_indent);
 bool begpar(const filestruct *const foo);
 bool inpar(const filestruct *const foo);
-void backup_lines(filestruct *first_line, size_t par_len);
-bool find_paragraph(size_t *const quote, size_t *const par);
+bool find_paragraph(size_t *const quote, filestruct **const last_par_line);
 void do_justify(bool full_justify);
 void do_justify_void(void);
 void do_full_justify(void);
Index: src/text.c
===================================================================
--- src/text.c	(revision 5049)
+++ src/text.c	(working copy)
@@ -36,14 +36,6 @@
 	/* The PID of the forked process in execute_command(), for use
 	 * with the cancel_command() signal handler. */
 #endif
-#ifndef DISABLE_WRAPPING
-static bool prepend_wrap = FALSE;
-	/* Should we prepend wrapped text to the next line? */
-#endif
-#ifndef DISABLE_JUSTIFY
-static filestruct *jusbottom = NULL;
-	/* Pointer to the end of the justify buffer. */
-#endif
 
 #ifndef NANO_TINY
 /* Toggle the mark. */
@@ -465,6 +457,19 @@
 	f->data = data;
 	goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_END:
+	undidmsg = _("text justify");
+	goto_line_posx(u->lineno, u->begin);
+	openfile->current_undo = openfile->current_undo->next;
+	openfile->last_action = OTHER;
+	while (openfile->current_undo->type != JUSTIFY_BEGIN)
+	    do_undo();
+	u = openfile->current_undo;
+	f = openfile->current;
+	goto_line_posx(u->mark_begin_lineno, u->mark_begin_x);
+    break;
+#endif   
 #ifndef DISABLE_WRAPPING
     case SPLIT_END:
 	undidmsg = _("line wrap");
@@ -607,8 +612,20 @@
     case ENTER:
 	redidmsg = _("line break");
 	goto_line_posx(u->lineno, u->begin);
-	do_enter(TRUE);
+	add_break(TRUE, u->mark_begin_x);
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_BEGIN:
+	redidmsg = _("text justify");
+	goto_line_posx(u->lineno, u->begin);
+	openfile->current_undo = u;
+	openfile->last_action = OTHER;
+	while (openfile->current_undo->type != JUSTIFY_END)
+	    do_redo();
+	u = openfile->current_undo;
+	goto_line_posx(u->lineno, u->begin);
+    break;
+#endif /*DISABLE_JUSTIFY*/
 #ifndef DISABLE_WRAPPING
     case SPLIT_BEGIN:
 	redidmsg = _("line wrap");
@@ -672,7 +689,7 @@
 #endif /* !NANO_TINY */
 
 /* Someone hits Enter *gasp!* */
-void do_enter(bool undoing)
+size_t do_enter(bool undoing, bool indent_newline, ssize_t const indent_len)
 {
     filestruct *newnode = make_new_node(openfile->current);
     size_t extra = 0;
@@ -684,11 +701,11 @@
 	add_undo(ENTER);
 
     /* Do auto-indenting, like the neolithic Turbo Pascal editor. */
-    if (ISSET(AUTOINDENT)) {
+    if (indent_newline) {
 	/* If we are breaking the line in the indentation, the new
 	 * indentation should have only current_x characters, and
 	 * current_x should not change. */
-	extra = indent_length(openfile->current->data);
+	extra = (indent_len == -1)? indent_length(openfile->current->data) : indent_len;
 	if (extra > openfile->current_x)
 	    extra = openfile->current_x;
     }
@@ -698,7 +715,7 @@
     strcpy(&newnode->data[extra], openfile->current->data +
 	openfile->current_x);
 #ifndef NANO_TINY
-    if (ISSET(AUTOINDENT)) {
+    if (indent_newline) {
 	strncpy(newnode->data, openfile->current->data, extra);
 	openfile->totsize += extra;
     }
@@ -733,12 +750,21 @@
 #endif
 
     edit_refresh_needed = TRUE;
+    
+    return indent_newline? extra : indent_len; 
 }
 
+/* add a break to the current line at current_x and 
+    and prepend the new line with current->data[indent_len]  */
+inline void add_break(bool undoing, ssize_t const indent_len)
+{
+    do_enter(undoing, TRUE, indent_len);
+}
+
 /* Need this again... */
-void do_enter_void(void)
+inline void do_enter_void(void)
 {
-    do_enter(FALSE);
+    do_enter(FALSE, ISSET(AUTOINDENT), -1);
 }
 
 #ifndef NANO_TINY
@@ -916,6 +942,11 @@
 	}
 	current_action = u->type = JOIN;
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_BEGIN:
+    case JUSTIFY_END:
+    break;
+#endif
 #ifndef DISABLE_WRAPPING
     case SPLIT_BEGIN:
 	current_action = fs->undotop->type;
@@ -1082,6 +1113,11 @@
     case ENTER:
 	u->mark_begin_x = fs->current_x;
 	break;
+#ifndef DISABLE_JUSTIFY
+    case JUSTIFY_BEGIN:
+    case JUSTIFY_END:
+    break;
+#endif    
 #ifndef DISABLE_WRAPPING
     case SPLIT_BEGIN:
     case SPLIT_END:
@@ -1099,114 +1135,70 @@
 #endif /* !NANO_TINY */
 
 #ifndef DISABLE_WRAPPING
-/* Unset the prepend_wrap flag.  We need to do this as soon as we do
- * something other than type text. */
-void wrap_reset(void)
-{
-    prepend_wrap = FALSE;
-}
 
-/* Try wrapping the given line.  Return TRUE if wrapped, FALSE otherwise. */
-bool do_wrap(filestruct *line)
+/* Return the index where the given line should be broken, or 0 if the
+ * line should not be broken. */
+ssize_t get_wrap_index(filestruct const *const line , ssize_t indent_len)
 {
-    size_t line_len;
-	/* The length of the line we wrap. */
-    ssize_t wrap_loc;
-	/* The index of line->data where we wrap. */
-#ifndef NANO_TINY
-    const char *indent_string = NULL;
-	/* Indentation to prepend to the new line. */
-    size_t indent_len = 0;
-	/* The length of indent_string. */
-#endif
-    const char *after_break;
-	/* The text after the wrap point. */
-    size_t after_break_len;
-	/* The length of after_break. */
-    const char *next_line = NULL;
-	/* The next line, minus indentation. */
-    size_t next_line_len = 0;
-	/* The length of next_line. */
+    if(indent_len < 0)
+    indent_len = 0;
 
-    /* There are three steps.  First, we decide where to wrap.  Then, we
-     * create the new wrap line.  Finally, we clean up. */
+    ssize_t wrap_loc = -1;
+    size_t leading_spaces_len = 0;
+    char const *buf = line->data + indent_len;
+    size_t line_len = strlen(line->data);
 
-    /* Step 1, finding where to wrap.  We are going to add a new line
-     * after a blank character.  In this step, we call break_line() to
-     * get the location of the last blank we can break the line at, and
-     * set wrap_loc to the location of the character after it, so that
-     * the blank is preserved at the end of the line.
-     *
-     * If there is no legal wrap point, or we reach the last character
-     * of the line while trying to find one, we should return without
-     * wrapping.  Note that if autoindent is turned on, we don't break
-     * at the end of it! */
-    assert(line != NULL && line->data != NULL);
+    assert(line_len > indent_len);    
 
-    /* Save the length of the line. */
-    line_len = strlen(line->data);
-
-    /* Find the last blank where we can break the line. */
-    wrap_loc = break_line(line->data, fill
+    /* Find the last blank where we can break the line. 
+     * but do not consider leading spaces as a location */
+    while( *buf != '\0' && (wrap_loc = break_line(buf, fill - (indent_len + \
leading_spaces_len)  #ifndef DISABLE_HELP
 	, FALSE
 #endif
-	);
+	)) == 0 ){
+    leading_spaces_len += parse_mbchar(buf, NULL, NULL);
+    buf = line->data + indent_len + leading_spaces_len;
+    }
 
-    /* If we couldn't break the line, or we've reached the end of it, we
-     * don't wrap. */
-    if (wrap_loc == -1 || line->data[wrap_loc] == '\0')
-	return FALSE;
+    /* , we don't wrap. */
+    if (wrap_loc == -1)
+	return 0;
 
+    wrap_loc += (indent_len + leading_spaces_len);
+
+    if (wrap_loc >= line_len){
+        size_t wrap_column = strnlenpt(line->data, wrap_loc);
+        if( wrap_column <= fill)
+        return 0;
+    }
+
     /* Otherwise, move forward to the character just after the blank. */
     wrap_loc += move_mbright(line->data + wrap_loc, 0);
 
-    /* If we've reached the end of the line, we don't wrap. */
-    if (line->data[wrap_loc] == '\0')
-	return FALSE;
+    /* After the move, check again.  If we've reached the end of the line,
+     * we don't wrap. */
+    if (wrap_loc >= line_len)
+	return line_len;
 
-#ifndef NANO_TINY
-    /* If autoindent is turned on, and we're on the character just after
-     * the indentation, we don't wrap. */
-    if (ISSET(AUTOINDENT)) {
-	/* Get the indentation of this line. */
-	indent_string = line->data;
-	indent_len = indent_length(indent_string);
-
-	if (wrap_loc == indent_len)
-	    return FALSE;
+    return wrap_loc;
     }
 
-    add_undo(SPLIT_BEGIN);
-#endif
+/*  join line with line->next  
+    old_x represents the x_location of line->next
+    adjusted for the new location that results from 
+    the join with line */
+void join_currentline(size_t *old_x){
+    filestruct *line = openfile->current;
+    if(line == openfile->filebot) return;
 
-    size_t old_x = openfile->current_x;
-    filestruct * oldLine = openfile->current;
-    openfile->current = line;
+    size_t line_len = strlen(line->data);
+    const char *end = line->data + move_mbleft(line->data, line_len); 
 
-    /* Step 2, making the new wrap line.  It will consist of indentation
-     * followed by the text after the wrap point, optionally followed by
-     * a space (if the text after the wrap point doesn't end in a blank)
-     * and the text of the next line, if they can fit without wrapping,
-     * the next line exists, and the prepend_wrap flag is set. */
-
-    /* after_break is the text that will be wrapped to the next line. */
-    after_break = line->data + wrap_loc;
-    after_break_len = line_len - wrap_loc;
-
-    assert(strlen(after_break) == after_break_len);
-
-    /* We prepend the wrapped text to the next line, if the prepend_wrap
-     * flag is set, there is a next line, and prepending would not make
-     * the line too long. */
-    if (prepend_wrap && line != openfile->filebot) {
-	const char *end = after_break + move_mbleft(after_break,
-		after_break_len);
-
 	/* Go to the end of the line. */
 	openfile->current_x = line_len;
 
-	/* If after_break doesn't end in a blank, make sure it ends in a
+	/* If the line doesn't end in a blank, make sure it ends in a
 	 * space. */
 	if (!is_blank_mbchar(end)) {
 #ifndef NANO_TINY
@@ -1216,8 +1208,7 @@
 	    line->data = charealloc(line->data, line_len + 1);
 	    line->data[line_len - 1] = ' ';
 	    line->data[line_len] = '\0';
-	    after_break = line->data + wrap_loc;
-	    after_break_len++;
+
 	    openfile->totsize++;
 	    openfile->current_x++;
 #ifndef NANO_TINY
@@ -1225,39 +1216,138 @@
 #endif
 	}
 
-	next_line = line->next->data;
-	next_line_len = strlen(next_line);
+    if(old_x != NULL)
+    *old_x += line_len;
 
-	if (after_break_len + next_line_len <= fill) {
 	    /* Delete the LF to join the two lines. */
 	    do_delete();
 	    /* Delete any leading blanks from the joined-on line. */
-	    while (is_blank_mbchar(&line->data[openfile->current_x]))
+    while (is_blank_mbchar(&line->data[openfile->current_x])){
+        if(old_x != NULL)
+        *old_x -= parse_mbchar(&line->data[openfile->current_x], NULL, NULL);
 		do_delete();
+    }
 	    renumber(line);
 	}
+
+        
+ssize_t copy_indent_string(filestruct *line, const size_t quote_len, bool \
cut_indent) +{
+    ssize_t indent_len = quote_len + indent_length(line->data + quote_len);
+     size_t old_x = openfile->current_x;
+    filestruct *oldline = openfile->current;
+   
+    openfile->mark_set = TRUE;
+    openfile->mark_begin =  line;
+    openfile->mark_begin_x = 0;
+    openfile->current = line;
+    openfile->current_x = indent_len;
+
+    if(cut_indent){
+    do_cut_text_void();
+    openfile->current = oldline;
+    } else
+    do_copy_text();
+    
+    openfile->current_x = old_x;
+    
+    return indent_len;
     }
 
+/* Try wrapping the given line.  Return TRUE if wrapped, FALSE otherwise. */
+void do_wrap(filestruct *line, ssize_t until_lineno, const size_t quote_len, bool \
justify_paragraph) +{
+    ssize_t wrap_loc;
+	/* The index of line->data where we wrap. */
+
+    size_t old_x = openfile->current_x;
+    filestruct *oldline = openfile->current;
+    ssize_t indent_len = -1;
+
+    bool prepend_wrap = FALSE;
+    bool next_line_inpar = TRUE;
+    
+    assert(line != NULL && line->data != NULL);    
+    
+    while (line->lineno <= until_lineno){
+    
+    openfile->current = line;
+
+    /* Find the last blank where we can break the line. */
+    wrap_loc = get_wrap_index(line, indent_len);
+    
+    if (line->lineno == until_lineno){
+        /* If we couldn't break the line, or we've reached the end of it, we
+         * don't wrap. */
+        if (wrap_loc == 0 || line->data[wrap_loc] == '\0')
+        goto Exit;
+        
+        next_line_inpar = line->next && !begpar(line->next) && \
!is_empty(line->next); +    }
+
+    if (justify_paragraph)
+    indent_len = copy_indent_string(next_line_inpar? line->next : line, quote_len, \
next_line_inpar); +
+    if (next_line_inpar){
+
+        if (oldline == line->next){
+        join_currentline(&old_x);
+        oldline = line;
+        } else
+        join_currentline(NULL);
+            
+        until_lineno--;
+    } else /* update the line we're pointing at, it may be invalid after the call to \
copy_indent_string */ +    line = openfile->current;
+    
+    if (wrap_loc == 0)
+    wrap_loc = get_wrap_index(line, indent_len);
+         
+    while (wrap_loc > indent_len) {
+        prepend_wrap = prepend_wrap || (old_x < wrap_loc && oldline == line);
     /* Go to the wrap location and split the line there. */
     openfile->current_x = wrap_loc;
-    do_enter(FALSE);
+        /* If indent_len is -1 and justify_paragraph is FALSE then indent_len will \
be determined +          in the call to do_enter and stored for subsequent iterations \
of the loop. +         If justify_paragraph is TRUE then indent_len will not be used \
or effected by do_enter */ +        indent_len = do_enter(FALSE, !justify_paragraph, \
indent_len); +        until_lineno++;
 
-    if (old_x < wrap_loc) {
-	openfile->current_x = old_x;
-	openfile->current = oldLine;
-	prepend_wrap = TRUE;
-    } else {
-	openfile->current_x += (old_x - wrap_loc);
-	prepend_wrap = FALSE;
+        /* paste the cutbuffer -- it contains the indent string */
+        if (justify_paragraph)
+        paste_text();
+        
+        if (!prepend_wrap && oldline == line){
+            old_x = openfile->current_x + old_x - wrap_loc;
+            oldline = openfile->current;
     }
 
+        line = openfile->current;
+        assert(line != NULL && line->data != NULL);
+        /* Find the last blank where we can break the line. */
+        wrap_loc = get_wrap_index(line, indent_len);
+    }
+    }
+
+Exit:
+	openfile->current = oldline;
+    openfile->current_x = old_x;
     openfile->placewewant = xplustabs();
+}
 
+void do_wrap_void(void)
+{
 #ifndef NANO_TINY
+    add_undo(SPLIT_BEGIN);
+#endif    
+
+    do_wrap(openfile->current, openfile->current->lineno, 0, FALSE);
+
+#ifndef NANO_TINY
     add_undo(SPLIT_END);
 #endif
 
-    return TRUE;
+    edit_refresh();    
 }
 #endif /* !DISABLE_WRAPPING */
 
@@ -1282,6 +1372,7 @@
 	/* Current column position in line. */
     int char_len = 0;
 	/* Length of current character, in bytes. */
+    bool non_blank_found = FALSE;
 
     assert(line != NULL);
 
@@ -1293,13 +1384,15 @@
 		|| (newln && *line == '\n')
 #endif
 		) {
+	    if(non_blank_found)
 	    blank_loc = cur_loc;
 
 #ifndef DISABLE_HELP
 	    if (newln && *line == '\n')
 		break;
 #endif
-	}
+	} else
+    non_blank_found = TRUE;
 
 	line += char_len;
 	cur_loc += char_len;
@@ -1361,190 +1454,37 @@
 }
 #endif /* !DISABLE_HELP || !DISABLE_WRAPJUSTIFY */
 
-#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
+#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY) || !defined(DISABLE_WRAPPING) \
|| !defined(DISABLE_WRAPJUSTIFY)   /* The "indentation" of a line is the whitespace \
                between the quote part
  * and the non-whitespace of the line. */
 size_t indent_length(const char *line)
 {
     size_t len = 0;
-    char *blank_mb;
     int blank_mb_len;
 
     assert(line != NULL);
 
-    blank_mb = charalloc(mb_cur_max());
-
     while (*line != '\0') {
-	blank_mb_len = parse_mbchar(line, blank_mb, NULL);
+	blank_mb_len = parse_mbchar(line, NULL, NULL);
 
-	if (!is_blank_mbchar(blank_mb))
+	if (!is_blank_mbchar(line))
 	    break;
 
 	line += blank_mb_len;
 	len += blank_mb_len;
     }
 
-    free(blank_mb);
-
     return len;
 }
-#endif /* !NANO_TINY || !DISABLE_JUSTIFY */
 
-#ifndef DISABLE_JUSTIFY
-/* justify_format() replaces blanks with spaces and multiple spaces by 1
- * (except it maintains up to 2 after a character in punct optionally
- * followed by a character in brackets, and removes all from the end).
- *
- * justify_format() might make paragraph->data shorter, and change the
- * actual pointer with null_at().
- *
- * justify_format() will not look at the first skip characters of
- * paragraph.  skip should be at most strlen(paragraph->data).  The
- * character at paragraph[skip + 1] must not be blank. */
-void justify_format(filestruct *paragraph, size_t skip)
+/* Test if the line contains only blank chars */
+inline bool is_empty(filestruct *line)
 {
-    char *end, *new_end, *new_paragraph_data;
-    size_t shift = 0;
-#ifndef NANO_TINY
-    size_t mark_shift = 0;
-#endif
-
-    /* These four asserts are assumptions about the input data. */
-    assert(paragraph != NULL);
-    assert(paragraph->data != NULL);
-    assert(skip < strlen(paragraph->data));
-    assert(!is_blank_mbchar(paragraph->data + skip));
-
-    end = paragraph->data + skip;
-    new_paragraph_data = charalloc(strlen(paragraph->data) + 1);
-    strncpy(new_paragraph_data, paragraph->data, skip);
-    new_end = new_paragraph_data + skip;
-
-    while (*end != '\0') {
-	int end_len;
-
-	/* If this character is blank, change it to a space if
-	 * necessary, and skip over all blanks after it. */
-	if (is_blank_mbchar(end)) {
-	    end_len = parse_mbchar(end, NULL, NULL);
-
-	    *new_end = ' ';
-	    new_end++;
-	    end += end_len;
-
-	    while (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		end += end_len;
-		shift += end_len;
-
-#ifndef NANO_TINY
-		/* Keep track of the change in the current line. */
-		if (openfile->mark_set && openfile->mark_begin ==
-			paragraph && openfile->mark_begin_x >= end -
-			paragraph->data)
-		    mark_shift += end_len;
-#endif
+    return indent_length(line->data) == strlen(line->data);
 	    }
-	/* If this character is punctuation optionally followed by a
-	 * bracket and then followed by blanks, change no more than two
-	 * of the blanks to spaces if necessary, and skip over all
-	 * blanks after them. */
-	} else if (mbstrchr(punct, end) != NULL) {
-	    end_len = parse_mbchar(end, NULL, NULL);
+#endif /* !NANO_TINY || !DISABLE_JUSTIFY || !DISABLE_WRAPPING || \
!DISABLE_WRAPJUSTIFY */  
-	    while (end_len > 0) {
-		*new_end = *end;
-		new_end++;
-		end++;
-		end_len--;
-	    }
-
-	    if (*end != '\0' && mbstrchr(brackets, end) != NULL) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		while (end_len > 0) {
-		    *new_end = *end;
-		    new_end++;
-		    end++;
-		    end_len--;
-		}
-	    }
-
-	    if (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		*new_end = ' ';
-		new_end++;
-		end += end_len;
-	    }
-
-	    if (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		*new_end = ' ';
-		new_end++;
-		end += end_len;
-	    }
-
-	    while (*end != '\0' && is_blank_mbchar(end)) {
-		end_len = parse_mbchar(end, NULL, NULL);
-
-		end += end_len;
-		shift += end_len;
-
-#ifndef NANO_TINY
-		/* Keep track of the change in the current line. */
-		if (openfile->mark_set && openfile->mark_begin ==
-			paragraph && openfile->mark_begin_x >= end -
-			paragraph->data)
-		    mark_shift += end_len;
-#endif
-	    }
-	/* If this character is neither blank nor punctuation, leave it
-	 * unchanged. */
-	} else {
-	    end_len = parse_mbchar(end, NULL, NULL);
-
-	    while (end_len > 0) {
-		*new_end = *end;
-		new_end++;
-		end++;
-		end_len--;
-	    }
-	}
-    }
-
-    assert(*end == '\0');
-
-    *new_end = *end;
-
-    /* If there are spaces at the end of the line, remove them. */
-    while (new_end > new_paragraph_data + skip &&
-	*(new_end - 1) == ' ') {
-	new_end--;
-	shift++;
-    }
-
-    if (shift > 0) {
-	openfile->totsize -= shift;
-	null_at(&new_paragraph_data, new_end - new_paragraph_data);
-	free(paragraph->data);
-	paragraph->data = new_paragraph_data;
-
-#ifndef NANO_TINY
-	/* Adjust the mark coordinates to compensate for the change in
-	 * the current line. */
-	if (openfile->mark_set && openfile->mark_begin == paragraph) {
-	    openfile->mark_begin_x -= mark_shift;
-	    if (openfile->mark_begin_x > new_end - new_paragraph_data)
-		openfile->mark_begin_x = new_end - new_paragraph_data;
-	}
-#endif
-    } else
-	free(new_paragraph_data);
-}
-
+#ifndef DISABLE_JUSTIFY
 /* The "quote part" of a line is the largest initial substring matching
  * the quote string.  This function returns the length of the quote part
  * of the given line.
@@ -1671,112 +1611,24 @@
 	quote_len)] != '\0');
 }
 
-/* Move the next par_len lines, starting with first_line, into the
- * justify buffer, leaving copies of those lines in place.  Assume that
- * par_len is greater than zero, and that there are enough lines after
- * first_line. */
-void backup_lines(filestruct *first_line, size_t par_len)
-{
-    filestruct *top = first_line;
-	/* The top of the paragraph we're backing up. */
-    filestruct *bot = first_line;
-	/* The bottom of the paragraph we're backing up. */
-    size_t i;
-	/* Generic loop variable. */
-    size_t current_x_save = openfile->current_x;
-    ssize_t fl_lineno_save = first_line->lineno;
-    ssize_t edittop_lineno_save = openfile->edittop->lineno;
-    ssize_t current_lineno_save = openfile->current->lineno;
-#ifndef NANO_TINY
-    bool old_mark_set = openfile->mark_set;
-    ssize_t mb_lineno_save = 0;
-    size_t mark_begin_x_save = 0;
-
-    if (old_mark_set) {
-	mb_lineno_save = openfile->mark_begin->lineno;
-	mark_begin_x_save = openfile->mark_begin_x;
-    }
-#endif
-
-    /* par_len will be one greater than the number of lines between
-     * current and filebot if filebot is the last line in the
-     * paragraph. */
-    assert(par_len > 0 && openfile->current->lineno + par_len <=
-	openfile->filebot->lineno + 1);
-
-    /* Move bot down par_len lines to the line after the last line of
-     * the paragraph, if there is one. */
-    for (i = par_len; i > 0 && bot != openfile->filebot; i--)
-	bot = bot->next;
-
-    /* Move the paragraph from the current buffer's filestruct to the
-     * justify buffer. */
-    move_to_filestruct(&jusbuffer, &jusbottom, top, 0, bot,
-	(i == 1 && bot == openfile->filebot) ? strlen(bot->data) : 0);
-
-    /* Copy the paragraph back to the current buffer's filestruct from
-     * the justify buffer. */
-    copy_from_filestruct(jusbuffer);
-
-    /* Move upward from the last line of the paragraph to the first
-     * line, putting first_line, edittop, current, and mark_begin at the
-     * same lines in the copied paragraph that they had in the original
-     * paragraph. */
-    if (openfile->current != openfile->fileage) {
-	top = openfile->current->prev;
-#ifndef NANO_TINY
-	if (old_mark_set &&
-		openfile->current->lineno == mb_lineno_save) {
-	    openfile->mark_begin = openfile->current;
-	    openfile->mark_begin_x = mark_begin_x_save;
-	}
-#endif
-    } else
-	top = openfile->current;
-    for (i = par_len; i > 0 && top != NULL; i--) {
-	if (top->lineno == fl_lineno_save)
-	    first_line = top;
-	if (top->lineno == edittop_lineno_save)
-	    openfile->edittop = top;
-	if (top->lineno == current_lineno_save)
-	    openfile->current = top;
-#ifndef NANO_TINY
-	if (old_mark_set && top->lineno == mb_lineno_save) {
-	    openfile->mark_begin = top;
-	    openfile->mark_begin_x = mark_begin_x_save;
-	}
-#endif
-	top = top->prev;
-    }
-
-    /* Put current_x at the same place in the copied paragraph that it
-     * had in the original paragraph. */
-    openfile->current_x = current_x_save;
-
-    set_modified();
-}
-
 /* Find the beginning of the current paragraph if we're in one, or the
  * beginning of the next paragraph if we're not.  Afterwards, save the
- * quote length and paragraph length in *quote and *par.  Return TRUE if
- * we found a paragraph, and FALSE if there was an error or we didn't
- * find a paragraph.
+ * quote length and the last line of the paragraph in *quote and 
+ * *last_par_line.  Return TRUE if we found a paragraph, and FALSE if 
+ * there was an error or we didn't find a paragraph.
  *
  * See the comment at begpar() for more about when a line is the
  * beginning of a paragraph. */
-bool find_paragraph(size_t *const quote, size_t *const par)
+bool find_paragraph(size_t *const quote, filestruct **const last_par_line)
 {
-    size_t quote_len;
-	/* Length of the initial quotation of the paragraph we search
-	 * for. */
-    size_t par_len;
-	/* Number of lines in the paragraph we search for. */
     filestruct *current_save;
 	/* The line at the beginning of the paragraph we search for. */
     ssize_t current_y_save;
 	/* The y-coordinate at the beginning of the paragraph we search
 	 * for. */
 
+    assert(quote != NULL && last_par_line != NULL);
+    
 #ifdef HAVE_REGEX_H
     if (quoterc != 0) {
 	statusbar(_("Bad quote string %s: %s"), quotestr, quoteerr);
@@ -1822,27 +1674,21 @@
     /* Now current is the first line of the paragraph.  Set quote_len to
      * the quotation length of that line, and set par_len to the number
      * of lines in this paragraph. */
-    quote_len = quote_length(openfile->current->data);
+    *quote = quote_length(openfile->current->data);
     current_save = openfile->current;
     current_y_save = openfile->current_y;
     do_para_end(FALSE);
-    par_len = openfile->current->lineno - current_save->lineno;
 
     /* If we end up past the beginning of the line, it means that we're
      * at the end of the last line of the file, and the line isn't
      * blank, in which case the last line of the file is part of the
      * paragraph. */
-    if (openfile->current_x > 0)
-	par_len++;
+    *last_par_line = (openfile->current_x > 0)?
+    openfile->current : openfile->current->prev;
+
     openfile->current = current_save;
     openfile->current_y = current_y_save;
 
-    /* Save the values of quote_len and par_len. */
-    assert(quote != NULL && par != NULL);
-
-    *quote = quote_len;
-    *par = par_len;
-
     return TRUE;
 }
 
@@ -1850,32 +1696,16 @@
  * the current paragraph. */
 void do_justify(bool full_justify)
 {
-    filestruct *first_par_line = NULL;
-	/* Will be the first line of the justified paragraph(s), if any.
-	 * For restoring after unjustify. */
-    filestruct *last_par_line = NULL;
-	/* Will be the line after the last line of the justified
-	 * paragraph(s), if any.  Also for restoring after unjustify. */
-    bool filebot_inpar = FALSE;
-	/* Whether the text at filebot is part of the current
+    filestruct *curr_last_par_line = NULL;
+	    /* The last line of the current paragraph. */        
+	size_t quote_len;
+	    /* Length of the initial quotation of the current
 	 * paragraph. */
+    filestruct *line_after_par = NULL;
+	    /* The next line after the end of the current paragraph. */        
 
-    /* We save these variables to be restored if the user
-     * unjustifies. */
-    filestruct *edittop_save = openfile->edittop;
-    filestruct *current_save = openfile->current;
-    size_t current_x_save = openfile->current_x;
-    size_t pww_save = openfile->placewewant;
-    size_t totsize_save = openfile->totsize;
-#ifndef NANO_TINY
-    filestruct *mark_begin_save = openfile->mark_begin;
-    size_t mark_begin_x_save = openfile->mark_begin_x;
-#endif
-    bool modified_save = openfile->modified;
+    add_undo(JUSTIFY_BEGIN);
 
-    int kbinput;
-    const sc *s;
-
     /* Move to the beginning of the current line, so that justifying at
      * the end of the last line of the file, if that line isn't blank,
      * will work the first time through. */
@@ -1885,386 +1715,31 @@
     if (full_justify)
 	openfile->current = openfile->fileage;
 
-#ifndef NANO_TINY
-    allow_pending_sigwinch(FALSE);
-#endif
-
     while (TRUE) {
-	size_t i;
-	    /* Generic loop variable. */
-	filestruct *curr_first_par_line;
-	    /* The first line of the current paragraph. */
-	size_t quote_len;
-	    /* Length of the initial quotation of the current
-	     * paragraph. */
-	size_t indent_len;
-	    /* Length of the initial indentation of the current
-	     * paragraph. */
-	size_t par_len;
-	    /* Number of lines in the current paragraph. */
-	ssize_t break_pos;
-	    /* Where we will break lines. */
-	char *indent_string;
-	    /* The first indentation that doesn't match the initial
-	     * indentation of the current paragraph.  This is put at the
-	     * beginning of every line broken off the first justified
-	     * line of the paragraph.  Note that this works because a
-	     * paragraph can only contain two indentations at most: the
-	     * initial one, and a different one starting on a line after
-	     * the first.  See the comment at begpar() for more about
-	     * when a line is part of a paragraph. */
 
-	/* Find the first line of the paragraph to be justified.  That
-	 * is the start of this paragraph if we're in one, or the start
-	 * of the next otherwise.  Save the quote length and paragraph
-	 * length (number of lines).  Don't refresh the screen yet,
-	 * since we'll do that after we justify.
-	 *
-	 * If the search failed, we do one of two things.  If we're
-	 * justifying the whole file, and we've found at least one
-	 * paragraph, it means that we should justify all the way to the
-	 * last line of the file, so set the last line of the text to be
-	 * justified to the last line of the file and break out of the
-	 * loop.  Otherwise, it means that there are no paragraph(s) to
-	 * justify, so refresh the screen and get out. */
-	if (!find_paragraph(&quote_len, &par_len)) {
-	    if (full_justify && first_par_line != NULL) {
-		last_par_line = openfile->filebot;
+	if (!find_paragraph(&quote_len, &curr_last_par_line) ) 
 		break;
-	    } else {
-		edit_refresh_needed = TRUE;
-		return;
-	    }
-	}
+    line_after_par = (curr_last_par_line == openfile->filebot)?
+    curr_last_par_line : curr_last_par_line->next;
+	/* openfile->current will have been set to the first line
+     * of the current paragraph */
+    do_wrap(openfile->current, curr_last_par_line->lineno, quote_len, TRUE);
 
-	/* par_len will be one greater than the number of lines between
-	 * current and filebot if filebot is the last line in the
-	 * paragraph.  Set filebot_inpar to TRUE if this is the case. */
-	filebot_inpar = (openfile->current->lineno + par_len ==
-		openfile->filebot->lineno + 1);
-
-	/* If we haven't already done it, move the original paragraph(s)
-	 * to the justify buffer, splice a copy of the original
-	 * paragraph(s) into the file in the same place, and set
-	 * first_par_line to the first line of the copy. */
-	if (first_par_line == NULL) {
-	    backup_lines(openfile->current, full_justify ?
-		openfile->filebot->lineno - openfile->current->lineno +
-		((openfile->filebot->data[0] != '\0') ? 1 : 0) :
-		par_len);
-	    first_par_line = openfile->current;
-	}
-
-	/* Set curr_first_par_line to the first line of the current
-	 * paragraph. */
-	curr_first_par_line = openfile->current;
-
-	/* Initialize indent_string to a blank string. */
-	indent_string = mallocstrcpy(NULL, "");
-
-	/* Find the first indentation in the paragraph that doesn't
-	 * match the indentation of the first line, and save it in
-	 * indent_string.  If all the indentations are the same, save
-	 * the indentation of the first line in indent_string. */
-	{
-	    const filestruct *indent_line = openfile->current;
-	    bool past_first_line = FALSE;
-
-	    for (i = 0; i < par_len; i++) {
-		indent_len = quote_len +
-			indent_length(indent_line->data + quote_len);
-
-		if (indent_len != strlen(indent_string)) {
-		    indent_string = mallocstrncpy(indent_string,
-			indent_line->data, indent_len + 1);
-		    indent_string[indent_len] = '\0';
-
-		    if (past_first_line)
-			break;
-		}
-
-		if (indent_line == openfile->current)
-		    past_first_line = TRUE;
-
-		indent_line = indent_line->next;
-	    }
-	}
-
-	/* Now tack all the lines of the paragraph together, skipping
-	 * the quoting and indentation on all lines after the first. */
-	for (i = 0; i < par_len - 1; i++) {
-	    filestruct *next_line = openfile->current->next;
-	    size_t line_len = strlen(openfile->current->data);
-	    size_t next_line_len =
-		strlen(openfile->current->next->data);
-
-	    indent_len = quote_len +
-		indent_length(openfile->current->next->data +
-		quote_len);
-
-	    next_line_len -= indent_len;
-	    openfile->totsize -= indent_len;
-
-	    /* We're just about to tack the next line onto this one.  If
-	     * this line isn't empty, make sure it ends in a space. */
-	    if (line_len > 0 &&
-		openfile->current->data[line_len - 1] != ' ') {
-		line_len++;
-		openfile->current->data =
-			charealloc(openfile->current->data,
-			line_len + 1);
-		openfile->current->data[line_len - 1] = ' ';
-		openfile->current->data[line_len] = '\0';
-		openfile->totsize++;
-	    }
-
-	    openfile->current->data =
-		charealloc(openfile->current->data, line_len +
-		next_line_len + 1);
-	    strcat(openfile->current->data, next_line->data +
-		indent_len);
-
-	    /* Don't destroy edittop or filebot! */
-	    if (next_line == openfile->edittop)
-		openfile->edittop = openfile->current;
-	    if (next_line == openfile->filebot)
-		openfile->filebot = openfile->current;
-
-#ifndef NANO_TINY
-	    /* Adjust the mark coordinates to compensate for the change
-	     * in the next line. */
-	    if (openfile->mark_set && openfile->mark_begin ==
-		next_line) {
-		openfile->mark_begin = openfile->current;
-		openfile->mark_begin_x += line_len - indent_len;
-	    }
-#endif
-
-	    unlink_node(next_line);
-	    delete_node(next_line);
-
-	    /* If we've removed the next line, we need to go through
-	     * this line again. */
-	    i--;
-
-	    par_len--;
-	    openfile->totsize--;
-	}
-
-	/* Call justify_format() on the paragraph, which will remove
-	 * excess spaces from it and change all blank characters to
-	 * spaces. */
-	justify_format(openfile->current, quote_len +
-		indent_length(openfile->current->data + quote_len));
-
-	while (par_len > 0 && strlenpt(openfile->current->data) >
-		fill) {
-	    size_t line_len = strlen(openfile->current->data);
-
-	    indent_len = strlen(indent_string);
-
-	    /* If this line is too long, try to wrap it to the next line
-	     * to make it short enough. */
-	    break_pos = break_line(openfile->current->data + indent_len,
-		fill - strnlenpt(openfile->current->data, indent_len)
-#ifndef DISABLE_HELP
-		, FALSE
-#endif
-		);
-
-	    /* We can't break the line, or don't need to, so get out. */
-	    if (break_pos == -1 || break_pos + indent_len == line_len)
-		break;
-
-	    /* Move forward to the character after the indentation and
-	     * just after the space. */
-	    break_pos += indent_len + 1;
-
-	    assert(break_pos <= line_len);
-
-	    /* Make a new line, and copy the text after where we're
-	     * going to break this line to the beginning of the new
-	     * line. */
-	    splice_node(openfile->current,
-		make_new_node(openfile->current),
-		openfile->current->next);
-
-	    /* If this paragraph is non-quoted, and autoindent isn't
-	     * turned on, set the indentation length to zero so that the
-	     * indentation is treated as part of the line. */
-	    if (quote_len == 0
-#ifndef NANO_TINY
-		&& !ISSET(AUTOINDENT)
-#endif
-		)
-		indent_len = 0;
-
-	    /* Copy the text after where we're going to break the
-	     * current line to the next line. */
-	    openfile->current->next->data = charalloc(indent_len + 1 +
-		line_len - break_pos);
-	    strncpy(openfile->current->next->data, indent_string,
-		indent_len);
-	    strcpy(openfile->current->next->data + indent_len,
-		openfile->current->data + break_pos);
-
-	    par_len++;
-	    openfile->totsize += indent_len + 1;
-
-#ifndef NANO_TINY
-	    /* Adjust the mark coordinates to compensate for the change
-	     * in the current line. */
-	    if (openfile->mark_set && openfile->mark_begin ==
-		openfile->current && openfile->mark_begin_x >
-		break_pos) {
-		openfile->mark_begin = openfile->current->next;
-		openfile->mark_begin_x -= break_pos - indent_len;
-	    }
-#endif
-
-	    /* Break the current line. */
-	    null_at(&openfile->current->data, break_pos);
-
-	    /* If the current line is the last line of the file, move
-	     * the last line of the file down to the next line. */
-	    if (openfile->filebot == openfile->current)
-		openfile->filebot = openfile->filebot->next;
-
-	    /* Go to the next line. */
-	    par_len--;
-	    openfile->current_y++;
-	    openfile->current = openfile->current->next;
-	}
-
-	/* We're done breaking lines, so we don't need indent_string
-	 * anymore. */
-	free(indent_string);
-
 	/* Go to the next line, if possible.  If there is no next line,
 	 * move to the end of the current line. */
-	if (openfile->current != openfile->filebot) {
-	    openfile->current_y++;
-	    openfile->current = openfile->current->next;
-	} else
-	    openfile->current_x = strlen(openfile->current->data);
+    openfile->current = line_after_par;
+    openfile->current_x = (openfile->current == openfile->filebot)?
+    strlen(openfile->current->data) : 0;
 
-	/* Renumber the lines of the now-justified current paragraph,
-	 * since both find_paragraph() and edit_refresh() need the line
-	 * numbers to be right. */
-	renumber(curr_first_par_line);
-
-	/* We've just finished justifying the paragraph.  If we're not
-	 * justifying the entire file, break out of the loop.
-	 * Otherwise, continue the loop so that we justify all the
-	 * paragraphs in the file. */
-	if (!full_justify)
+    /* if the filebot is found, break,  the current line will be empty */
+	if (!full_justify || openfile->current == openfile->filebot)
 	    break;
     }
 
-    /* We are now done justifying the paragraph or the file, so clean
-     * up.  current_y and totsize have been maintained above.  If we
-     * actually justified something, set last_par_line to the new end of
-     * the paragraph. */
-    if (first_par_line != NULL)
-	last_par_line = openfile->current;
-
+    add_undo(JUSTIFY_END);
     edit_refresh();
-
-#ifndef NANO_TINY
-    /* We're going to set jump_buf so that we return here after a
-     * SIGWINCH instead of to main().  Indicate this. */
-    jump_buf_main = FALSE;
-
-    /* Return here after a SIGWINCH. */
-    sigsetjmp(jump_buf, 1);
-#endif
-
-    statusbar(_("Can now UnJustify!"));
-
-    /* If constant cursor position display is on, make sure the current
-     * cursor position will be properly displayed on the statusbar. */
-    if (ISSET(CONST_UPDATE))
-	do_cursorpos(TRUE);
-
-    /* Display the shortcut list with UnJustify. */
-    uncutfunc->desc = unjust_tag;
-    currmenu = MMAIN;
-    display_main_list();
-
-    /* Now get a keystroke and see if it's unjustify.  If not, put back
-     * the keystroke and return. */
-    kbinput = do_input(FALSE);
-    s = get_shortcut(&kbinput);
-
-    if (s && s->scfunc == do_uncut_text) {
-	/* Splice the justify buffer back into the file, but only if we
-	 * actually justified something. */
-	if (first_par_line != NULL) {
-	    filestruct *top_save;
-
-	    /* Partition the filestruct so that it contains only the
-	     * text of the justified paragraph. */
-	    filepart = partition_filestruct(first_par_line, 0,
-		last_par_line, filebot_inpar ?
-		strlen(last_par_line->data) : 0);
-
-	    /* Remove the text of the justified paragraph, and
-	     * replace it with the text in the justify buffer. */
-	    free_filestruct(openfile->fileage);
-	    openfile->fileage = jusbuffer;
-	    openfile->filebot = jusbottom;
-
-	    top_save = openfile->fileage;
-
-	    /* Unpartition the filestruct so that it contains all the
-	     * text again.  Note that the justified paragraph has been
-	     * replaced with the unjustified paragraph. */
-	    unpartition_filestruct(&filepart);
-
-	     /* Renumber starting with the beginning line of the old
-	      * partition. */
-	    renumber(top_save);
-
-	    /* Restore the justify we just did (ungrateful user!). */
-	    openfile->edittop = edittop_save;
-	    openfile->current = current_save;
-	    openfile->current_x = current_x_save;
-	    openfile->placewewant = pww_save;
-	    openfile->totsize = totsize_save;
-#ifndef NANO_TINY
-	    if (openfile->mark_set) {
-		openfile->mark_begin = mark_begin_save;
-		openfile->mark_begin_x = mark_begin_x_save;
 	    }
-#endif
-	    openfile->modified = modified_save;
 
-	    /* Clear the justify buffer. */
-	    jusbuffer = NULL;
-
-	    if (!openfile->modified)
-		titlebar(NULL);
-	    edit_refresh_needed = TRUE;
-	}
-    } else {
-	unget_kbinput(kbinput, meta_key, func_key);
-
-	/* Blow away the text in the justify buffer. */
-	free_filestruct(jusbuffer);
-	jusbuffer = NULL;
-    }
-
-    blank_statusbar();
-
-    /* Display the shortcut list with UnCut. */
-    uncutfunc->desc = uncut_tag;
-    display_main_list();
-
-#ifndef NANO_TINY
-    allow_pending_sigwinch(TRUE);
-#endif
-}
-
 /* Justify the current paragraph. */
 void do_justify_void(void)
 {



_______________________________________________
Nano-devel mailing list
Nano-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/nano-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic