diff --git a/ChangeLog b/ChangeLog index 8e894f89..56516679 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,9 +2,26 @@ CVS code - - General - Update copyright notice on all source files to reflect new holder. +- files.c: + browser_init() + - Fix off-by-one error when calculating longest that kept the + rightmost column of the screen from being used. (DLR) + do_browser() + - Fix potential crash when strlen(tail(filelist[j])) is greater + than (longest + 8). (DLR) + - If we click off the edge of the screen, and the file selected + is the same one that was selected before, read it in, as Pico + does. (DLR) + - Fix problem where width wouldn't be properly initialized if + the file list took up one line or less. (DLR) - nano.c: + handle_sigwinch() + - Simplify and remove unneeded erase() call. (DLR) main() - Refer to KEY_SUSPEND instead of 407. (DLR) +- utils.c: + num_of_digits() + - Return the proper number of digits when n is exactly 10. (DLR) - winio.c: blocking_wgetch() - Only save all open buffers and hang up when a blocking @@ -19,6 +36,13 @@ CVS code - - Refer to KEY_ENTER instead of 343, and handle all of PDCurses' Shift, Control, and Alt key values by name instead of referring to 541-545, which leaves out one key value. (DLR) + edit_add() + - Properly ignore zero-length regexes in multi-line regexes as + well as single-line ones. This avoids a segfault when trying + to color e.g. "start="$" end="$"". (DLR, found by Trevor + Caira) + total_refresh() + - Simplify. (DLR) do_credits() - Add DLR as new copyright holder. - README.CVS: @@ -28,7 +52,12 @@ CVS code - broken links to contributed RedHat nano packages. (DLR) - nano.texi: - Change license to GPL as it is heavily based on the source - code which is licensed GPL (DLR) + code which is licensed GPL. (DLR) + - Add missing description of -H/--historylog, and move + -x/--nohelp down so that all the command line options are in + alphabetical order. (Benno Schulenberg) + - Wrap lines at 72 characters when possible, and remove unneeded + whitespace at the ends of lines. (DLR) GNU nano 1.2.5 - 2005.05.15 - files.c: diff --git a/files.c b/files.c index 61626311..6184a271 100644 --- a/files.c +++ b/files.c @@ -2487,8 +2487,8 @@ char **browser_init(const char *path, int *longest, int *numents) } closedir(dir); - if (*longest > COLS - 1) - *longest = COLS - 1; + if (*longest > COLS) + *longest = COLS; return filelist; } @@ -2583,7 +2583,7 @@ char *do_browser(const char *inpath) If we clicked where we did last time, select this name! */ if (selected > numents - 1) selected = numents - 1; - else if (selectedbackup == selected) + if (selectedbackup == selected) ungetch('s'); /* Unget the 'select' key */ } else /* Must be clicking a shortcut */ do_mouse(); @@ -2766,7 +2766,7 @@ char *do_browser(const char *inpath) for (j = i; j < numents && editline <= editwinrows - 1; j++) { filecols++; - strncpy(foo, tail(filelist[j]), strlen(tail(filelist[j])) + 1); + snprintf(foo, longest + 1, "%s", tail(filelist[j])); while (strlen(foo) < longest) strcat(foo, " "); col += strlen(foo); @@ -2822,6 +2822,10 @@ char *do_browser(const char *inpath) width = filecols; } } + + if (width == 0) + width = COLS % longest; + wrefresh(edit); } while ((kbinput = blocking_wgetch(edit)) != NANO_EXIT_KEY); curs_set(1); diff --git a/nano.c b/nano.c index f8dd1c10..59b6d8be 100644 --- a/nano.c +++ b/nano.c @@ -2918,7 +2918,7 @@ void handle_sigwinch(int s) /* Do the equivalent of what Minimum Profit does: Leave and * immediately reenter curses mode. */ endwin(); - refresh(); + doupdate(); #endif /* Do the equivalent of what both mutt and Minimum Profit do: @@ -2930,14 +2930,10 @@ void handle_sigwinch(int s) if (current_y > editwinrows - 1) edit_update(editbot, CENTER); - erase(); - /* Do these b/c width may have changed... */ - refresh(); - titlebar(NULL); - edit_refresh(); - display_main_list(); + /* Redraw the contents of the windows that need it. */ blank_statusbar(); + display_main_list(); total_refresh(); /* Turn cursor back on for sure */ diff --git a/nano.texi b/nano.texi index 66953907..8ac25678 100644 --- a/nano.texi +++ b/nano.texi @@ -77,10 +77,10 @@ internationalization support, and filename tab completion. The original goal for @code{nano} was a complete bug-for-bug compatible emulation of Pico, but nano's main goal is to be as compatible as -possible while offering a superset of Pico's functionality. -Also see @xref{Pico Compatibility}, for other differences. +possible while offering a superset of Pico's functionality. Also see +@xref{Pico Compatibility}, for other differences. -Email bug reports to @email{nano@@nano-editor.org}. +Email bug reports to @email{nano@@nano-editor.org}. @node Command Line Options, , Overview, Introduction @section Command Line Options @@ -99,6 +99,10 @@ Write file in DOS format. @item -F, --multibuffer Enable multiple file buffers, if available. +@item -H, --historylog +Log search and replace strings to ~/.nano_history, so they can be +retrieved in later sessions, if nanorc support is available. + @item -I, --ignorercfiles Don't look at $SYSCONFDIR/nanorc or ~/.nanorc, if nanorc support is available. @@ -133,7 +137,7 @@ Enable smooth scrolling. @item -T [num], --tabsize=[num] Set the displayed tab length to [num] columns. -@item -V, --version +@item -V, --version Print the version number and copyright and quit. @item -Y, --syntax=[str] @@ -167,10 +171,10 @@ Set operating directory. Makes @code{nano} set up something similar to a chroot. @item -p, --preserve -Preserve the ^Q (XON) and ^S (XOFF) sequences so data being sent to the editor -can be can be stopped and started. +Preserve the ^Q (XON) and ^S (XOFF) sequences so data being sent to the +editor can be can be stopped and started. -@item -r [#cols], --fill=[#cols]. +@item -r [#cols], --fill=[#cols] Wrap lines at column #cols. By default this is the width of the screen, less eight. If this value is negative, wrapping will occur at #cols from the right of the screen, allowing it to vary along with the screen width @@ -186,23 +190,23 @@ Do not ask whether or not to save the current contents of the file when exiting, assume yes. This is most useful when using @code{nano} as the composer of a mailer program. -@anchor{Expert Mode} -@item -x, --nohelp -In Expert Mode, the Shortcut Lists will not appear at the bottom of the -screen. This affects the location of the statusbar as well, as in Expert -Mode it is located at the very bottom of the editor. - -Note: When accessing the help system, Expert Mode is temporarily disabled -to display the help system navigation keys. - @item -v, --view Do not allow the contents of the file to be altered. Note that this -flag should NOT be used in place of correct file permissions to implement -a read-only file. +flag should NOT be used in place of correct file permissions to +implement a read-only file. @item -w, --nowrap -Do not wrap long lines at any length. This option overrides any value for --r. +Do not wrap long lines at any length. This option overrides any value +for -r. + +@anchor{Expert Mode} +@item -x, --nohelp +In Expert Mode, the Shortcut Lists will not appear at the bottom of the +screen. This affects the location of the statusbar as well, as in +Expert Mode it is located at the very bottom of the editor. + +Note: When accessing the help system, Expert Mode is temporarily +disabled to display the help system navigation keys. @item -z, --suspend Enable suspend ability of @code{nano} using the system's suspend @@ -231,27 +235,27 @@ Start at line number LINE instead of the default of line 1. All key sequences in @code{nano} are entered using the keyboard. @code{nano} is a ``modeless'' editor. All keys with the exception of Control and Meta key sequences will enter text into the file being -edited. +edited. @node Special Functions, The Titlebar, Entering Text, Editor Basics @section Special Functions Special functions use the Control key (displayed in the help and shortcut lists as ^) or the Meta key (displayed as M). - + @itemize @bullet - + @item Control key sequences are entered by holding down the Control key and -pressing the desired letter. +pressing the desired letter. @item -Meta key sequences can be entered in a number of -possible ways: Pressing the Escape key, then releasing it and pressing -the desired key, or holding down the Alt key while pressing the desired -key. This varies from keyboard to keyboard, and certain commercial -operating systems ``swallow'' the Alt key so that it never reaches the -application. If your operating system does this, you should use the -Escape key to generate Meta key sequences. +Meta key sequences can be entered in a number of possible ways: Pressing +the Escape key, then releasing it and pressing the desired key, or +holding down the Alt key while pressing the desired key. This varies +from keyboard to keyboard, and certain commercial operating systems +``swallow'' the Alt key so that it never reaches the application. If +your operating system does this, you should use the Escape key to +generate Meta key sequences. @end itemize @node The Titlebar, The Statusbar, Special Functions, Editor Basics @@ -284,24 +288,24 @@ the statusbar. @section Shortcut Lists The Shortcut Lists are the two lines at the bottom of the screen which -show some of the more commonly used functions in the editor. +show some of the more commonly used functions in the editor. @node Online Help, Feature Toggles, Editor Basics, Top @chapter Online Help -The online help system in @code{nano} is available by pressing ^G. -It is fairly self explanatory, documenting the various parts of the -editor and available keystrokes. Navigation is via the ^Y (Page Up) -and ^V (Page Down) keys. ^X exits the help system. +The online help system in @code{nano} is available by pressing ^G. It is +fairly self explanatory, documenting the various parts of the editor and +available keystrokes. Navigation is via the ^Y (Page Up) and ^V (Page +Down) keys. ^X exits the help system. @node Feature Toggles, The File Browser, Online Help, Top @chapter Feature Toggles -Toggles allow you to change certain aspects of the editor that -would normally be done via command line flags. They are invoked via -certain Meta key sequences. @xref{Special Functions}, for more info. -The following global toggles are available: +Toggles allow you to change certain aspects of the editor that would +normally be done via command line flags. They are invoked via certain +Meta key sequences. @xref{Special Functions}, for more info. The +following global toggles are available: @table @code @@ -357,7 +361,7 @@ find the desired file. Basic movement in the file browser is accomplished with the arrow keys and page up/down. The behavior of the enter (or `s') key varies by what is currently selected. If the currently selected object is a directory, -the file browser will enter and display the contents of the directory. +the file browser will enter and display the contents of the directory. If the object is a file, this filename and path are copied to the statusbar and the file browser is exited. @@ -370,15 +374,15 @@ are certain differences between the editors: @table @code @item Search and Replace History As of version 1.2.5 of @code{nano}, text entered as search or replace -strings will be stored and can be accessed with the up/down -arrow keys. Previously, @code{nano} offered a more consistent, but incompatible -with Pico, method for entering search and replace strings. In the old -method, previous entries would be displayed by default as editable text -in front of the cursor, as opposed to being bracketed and uneditable as -it is in Pico. The old behavior could be made compatible with Pico via the -@code{-p} flag, but recent versions of Pico use the @code{-p} flag -to preserve the XON and XOFF sequences within the editor. Since with the new -method search and replace strings can still be edited by simply +strings will be stored and can be accessed with the up/down arrow keys. +Previously, @code{nano} offered a more consistent, but incompatible with +Pico, method for entering search and replace strings. In the old +method, previous entries would be displayed by default as editable text +in front of the cursor, as opposed to being bracketed and uneditable as +it is in Pico. The old behavior could be made compatible with Pico via +the @code{-p} flag, but recent versions of Pico use the @code{-p} flag +to preserve the XON and XOFF sequences within the editor. Since with +the new method search and replace strings can still be edited by simply hitting the up arrow key once, the old method was removed completely. @@ -387,13 +391,12 @@ Text selected using the Control-Caret (^^) key can be written out or appended to a new or existing file using the Writeout key (^O). @item Toggles -Many options which alter the functionality of the program can be -"toggled" on or off using Meta key sequences, meaning the program does -not have to be restarted to turn a particular feature of the editor -on or off. Please see the internal help function (^G) for a list of -what functions can be toggled for a particular version of -@code{nano}. Also see @xref{Feature Toggles}, though this may be out -of date. +Many options which alter the functionality of the program can be +"toggled" on or off using Meta key sequences, meaning the program does +not have to be restarted to turn a particular feature of the editor on +or off. Please see the internal help function (^G) for a list of what +functions can be toggled for a particular version of @code{nano}. Also +see @xref{Feature Toggles}, though this may be out of date. @item Cursor Position Display The output of the "Display Cursor Position" in @code{nano} displays @@ -402,21 +405,21 @@ position of the cursor. @item Interactive Replace and Spell Checker It is worth noting that the @code{nano} replace function is interactive, -i.e. it does not stop after one search string is found and automatically +i.e. it does not stop after one search string is found and automatically replace it. The @code{nano} implementation will stop at each search -string found and query whether to replace this instance or not. The -internal spell checker operates similarly. Note that these is no way -to force these functions to behave in the Pico fashion. As of -version 1.2.5, misspelled words are sorted and trimmed for -uniqueness in the internal spell checker such that the words 'apple' -and 'Apple' will be prompted for correction separately. +string found and query whether to replace this instance or not. The +internal spell checker operates similarly. Note that these is no way +to force these functions to behave in the Pico fashion. As of +version 1.2.5, misspelled words are sorted and trimmed for +uniqueness in the internal spell checker such that the words 'apple' +and 'Apple' will be prompted for correction separately. @end table @node Building and Configure Options, , Pico Compatibility, Top @chapter Building and Configure Options -Building @code{nano} from source is fairly straightforward if you are familiar -with compiling programs with autoconf support: +Building @code{nano} from source is fairly straightforward if you are +familiar with compiling programs with autoconf support: @itemize @bullet @item tar xvfz nano-x.y.z.tar.gz (where x.y.z is the version of nano) diff --git a/utils.c b/utils.c index bb02a5db..1d920ffc 100644 --- a/utils.c +++ b/utils.c @@ -56,7 +56,7 @@ int num_of_digits(int n) if (n < 0) n = -n; - while (n > 10) { + while (n >= 10) { n /= 10; i++; } diff --git a/winio.c b/winio.c index 72d0d43a..d80e5198 100644 --- a/winio.c +++ b/winio.c @@ -869,118 +869,129 @@ void edit_add(const filestruct *fileptr, int yval, int start goto step_two; start_line = start_line->prev; } - /* No start found, so skip to the next step. */ - if (start_line == NULL) - goto step_two; - /* Now start_line is the first line before fileptr - * containing a start match. Is there a start on this - * line not followed by an end on this line? */ - start_col = 0; - while (1) { - start_col += startmatch.rm_so; - startmatch.rm_eo -= startmatch.rm_so; - if (regexec(tmpcolor->end, + if (startmatch.rm_so == startmatch.rm_eo) { + startmatch.rm_eo++; + statusbar(_("Refusing 0 length regex match")); + } else { + /* No start found, so skip to the next step. */ + if (start_line == NULL) + goto step_two; + /* Now start_line is the first line before fileptr + * containing a start match. Is there a start on + * this line not followed by an end on this line? */ + + start_col = 0; + while (1) { + start_col += startmatch.rm_so; + startmatch.rm_eo -= startmatch.rm_so; + if (regexec(tmpcolor->end, start_line->data + start_col + startmatch.rm_eo, 1, &endmatch, start_col + startmatch.rm_eo == 0 ? 0 : REG_NOTBOL)) - /* No end found after this start */ - break; - start_col++; - if (regexec(&tmpcolor->start, + /* No end found after this start */ + break; + start_col++; + if (regexec(&tmpcolor->start, start_line->data + start_col, 1, &startmatch, REG_NOTBOL)) /* No later start on this line. */ goto step_two; - } - /* Indeed, there is a start not followed on this line by an - * end. */ - - /* We have already checked that there is no end before - * fileptr and after the start. Is there an end after - * the start at all? We don't paint unterminated starts. */ - end_line = fileptr; - while (end_line != NULL && - regexec(tmpcolor->end, end_line->data, 1, &endmatch, 0)) - end_line = end_line->next; - - /* No end found, or it is too early. */ - if (end_line == NULL || end_line->lineno < fileptr->lineno || - (end_line == fileptr && endmatch.rm_eo <= start)) - goto step_two; - - /* Now paint the start of fileptr. */ - paintlen = end_line != fileptr - ? COLS : endmatch.rm_eo - start; - if (paintlen > COLS) - paintlen = COLS; - - assert(0 < paintlen && paintlen <= COLS); - mvwaddnstr(edit, yval, 0, fileptr->data + start, paintlen); - - /* We have already painted the whole line. */ - if (paintlen == COLS) - goto skip_step_two; - - step_two: /* Second step, we look for starts on this line. */ - start_col = 0; - while (start_col < start + COLS) { - if (regexec(&tmpcolor->start, fileptr->data + start_col, 1, - &startmatch, start_col == 0 ? 0 : REG_NOTBOL) - || start_col + startmatch.rm_so >= start + COLS) - /* No more starts on this line. */ - break; - /* Translate the match to be relative to the - * beginning of the line. */ - startmatch.rm_so += start_col; - startmatch.rm_eo += start_col; - - x_start = startmatch.rm_so - start; - if (x_start < 0) { - x_start = 0; - startmatch.rm_so = start; } - if (!regexec(tmpcolor->end, fileptr->data + startmatch.rm_eo, - 1, &endmatch, - startmatch.rm_eo == 0 ? 0 : REG_NOTBOL)) { - /* Translate the end match to be relative to the - beginning of the line. */ - endmatch.rm_so += startmatch.rm_eo; - endmatch.rm_eo += startmatch.rm_eo; - /* There is an end on this line. But does it - appear on this page, and is the match more than - zero characters long? */ - if (endmatch.rm_eo > start && - endmatch.rm_eo > startmatch.rm_so) { - paintlen = endmatch.rm_eo - start - x_start; - if (x_start + paintlen > COLS) - paintlen = COLS - x_start; + /* Indeed, there is a start not followed on this + * line by an end. */ - assert(0 <= x_start && 0 < paintlen && - x_start + paintlen <= COLS); - mvwaddnstr(edit, yval, x_start, - fileptr->data + start + x_start, paintlen); + /* We have already checked that there is no end + * before fileptr and after the start. Is there an + * end after the start at all? We don't paint + * unterminated starts. */ + end_line = fileptr; + while (end_line != NULL && + regexec(tmpcolor->end, end_line->data, 1, &endmatch, 0)) + end_line = end_line->next; + + /* No end found, or it is too early. */ + if (end_line == NULL || end_line->lineno < + fileptr->lineno || (end_line == fileptr && + endmatch.rm_eo <= start)) + goto step_two; + + /* Now paint the start of fileptr. */ + paintlen = end_line != fileptr + ? COLS : endmatch.rm_eo - start; + if (paintlen > COLS) + paintlen = COLS; + + assert(0 < paintlen && paintlen <= COLS); + mvwaddnstr(edit, yval, 0, fileptr->data + start, paintlen); + + /* We have already painted the whole line. */ + if (paintlen == COLS) + goto skip_step_two; + + step_two: /* Second step, we look for starts on this line. */ + start_col = 0; + while (start_col < start + COLS) { + if (regexec(&tmpcolor->start, fileptr->data + + start_col, 1, &startmatch, start_col == 0 ? + 0 : REG_NOTBOL) + || start_col + startmatch.rm_so >= start + COLS) + /* No more starts on this line. */ + break; + /* Translate the match to be relative to the + * beginning of the line. */ + startmatch.rm_so += start_col; + startmatch.rm_eo += start_col; + + x_start = startmatch.rm_so - start; + if (x_start < 0) { + x_start = 0; + startmatch.rm_so = start; } - } else if (!searched_later_lines) { - searched_later_lines = 1; - /* There is no end on this line. But we haven't - * yet looked for one on later lines. */ - end_line = fileptr->next; - while (end_line != NULL && regexec(tmpcolor->end, + if (!regexec(tmpcolor->end, fileptr->data + + startmatch.rm_eo, 1, &endmatch, + startmatch.rm_eo == 0 ? 0 : REG_NOTBOL)) { + /* Translate the end match to be relative to + * the beginning of the line. */ + endmatch.rm_so += startmatch.rm_eo; + endmatch.rm_eo += startmatch.rm_eo; + /* There is an end on this line. But does + it appear on this page, and is the match + more than zero characters long? */ + if (endmatch.rm_eo > start && + endmatch.rm_eo > startmatch.rm_so) { + paintlen = endmatch.rm_eo - start - x_start; + if (x_start + paintlen > COLS) + paintlen = COLS - x_start; + + assert(0 <= x_start && 0 < paintlen && + x_start + paintlen <= COLS); + mvwaddnstr(edit, yval, x_start, + fileptr->data + start + x_start, + paintlen); + } + } else if (!searched_later_lines) { + searched_later_lines = 1; + /* There is no end on this line. But we + * haven't yet looked for one on later + * lines. */ + end_line = fileptr->next; + while (end_line != NULL && regexec(tmpcolor->end, end_line->data, 1, &endmatch, 0)) - end_line = end_line->next; - if (end_line != NULL) { - assert(0 <= x_start && x_start < COLS); - mvwaddnstr(edit, yval, x_start, + end_line = end_line->next; + if (end_line != NULL) { + assert(0 <= x_start && x_start < COLS); + mvwaddnstr(edit, yval, x_start, fileptr->data + start + x_start, COLS - x_start); - /* We painted to the end of the line, so - * don't bother checking any more starts. */ - break; + /* We painted to the end of the line, so + * don't bother checking any more starts. */ + break; + } } - } - start_col = startmatch.rm_so + 1; - } /* while start_col < start + COLS */ + start_col = startmatch.rm_so + 1; + } /* while start_col < start + COLS */ + } /* if (startmatch.rm_so == startmatch.rm_eo) */ } /* if (tmp_color->end != NULL) */ skip_step_two: @@ -1406,18 +1417,18 @@ int do_yesno(int all, int leavecursor, const char *msg, ...) int total_refresh(void) { - clearok(edit, TRUE); - clearok(topwin, TRUE); - clearok(bottomwin, TRUE); - wnoutrefresh(edit); - wnoutrefresh(topwin); - wnoutrefresh(bottomwin); - doupdate(); - clearok(edit, FALSE); - clearok(topwin, FALSE); - clearok(bottomwin, FALSE); - edit_refresh(); +#ifdef USE_SLANG + /* Slang curses emulation brain damage: Slang doesn't define + * curscr. */ + SLsmg_touch_screen(); + SLsmg_refresh(); +#else + wrefresh(curscr); +#endif + titlebar(NULL); + edit_refresh(); + return 1; }