]> git.wh0rd.org Git - nano.git/commitdiff
DB's latest patch
authorChris Allegretta <chrisa@asty.org>
Sat, 6 Apr 2002 05:02:14 +0000 (05:02 +0000)
committerChris Allegretta <chrisa@asty.org>
Sat, 6 Apr 2002 05:02:14 +0000 (05:02 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1170 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

BUGS
ChangeLog
acconfig.h
configure.ac
faq.html
files.c
global.c
nano.1
nano.1.html
nano.c
proto.h

diff --git a/BUGS b/BUGS
index 731dbab52bdf6a219994dd0c774da4f03baa91d2..6ed8598e7f150215025fb41609b7c5569d4327f4 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -71,7 +71,7 @@
   [FIXED]
 - Alt-Z is currently broken to toggle suspend.  I guess I still don't know
   signals very well =-) (41) [FIXED].
-- Unable to cut the entire file using the marker (discovered by Kev Tyler)
+- Unable to cut the entire file using the marker (discovered by Ken Tyler)
   (42). [FIXED]
 - The keypad does not work when nano runs in the Gnome terminal (43). [FIXED]
 - When reading in a file, if the file is a directory, the contents of the
index aecdb22c667385740b887b3003b09cc9d7bfe6f7..c3ba93ee89c37aacb0978637171ecd5c575460fe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,24 @@
 CVS code -
+- General:
+       - Typos n misspellings all over the place (David Benbennick).
+       - Allow --tiny and --multibuffer to cooperate (who the heck
+         would want this is beyond me but ;-).  Changes to 
+         configure.ac, global.c, ,  (David Benbennick).
+- configure.ac:
+       - Define NDEBUG to silence asserts (David Benbennick).
+- files.c:
+  get_next_filename()
+       - Optimizations (David Benbennick).
+- global.c:
+  shortcut_init()
+       - Add missing free_shortcutage()s (David Benbennick).
+- nano.c:
+  die_save_file()
+       - Add missing free (David Benbennick).
+  do_justify()
+       - Optimizations (David Benbennick).
+  do_wrap()
+       - Complete rewrite (David Benbennick).
 - nano.h:
        - NANO_ALT_COMMAND and NANO_ALT_PERIOD were reversed (lol)
          (David Benbennick).
index ac28286863446eb79609c823ce29c944b490dd26..32dba2f37b18945d109c0a4e0ec09c3964f6e69d 100644 (file)
@@ -57,7 +57,7 @@
 /* Define this to disable setting of the operating directory (chroot of sorts) */
 #undef DISABLE_OPERATINGDIR
 
-/* Define this to enable multiple file buffers; this is disabled if NANO_SMALL is defined */
+/* Define this to enable multiple file buffers */
 #undef ENABLE_MULTIBUFFER
 
 /* Define this to use the .nanorc file */
@@ -71,3 +71,6 @@
 
 /* Define this to enable undoing....something */
 #undef ENABLE_UNDO
+
+/* Shut up the assert warnings :-) */
+#undef NDEBUG
index 7c98c9e665d21b59a7231ecaed8a9d257fdb32c8..257397461e6ae1e93dd6a6d7f88ed5f7ae8d7fa8 100644 (file)
@@ -17,6 +17,9 @@ dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS(fcntl.h unistd.h malloc.h termios.h termio.h limits.h getopt.h regex.h)
 
