diff --git a/BUGS b/BUGS index 731dbab5..6ed8598e 100644 --- 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 diff --git a/ChangeLog b/ChangeLog index aecdb22c..c3ba93ee 100644 --- 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). diff --git a/acconfig.h b/acconfig.h index ac282868..32dba2f3 100644 --- a/acconfig.h +++ b/acconfig.h @@ -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 diff --git a/configure.ac b/configure.ac index 7c98c9e6..25739746 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/faq.html b/faq.html index f203cd51..8bf25fa0 100644 --- a/faq.html +++ b/faq.html @@ -184,7 +184,7 @@ had no help menu, spell checker, and so forth.  But over time it improved, and with the help of a few great coders it matured to the (hopefully) stable state it is today.

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.

diff --git a/files.c b/files.c index 5a9a7238..006c2143 100644 --- 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)) diff --git a/global.c b/global.c index 06d88f48..a46b4b3e 100644 --- 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 5043a7cf..0fe49e77 100644 --- 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) diff --git a/nano.1.html b/nano.1.html index ed748437..654654fe 100644 --- a/nano.1.html +++ b/nano.1.html @@ -108,7 +108,7 @@ Enable cut from cursor to end of line with ^K.
-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?
-m (--mouse) diff --git a/nano.c b/nano.c index bb75156f..72ac3c17 100644 --- 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 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 */ - int down = 0; - int right = 0; - struct filestruct *temp = NULL; +/* 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; +/* 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_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) + i = 0; +#ifndef NANO_SMALL + if (ISSET(AUTOINDENT)) { + while (inptr->data[i] == ' ' || inptr->data[i] == '\t') + i++; + } +#endif + for(; idata[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; - } - - /* 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; - - current_x = 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; + /* 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; } } - - /* 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); - - } + if (wrap_loc < 0 || wrap_loc == (len - 1)) + return; - /* 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]); +/* 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). */ - down = 1; + /* 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)); - 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; + /* new_line_len will later be increased by the lengths of indentation + * and wrap_line. */ + new_line_len = after_break_len; - /* 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); - } - - - /* 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; - - while (isspace((int) inptr->data[i])) { - i--; - assert(i >= 0); - } - - /* 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); - } - } - - /* We pre-pend wrapped part to next line. */ + /* 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) { - int old_x = current_x, old_y = current_y; + wrap_line = inptr->next->data; + wrap_line_len = strlen(wrap_line); - /* 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)); - - /* 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--; + /* +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); + } + } #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); - } - - free(inptr->next->data); - inptr->next->data = p; - - free(temp->data); - free(temp); - - current_x = old_x; - current_y = old_y; + 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; } - /* Else we start a new line. */ - else { +#endif + /* 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)) + 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 = 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); +/* Step 3, clean up. Here we reposition the cursor and mark, and do some + * other sundry things. */ + + /* 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); + + /* 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 - 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; - } - } + indent_len + #endif + current_x - wrap_loc; + + /* note that do_right depends on the value of current_x */ + current_x = wrap_loc; + while (right--) + do_right(); } - - 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++; */ - - renumber(inptr); - edit_update(edittop, TOP); - - - /* Move the cursor to the new line if appropriate. */ - if (down) { - do_right(); + /* 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; } - /* Move the cursor to the correct spot in the line if appropriate. */ - while (right--) { - do_right(); - } - - edit_update(edittop, TOP); +/* 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 */ + int last_space = -1; /* index of the last breakpoint */ - for(i=qdepth; idata[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; - } - } + for(i=qdepth; idata[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(; idata[i+1]); i++) ; + for(; idata[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 945aa86b..b88c36ee 100644 --- 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);