return space_loc;
}
-/* This function performs operations on paragraphs: justify, go to
- * beginning, and go to end. */
-int do_para_operation(int operation)
-{
-/* operation == 0 means we're justifying the paragraph, operation == 1
- * means we're moving to the beginning line of the paragraph, and
- * operation == 2 means we're moving to the ending line of the
+/* Search a paragraph. If search_type is 0, search for the beginning of
+ * the current paragraph or, if we're at the end of it, the beginning of
+ * the next paragraph. If search_type is 1, search for the beginning of
+ * the current paragraph or, if we're already there, the beginning of
+ * the previous paragraph. If search_type is 2, search for the end of
+ * the current paragraph or, if we're already there, the end of the next
+ * paragraph. Afterwards, save the quote length, paragraph length, and
+ * indentation length in *quote, *par, and *indent if they aren't NULL,
+ * and refresh the screen if do_refresh is nonzero. Return 0 if we
+ * found a paragraph, or 1 if there was an error or we didn't find a
* paragraph.
*
- * To explain the justifying algorithm, I first need to define some
+ * To explain the searching algorithm, I first need to define some
* phrases about paragraphs and quotation:
* A line of text consists of a "quote part", followed by an
* "indentation part", followed by text. The functions quote_length()
* A contiguous set of lines is a "paragraph" if each line is part of
* a paragraph and only the first line is the beginning of a
* paragraph. */
-
+int do_para_search(int search_type, size_t *quote, size_t *par, size_t
+ *indent, int do_refresh)
+{
size_t quote_len;
/* Length of the initial quotation of the paragraph we
- * justify. */
+ * search. */
size_t par_len;
/* Number of lines in that paragraph. */
- filestruct *first_mod_line = NULL;
- /* Will be the first line of the resulting justified paragraph
- * that differs from the original. For restoring after
- * uncut. */
- filestruct *last_par_line = current;
- /* Will be the last line of the result, also for uncut. */
- filestruct *cutbuffer_save = cutbuffer;
- /* When the paragraph gets modified, all lines from the changed
- * one down are stored in the cut buffer. We back up the
- * original to restore it later. */
- /* We save these global variables to be restored if the user
- * unjustifies. Note we don't need to save totlines. */
- int current_x_save = current_x;
- int current_y_save = current_y;
+ /* We save this global variable to see if we're where we started
+ * when searching for the beginning of the paragraph. */
filestruct *current_save = current;
- int flags_save = flags;
- long totsize_save = totsize;
- filestruct *edittop_save = edittop;
- filestruct *editbot_save = editbot;
-#ifndef NANO_SMALL
- filestruct *mark_beginbuf_save = mark_beginbuf;
- int mark_beginx_save = mark_beginx;
-#endif
size_t indent_len; /* Generic indentation length. */
filestruct *line; /* Generic line of text. */
- size_t i; /* Generic loop variable. */
- static int no_restart = 0;
- /* Whether we're blocking restarting when searching for the
- * beginning line of the paragraph. */
+ static int do_restart = 1;
+ /* Whether we're restarting when searching for the beginning
+ * line of the paragraph. */
#ifdef HAVE_REGEX_H
- regex_t qreg; /* qreg is the compiled quotation regexp.
- * We no longer care about quotestr. */
+ regex_t qreg; /* qreg is the compiled quotation regexp. We no
+ * longer care about quotestr. */
int rc = regcomp(&qreg, quotestr, REG_EXTENDED);
- if (rc) {
+ if (rc != 0) {
size_t size = regerror(rc, &qreg, NULL, 0);
char *strerror = charalloc(size);
regerror(rc, &qreg, strerror, size);
statusbar(_("Bad quote string %s: %s"), quotestr, strerror);
free(strerror);
- return -1;
+ return 1;
}
#endif
current_x = 0;
- restart_bps:
-/* Here we find the first line of the paragraph to justify. If the
+ restart_para_search:
+/* Here we find the first line of the paragraph to search. If the
* current line is in a paragraph, then we move back to the first line.
- * Otherwise we move down to the first line that is in a paragraph. */
+ * Otherwise we move to the first line that is in a paragraph. */
quote_len = quote_length(IFREG(current->data, &qreg));
indent_len = indent_length(current->data + quote_len);
/* The indentation length of the previous line. */
/* Is this line the beginning of a paragraph, according to
- items 2), 5), or 4) above? If so, stop. */
+ * items 2), 5), or 4) above? If so, stop. */
if (current->prev->data[quote_len + temp_id_len] == '\0' ||
(quote_len == 0 && indent_len > 0
#ifndef NANO_SMALL
current = current->prev;
current_y--;
}
- } else if (operation == 1) {
+ } else if (search_type == 1) {
/* This line is not part of a paragraph. Move up until we get
* to a non "blank" line, and then move down once. */
do {
/* There is no previous paragraph, so nothing to move to. */
if (current->prev == NULL) {
placewewant = 0;
- if (current_y < 0)
- edit_update(current, CENTER);
- else
- edit_refresh();
- return 0;
+ if (do_refresh) {
+ if (current_y < 0)
+ edit_update(current, CENTER);
+ else
+ edit_refresh();
+ }
+#ifdef HAVE_REGEX_H
+ if (!do_restart)
+ regfree(&qreg);
+#endif
+ return 1;
}
current = current->prev;
current_y--;
/* This line is not part of a paragraph. Move down until we get
* to a non "blank" line. */
do {
- /* There is no next paragraph, so nothing to justify. */
+ /* There is no next paragraph, so nothing to move to. */
if (current->next == NULL) {
placewewant = 0;
- edit_refresh();
+ if (do_refresh)
+ edit_refresh();
#ifdef HAVE_REGEX_H
regfree(&qreg);
#endif
- return 0;
+ return 1;
}
current = current->next;
current_y++;
indent_len = indent_length(current->data + quote_len);
} while (current->data[quote_len + indent_len] == '\0');
}
-/* Now current is the first line of the paragraph, and quote_len
- * is the quotation length of that line. */
+
+/* Now current is the first line of the paragraph, and quote_len is the
+ * quotation length of that line. */
/* Next step, compute par_len, the number of lines in this paragraph. */
line = current;
line = line->next;
par_len++;
}
+
+ if (search_type == 1) {
+ /* We're on the same line we started on. Move up until we get
+ * to a non-"blank" line, restart the search from there until we
+ * find a line that's part of a paragraph, and search once more
+ * so that we end up at the beginning of that paragraph. */
+ if (current != fileage && current == current_save && do_restart) {
+ while (current->prev != NULL) {
+ size_t i, j = 0;
+ current = current->prev;
+ current_y--;
+ /* Skip over lines consisting only of spacing
+ * characters, as searching for the end of the paragraph
+ * does. */
+ for (i = 0; current->data[i] != '\0'; i++) {
+ if (isspace(current->data[i]))
+ j++;
+ else {
+ i = 0;
+ j = 1;
+ break;
+ }
+ }
+ if (i != j && strlen(current->data) >=
+ (quote_len + indent_len) &&
+ current->data[quote_len + indent_len] != '\0') {
+ do_restart = 0;
+ break;
+ }
+ }
+ goto restart_para_search;
+ } else
+ do_restart = 1;
+ }
+
#ifdef HAVE_REGEX_H
- /* We no longer need to check quotation, unless we're searching for
- * the beginning of the paragraph. */
- if (operation != 1)
- regfree(&qreg);
-#endif
-/* Now par_len is the number of lines in this paragraph. Should never
- * call quotes_match() or quote_length() again. */
-
- /* If we're searching for the beginning of the paragraph, skip the
- * justification. If we're searching for the end of the paragraph,
- * move down the number of lines in the paragraph and skip the
- * justification. */
- if (operation == 1)
- goto skip_justify;
- else if (operation == 2) {
- while (par_len > 0) {
+ /* We no longer need to check quotation. */
+ regfree(&qreg);
+#endif
+
+/* Now par_len is the number of lines in this paragraph. We should
+ * never call quotes_match() or quote_length() again. */
+
+ /* If we're searching for the end of the paragraph, move down the
+ * number of lines in the paragraph. */
+ if (search_type == 2) {
+ for (; par_len > 0; current_y++, par_len--)
current = current->next;
- current_y++;
- par_len--;
- }
- goto skip_justify;
+ }
+
+ /* Refresh the screen if needed. */
+ if (do_refresh) {
+ if (((search_type == 0 || search_type == 2) && current_y >
+ editwinrows - 1) || (search_type == 1 && current_y < 0))
+ edit_update(current, CENTER);
+ else
+ edit_refresh();
+ }
+
+ /* Save the values of quote_len, par_len, and indent_len if
+ * needed. */
+ if (quote != NULL)
+ *quote = quote_len;
+ if (par != NULL)
+ *par = par_len;
+ if (indent != NULL)
+ *indent = indent_len;
+
+ return 0;
+}
+
+int do_para_begin(void)
+{
+ return do_para_search(1, NULL, NULL, NULL, TRUE);
+}
+
+int do_para_end(void)
+{
+ return do_para_search(2, NULL, NULL, NULL, TRUE);
+}
+#endif
+
+/* Justify a paragraph. */
+int do_justify(void)
+{
+#ifdef DISABLE_JUSTIFY
+ nano_disabled_msg();
+ return 1;
+#else
+ size_t quote_len;
+ /* Length of the initial quotation of the paragraph we
+ * justify. */
+ size_t par_len;
+ /* Number of lines in that paragraph. */
+ filestruct *first_mod_line = NULL;
+ /* Will be the first line of the resulting justified paragraph
+ * that differs from the original. For restoring after
+ * uncut. */
+ filestruct *last_par_line = current;
+ /* Will be the last line of the result, also for uncut. */
+ filestruct *cutbuffer_save = cutbuffer;
+ /* When the paragraph gets modified, all lines from the changed
+ * one down are stored in the cut buffer. We back up the
+ * original to restore it later. */
+
+ /* We save these global variables to be restored if the user
+ * unjustifies. Note we don't need to save totlines. */
+ int current_x_save = current_x;
+ int current_y_save = current_y;
+ filestruct *current_save = current;
+ int flags_save = flags;
+ long totsize_save = totsize;
+ filestruct *edittop_save = edittop;
+ filestruct *editbot_save = editbot;
+#ifndef NANO_SMALL
+ filestruct *mark_beginbuf_save = mark_beginbuf;
+ int mark_beginx_save = mark_beginx;
+#endif
+
+ size_t indent_len; /* Generic indentation length. */
+ size_t i; /* Generic loop variable. */
+
+ /* First, search for the beginning of the current paragraph or, if
+ * we're at the end of it, the beginning of the next paragraph.
+ * Save the quote length, paragraph length, and indentation length
+ * and don't refresh the screen yet (since we'll do that after we
+ * justify). If the search failed, refresh the screen and get
+ * out. */
+ if (do_para_search(0, "e_len, &par_len, &indent_len, FALSE) != 0) {
+ edit_refresh();
+ return 0;
}
/* Next step, we loop through the lines of this paragraph, justifying
#endif
next_line_len = strlen(current->next->data);
if (indent_len + break_pos == next_line_len) {
- line = current->next;
+ filestruct *line = current->next;
/* Don't destroy edittop! */
if (line == edittop)
renumber(first_mod_line);
}
- skip_justify:
- if (operation == 1) {
- /* We're on the same line we started on. Search for the first
- * non-"blank" line before the line we're on (if there is one),
- * continually restart that search from the current position
- * until we find a line that's part of a paragraph, and then
- * search once more from there, so that we end up on the first
- * line of that paragraph. In the process, skip over lines
- * consisting only of spacing characters, as searching for the
- * end of the paragraph does. Then update the screen. */
- if (current != fileage && current == current_save && !no_restart) {
- while (current->prev != NULL) {
- int j, j_space = 0;
- current = current->prev;
- current_y--;
- for (j = 0; j < strlen(current->data); j++) {
- if (isspace(current->data[j]))
- j_space++;
- else {
- j = -1;
- break;
- }
- }
- if (j != j_space && strlen(current->data) >=
- (quote_len + indent_len) &&
- current->data[quote_len + indent_len] != '\0') {
- no_restart = 1;
- break;
- }
- }
- goto restart_bps;
- } else
- no_restart = 0;
-#ifdef HAVE_REGEX_H
- /* We no longer need to check quotation, if we were
- * searching for the beginning of the paragraph. */
- regfree(&qreg);
-#endif
- if (current_y < 0)
- edit_update(current, CENTER);
- else
- edit_refresh();
- return 0;
- } else if (operation == 2) {
- /* We've already moved to the end of the paragraph. Update the
- * screen. */
- if (current_y > editwinrows - 1)
- edit_update(current, CENTER);
- else
- edit_refresh();
- return 0;
- }
-
if (current_y > editwinrows - 1)
edit_update(current, CENTER);
else
display_main_list();
return 0;
-}
#endif /* !DISABLE_JUSTIFY */
-
-int do_justify(void)
-{
-#ifdef DISABLE_JUSTIFY
- nano_disabled_msg();
- return 1;
-#else
- return do_para_operation(0);
-#endif
}
-#ifndef DISABLE_JUSTIFY
-int do_para_begin(void)
-{
- return do_para_operation(1);
-}
-
-int do_para_end(void)
-{
- return do_para_operation(2);
-}
-#endif
-
int do_exit(void)
{
int i;