overhaul the justify code to make it leave the right number of spaces at
the ends of the lines of a paragraph, and also to make it simpler git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2354 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
59fe758a10
commit
e9ac1d7930
|
@ -171,6 +171,10 @@ CVS code -
|
||||||
parse_syntax(), parse_colors(), parse_rcfile(), do_rcfile(),
|
parse_syntax(), parse_colors(), parse_rcfile(), do_rcfile(),
|
||||||
etc. (David Benbennick) DLR: Rename colortoint() to
|
etc. (David Benbennick) DLR: Rename colortoint() to
|
||||||
color_to_int(), and add a few miscellaneous tweaks.
|
color_to_int(), and add a few miscellaneous tweaks.
|
||||||
|
- Overhaul the justify code to make it leave the right number of
|
||||||
|
spaces at the ends of the lines of a paragraph, and also to
|
||||||
|
make it simpler. Changes to justify_format() and
|
||||||
|
do_justify(); removal of breakable(). (DLR)
|
||||||
- Still more steps toward full wide/multibyte character support.
|
- Still more steps toward full wide/multibyte character support.
|
||||||
Make whitespace display mode work with multibyte characters,
|
Make whitespace display mode work with multibyte characters,
|
||||||
and add a few related documentation updates. New function
|
and add a few related documentation updates. New function
|
||||||
|
|
512
src/nano.c
512
src/nano.c
|
@ -2354,8 +2354,8 @@ size_t indent_length(const char *line)
|
||||||
#ifndef DISABLE_JUSTIFY
|
#ifndef DISABLE_JUSTIFY
|
||||||
/* justify_format() replaces tabs with spaces and multiple spaces by 1
|
/* justify_format() replaces tabs with spaces and multiple spaces by 1
|
||||||
* (except it maintains 2 after a non-repeated character in punct
|
* (except it maintains 2 after a non-repeated character in punct
|
||||||
* followed by a character in brackets). Note that the terminating \0
|
* followed by a character in brackets, and removes all at the end of
|
||||||
* counts as a space.
|
* the line).
|
||||||
*
|
*
|
||||||
* justify_format() might make line->data shorter, and change the actual
|
* justify_format() might make line->data shorter, and change the actual
|
||||||
* pointer with null_at().
|
* pointer with null_at().
|
||||||
|
@ -2363,74 +2363,146 @@ size_t indent_length(const char *line)
|
||||||
* justify_format() will not look at the first skip characters of line.
|
* justify_format() will not look at the first skip characters of line.
|
||||||
* skip should be at most strlen(line->data). The character at
|
* skip should be at most strlen(line->data). The character at
|
||||||
* line[skip + 1] must not be whitespace. */
|
* line[skip + 1] must not be whitespace. */
|
||||||
void justify_format(filestruct *line, size_t skip)
|
void justify_format(filestruct *paragraph, size_t skip)
|
||||||
{
|
{
|
||||||
char *back, *front;
|
char *end, *new_end, *new_paragraph_data;
|
||||||
|
size_t shift = 0;
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
size_t mark_shift = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* These four asserts are assumptions about the input data. */
|
/* These four asserts are assumptions about the input data. */
|
||||||
assert(line != NULL);
|
assert(paragraph != NULL);
|
||||||
assert(line->data != NULL);
|
assert(paragraph->data != NULL);
|
||||||
assert(skip < strlen(line->data));
|
assert(skip < strlen(paragraph->data));
|
||||||
assert(!is_blank_char(line->data[skip]));
|
assert(!is_blank_char(paragraph->data[skip]));
|
||||||
|
|
||||||
back = line->data + skip;
|
end = paragraph->data + skip;
|
||||||
for (front = back; ; front++) {
|
new_paragraph_data = charalloc(strlen(paragraph->data) + 1);
|
||||||
bool remove_space = FALSE;
|
charcpy(new_paragraph_data, paragraph->data, skip);
|
||||||
/* Do we want to remove this space? */
|
new_end = new_paragraph_data + skip;
|
||||||
|
|
||||||
if (*front == '\t')
|
while (*end != '\0') {
|
||||||
*front = ' ';
|
/* If this character is blank, make sure that it's a space with
|
||||||
|
* no blanks after it. */
|
||||||
|
if (is_blank_char(*end)) {
|
||||||
|
*new_end = ' ';
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
|
||||||
/* These tests are safe since line->data + skip is not a
|
while (*end != '\0' && is_blank_char(*end)) {
|
||||||
* space. */
|
end++;
|
||||||
if ((*front == '\0' || *front == ' ') && *(front - 1) == ' ') {
|
shift++;
|
||||||
const char *bob = back - 2;
|
#ifndef NANO_SMALL
|
||||||
|
if (mark_beginbuf == paragraph &&
|
||||||
remove_space = TRUE;
|
mark_beginx >= end - paragraph->data)
|
||||||
for (; bob >= line->data + skip; bob--) {
|
mark_shift++;
|
||||||
if (strchr(punct, *bob) != NULL) {
|
#endif
|
||||||
/* If this character is in punct, don't remove the
|
|
||||||
* space unless this character and the character
|
|
||||||
* before it are the same. */
|
|
||||||
remove_space = (bob > line->data + skip &&
|
|
||||||
*bob == *(bob - 1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (strchr(brackets, *bob) == NULL)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
/* If this character is punctuation, there are two ways we can
|
||||||
|
* handle it. */
|
||||||
|
} else if (strchr(punct, *end) != NULL) {
|
||||||
|
*new_end = *end;
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
|
||||||
if (remove_space) {
|
/* If this character is punctuation followed by itself and
|
||||||
/* Now *front is a space we want to remove. We do that by
|
* optionally followed by a bracket, make sure there is no
|
||||||
* simply failing to assign it to *back. */
|
* more than one blank after it, and make sure that the
|
||||||
|
* blank is a space. */
|
||||||
|
if (*end != '\0' && *end == *(end - 1)) {
|
||||||
|
*new_end = *end;
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
|
||||||
|
if (*end != '\0' && strchr(brackets, *end) != NULL) {
|
||||||
|
*new_end = *end;
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*end != '\0' && is_blank_char(*end)) {
|
||||||
|
*new_end = ' ';
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*end != '\0' && is_blank_char(*end)) {
|
||||||
|
end++;
|
||||||
|
shift++;
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
if (mark_beginbuf == line && back - line->data < mark_beginx)
|
if (mark_beginbuf == paragraph &&
|
||||||
mark_beginx--;
|
mark_beginx >= end - paragraph->data)
|
||||||
|
mark_shift++;
|
||||||
#endif
|
#endif
|
||||||
if (*front == '\0')
|
}
|
||||||
*(back - 1) = '\0';
|
/* If this character is punctuation optionally followed by a
|
||||||
|
* bracket and then followed by spaces, make sure there are
|
||||||
|
* no more than two blanks after it, and make sure that the
|
||||||
|
* blanks are spaces. */
|
||||||
|
} else {
|
||||||
|
if (*end != '\0' && strchr(brackets, *end) != NULL) {
|
||||||
|
*new_end = *end;
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*end != '\0' && is_blank_char(*end)) {
|
||||||
|
*new_end = ' ';
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*end != '\0' && is_blank_char(*end)) {
|
||||||
|
*new_end = ' ';
|
||||||
|
new_end++;
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*end != '\0' && is_blank_char(*end)) {
|
||||||
|
end++;
|
||||||
|
shift++;
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
if (mark_beginbuf == paragraph &&
|
||||||
|
mark_beginx >= end - paragraph->data)
|
||||||
|
mark_shift++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*back = *front;
|
*new_end = *end;
|
||||||
back++;
|
new_end++;
|
||||||
|
end++;
|
||||||
}
|
}
|
||||||
if (*front == '\0')
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
back--;
|
assert(*end == '\0');
|
||||||
|
|
||||||
assert(*back == '\0' && *front == '\0');
|
*new_end = *end;
|
||||||
|
|
||||||
|
while (new_end > new_paragraph_data + skip &&
|
||||||
|
*(new_end - 1) == ' ') {
|
||||||
|
new_end--;
|
||||||
|
shift++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift > 0) {
|
||||||
|
totsize -= shift;
|
||||||
|
null_at(&new_paragraph_data, new_end - new_paragraph_data);
|
||||||
|
free(paragraph->data);
|
||||||
|
paragraph->data = new_paragraph_data;
|
||||||
|
|
||||||
/* Now back is the new end of line->data. */
|
|
||||||
if (back != front) {
|
|
||||||
totsize -= front - back;
|
|
||||||
null_at(&line->data, back - line->data);
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
if (mark_beginbuf == line && back - line->data < mark_beginx)
|
/* Adjust the mark coordinates to compensate for the change in
|
||||||
mark_beginx = back - line->data;
|
* the current line. */
|
||||||
|
if (mark_beginbuf == paragraph) {
|
||||||
|
mark_beginx -= mark_shift;
|
||||||
|
if (mark_beginx > new_end - new_paragraph_data)
|
||||||
|
mark_beginx = new_end - new_paragraph_data;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
} else
|
||||||
|
free(new_paragraph_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The "quote part" of a line is the largest initial substring matching
|
/* The "quote part" of a line is the largest initial substring matching
|
||||||
|
@ -2668,25 +2740,6 @@ filestruct *backup_lines(filestruct *first_line, size_t par_len, size_t
|
||||||
return first_line;
|
return first_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is it possible to break line at or before goal? */
|
|
||||||
bool breakable(const char *line, ssize_t goal)
|
|
||||||
{
|
|
||||||
while (*line != '\0' && goal >= 0) {
|
|
||||||
size_t pos = 0;
|
|
||||||
|
|
||||||
if (is_blank_char(*line))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
line += parse_mbchar(line, NULL, NULL, &pos);
|
|
||||||
|
|
||||||
goal -= pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If goal is not negative, the whole line (one word) was short
|
|
||||||
* enough. */
|
|
||||||
return (goal >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We are trying to break a chunk off line. We find the last space such
|
/* We are trying to break a chunk off line. We find the last space such
|
||||||
* that the display length to there is at most goal + 1. If there is no
|
* that the display length to there is at most goal + 1. If there is no
|
||||||
* such space, and force is TRUE, then we find the first space. Anyway,
|
* such space, and force is TRUE, then we find the first space. Anyway,
|
||||||
|
@ -2871,10 +2924,6 @@ void do_justify(bool full_justify)
|
||||||
filestruct *last_par_line;
|
filestruct *last_par_line;
|
||||||
/* Will be the line containing the newline after the last line
|
/* Will be the line containing the newline after the last line
|
||||||
* of the result. Also for restoring after unjustify. */
|
* of the result. Also for restoring after unjustify. */
|
||||||
bool allow_respacing;
|
|
||||||
/* Whether we should change the spacing at the end of a line
|
|
||||||
* after justifying it. This should be TRUE whenever we move
|
|
||||||
* to the next line after justifying the current line. */
|
|
||||||
|
|
||||||
/* We save these global variables to be restored if the user
|
/* We save these global variables to be restored if the user
|
||||||
* unjustifies. Note that we don't need to save totlines. */
|
* unjustifies. Note that we don't need to save totlines. */
|
||||||
|
@ -2897,11 +2946,18 @@ void do_justify(bool full_justify)
|
||||||
last_par_line = current;
|
last_par_line = current;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
size_t i;
|
||||||
|
/* Generic loop variable. */
|
||||||
size_t quote_len;
|
size_t quote_len;
|
||||||
/* Length of the initial quotation of the paragraph we
|
/* Length of the initial quotation of the paragraph we
|
||||||
* justify. */
|
* justify. */
|
||||||
|
size_t indent_len;
|
||||||
|
/* Length of the initial indentation of the paragraph we
|
||||||
|
* justify. */
|
||||||
size_t par_len;
|
size_t par_len;
|
||||||
/* Number of lines in that paragraph. */
|
/* Number of lines in the paragraph we justify. */
|
||||||
|
ssize_t break_pos;
|
||||||
|
/* Where we will break lines. */
|
||||||
|
|
||||||
/* Find the first line of the paragraph to be justified. That
|
/* 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
|
* is the start of this paragraph if we're in one, or the start
|
||||||
|
@ -2923,213 +2979,143 @@ void do_justify(bool full_justify)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next step, we loop through the lines of this paragraph,
|
/* If we haven't already done it, copy the original paragraph(s)
|
||||||
* justifying each one individually. */
|
* to the justify buffer. */
|
||||||
for (; par_len > 0; current_y++, par_len--) {
|
if (first_par_line == NULL)
|
||||||
size_t indent_len;
|
first_par_line = backup_lines(current, full_justify ?
|
||||||
/* Generic indentation length. */
|
filebot->lineno - current->lineno : par_len, quote_len);
|
||||||
size_t line_len;
|
|
||||||
size_t display_len;
|
|
||||||
/* The width of current in screen columns. */
|
|
||||||
ssize_t break_pos;
|
|
||||||
/* Where we will break the line. */
|
|
||||||
|
|
||||||
/* We'll be moving to the next line after justifying the
|
/* Next step, we tack all the lines of the paragraph together,
|
||||||
* current line in almost all cases, so allow changing the
|
* skipping the quoting and indentation on all lines after the
|
||||||
* spacing at the ends of justified lines by default. */
|
* first. */
|
||||||
allow_respacing = TRUE;
|
for (i = 0; i < par_len - 1; i++) {
|
||||||
|
filestruct *next_line = current->next;
|
||||||
|
size_t line_len = strlen(current->data);
|
||||||
|
size_t next_line_len = strlen(current->next->data);
|
||||||
|
|
||||||
|
indent_len = quote_len + indent_length(current->next->data +
|
||||||
|
quote_len);
|
||||||
|
next_line_len -= indent_len;
|
||||||
|
totsize -= indent_len;
|
||||||
|
|
||||||
|
if (line_len > 0 && current->data[line_len - 1] != ' ') {
|
||||||
|
line_len++;
|
||||||
|
current->data = charealloc(current->data, line_len + 1);
|
||||||
|
current->data[line_len - 1] = ' ';
|
||||||
|
current->data[line_len] = '\0';
|
||||||
|
totsize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
current->data = charealloc(current->data, line_len +
|
||||||
|
next_line_len + 1);
|
||||||
|
strcat(current->data, next_line->data + indent_len);
|
||||||
|
|
||||||
|
/* Don't destroy edittop! */
|
||||||
|
if (edittop == next_line)
|
||||||
|
edittop = current;
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
/* Adjust the mark coordinates to compensate for the change
|
||||||
|
* in the next line. */
|
||||||
|
if (mark_beginbuf == next_line) {
|
||||||
|
mark_beginbuf = current;
|
||||||
|
mark_beginx += line_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--;
|
||||||
|
totlines--;
|
||||||
|
totsize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we call justify_format() on the paragraph, which will
|
||||||
|
* remove excess spaces from it and change tabs to spaces. */
|
||||||
|
justify_format(current, quote_len +
|
||||||
|
indent_length(current->data + quote_len));
|
||||||
|
|
||||||
|
while (par_len > 0 && strlenpt(current->data) > fill) {
|
||||||
|
size_t line_len = strlen(current->data);
|
||||||
|
|
||||||
indent_len = quote_len + indent_length(current->data +
|
indent_len = quote_len + indent_length(current->data +
|
||||||
quote_len);
|
quote_len);
|
||||||
|
|
||||||
/* If we haven't already done it, copy the original
|
/* If this line is too long, try to wrap it to the next line
|
||||||
* paragraph to the justify buffer. */
|
* to make it short enough. */
|
||||||
if (first_par_line == NULL)
|
break_pos = break_line(current->data + indent_len,
|
||||||
first_par_line = backup_lines(current, full_justify ?
|
fill - strnlenpt(current->data, indent_len), TRUE);
|
||||||
filebot->lineno - current->lineno : par_len,
|
|
||||||
quote_len);
|
|
||||||
|
|
||||||
/* Now we call justify_format() on the current line of the
|
/* We can't break the line, or don't need to, so get out. */
|
||||||
* paragraph, which will remove excess spaces from it and
|
if (break_pos == -1 || break_pos + indent_len == line_len)
|
||||||
* change tabs to spaces. */
|
break;
|
||||||
justify_format(current, quote_len +
|
|
||||||
indent_length(current->data + quote_len));
|
|
||||||
|
|
||||||
line_len = strlen(current->data);
|
break_pos += indent_len;
|
||||||
display_len = strlenpt(current->data);
|
|
||||||
|
|
||||||
if (display_len > fill) {
|
assert(break_pos < line_len);
|
||||||
/* The line is too long. Try to wrap it to the next. */
|
|
||||||
break_pos = break_line(current->data + indent_len,
|
|
||||||
fill - strnlenpt(current->data, indent_len),
|
|
||||||
TRUE);
|
|
||||||
if (break_pos == -1 ||
|
|
||||||
break_pos + indent_len == line_len)
|
|
||||||
/* We can't break the line, or don't need to, so
|
|
||||||
* just go on to the next. */
|
|
||||||
goto continue_loc;
|
|
||||||
break_pos += indent_len;
|
|
||||||
|
|
||||||
assert(break_pos < line_len);
|
/* Make a new line and copy the text after where we broke
|
||||||
|
* this line to the beginning of the new line. */
|
||||||
|
splice_node(current, make_new_node(current), current->next);
|
||||||
|
|
||||||
if (par_len == 1) {
|
/* If this paragraph is non-quoted, and autoindent is turned
|
||||||
/* There is no next line in this paragraph. We make
|
* on, set the indentation length to zero so that
|
||||||
* a new line and copy text after break_pos into
|
* indentation is treated as part of the line. */
|
||||||
* it. */
|
if (quote_len == 0
|
||||||
splice_node(current, make_new_node(current),
|
|
||||||
current->next);
|
|
||||||
/* In a non-quoted paragraph, we copy the indent
|
|
||||||
* only if AUTOINDENT is turned on. */
|
|
||||||
if (quote_len == 0
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
&& !ISSET(AUTOINDENT)
|
&& !ISSET(AUTOINDENT)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
indent_len = 0;
|
indent_len = 0;
|
||||||
current->next->data = charalloc(indent_len +
|
|
||||||
line_len - break_pos);
|
|
||||||
strncpy(current->next->data, current->data,
|
|
||||||
indent_len);
|
|
||||||
strcpy(current->next->data + indent_len,
|
|
||||||
current->data + break_pos + 1);
|
|
||||||
|
|
||||||
assert(strlen(current->next->data) ==
|
current->next->data = charalloc(indent_len + line_len -
|
||||||
indent_len + line_len - break_pos - 1);
|
break_pos);
|
||||||
|
charcpy(current->next->data, current->data, indent_len);
|
||||||
|
strcpy(current->next->data + indent_len, current->data +
|
||||||
|
break_pos + 1);
|
||||||
|
|
||||||
totlines++;
|
assert(strlen(current->next->data) == indent_len + line_len - break_pos - 1);
|
||||||
totsize += indent_len;
|
|
||||||
par_len++;
|
|
||||||
} else {
|
|
||||||
size_t next_line_len = strlen(current->next->data);
|
|
||||||
|
|
||||||
indent_len = quote_len +
|
par_len++;
|
||||||
indent_length(current->next->data + quote_len);
|
totlines++;
|
||||||
current->next->data =
|
totsize += indent_len;
|
||||||
charealloc(current->next->data, next_line_len +
|
|
||||||
line_len - break_pos + 1);
|
|
||||||
|
|
||||||
charmove(current->next->data + indent_len +
|
|
||||||
line_len - break_pos, current->next->data +
|
|
||||||
indent_len, next_line_len - indent_len + 1);
|
|
||||||
strcpy(current->next->data + indent_len,
|
|
||||||
current->data + break_pos + 1);
|
|
||||||
current->next->data[indent_len + line_len -
|
|
||||||
break_pos - 1] = ' ';
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
if (mark_beginbuf == current->next) {
|
/* Adjust the mark coordinates to compensate for the change
|
||||||
if (mark_beginx < indent_len)
|
* in the current line. */
|
||||||
mark_beginx = indent_len;
|
if (mark_beginbuf == current && mark_beginx > break_pos) {
|
||||||
mark_beginx += line_len - break_pos;
|
mark_beginbuf = current->next;
|
||||||
}
|
mark_beginx -= break_pos + 1 - indent_len;
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifndef NANO_SMALL
|
|
||||||
if (mark_beginbuf == current &&
|
|
||||||
mark_beginx > break_pos) {
|
|
||||||
mark_beginbuf = current->next;
|
|
||||||
mark_beginx -= break_pos + 1 - indent_len;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
null_at(¤t->data, break_pos);
|
|
||||||
|
|
||||||
/* Go to the next line. */
|
|
||||||
current = current->next;
|
|
||||||
} else if (display_len < fill && par_len > 1) {
|
|
||||||
size_t next_line_len;
|
|
||||||
|
|
||||||
indent_len = quote_len +
|
|
||||||
indent_length(current->next->data + quote_len);
|
|
||||||
/* If we can't pull a word from the next line up to this
|
|
||||||
* one, just go on. */
|
|
||||||
if (!breakable(current->next->data + indent_len,
|
|
||||||
fill - display_len - 1))
|
|
||||||
goto continue_loc;
|
|
||||||
|
|
||||||
break_pos = break_line(current->next->data + indent_len,
|
|
||||||
fill - display_len - 1, FALSE);
|
|
||||||
|
|
||||||
assert(break_pos != -1);
|
|
||||||
|
|
||||||
current->data = charealloc(current->data,
|
|
||||||
line_len + break_pos + 2);
|
|
||||||
current->data[line_len] = ' ';
|
|
||||||
strncpy(current->data + line_len + 1,
|
|
||||||
current->next->data + indent_len, break_pos);
|
|
||||||
current->data[line_len + break_pos + 1] = '\0';
|
|
||||||
#ifndef NANO_SMALL
|
|
||||||
if (mark_beginbuf == current->next) {
|
|
||||||
if (mark_beginx < indent_len + break_pos) {
|
|
||||||
mark_beginbuf = current;
|
|
||||||
if (mark_beginx <= indent_len)
|
|
||||||
mark_beginx = line_len + 1;
|
|
||||||
else
|
|
||||||
mark_beginx = line_len + 1 + mark_beginx -
|
|
||||||
indent_len;
|
|
||||||
} else
|
|
||||||
mark_beginx -= break_pos + 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
next_line_len = strlen(current->next->data);
|
|
||||||
if (indent_len + break_pos == next_line_len) {
|
|
||||||
filestruct *line = current->next;
|
|
||||||
|
|
||||||
/* Don't destroy edittop! */
|
|
||||||
if (line == edittop)
|
|
||||||
edittop = current;
|
|
||||||
|
|
||||||
unlink_node(line);
|
|
||||||
delete_node(line);
|
|
||||||
totlines--;
|
|
||||||
totsize -= indent_len;
|
|
||||||
current_y--;
|
|
||||||
|
|
||||||
/* Don't go to the next line. Accordingly, don't
|
|
||||||
* allow changing the spacing at the end of the
|
|
||||||
* previous justified line, so that we don't end up
|
|
||||||
* doing it more than once on the same line. */
|
|
||||||
allow_respacing = FALSE;
|
|
||||||
} else {
|
|
||||||
charmove(current->next->data + indent_len,
|
|
||||||
current->next->data + indent_len + break_pos + 1,
|
|
||||||
next_line_len - break_pos - indent_len);
|
|
||||||
null_at(¤t->next->data,
|
|
||||||
next_line_len - break_pos);
|
|
||||||
|
|
||||||
/* Go to the next line. */
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
continue_loc:
|
|
||||||
/* Go to the next line. */
|
|
||||||
current = current->next;
|
|
||||||
|
|
||||||
/* We've moved to the next line after justifying the
|
|
||||||
* current line. If the justified line was not the last
|
|
||||||
* line of the paragraph, add a space to the end of it to
|
|
||||||
* replace the one removed or left out by justify_format().
|
|
||||||
* If it was the last line of the paragraph, and
|
|
||||||
* justify_format() left a space on the end of it, remove
|
|
||||||
* the space. */
|
|
||||||
if (allow_respacing) {
|
|
||||||
size_t prev_line_len = strlen(current->prev->data);
|
|
||||||
|
|
||||||
if (par_len > 1) {
|
|
||||||
current->prev->data =
|
|
||||||
charealloc(current->prev->data,
|
|
||||||
prev_line_len + 2);
|
|
||||||
current->prev->data[prev_line_len] = ' ';
|
|
||||||
current->prev->data[prev_line_len + 1] = '\0';
|
|
||||||
totsize++;
|
|
||||||
} else if (par_len == 1 &&
|
|
||||||
current->prev->data[prev_line_len - 1] == ' ') {
|
|
||||||
current->prev->data =
|
|
||||||
charealloc(current->prev->data, prev_line_len);
|
|
||||||
current->prev->data[prev_line_len - 1] = '\0';
|
|
||||||
totsize--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Break the line. If this isn't the last line of the
|
||||||
|
* paragraph, add a space after where we break it. */
|
||||||
|
null_at(¤t->data, break_pos);
|
||||||
|
if (par_len > 1) {
|
||||||
|
current->data = charealloc(current->data,
|
||||||
|
break_pos + 2);
|
||||||
|
current->data[break_pos] = ' ';
|
||||||
|
current->data[break_pos + 1] = '\0';
|
||||||
|
totsize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go to the next line. */
|
||||||
|
par_len--;
|
||||||
|
current_y++;
|
||||||
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Go to the next line, the line after the last line of the
|
||||||
|
* paragraph. */
|
||||||
|
current_y++;
|
||||||
|
current = current->next;
|
||||||
|
|
||||||
/* We've just justified a paragraph. If we're not justifying the
|
/* We've just justified a paragraph. If we're not justifying the
|
||||||
* entire file, break out of the loop. Otherwise, continue the
|
* entire file, break out of the loop. Otherwise, continue the
|
||||||
* loop so that we justify all the paragraphs in the file. */
|
* loop so that we justify all the paragraphs in the file. */
|
||||||
|
|
|
@ -414,7 +414,7 @@ void do_spell(void);
|
||||||
size_t indent_length(const char *line);
|
size_t indent_length(const char *line);
|
||||||
#endif
|
#endif
|
||||||
#ifndef DISABLE_JUSTIFY
|
#ifndef DISABLE_JUSTIFY
|
||||||
void justify_format(filestruct *line, size_t skip);
|
void justify_format(filestruct *paragraph, size_t skip);
|
||||||
size_t quote_length(const char *line);
|
size_t quote_length(const char *line);
|
||||||
bool quotes_match(const char *a_line, size_t a_quote, const char
|
bool quotes_match(const char *a_line, size_t a_quote, const char
|
||||||
*b_line);
|
*b_line);
|
||||||
|
@ -426,7 +426,6 @@ bool inpar(const char *str);
|
||||||
void do_para_end(void);
|
void do_para_end(void);
|
||||||
filestruct *backup_lines(filestruct *first_line, size_t par_len, size_t
|
filestruct *backup_lines(filestruct *first_line, size_t par_len, size_t
|
||||||
quote_len);
|
quote_len);
|
||||||
bool breakable(const char *line, ssize_t goal);
|
|
||||||
ssize_t break_line(const char *line, ssize_t goal, bool force);
|
ssize_t break_line(const char *line, ssize_t goal, bool force);
|
||||||
bool do_para_search(size_t *const quote, size_t *const par);
|
bool do_para_search(size_t *const quote, size_t *const par);
|
||||||
void do_justify(bool full_justify);
|
void do_justify(bool full_justify);
|
||||||
|
|
Loading…
Reference in New Issue