]> git.wh0rd.org Git - nano.git/commitdiff
add support for Pico's ability to justify the entire file at once ("full
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Thu, 13 May 2004 17:28:03 +0000 (17:28 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Thu, 13 May 2004 17:28:03 +0000 (17:28 +0000)
justify", accessible via ^W^J)

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1731 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
TODO
src/global.c
src/nano.c
src/nano.h
src/proto.h
src/winio.c

index 1353858a20df72fe56b4631137cb7424a2e81d5c..51d2902111eb66fab7e8801c1a4b80bcfd870b4a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,6 +34,10 @@ CVS code -
        - Clarifications to comments explaining exactly what control
          characters and escape sequences are supported. (DLR)
        - Disable "Where Is Next" in tiny mode. (DLR)
+       - Added the ability to justify the entire file at once, which
+         Pico has via ^W^J.  Changes to do_justify(); new functions
+         do_justify_void() and do_full_justify().  Note that this
+         feature is disabled if justification is disabled. (DLR)
 - files.c:
   add_open_file()
        - Rearrange the NANO_SMALL #ifdef so that the code to set the
@@ -111,6 +115,11 @@ CVS code -
          never be negative. (DLR)
        - Add proper support for the keypad values and escape sequences
          generated by the NumLock glitch. (DLR)
+  bottombars()
+       - Don't display any more than MAIN_VISIBLE shortcuts.  Adding
+         justification of the entire file above made the search
+         shortcut list longer than this and hence made the shortcuts in
+         it so short as to be almost incomprehensible. (DLR)
   edit_add()
        - Minor cosmetic reformatting.  Also remove unused int
          searched_later_lines. (DLR)
@@ -153,6 +162,10 @@ CVS code -
          technically also work with automake 1.6c, but that is a CVS
          version as opposed to a stable release version, and automake
          1.7 requires at least autoconf 2.54 in any case. (DLR)
+- TODO:
+       - Added entry for justifying the entire file at once, since Pico
+         can do it, and with "[DONE]" since it's already been
+         implemented. (DLR)
 
 GNU nano 1.3.2 - 2004.03.31
 - General:
diff --git a/TODO b/TODO
index 8f8f51c067e351c676d4a360abb63555bd805680..349ae1d648f1aa8b8145d3aa294f1c3f4d301bf3 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,6 +4,7 @@ TODO file (? means the feature may be implemented, but not definitely)
 For version 1.4:
 - UTF-8 support.
 - Support for paragraph searches. [DONE]
+- Support for justifying the entire file at once. [DONE]
 - Support for filename searches in the file browser.
 - Undo/Redo key?
 - Rebindable keys?
index 3b1a0fa2bec4d96cfd6f7baeaf7f13b7fd6c8372..f064339b01e12d191c909deedd62a9f61da6adee 100644 (file)
@@ -473,7 +473,7 @@ void shortcut_init(int unjustify)
                IFHELP(nano_justify_msg, NANO_NO_KEY),
                NANO_JUSTIFY_FKEY, NANO_NO_KEY, NOVIEW,
 #ifndef NANO_SMALL
-               do_justify
+               do_justify_void
 #else
                nano_disabled_msg
 #endif
@@ -681,6 +681,11 @@ void shortcut_init(int unjustify)
     sc_init_one(&whereis_list, NANO_PARAEND_KEY, _("End of Par"),
                IFHELP(nano_paraend_msg, NANO_NO_KEY), NANO_NO_KEY,
                NANO_NO_KEY, VIEW, do_para_end);
+
+    /* Translators: try to keep this string under 10 characters long */
+    sc_init_one(&whereis_list, NANO_FULLJUSTIFY_KEY, _("FullJstify"),
+               IFHELP(nano_paraend_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_full_justify);
 #endif
 
 #ifndef NANO_SMALL
index 0d7a2ddc55a44416d104930a8ef276cff62390c7..ac9e4b18765b391c7dab6290cff224c473e35df2 100644 (file)
@@ -1922,7 +1922,7 @@ int justify_format(int changes_allowed, filestruct *line, size_t skip)
     back = line->data + skip;
     front = back;
     for (front = back; ; front++) {
-       int remove_space = 0;
+       int remove_space = FALSE;
            /* Do we want to remove this space? */
 
        if (*front == '\t') {
@@ -1934,10 +1934,10 @@ int justify_format(int changes_allowed, filestruct *line, size_t skip)
        if ((*front == '\0' || *front == ' ') && *(front - 1) == ' ') {
            const char *bob = front - 2;
 
-           remove_space = 1;
+           remove_space = TRUE;
            for (bob = back - 2; bob >= line->data + skip; bob--) {
                if (strchr(punct, *bob) != NULL) {
-                   remove_space = 0;
+                   remove_space = FALSE;
                    break;
                }
                if (strchr(brackets, *bob) == NULL)
@@ -2063,7 +2063,7 @@ filestruct *backup_lines(filestruct *first_line, size_t par_len,
        if (alice == mark_beginbuf)
            mark_beginbuf = bob;
 #endif
-       justify_format(1, bob,
+       justify_format(TRUE, bob,
                        quote_len + indent_length(bob->data + quote_len));
 
        assert(alice != NULL && bob != NULL);
@@ -2104,7 +2104,7 @@ int break_line(const char *line, int goal, int force)
        /* Current tentative return value.  Index of the last space we
         * found with short enough display width.  */
     int cur_loc = 0;
-       /* Current index in line */
+       /* Current index in line. */
 
     assert(line != NULL);
     for (; *line != '\0' && goal >= 0; line++, cur_loc++) {
@@ -2400,8 +2400,9 @@ int do_para_end(void)
     return do_para_search(2, NULL, NULL, NULL, TRUE);
 }
 
-/* Justify a paragraph. */
-int do_justify(void)
+/* If full_justify is TRUE, justify the entire file.  Otherwise, justify
+ * the current paragraph. */
+int do_justify(int full_justify)
 {
     size_t quote_len;
        /* Length of the initial quotation of the paragraph we
@@ -2435,184 +2436,217 @@ int do_justify(void)
     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, &quote_len, &par_len, &indent_len, FALSE) != 0) {
-       edit_refresh();
-       return 0;
+    /* If we're justifying the entire file, start at the beginning of
+     * it and move the first line of the text we're justifying to it. */
+    if (full_justify) {
+       current = fileage;
+       last_par_line = fileage;
     }
 
-/* Next step, we loop through the lines of this paragraph, justifying
- * each one individually. */
-    for (; par_len > 0; current_y++, par_len--) {
-       size_t line_len;
-       size_t display_len;
-           /* The width of current in screen columns. */
-       int break_pos;
-           /* Where we will break the line. */
-
-       indent_len = indent_length(current->data + quote_len) +
-                       quote_len; 
-       /* justify_format() removes excess spaces from the line, and
-        * changes tabs to spaces.  The first argument, 0, means don't
-        * change the line, just say whether there are changes to be
-        * made.  If there are, we do backup_lines(), which copies the
-        * original paragraph to the cutbuffer for unjustification, and
-        * then calls justify_format() on the remaining lines. */
-       if (first_mod_line == NULL && justify_format(0, current, indent_len))
-           first_mod_line = backup_lines(current, par_len, quote_len);
-
-       line_len = strlen(current->data);
-       display_len = strlenpt(current->data);
-
-       if (display_len > fill) {
-           /* 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),
-                           1);
-           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);
-           /* If we haven't backed up the paragraph, do it now. */
-           if (first_mod_line == NULL)
-               first_mod_line = backup_lines(current, par_len, quote_len);
-           if (par_len == 1) {
-               /* There is no next line in this paragraph.  We make a
-                * new line and copy text after break_pos into it. */
-               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)
+    while (TRUE) {
+
+       /* 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 and
+        * we're justifying the whole file, move the last line of the
+        * text we're justifying to just before the magicline, which is
+        * where it'll be anyway if we've searched the entire file, and
+        * break out of the loop; otherwise, refresh the screen and get
+        * out. */
+       if (do_para_search(0, &quote_len, &par_len, &indent_len, FALSE) != 0) {
+           if (full_justify) {
+               /* This should be safe in the event of filebot->prev's
+                * being NULL, since only last_par_line->next is used if
+                * we eventually unjustify. */
+               last_par_line = filebot->prev;
+               break;
+           } else {
+               edit_refresh();
+               return 0;
+           }
+       }
+
+       /* Next step, we loop through the lines of this paragraph,
+        * justifying each one individually. */
+       for (; par_len > 0; current_y++, par_len--) {
+           size_t line_len;
+           size_t display_len;
+               /* The width of current in screen columns. */
+           int break_pos;
+               /* Where we will break the line. */
+
+           indent_len = indent_length(current->data + quote_len) +
+               quote_len; 
+
+           /* justify_format() removes excess spaces from the line, and
+            * changes tabs to spaces.  The first argument, 0, means
+            * don't change the line, just say whether there are changes
+            * to be made.  If there are, we do backup_lines(), which
+            * copies the original paragraph to the cutbuffer for
+            * unjustification, and then calls justify_format() on the
+            * remaining lines. */
+           if (first_mod_line == NULL && justify_format(FALSE, current, indent_len))
+               first_mod_line = backup_lines(current, full_justify ?
+                       filebot->lineno - current->lineno : par_len, quote_len);
+
+           line_len = strlen(current->data);
+           display_len = strlenpt(current->data);
+
+           if (display_len > fill) {
+               /* 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);
+               /* If we haven't backed up the paragraph, do it now. */
+               if (first_mod_line == NULL)
+                   first_mod_line = backup_lines(current, full_justify ?
+                       filebot->lineno - current->lineno : par_len, quote_len);
+               if (par_len == 1) {
+                   /* There is no next line in this paragraph.  We make
+                    * a new line and copy text after break_pos into
+                    * it. */
+                   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
-                   if (!ISSET(AUTOINDENT))
-#endif
-                       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,
+                       if (!ISSET(AUTOINDENT))
+#endif
+                           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) ==
+                   assert(strlen(current->next->data) ==
                        indent_len + line_len - break_pos - 1);
-               totlines++;
-               totsize += indent_len;
-               par_len++;
-           } else {
-               size_t next_line_len = strlen(current->next->data);
+                   totlines++;
+                   totsize += indent_len;
+                   par_len++;
+               } else {
+                   size_t next_line_len = strlen(current->next->data);
 
-               indent_len = quote_len +
+                   indent_len = quote_len +
                        indent_length(current->next->data + quote_len);
-               current->next->data = charealloc(current->next->data,
+                   current->next->data = 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,
+                   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,
+                   strcpy(current->next->data + indent_len,
                        current->data + break_pos + 1);
-               current->next->data[indent_len + line_len - break_pos - 1]
+                   current->next->data[indent_len + line_len - break_pos - 1]
                        = ' ';
 #ifndef NANO_SMALL
-               if (mark_beginbuf == current->next) {
-                   if (mark_beginx < indent_len)
-                       mark_beginx = indent_len;
-                   mark_beginx += line_len - break_pos;
-               }
+                   if (mark_beginbuf == current->next) {
+                       if (mark_beginx < indent_len)
+                           mark_beginx = indent_len;
+                       mark_beginx += line_len - break_pos;
+                   }
 #endif
-           }
+               }
 #ifndef NANO_SMALL
-           if (mark_beginbuf == current && mark_beginx > break_pos) {
-               mark_beginbuf = current->next;
-               mark_beginx -= break_pos + 1 - indent_len;
-           }
+               if (mark_beginbuf == current && mark_beginx > break_pos) {
+                   mark_beginbuf = current->next;
+                   mark_beginx -= break_pos + 1 - indent_len;
+               }
 #endif
-           null_at(&current->data, break_pos);
-           current = current->next;
-       } else if (display_len < fill && par_len > 1) {
-           size_t next_line_len;
+               null_at(&current->data, break_pos);
+               current = current->next;
+           } else if (display_len < fill && par_len > 1) {
+               size_t next_line_len;
 
-           indent_len = quote_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;
-
-           /* If we haven't backed up the paragraph, do it now. */
-           if (first_mod_line == NULL)
-               first_mod_line = backup_lines(current, par_len, quote_len);
-
-           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,
+               /* 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;
+
+               /* If we haven't backed up the paragraph, do it now. */
+               if (first_mod_line == NULL)
+                   first_mod_line = backup_lines(current, full_justify ?
+                       filebot->lineno - current->lineno : par_len, quote_len);
+
+               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';
+               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;
-           }
+               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--;
-           } else {
-               charmove(current->next->data + indent_len,
+               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--;
+               } else {
+                   charmove(current->next->data + indent_len,
                        current->next->data + indent_len + break_pos + 1,
                        next_line_len - break_pos - indent_len);
-               null_at(&current->next->data,
-                       next_line_len - break_pos);
-               current = current->next;
-           }
-       } else
+                   null_at(&current->next->data, next_line_len - break_pos);
+                   current = current->next;
+               }
+           } else
   continue_loc:
-           current = current->next;
-    }
+               current = current->next;
+       }
 
-/* We are now done justifying the paragraph.  There are cleanup things
* to do, and we check for unjustify. */
+       /* We are now done justifying the paragraph.  There are cleanup
       * things to do, and we check for unjustify. */
 
-    /* totlines, totsize, and current_y have been maintained above.  We
-     * now set last_par_line to the new end of the paragraph, update
-     * fileage, set current_x.  Also, edit_refresh() needs the line
-     * numbers to be right, so we renumber(). */
-    last_par_line = current->prev;
-    if (first_mod_line != NULL) {
-       if (first_mod_line->prev == NULL)
-           fileage = first_mod_line;
-       renumber(first_mod_line);
-    }
+       /* totlines, totsize, and current_y have been maintained above.
+        * We now set last_par_line to the new end of the paragraph,
+        * update fileage, set current_x.  Also, edit_refresh() needs
+        * the line numbers to be right, so we renumber(). */
+       last_par_line = current->prev;
+       if (first_mod_line != NULL) {
+           if (first_mod_line->prev == NULL)
+               fileage = first_mod_line;
+           renumber(first_mod_line);
+       }
+
+       /* We've just justified a paragraph and renumbered the lines in
+        * it.  If we're not justifying the entire file, break out of
+        * the loop.  Otherwise, continue the loop so that we justify
+        * and renumber the lines in all paragraphs down to the end of
+        * the file. */
+       if (!full_justify)
+           break;
+
+    } /* while (TRUE) */
 
     if (current_y > editwinrows - 1)
        edit_update(current, CENTER);
@@ -2620,7 +2654,7 @@ int do_justify(void)
        edit_refresh();
 
     statusbar(_("Can now UnJustify!"));
-    /* Change the shortcut list to display the unjustify code. */
+    /* Display the shortcut list with UnJustify. */
     shortcut_init(1);
     display_main_list();
     reset_cursor();
@@ -2674,7 +2708,7 @@ int do_justify(void)
            last_par_line->next = NULL;
            free_filestruct(first_mod_line);
 
-           /* Restore global variables from before justify */
+           /* Restore global variables from before the justify. */
            totsize = totsize_save;
            totlines = filebot->lineno;
 #ifndef NANO_SMALL
@@ -2691,12 +2725,22 @@ int do_justify(void)
     }
     cutbuffer = cutbuffer_save;
     blank_statusbar_refresh();
-    /* display shortcut list with UnCut */
+    /* Display the shortcut list with UnCut. */
     shortcut_init(0);
     display_main_list();
 
     return 0;
 }
+
+int do_justify_void(void)
+{
+    return do_justify(FALSE);
+}
+
+int do_full_justify(void)
+{
+    return do_justify(TRUE);
+}
 #endif /* !DISABLE_JUSTIFY */
 
 int do_exit(void)
index 0f1c883edec608436851e8e2284bce28cf9d0780..ffdd6bfd01b000c0c3731f5dc2480a540cb20b36 100644 (file)
@@ -423,6 +423,7 @@ typedef struct historyheadtype {
 #define NANO_PREVWORD_KEY      NANO_ALT_SPACE
 #define NANO_PARABEGIN_KEY     NANO_CONTROL_W
 #define NANO_PARAEND_KEY       NANO_CONTROL_O
+#define NANO_FULLJUSTIFY_KEY   NANO_CONTROL_J
 #define NANO_VERBATIM_KEY      NANO_ALT_V
 
 #ifndef NANO_SMALL
index 895ac48dd2c46b544a5ea45d09b650f7c313845a..93f45c1075d230b72b228f3e214cc83e361c55ec 100644 (file)
@@ -326,7 +326,9 @@ int do_para_search(int search_type, size_t *quote, size_t *par, size_t
        *indent, int do_refresh);
 int do_para_begin(void);
 int do_para_end(void);
-int do_justify(void);
+int do_justify(int justify_all);
+int do_justify_void(void);
+int do_full_justify(void);
 #endif /* !DISABLE_JUSTIFY */
 int do_exit(void);
 void signal_init(void);
index 44a8b9815a4089731887326fb3e2924e877212b2..3283ad3c02e0ca2a2d01ec0ae336a3d29a9f01ed 100644 (file)
@@ -1609,9 +1609,14 @@ void bottombars(const shortcut *s)
     if (s == main_list) {
        slen = MAIN_VISIBLE;
        assert(MAIN_VISIBLE <= length_of_list(s));
-    } else
+    } else {
        slen = length_of_list(s);
 
+       /* Don't show any more shortcuts than the main list does */
+       if (slen > MAIN_VISIBLE)
+           slen = MAIN_VISIBLE;
+    }
+
     /* There will be this many columns of shortcuts */
     numcols = (slen + (slen % 2)) / 2;
 
@@ -2229,6 +2234,10 @@ int statusq(int allowtabs, const shortcut *s, const char *def,
        do_para_end();
        resetstatuspos = 1;
        break;
+    case NANO_FULLJUSTIFY_KEY:
+       do_full_justify();
+       resetstatuspos = 1;
+       break;
 #endif
     case NANO_CANCEL_KEY:
        ret = -1;