+dnl Turn off assert statements.
+AC_DEFINE(NDEBUG)
+
 dnl options
 AC_ARG_ENABLE(tiny,
 [  --enable-tiny           Disable features for the sake of size
@@ -47,8 +50,8 @@ AC_ARG_ENABLE(undo,
  fi])
 
 AC_ARG_ENABLE(multibuffer,
-[  --enable-multibuffer    Enable multiple file buffers; this is disabled if --enable-tiny is used],
-[if test x$enableval = xyes && test x$tiny_support != xyes; then
+[  --enable-multibuffer    Enable multiple file buffers],
+[if test x$enableval = xyes; then
     AC_DEFINE(ENABLE_MULTIBUFFER) multibuffer_support=yes
  fi])
 
index f203cd51ee9baaa95fd60868caec40a803f107d4..8bf25fa07fab206303282510118154f76a564847 100644 (file)
--- a/faq.html
+++ b/faq.html
@@ -184,7 +184,7 @@ had no help menu, spell checker, and so forth.&nbsp; But over time it improved,
 and with the help of a few great coders it matured to the (hopefully) stable
 state it is today.
 <p><font color="#330000">In February 2001, nano has been declared an
-official GNU program by Richard Stallman.  Nano also reached it's first
+official GNU program by Richard Stallman.  Nano also reached its first
 production release on March 22, 2001.</font></blockquote>
 
 <h2>
diff --git a/files.c b/files.c
index 5a9a7238ae971ac5489addd471329b3fef2da074..006c2143b41732b9a8ee636beefe18c575ab84ee 100644 (file)
--- a/files.c
+++ b/files.c
@@ -336,8 +336,8 @@ int open_file(char *filename, int insert, int quiet)
 /* This function will return the name of the first available extension
    of a filename (starting with the filename, then filename.1, etc).
    Memory is allocated for the return value.  If no writable extension 
-   exists we return "" */
-char *get_next_filename(char *name)
+   exists, we return "". */
+char *get_next_filename(const char *name)
 {
     int i = 0;
     char *buf = NULL;
@@ -346,10 +346,10 @@ char *get_next_filename(char *name)
     buf = charalloc(strlen(name) + num_of_digits(INT_MAX) + 2);
     strcpy(buf, name);
 
-    while(1) {
+    while (1) {
 
        if (stat(buf, &fs) == -1)
-           break;
+           return buf;
        if (i == INT_MAX)
            break;
 
@@ -358,8 +358,8 @@ char *get_next_filename(char *name)
        sprintf(&buf[strlen(name)], ".%d", i);
     }
 
-    if (i == INT_MAX)
-       buf[0] = '\0';
+    /* We get here only if there is no possible save file. */
+    buf[0] = '\0';
 
     return buf;
 }
@@ -376,7 +376,7 @@ int do_insertfile(int loading_file)
 #endif
 
 #ifndef DISABLE_OPERATINGDIR
-    if ((operating_dir) && (strcmp(operating_dir,"."))){
+    if (operating_dir && (strcmp(operating_dir, "."))) {
        i = statusq(1, insertfile_list, "", _("File to insert [from %s] "),
                operating_dir);
     } else {
@@ -643,8 +643,8 @@ int load_open_file(void)
     totlines = open_files->file_totlines;
     totsize = open_files->file_totsize;
 
-    /* Unset the marker because nano can't (yet) handle marked text flipping between
-       open files */
+    /* Unset the marker because nano can't (yet) handle marked text
+       flipping between open files */
     UNSET(MARK_ISSET);
 
     /* restore full file position: line number, x-coordinate, y-
@@ -815,6 +815,8 @@ int close_open_file(void)
     if (!open_files)
        return 1;
 
+    open_files->file = fileage;
+
     tmp = open_files;
     if (open_nextfile(1)) {
        if (open_prevfile(1))
index 06d88f48f5f874d7cd1ab9ff47bc9d2d81e19969..a46b4b3ebd9e7032d45d96ee42c494f21cf3fad6 100644 (file)
--- a/global.c
+++ b/global.c
@@ -99,7 +99,9 @@ shortcut *writefile_list = NULL;
 shortcut *insertfile_list = NULL;
 shortcut *help_list = NULL;
 shortcut *spell_list = NULL;
+#ifndef NANO_SMALL
 shortcut *extcmd_list = NULL;
+#endif
 #ifndef DISABLE_BROWSER
 shortcut *browser_list = NULL;
 #endif
@@ -272,6 +274,10 @@ void shortcut_init(int unjustify)
        "", *nano_unjustify_msg = "", *nano_append_msg =
        ""; 
 
+#ifdef ENABLE_MULTIBUFFER
+    char *nano_openprev_msg = "", *nano_opennext_msg = "";
+#endif
+
 #ifndef NANO_SMALL
     char *nano_tofiles_msg = "", *nano_gotodir_msg = "", *nano_case_msg =
        "", *nano_reverse_msg = "", *nano_execute_msg = "";
@@ -280,9 +286,6 @@ void shortcut_init(int unjustify)
 #ifdef HAVE_REGEX_H
     char *nano_regexp_msg = "", *nano_bracket_msg = "";
 #endif
-#ifdef ENABLE_MULTIBUFFER
-    char *nano_openprev_msg = "", *nano_opennext_msg = "";
-#endif
 
     nano_help_msg = _("Invoke the help menu");
     nano_writeout_msg = _("Write the current file to disk");
@@ -650,6 +653,9 @@ void shortcut_init(int unjustify)
                nano_execute_msg, 0, 0, 0, NOVIEW, 0);
 #endif
 
+    if (spell_list != NULL)
+       free_shortcutage(&spell_list);
+
     sc_init_one(&spell_list, NANO_HELP_KEY,
                _("Get Help"), nano_help_msg, 0, 0, 0, VIEW, do_help);
 
@@ -657,6 +663,9 @@ void shortcut_init(int unjustify)
                nano_cancel_msg, 0, 0, 0, VIEW, 0);
 
 #ifndef NANO_SMALL
+    if (extcmd_list != NULL)
+       free_shortcutage(&extcmd_list);
+
     sc_init_one(&extcmd_list, NANO_HELP_KEY,
                _("Get Help"), nano_help_msg, 0, 0, 0, VIEW, do_help);
 
diff --git a/nano.1 b/nano.1
index 5043a7cff7ecaea8b677304b2adce1aa8a24b676..0fe49e771365ca56724ab09c2d230c08ece6403f 100644 (file)
--- a/nano.1
+++ b/nano.1
@@ -79,7 +79,7 @@ source code.
 Enable cut from cursor to end of line with ^K.
 .TP
 .B \-l (\-\-nofollow)
-If the file being edited is a symbolic link, replace the link with a 
+If the file being edited is a symbolic link, replace the link with
 a new file, do not follow it.  Good for editing files in /tmp, perhaps?
 .TP
 .B \-m (\-\-mouse)
index ed74843771958c4d8f5c2367251702300b97bd66..654654fe112f09861919dd31317d8440f4508cfc 100644 (file)
@@ -108,7 +108,7 @@ Enable cut from cursor to end of line with ^K.
 <DT><B>-l (--nofollow)</B>
 
 <DD>
-If the file being edited is a symbolic link, replace the link with a 
+If the file being edited is a symbolic link, replace the link with
 a new file, do not follow it.  Good for editing files in /tmp, perhaps?
 <DT><B>-m (--mouse)</B>
 
diff --git a/nano.c b/nano.c
index bb75156f1edfe2de310f4c40a4932653c5298e23..72ac3c17e63e77b266ae7f7d41ebc35369994edb 100644 (file)
--- a/nano.c
+++ b/nano.c
@@ -180,6 +180,7 @@ void die_save_file(char *die_filename)
        if (strcmp(ret, ""))
            i = write_file(ret, 1, 0, 0);
        name = ret;
+       free(buf);
     }
 
     if (i != -1)
@@ -642,13 +643,17 @@ void do_char(char ch)
     current->data[current_x] = ch;
     do_right();
 
+    /* note that current_x has already been incremented */
+    if (current == mark_beginbuf && mark_beginx >= current_x)
+       mark_beginx++;
+
 #ifdef ENABLE_COLOR
     edit_refresh();
 #endif
 
 #ifndef DISABLE_WRAPPING
     if (!ISSET(NO_WRAP) && (ch != '\t'))
-       check_wrap(current, ch);
+       check_wrap(current);
 #endif
 
     set_modified();
@@ -861,364 +866,225 @@ void do_prev_word(void)
 #endif /* NANO_SMALL */
 
 #ifndef DISABLE_WRAPPING
-void do_wrap(filestruct * inptr, char input_char)
+/* We wrap the given line.  Precondition: we assume the cursor has been 
+ * moved forward since the last typed character. */
+void do_wrap(filestruct * inptr)
 {
-    int i = 0;                 /* Index into ->data for line. */
-    int i_tabs = 0;            /* Screen position of ->data[i]. */
-    int last_word_end = -1;    /* Location of end of last word found. */
-    int current_word_start = -1;       /* Location of start of current word. */
-    int current_word_start_t = -1;     /* Location of start of current word screen position. */
-    int current_word_end = -1; /* Location of end   of current word */
-    int current_word_end_t = -1;       /* Location of end   of current word screen position. */
-    int len = strlen(inptr->data);
-
-    int down = 0;
-    int right = 0;
-    struct filestruct *temp = NULL;
-
+    int len = strlen(inptr->data);     /* length of the line we wrap */
+    int i;                     /* generic loop variable */
+    int wrap_loc = -1;         /* index of inptr->data where we wrap */
+    int word_back = -1;
+#ifndef NANO_SMALL
+    char *indentation = NULL;  /* indentation to prepend to the new line */
+    int indent_len = 0;                /* strlen(indentation) */
+#endif
+    char *after_break;         /* text after the wrap point */
+    int after_break_len;       /* strlen(after_break) */
+    int wrapping = 0;          /* do we prepend to the next line? */
+    char *wrap_line = NULL;    /* the next line, minus indentation */
+    int wrap_line_len = 0;     /* strlen(wrap_line) */
+    char *newline = NULL;      /* the line we create */
+    int new_line_len = 0;      /* eventual length of newline */
+
+/* There are three steps.  First, we decide where to wrap.  Then, we
+ * create the new wrap line.  Finally, we clean up. */
+
+    /* We need the following assertion, since otherwise we would wrap the
+     * last word to the next line regardless. */
     assert(strlenpt(inptr->data) > fill);
 
-    for (i = 0, i_tabs = 0; i < len; i++, i_tabs++) {
-       if (!isspace((int) inptr->data[i])) {
-           last_word_end = current_word_end;
-
-           current_word_start = i;
-           current_word_start_t = i_tabs;
-
-           while (!isspace((int) inptr->data[i])
-                  && inptr->data[i]) {
-               i++;
-               i_tabs++;
-               if (inptr->data[i] < 32)
-                   i_tabs++;
-           }
-
-           if (inptr->data[i]) {
-               current_word_end = i;
-               current_word_end_t = i_tabs;
-           } else {
-               current_word_end = i - 1;
-               current_word_end_t = i_tabs - 1;
-           }
-       }
-
-       if (inptr->data[i] == NANO_CONTROL_I) {
-           if (i_tabs % tabsize != 0);
-           i_tabs += tabsize - (i_tabs % tabsize);
-       }
-
-       if (current_word_end_t > fill)
-           break;
-    }
-
-    /* There are a few (ever changing) cases of what the line could look like.
-     * 1) only one word on the line before wrap point.
-     *    a) one word takes up the whole line with no starting spaces.
-     *         - do nothing and return.
-     *    b) cursor is on word or before word at wrap point and there are spaces at beginning.
-     *         - word starts new line.
-     *         - keep white space on original line up to the cursor.
-     *    *) cursor is after word at wrap point
-     *         - either it's all white space after word, and this routine isn't called.
-     *         - or we are actually in case 2 (2 words).
-     * 2) Two or more words on the line before wrap point.
-     *    a) cursor is at a word or space before wrap point
-     *         - word at wrap point starts a new line.
-     *         - white space at end of original line is cleared, unless
-     *           it is all spaces between previous word and next word which appears after fill.
-     *    b) cursor is at the word at the wrap point.
-     *         - word at wrap point starts a new line.
-     *         - white space on original line is kept to where cursor was.
-     *    c) cursor is past the word at the wrap point.
-     *         - word at wrap point starts a new line.
-     *         - white space at end of original line is cleared
-     */
-
-    temp = nmalloc(sizeof(filestruct));
-
-    /* Category 1a: one word taking up the whole line with no beginning spaces. */
-    if ((last_word_end == -1) && (!isspace((int) inptr->data[0]))) {
-       for (i = current_word_end; i < len; i++) {
-           if (!isspace((int) inptr->data[i]) && i < len) {
-               current_word_start = i;
-               while (!isspace((int) inptr->data[i]) && (i < len)) {
-                   i++;
-               }
-               last_word_end = current_word_end;
-               current_word_end = i;
-               break;
-           }
-       }
-
-       if (last_word_end == -1) {
-           free(temp);
-           return;
-       }
-       if (current_x >= last_word_end) {
-           right = (current_x - current_word_start) + 1;
-           current_x = last_word_end;
-           down = 1;
-       }
-
-       /* Subtract length of original line, plus one for the newline, from
-          totsize. */
-       totsize -= (strlen(inptr->data) + 1);
-
-       temp->data = charalloc(strlen(&inptr->data[current_word_start]) + 1);
-       strcpy(temp->data, &inptr->data[current_word_start]);
-       inptr->data = nrealloc(inptr->data, last_word_end + 2);
-       inptr->data[last_word_end + 1] = 0;
-
-       /* Now add lengths of new lines, plus two for the newlines, to totsize. */
-       totsize += (strlen(inptr->data) + strlen(temp->data) + 2);
-
-    } else
-       /* Category 1b: one word on the line and word not taking up whole line
-          (i.e. there are spaces at the beginning of the line) */
-    if (last_word_end == -1) {
-       temp->data = charalloc(strlen(&inptr->data[current_word_start]) + 1);
-       strcpy(temp->data, &inptr->data[current_word_start]);
-
-       /* Inside word, remove it from original, and move cursor to right spot. */
-       if (current_x >= current_word_start) {
-           right = current_x - current_word_start;
+/* Step 1, finding where to wrap.  We are going to replace a white-space
+ * character with a new-line.  In this step, we set wrap_loc as the
+ * location of this replacement.
+ *
+ * Where should we break the line?  We need the last "legal wrap point"
+ * such that the last word before it ended at or before fill.  If there
+ * is no such point, we settle for the first legal wrap point.
+ *
+ * A "legal wrap point" is a white-space character that is not the last
+ * typed character and is not followed by white-space.
+ *
+ * If there is no legal wrap point or we found the last character of the
+ * line, we should return without wrapping.
+ *
+ * Note that the initial indentation does not count as a legal wrap
+ * point if we are going to auto-indent!
+ *
+ * Note that the code below could be optimised, by not calling strlenpt
+ * so often, and by not calling isspace(inptr->data[i+1]) and then in
+ * the next loop calling isspace(inptr->data[i]).  Oh well, fixing the
+ * first point would entail expanding the definition of strnlenpt, which
+ * I won't do since it will probably change soon.  Fixing the second
+ * point would entail nested loops.
+ */
 
-           current_x = 0;
+    i = 0;
 #ifndef NANO_SMALL
-           if (ISSET(AUTOINDENT)) {
-               int i = 0;
-               while ((inptr->next->data[i] == ' '
-                       || inptr->next->data[i] == '\t')) {
-                   i++;
-               }
-           }
-#endif
-           down = 1;
-       }
-
-       /* Subtract length of original line, plus one for the newline, from
-          totsize. */
-       totsize -= (strlen(inptr->data) + 1);
-
-       null_at(&inptr->data, current_x);
-
-       /* Now add lengths of new lines, plus two for the newlines, to totsize. */
-       totsize += (strlen(inptr->data) + strlen(temp->data) + 2);
-
-       if (ISSET(MARK_ISSET) && (mark_beginbuf == inptr)) {
-           mark_beginbuf = temp;
-           mark_beginx = 0;
-       }
+    if (ISSET(AUTOINDENT)) {
+       while (inptr->data[i] == ' ' || inptr->data[i] == '\t')
+           i++;
     }
-
-    /* Category 2: two or more words on the line. */
-    else {
-       /* Case 2a: cursor before word at wrap point. */
-       if (current_x < current_word_start) {
-           temp->data =
-               charalloc(strlen(&inptr->data[current_word_start]) + 1);
-           strcpy(temp->data, &inptr->data[current_word_start]);
-
-           if (!isspace((int) input_char)) {
-               i = current_word_start - 1;
-
-               while (isspace((int) inptr->data[i])) {
-                   i--;
-                   assert(i >= 0);
-               }
-           } else if (current_x <= last_word_end)
-               i = last_word_end - 1;
-           else
-               i = current_x;
-
-           /* Subtract length of original line, plus one for the newline, from
-              totsize. */
-           totsize -= (strlen(inptr->data) + 1);
-
-           inptr->data = nrealloc(inptr->data, i + 2);
-           inptr->data[i + 1] = 0;
-
-           /* Now add lengths of new lines, plus two for the newlines, to totsize. */
-           totsize += (strlen(inptr->data) + strlen(temp->data) + 2);
-
-       }
-
-
-       /* Case 2b: cursor at word at wrap point. */
-       else if ((current_x >= current_word_start)
-                && (current_x <= (current_word_end + 1))) {
-           temp->data =
-               charalloc(strlen(&inptr->data[current_word_start]) + 1);
-           strcpy(temp->data, &inptr->data[current_word_start]);
-
-           down = 1;
-
-           right = current_x - current_word_start;
-#ifndef NANO_SMALL
-           if (ISSET(AUTOINDENT)) {
-               int i = 0;
-               while ((inptr->next->data[i] == ' '
-                       || inptr->next->data[i] == '\t')) {
-                   i++;
-               }
-           }
 #endif
-           i = current_word_start - 1;
-           current_x = current_word_start;
-
-           /* Subtract length of original line, plus one for the newline, from
-              totsize. */
-           totsize -= (strlen(inptr->data) + 1);
-
-           null_at(&inptr->data, current_word_start);
-
-           /* Now add lengths of new lines, plus two for the newlines, to totsize. */
-           totsize += (strlen(inptr->data) + strlen(temp->data) + 2);
+    for(; i<len; i++) {
+       /* record where the last word ended */
+       if (!isspace((int) inptr->data[i]))
+           word_back = i;
+       /* if we have found a "legal wrap point" and the current word
+        * extends too far, then we stop */
+       if (wrap_loc != -1 && strnlenpt(inptr->data,word_back) > fill)
+           break;
+       /* we record the latest "legal wrap point" */
+       if (i != (current_x - 1) && isspace((int) inptr->data[i]) &&
+          (i == (len - 1) || !isspace((int)inptr->data[i + 1]))) {
+           wrap_loc = i;
        }
+    }
+    if (wrap_loc < 0 || wrap_loc == (len - 1))
+       return;
 
 
-       /* Case 2c: cursor past word at wrap point. */
-       else {
-           temp->data =
-               charalloc(strlen(&inptr->data[current_word_start]) + 1);
-           strcpy(temp->data, &inptr->data[current_word_start]);
-
-           down = 1;
-           right = current_x - current_word_start;
-
-           current_x = current_word_start;
-           i = current_word_start - 1;
+/* Step 2, making the new wrap line.  It will consist of indentation +
+ * after_break + " " + wrap_line (although indentation and wrap_line are
+ * conditional on flags and #defines). */
 
-           while (isspace((int) inptr->data[i])) {
-               i--;
-               assert(i >= 0);
-           }
+    /* after_break is the text that will be moved to the next line. */
+    after_break = inptr->data + wrap_loc + 1;
+    after_break_len = len - wrap_loc - 1;
+    assert(after_break_len == strlen(after_break));
 
-           /* Subtract length of original line, plus one for the newline, from
-              totsize. */
-           totsize -= (strlen(inptr->data) + 1);
+    /* new_line_len will later be increased by the lengths of indentation
+     * and wrap_line. */
+    new_line_len = after_break_len;
 
-           inptr->data = nrealloc(inptr->data, i + 2);
-           inptr->data[i + 1] = 0;
+    /* We prepend the wrapped text to the next line, if the flag is set,
+     * and there is a next line, and prepending would not make the line
+     * too long. */
+    if (ISSET(SAMELINEWRAP) && inptr->next) {
+       wrap_line = inptr->next->data;
+       wrap_line_len = strlen(wrap_line);
 
-           /* Now add lengths of new lines, plus two for the newlines, to totsize. */
-           totsize += (strlen(inptr->data) + strlen(temp->data) + 2);
+       /* +1 for the space between after_break and wrap_line */
+       if ((new_line_len + 1 + wrap_line_len) <= fill) {
+           wrapping = 1;
+           new_line_len += (1 + wrap_line_len);
        }
     }
 
-    /* We pre-pend wrapped part to next line. */
-    if (ISSET(SAMELINEWRAP) && inptr->next) {
-       int old_x = current_x, old_y = current_y;
-
-       /* Plus one for the space which concatenates the two lines together plus 1 for \0. */
-       char *p =
-           charalloc((strlen(temp->data) + strlen(inptr->next->data) + 2));
+#ifndef NANO_SMALL
+    if (ISSET(AUTOINDENT)) {
+       /* indentation comes from the next line if wrapping, else from
+        * this line */
+       indentation = (wrapping ? wrap_line : inptr->data);
+       while (indentation[indent_len] == ' ' ||
+               indentation[indent_len] == '\t')
+           indent_len++;
+       if (wrapping)
+           /* The wrap_line text should not duplicate indentation.  Note
+            * in this case we need not increase new_line_len. */
+           wrap_line += indent_len;
+       else
+           new_line_len += indent_len;
+    }
+#endif
 
-       /* We're adding to an existing line instead of creating a new
-          one; decrement totlines here so that when it gets incremented
-          below, it won't end up being high by one. */
-       totlines--;
+    /* Now we allocate the new line and copy into it. */
+    newline = charalloc(new_line_len + 1);  /* +1 for \0 */
+    *newline = '\0';
 
 #ifndef NANO_SMALL
-       if (ISSET(AUTOINDENT)) {
-           int non = 0;
-
-           /* Grab the beginning of the next line until it's not a 
-              space or tab, then null terminate it so we can strcat it
-              to hell */
-           while ((inptr->next->data[non] == ' '
-                   || inptr->next->data[non] == '\t')) {
-               p[non] = inptr->next->data[non];
-               non++;
-           }
-           p[non] = 0;
-           strcat(p, temp->data);
-           strcat(p, " ");
-
-           /* Now tack on the rest of the next line after the spaces and
-              tabs */
-           strcat(p, &inptr->next->data[non]);
-       } else 
-#endif
-       {
-           strcpy(p, temp->data);
-           strcat(p, " ");
-           strcat(p, inptr->next->data);
-       }
-
+    if (ISSET(AUTOINDENT))
+       strncpy(newline, indentation, indent_len);
+#endif
+    strcat(newline, after_break);
+    after_break = NULL;
+    /* We end the old line at wrap_loc.  Note this eats the space. */
+    null_at(&inptr->data, wrap_loc);
+    if (wrapping) {
+       /* In this case, totsize does not change.  We ate a space in the
+        * null_at() above, but we add a space between after_break and
+        * wrap_line below. */
+       strcat(newline, " ");
+       strcat(newline, wrap_line);
        free(inptr->next->data);
-       inptr->next->data = p;
-
-       free(temp->data);
-       free(temp);
-
-       current_x = old_x;
-       current_y = old_y;
-    }
-    /* Else we start a new line. */
-    else {
-
+       inptr->next->data = newline;
+    } else {
+       filestruct *temp = (filestruct *)nmalloc(sizeof(filestruct));
+       /* In this case, the file size changes by -1 for the eaten
+        * space, +1 for the new line, and +indent_len for the new
+        * indentation. */
+#ifndef NANO_SMALL
+       totsize += indent_len;
+#endif
+       totlines++;
+       temp->data = newline;
        temp->prev = inptr;
        temp->next = inptr->next;
-
-       if (inptr->next)
-           inptr->next->prev = temp;
-       inptr->next = temp;
-
-       if (!temp->next)
+       temp->prev->next = temp;
+       /* If !temp->next, then temp is the last line of the file, so we
+        * must set filebot */
+       if (temp->next)
+           temp->next->prev = temp;
+       else
            filebot = temp;
-
-       SET(SAMELINEWRAP);
-
-#ifndef NANO_SMALL
-       if (ISSET(AUTOINDENT)) {
-           char *spc = inptr->data;
-           char *t = NULL;
-           int extra = 0;
-           if (spc) {
-               while ((*spc == ' ') || (*spc == '\t')) {
-                   extra++;
-                   spc++;
-                   totsize++;
-                   right++;
-               }
-               t = charalloc(strlen(temp->data) + extra + 1);
-               strncpy(t, inptr->data, extra);
-               strcpy(t + extra, temp->data);
-               free(temp->data);
-               temp->data = t;
-           }
-       }
-#endif
     }
 
 
-    totlines++;
-    /* Everything about it makes me want this line here, but it causes
-     * totsize to be high by one for some reason.  Sigh. (Rob) */
-    /* totsize++; */
+/* Step 3, clean up.  Here we reposition the cursor and mark, and do some
+ * other sundry things. */
 
-    renumber(inptr);
-    edit_update(edittop, TOP);
+    /* later wraps of this line will be prepended to the next line. */
+    SET(SAMELINEWRAP);
 
+    /* Each line knows its line number.  We recalculate these if we
+     * inserted a new line. */
+    if (!wrapping)
+       renumber(inptr);
+    edit_update(edittop, TOP);
 
-    /* Move the cursor to the new line if appropriate. */
-    if (down) {
-       do_right();
-    }
+    /* if the cursor was after the break point, we must move it */
+    if (current_x > wrap_loc) {
+       /* We move it right by the number of characters that come before
+        * its corresponding position in the new line.  That is,
+        * current_x - wrap_loc + indent_len.  We actually need to go one
+        * further for the new line, but remember that current_x has
+        * already been incremented. */
+       int right =
+#ifndef NANO_SMALL
+               indent_len +
+#endif
+               current_x - wrap_loc;
 
-    /* Move the cursor to the correct spot in the line if appropriate. */
-    while (right--) {
-       do_right();
+       /* note that do_right depends on the value of current_x */
+       current_x = wrap_loc;
+       while (right--)
+           do_right();
     }
 
-    edit_update(edittop, TOP);
+    /* If the mark was on this line after the wrap point, we move it down.
+     * If it was on the next line and we wrapped, we must move it right.
+     */
+    if (mark_beginbuf == inptr && mark_beginx > wrap_loc) {
+       mark_beginbuf = inptr->next;
+       mark_beginx -= wrap_loc;
+    } else if (wrapping && mark_beginbuf == inptr->next) {
+       mark_beginx += after_break_len;
+    }
+
+/* The following lines are all copied from do_wrap() in version 1.1.7.  It
+ * is not clear whether they are necessary.  It looks like do_right()
+ * takes care of these things.  It also appears that do_right() is very
+ * inefficient. */
+    /* Perhaps the global variable editbot, the last visible line in the
+     * editor, needs to change. */
+    fix_editbot();
+    /* Place the cursor. */
     reset_cursor();
+    /* Display the changes on the screen. */
     edit_refresh();
 }
 
 /* Check to see if we've just caused the line to wrap to a new line */
-void check_wrap(filestruct * inptr, char ch)
+void check_wrap(filestruct * inptr)
 {
     int len = strlenpt(inptr->data);
 #ifdef DEBUG
@@ -1252,7 +1118,7 @@ void check_wrap(filestruct * inptr, char ch)
        }
 
        if (char_found == 2)
-           do_wrap(inptr, ch);
+           do_wrap(inptr);
     }
 }
 #endif                         /* DISABLE_WRAPPING */
@@ -1734,7 +1600,7 @@ int do_spell(void)
 }
 
 #ifndef NANO_SMALL
-static int pid;                /* this is the PID of the newly forked process below.  
+static int pid;                /* this is the PID of the newly forked process below.
                         * It must be global since the signal handler needs it.
                         */
 
@@ -1751,7 +1617,7 @@ int open_pipe(char *command)
     struct termios term, newterm;
 #endif   /* _POSIX_VDISABLE */
     int cancel_sigs = 0;
-    /* cancel_sigs==1 means that sigaction failed without changing the 
+    /* cancel_sigs==1 means that sigaction failed without changing the
      * signal handlers.  cancel_sigs==2 means the signal handler was
      * changed, but the tcsetattr didn't succeed.
      * I use this variable since it is important to put things back when
@@ -1787,7 +1653,7 @@ int open_pipe(char *command)
        return 1;
     }
 
-    /* before we start reading the forked command's output, we set 
+    /* before we start reading the forked command's output, we set
      * things up so that ^C will cancel the new process.
      */
     if (sigaction(SIGINT, NULL, &newaction)==-1) {
@@ -1800,8 +1666,8 @@ int open_pipe(char *command)
            nperror("sigaction");
        }
     }
-    /* note that now oldaction is the previous SIGINT signal handler, to 
-       be restored later */
+    /* note that now oldaction is the previous SIGINT signal handler, to
+     * be restored later */
 
     /* if the platform supports disabling individual control characters */
 #ifdef _POSIX_VDISABLE
@@ -1823,7 +1689,7 @@ int open_pipe(char *command)
     read_file(fd[0],"stdin",0);
     set_modified();
 
-    if (wait(NULL) == -1) 
+    if (wait(NULL) == -1)
        nperror("wait");
 
 #ifdef _POSIX_VDISABLE
@@ -2395,12 +2261,10 @@ int do_justify(void)
     slen = strlen(current->data);
     totsize += slen;
 
-    if ((strlenpt(current->data) > (fill))
-       && !no_spaces(current->data + qdepth)) {
-       do {
-           int i = 0, j = 0;
-           filestruct *tmpline = nmalloc(sizeof(filestruct));
-
+    while (strlenpt(current->data) > fill
+           && !no_spaces(current->data + qdepth)) {
+       int i = 0, j = 0;
+       filestruct *tmpline = nmalloc(sizeof(filestruct));
 
 /* The following code maybe could be better.  In particular, can we 
  * merely increment instead of calling strnlenpt for each new character?  
@@ -2408,48 +2272,48 @@ int do_justify(void)
  */
 /* Note that we CAN break before the first word, since that is how 
  * pico does it. */
-            int last_space = -1;  /* index of the last breakpoint */
-
-           for(i=qdepth; i<slen; i++) {
-              if (isspace((int) current->data[i])) last_space = i;
-              if (last_space!=-1 &&
-     /* ARGH!  We must look at the length of the first i+1 characters. */
-                 strnlenpt(current->data,i+1) > fill) {
-                i = last_space;
-                break;
-              }
-            }
+       int last_space = -1;  /* index of the last breakpoint */
+
+       for(i=qdepth; i<slen; i++) {
+           if (isspace((int) current->data[i]))
+               last_space = i;
+           /* Note we must look at the length of the first i+1 chars. */
+           if (last_space!=-1 &&
+                   strnlenpt(current->data,i+1) > fill) {
+               i = last_space;
+               break;
+           }
+       }
 /* Now data[i] is a space.  We want to break at the LAST space in this
  * group.  Probably, the only possibility is two in a row, but let's be 
  * generic.  Note that we actually replace this final space with \0.  Is
  * this okay?  It seems to work fine. */
-            for(; i<slen-1 && isspace((int) current->data[i+1]); i++) ;
+       for(; i<slen-1 && isspace((int) current->data[i+1]); i++)
+           ;
 
-           current->data[i] = '\0';
+       current->data[i] = '\0';
 
-           slen -= i + 1 - qdepth;   /* note i > qdepth */
-           tmpline->data = charalloc(slen + 1);
+       slen -= i + 1 - qdepth;   /* note i > qdepth */
+       tmpline->data = charalloc(slen + 1);
 
-           for (j = 0; j < qdepth; j += strlen(quotestr))
-               strcpy(&tmpline->data[j], quotestr);
+       for (j = 0; j < qdepth; j += strlen(quotestr))
+           strcpy(&tmpline->data[j], quotestr);
 
-           /* Skip the white space in current. */
-           memcpy(&tmpline->data[qdepth], current->data + i + 1, slen-qdepth);
-           tmpline->data[slen] = '\0';
+       /* Skip the white space in current. */
+       memcpy(&tmpline->data[qdepth], current->data + i + 1, slen-qdepth);
+       tmpline->data[slen] = '\0';
 
-           current->data = nrealloc(current->data, i + 1);
+       current->data = nrealloc(current->data, i + 1);
 
-           tmpline->prev = current;
-           tmpline->next = current->next;
-           if (current->next != NULL)
-               current->next->prev = tmpline;
+       tmpline->prev = current;
+       tmpline->next = current->next;
+       if (current->next != NULL)
+           current->next->prev = tmpline;
 
-           current->next = tmpline;
-           current = tmpline;
-           current_y++;
-       } while ((strlenpt(current->data) > (fill))
-                && !no_spaces(current->data + qdepth));
-    }
+       current->next = tmpline;
+       current = tmpline;
+       current_y++;
+    } /* end of while (!no_spaces) */
     tmpbot = current;
 
     if (current->next)
diff --git a/proto.h b/proto.h
index 945aa86b2ba6235f2ec22a745467bd407d22cab2..b88c36ee37351407fc97109fe16a8aa1539c84dd 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -30,7 +30,7 @@
 #include "nano.h"
 
 extern int editwinrows;
-extern int current_x, current_y, posible_max, totlines;
+extern int current_x, current_y, totlines;
 extern int placewewant;
 extern int mark_beginx, samelinewrap;
 extern long totsize;
@@ -72,7 +72,10 @@ extern shortcut *shortcut_list;
 extern shortcut *main_list, *whereis_list;
 extern shortcut *replace_list, *goto_list;
 extern shortcut *writefile_list, *insertfile_list;
-extern shortcut *spell_list, *replace_list_2, *extcmd_list;
+extern shortcut *spell_list, *replace_list_2;
+#ifndef NANO_SMALL
+extern shortcut *extcmd_list;
+#endif
 extern shortcut *help_list;
 #ifndef DISABLE_BROWSER
 extern shortcut *browser_list, *gotodir_list;
@@ -87,7 +90,7 @@ extern regmatch_t regmatches[10];
 #ifdef ENABLE_COLOR
 extern regex_t color_regexp;
 extern regmatch_t colormatches[1];  
-#endif /* HJAVE_COLOR */
+#endif /* ENABLE_COLOR */
 #endif
 
 extern toggle *toggles;
@@ -152,7 +155,7 @@ void shortcut_init(int unjustify);
 void signal_init(void);
 void lowercase(char *src);
 void blank_bottombars(void);
-void check_wrap(filestruct * inptr, char ch);
+void check_wrap(filestruct * inptr);
 void dump_buffer(filestruct * inptr);
 void align(char **strp);
 void edit_refresh(void), edit_refresh_clearok(void);
@@ -172,7 +175,6 @@ void previous_line(void);
 void center_cursor(void);
 void bottombars(shortcut *s);
 void blank_statusbar_refresh(void);
-void *nmalloc (size_t howmuch);
 void nperror(const char *s);
 void *mallocstrcpy(char *dest, char *src);
 void wrap_reset(void);
@@ -221,7 +223,6 @@ int load_open_file(void), close_open_file(void);
 
 int do_page_up(void), do_page_down(void);
 int do_cursorpos(int constant), do_cursorpos_void(void), do_spell(void);
-int do_up(void), do_down (void), do_right(void), do_left (void);
 int do_home(void), do_end(void), total_refresh(void), do_mark(void);
 int do_delete(void), do_backspace(void), do_tab(void), do_justify(void);
 int do_first_line(void), do_last_line(void);
@@ -234,7 +235,7 @@ int open_prevfile_void(void), open_nextfile_void(void);
 #endif
 
 char *charalloc (size_t howmuch);
-char *get_next_filename(char *name);
+char *get_next_filename(const char *name);
 
 #if !defined (DISABLE_SPELLER) || !defined (DISABLE_OPERATINGDIR)
 char *get_full_path(const char *origpath);