diff --git a/ChangeLog b/ChangeLog index e9f2531d..212a4945 100644 --- a/ChangeLog +++ b/ChangeLog @@ -76,10 +76,21 @@ CVS code - - Simplify by reusing variables whereever possible, and add a parameter execute to indicate whether or not to be in "Execute Command" mode. (DLR) - - If file browsing succeeds, copy the filename we browsed to - into ans, put back Enter, and show the prompt one last time so - that it's exited properly and the cursor position at the - statusbar is reset. (DLR) + - Rework so that goto is no longer needed, using do_writeout() + as a model. (DLR) + - If file browsing succeeds, call statusq_abort() so that the + cursor position at the statusbar is reset. (DLR) + do_writeout() + - Restructure if blocks for greater efficiency, using + do_insertfile() as a model. (DLR) + - Simplify where possible, and use an int retval to hold the + return value instead of i. (DLR) + - If file browsing succeeds, call statusq_abort() so that the + cursor position at the statusbar is reset. (DLR) + - Remove unneeded calls to display_main_list(). (DLR) + do_writeout_void() + - Call display_main_list(), for consistency with + do_insertfile_void(). (DLR) open_prevfile(), open_nextfile() - Translate the "New Buffer" string when displaying "Switched to" messages on the statusbar. (DLR) @@ -165,13 +176,14 @@ CVS code - - Refresh the screen when Ctrl-L is pressed at the statusbar prompt, as Pico does. (DLR) - Always return the key pressed by the user. (DLR) - - Take new parameter reset_x, containing the value of - resetstatuspos, so that resetstatuspos can be a static - variable for just statusq(). (DLR) statusq() - Rework slightly to reset the cursor position when the user hits Enter as well as Cancel. This means that resetstatuspos no longer needs to be global. (DLR) + statusq_abort() + - New function to set resetstatuspos to FALSE when we don't + properly exit the statusbar prompt, e.g. when we get a file + from the file browser). (DLR) reset_cursor() - If this is called before any files have been opened, as it can be by statusbar(), put the cursor at the top left corner of diff --git a/src/files.c b/src/files.c index 887ff537..e3f5b1e4 100644 --- a/src/files.c +++ b/src/files.c @@ -494,36 +494,32 @@ void do_insertfile( int i; const char *msg; char *ans = mallocstrcpy(NULL, ""); - /* The last answer the user typed on the statusbar. Saved for if - * they do M-F or cancel the file browser. */ + /* The last answer the user typed on the statusbar. */ wrap_reset(); -#if !defined(DISABLE_BROWSER) || (!defined(NANO_SMALL) && defined(ENABLE_MULTIBUFFER)) - start_again: -#endif - + while (TRUE) { #ifndef NANO_SMALL - if (execute) { + if (execute) { #ifdef ENABLE_MULTIBUFFER - if (ISSET(MULTIBUFFER)) - msg = N_("Command to execute in new buffer [from %s] "); - else + if (ISSET(MULTIBUFFER)) + msg = N_("Command to execute in new buffer [from %s] "); + else #endif - msg = N_("Command to execute [from %s] "); - } else { + msg = N_("Command to execute [from %s] "); + } else { #endif #ifdef ENABLE_MULTIBUFFER - if (ISSET(MULTIBUFFER)) { - msg = N_("File to insert into new buffer [from %s] "); - } else + if (ISSET(MULTIBUFFER)) { + msg = N_("File to insert into new buffer [from %s] "); + } else #endif - msg = N_("File to insert [from %s] "); + msg = N_("File to insert [from %s] "); #ifndef NANO_SMALL } #endif - i = statusq(TRUE, + i = statusq(TRUE, #ifndef NANO_SMALL execute ? extcmd_list : #endif @@ -538,73 +534,78 @@ void do_insertfile( #endif "./"); - if (i < 0) { - statusbar(_("Cancelled")); - } else { - int old_current_x = current_x; + if (i < 0) { + statusbar(_("Cancelled")); + break; + } else { + int old_current_x = current_x; - ans = mallocstrcpy(ans, answer); + ans = mallocstrcpy(ans, answer); #if !defined(NANO_SMALL) && defined(ENABLE_MULTIBUFFER) - if (i == TOGGLE_MULTIBUFFER_KEY) { - /* Don't allow toggling if we're in view mode. */ - if (!ISSET(VIEW_MODE)) - TOGGLE(MULTIBUFFER); - goto start_again; - } + if (i == TOGGLE_MULTIBUFFER_KEY) { + /* Don't allow toggling if we're in view mode. */ + if (!ISSET(VIEW_MODE)) + TOGGLE(MULTIBUFFER); + continue; + } #endif #ifndef DISABLE_BROWSER - if (i == NANO_TOFILES_KEY) { - char *tmp = do_browse_from(answer); + if (i == NANO_TOFILES_KEY) { + char *tmp = do_browse_from(answer); - if (tmp != NULL) { + if (tmp == NULL) + continue; free(answer); answer = tmp; - ans = mallocstrcpy(ans, answer); - unget_kbinput(NANO_ENTER_KEY, FALSE); + + /* We have a file now. Get out of the statusbar prompt + * cleanly. */ + statusq_abort(); } - goto start_again; - } #endif #ifndef NANO_SMALL - if (i == NANO_TOOTHERINSERT_KEY) { - execute = !execute; - goto start_again; - } + if (i == NANO_TOOTHERINSERT_KEY) { + execute = !execute; + continue; + } - if (execute) - execute_command(answer); - else { + if (execute) + execute_command(answer); + else { #endif - answer = mallocstrassn(answer, real_dir_from_tilde(answer)); - load_buffer(answer); + answer = mallocstrassn(answer, real_dir_from_tilde(answer)); + load_buffer(answer); #ifndef NANO_SMALL - } + } #endif #ifdef ENABLE_MULTIBUFFER - if (ISSET(MULTIBUFFER)) { - /* Update the titlebar. */ - titlebar(NULL); + if (ISSET(MULTIBUFFER)) { + /* Update the titlebar. */ + titlebar(NULL); - /* Reinitialize the shortcut list. */ - shortcut_init(FALSE); - } else { + /* Reinitialize the shortcut list. */ + shortcut_init(FALSE); + } else { #endif - /* Mark the file as modified. */ - set_modified(); + /* Mark the file as modified. */ + set_modified(); - /* Restore the old x-coordinate position. */ - current_x = old_current_x; + /* Restore the old x-coordinate position. */ + current_x = old_current_x; #ifdef ENABLE_MULTIBUFFER - } + } #endif - /* Refresh the screen. */ - edit_refresh(); - } + /* Refresh the screen. */ + edit_refresh(); + + break; + } + } /* while (TRUE) */ free(ans); } @@ -1770,7 +1771,9 @@ int write_marked(const char *name, int tmp, int append) int do_writeout(bool exiting) { int i; - int append = 0; + int retval = 0, append = 0; + char *ans; + /* The last answer the user typed on the statusbar. */ #ifdef NANO_EXTRA static bool did_cred = FALSE; #endif @@ -1780,25 +1783,23 @@ int do_writeout(bool exiting) #endif if (exiting && filename[0] != '\0' && ISSET(TEMP_FILE)) { - i = write_file(filename, FALSE, 0, FALSE); - if (i == 1) { - /* Write succeeded. */ - display_main_list(); - return 1; - } + retval = write_file(filename, FALSE, 0, FALSE); + + /* Write succeeded. */ + if (retval == 1) + return retval; } #ifndef NANO_SMALL if (ISSET(MARK_ISSET) && !exiting) - answer = mallocstrcpy(answer, ""); + ans = mallocstrcpy(NULL, ""); else #endif - answer = mallocstrcpy(answer, filename); + ans = mallocstrcpy(NULL, filename); while (TRUE) { const char *msg; #ifndef NANO_SMALL - char *ans = mallocstrcpy(NULL, answer); const char *formatstr, *backupstr; if (ISSET(DOS_FILE)) @@ -1834,117 +1835,125 @@ int do_writeout(bool exiting) * and we're at the "Write File" prompt, disable tab * completion. */ i = statusq(!ISSET(RESTRICTED) || filename[0] == '\0', - writefile_list, + writefile_list, ans, #ifndef NANO_SMALL - ans, NULL, "%s%s%s", _(msg), formatstr, backupstr + NULL, "%s%s%s", _(msg), formatstr, backupstr #else - filename, "%s", _(msg) + "%s", _(msg) #endif ); -#ifndef NANO_SMALL - free(ans); -#endif - if (i < 0) { statusbar(_("Cancelled")); - display_main_list(); - return -1; - } + retval = -1; + break; + } else { + ans = mallocstrcpy(ans, answer); #ifndef DISABLE_BROWSER - if (i == NANO_TOFILES_KEY) { - char *tmp = do_browse_from(answer); + if (i == NANO_TOFILES_KEY) { + char *tmp = do_browse_from(answer); - currshortcut = writefile_list; - if (tmp == NULL) - continue; - free(answer); - answer = tmp; - } else + currshortcut = writefile_list; + + if (tmp == NULL) + continue; + free(answer); + answer = tmp; + + /* We have a file now. Get out of the statusbar prompt + * cleanly. */ + statusq_abort(); + } else #endif /* !DISABLE_BROWSER */ #ifndef NANO_SMALL - if (i == TOGGLE_DOS_KEY) { - UNSET(MAC_FILE); - TOGGLE(DOS_FILE); - continue; - } else if (i == TOGGLE_MAC_KEY) { - UNSET(DOS_FILE); - TOGGLE(MAC_FILE); - continue; - } else if (i == TOGGLE_BACKUP_KEY) { - TOGGLE(BACKUP_FILE); - continue; - } else + if (i == TOGGLE_DOS_KEY) { + UNSET(MAC_FILE); + TOGGLE(DOS_FILE); + continue; + } else if (i == TOGGLE_MAC_KEY) { + UNSET(DOS_FILE); + TOGGLE(MAC_FILE); + continue; + } else if (i == TOGGLE_BACKUP_KEY) { + TOGGLE(BACKUP_FILE); + continue; + } else #endif /* !NANO_SMALL */ - if (i == NANO_PREPEND_KEY) { - append = (append == 2) ? 0 : 2; - continue; - } else if (i == NANO_APPEND_KEY) { - append = (append == 1) ? 0 : 1; - continue; - } + if (i == NANO_PREPEND_KEY) { + append = (append == 2) ? 0 : 2; + continue; + } else if (i == NANO_APPEND_KEY) { + append = (append == 1) ? 0 : 1; + continue; + } #ifdef DEBUG - fprintf(stderr, "filename is %s\n", answer); + fprintf(stderr, "filename is %s\n", answer); #endif #ifdef NANO_EXTRA - if (exiting && !ISSET(TEMP_FILE) && strcasecmp(answer, "zzy") == 0 - && !did_cred) { - do_credits(); - did_cred = TRUE; - return -1; - } -#endif - if (append == 0 && strcmp(answer, filename) != 0) { - struct stat st; - - if (!stat(answer, &st)) { - i = do_yesno(FALSE, _("File exists, OVERWRITE ? ")); - if (i == 0 || i == -1) - continue; - /* If we're using restricted mode, we aren't allowed to - * change the name of a file once it has one because that - * would allow reading from or writing to files not - * specified on the command line. In this case, don't - * bother showing the "Different Name" prompt. */ - } else if (!ISSET(RESTRICTED) && filename[0] != '\0' -#ifndef NANO_SMALL - && (exiting || !ISSET(MARK_ISSET)) -#endif - ) { - i = do_yesno(FALSE, _("Save file under DIFFERENT NAME ? ")); - if (i == 0 || i == -1) - continue; + if (exiting && !ISSET(TEMP_FILE) && + strcasecmp(answer, "zzy") == 0 && !did_cred) { + do_credits(); + did_cred = TRUE; + retval = -1; + break; + } +#endif + if (append == 0 && strcmp(answer, filename) != 0) { + struct stat st; + + if (!stat(answer, &st)) { + i = do_yesno(FALSE, _("File exists, OVERWRITE ? ")); + if (i == 0 || i == -1) + continue; + /* If we're using restricted mode, we aren't allowed to + * change the name of a file once it has one because + * that would allow reading from or writing to files not + * specified on the command line. In this case, don't + * bother showing the "Different Name" prompt. */ + } else if (!ISSET(RESTRICTED) && filename[0] != '\0' +#ifndef NANO_SMALL + && (exiting || !ISSET(MARK_ISSET)) +#endif + ) { + i = do_yesno(FALSE, _("Save file under DIFFERENT NAME ? ")); + if (i == 0 || i == -1) + continue; + } } - } #ifndef NANO_SMALL - /* Here's where we allow the selected text to be written to a - * separate file. If we're using restricted mode, this is - * disabled since it allows reading from or writing to files not - * specified on the command line. */ - if (!ISSET(RESTRICTED) && !exiting && ISSET(MARK_ISSET)) - i = write_marked(answer, FALSE, append); - else + /* Here's where we allow the selected text to be written to + * a separate file. If we're using restricted mode, this is + * disabled since it allows reading from or writing to files + * not specified on the command line. */ + if (!ISSET(RESTRICTED) && !exiting && ISSET(MARK_ISSET)) + retval = write_marked(answer, FALSE, append); + else #endif /* !NANO_SMALL */ - i = write_file(answer, FALSE, append, FALSE); + retval = write_file(answer, FALSE, append, FALSE); #ifdef ENABLE_MULTIBUFFER - /* If we're not about to exit, update the current entry in - * the open_files structure. */ - if (!exiting) - add_open_file(TRUE); + /* If we're not about to exit, update the current entry in + * the open_files structure. */ + if (!exiting) + add_open_file(TRUE); #endif - display_main_list(); - return i; + + break; + } } /* while (TRUE) */ + + free(ans); + return retval; } void do_writeout_void(void) { do_writeout(FALSE); + display_main_list(); } /* Return a malloc()ed string containing the actual directory, used diff --git a/src/proto.h b/src/proto.h index c94077e4..a4061761 100644 --- a/src/proto.h +++ b/src/proto.h @@ -551,15 +551,21 @@ void check_statusblank(void); void blank_bottombars(void); char *display_string(const char *buf, size_t start_col, size_t len); void nanoget_repaint(const char *buf, const char *inputbuf, size_t x); -int nanogetstr(int allowtabs, const char *buf, const char *def, +int nanogetstr(bool allow_tabs, const char *buf, const char *def, #ifndef NANO_SMALL historyheadtype *history_list, #endif - const shortcut *s, bool reset_x + const shortcut *s #ifndef DISABLE_TABCOMP , bool *list #endif ); +int statusq(bool allow_tabs, const shortcut *s, const char *def, +#ifndef NANO_SMALL + historyheadtype *history_list, +#endif + const char *msg, ...); +void statusq_abort(void); void titlebar(const char *path); void set_modified(void); void statusbar(const char *msg, ...); @@ -579,12 +585,7 @@ void edit_scroll(updown direction, int nlines); void edit_redraw(const filestruct *old_current, size_t old_pww); void edit_refresh(void); void edit_update(topmidnone location); -int statusq(int allowtabs, const shortcut *s, const char *def, -#ifndef NANO_SMALL - historyheadtype *history_list, -#endif - const char *msg, ...); -int do_yesno(int all, const char *msg); +int do_yesno(bool all, const char *msg); void total_refresh(void); void display_main_list(void); void do_cursorpos(bool constant); diff --git a/src/winio.c b/src/winio.c index 9823433b..5282369c 100644 --- a/src/winio.c +++ b/src/winio.c @@ -33,6 +33,9 @@ static int statusblank = 0; /* Number of keystrokes left after * we call statusbar(), before we * actually blank the statusbar. */ +static bool resetstatuspos = FALSE; + /* Should we reset the cursor position + * at the statusbar prompt? */ /* Control character compatibility: * @@ -1755,11 +1758,11 @@ void nanoget_repaint(const char *buf, const char *inputbuf, size_t x) /* Get the input from the keyboard; this should only be called from * statusq(). */ -int nanogetstr(int allowtabs, const char *buf, const char *def, +int nanogetstr(bool allow_tabs, const char *buf, const char *def, #ifndef NANO_SMALL historyheadtype *history_list, #endif - const shortcut *s, bool reset_x + const shortcut *s #ifndef DISABLE_TABCOMP , bool *list #endif @@ -1793,11 +1796,11 @@ int nanogetstr(int allowtabs, const char *buf, const char *def, xend = strlen(def); /* Only put x at the end of the string if it's uninitialized, if it - would be past the end of the string as it is, or if reset_x is - TRUE. Otherwise, leave it alone. This is so the cursor position - stays at the same place if a prompt-changing toggle is - pressed. */ - if (x == -1 || x > xend || reset_x) + would be past the end of the string as it is, or if + resetstatuspos is TRUE. Otherwise, leave it alone. This is so + the cursor position stays at the same place if a prompt-changing + toggle is pressed. */ + if (x == -1 || x > xend || resetstatuspos) x = xend; answer = charealloc(answer, xend + 1); @@ -1944,7 +1947,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def, #endif #endif #ifndef DISABLE_TABCOMP - if (allowtabs) { + if (allow_tabs) { int shift = 0; answer = input_tab(answer, x, &tabbed, &shift, list); @@ -2090,6 +2093,106 @@ int nanogetstr(int allowtabs, const char *buf, const char *def, return kbinput; } +/* Ask a question on the statusbar. Answer will be stored in answer + * global. Returns -1 on aborted enter, -2 on a blank string, and 0 + * otherwise, the valid shortcut key caught. def is any editable text + * we want to put up by default. + * + * New arg tabs tells whether or not to allow tab completion. */ +int statusq(bool allow_tabs, const shortcut *s, const char *def, +#ifndef NANO_SMALL + historyheadtype *which_history, +#endif + const char *msg, ...) +{ + va_list ap; + char *foo = charalloc(COLS - 3); + int ret; +#ifndef DISABLE_TABCOMP + bool list = FALSE; +#endif + + bottombars(s); + + va_start(ap, msg); + vsnprintf(foo, COLS - 4, msg, ap); + va_end(ap); + foo[COLS - 4] = '\0'; + + ret = nanogetstr(allow_tabs, foo, def, +#ifndef NANO_SMALL + which_history, +#endif + s +#ifndef DISABLE_TABCOMP + , &list +#endif + ); + free(foo); + resetstatuspos = FALSE; + + switch (ret) { + case NANO_FIRSTLINE_KEY: + case NANO_FIRSTLINE_FKEY: + do_first_line(); + resetstatuspos = TRUE; + break; + case NANO_LASTLINE_KEY: + case NANO_LASTLINE_FKEY: + do_last_line(); + resetstatuspos = TRUE; + break; +#ifndef DISABLE_JUSTIFY + case NANO_PARABEGIN_KEY: + case NANO_PARABEGIN_ALTKEY1: + case NANO_PARABEGIN_ALTKEY2: + do_para_begin(); + resetstatuspos = TRUE; + break; + case NANO_PARAEND_KEY: + case NANO_PARAEND_ALTKEY1: + case NANO_PARAEND_ALTKEY2: + do_para_end(); + resetstatuspos = TRUE; + break; + case NANO_FULLJUSTIFY_KEY: + case NANO_FULLJUSTIFY_ALTKEY: + if (!ISSET(VIEW_MODE)) + do_full_justify(); + resetstatuspos = TRUE; + break; +#endif + case NANO_CANCEL_KEY: + ret = -1; + resetstatuspos = TRUE; + break; + case NANO_ENTER_KEY: + ret = (answer[0] == '\0') ? -2 : 0; + resetstatuspos = TRUE; + break; + } + blank_statusbar(); + +#ifdef DEBUG + fprintf(stderr, "I got \"%s\"\n", answer); +#endif + +#ifndef DISABLE_TABCOMP + /* if we've done tab completion, there might be a list of + filename matches on the edit window at this point; make sure + they're cleared off. */ + if (list) + edit_refresh(); +#endif + + return ret; +} + +void statusq_abort(void) +{ + resetstatuspos = TRUE; +} + void titlebar(const char *path) { size_t space; @@ -2972,106 +3075,10 @@ void edit_update(topmidnone location) edit_refresh(); } -/* Ask a question on the statusbar. Answer will be stored in answer - * global. Returns -1 on aborted enter, -2 on a blank string, and 0 - * otherwise, the valid shortcut key caught. def is any editable text - * we want to put up by default. - * - * New arg tabs tells whether or not to allow tab completion. */ -int statusq(int allowtabs, const shortcut *s, const char *def, -#ifndef NANO_SMALL - historyheadtype *which_history, -#endif - const char *msg, ...) -{ - va_list ap; - char *foo = charalloc(COLS - 3); - int ret; - static bool resetstatuspos = FALSE; -#ifndef DISABLE_TABCOMP - bool list = FALSE; -#endif - - bottombars(s); - - va_start(ap, msg); - vsnprintf(foo, COLS - 4, msg, ap); - va_end(ap); - foo[COLS - 4] = '\0'; - - ret = nanogetstr(allowtabs, foo, def, -#ifndef NANO_SMALL - which_history, -#endif - s, resetstatuspos -#ifndef DISABLE_TABCOMP - , &list -#endif - ); - free(foo); - resetstatuspos = FALSE; - - switch (ret) { - case NANO_FIRSTLINE_KEY: - case NANO_FIRSTLINE_FKEY: - do_first_line(); - resetstatuspos = TRUE; - break; - case NANO_LASTLINE_KEY: - case NANO_LASTLINE_FKEY: - do_last_line(); - resetstatuspos = TRUE; - break; -#ifndef DISABLE_JUSTIFY - case NANO_PARABEGIN_KEY: - case NANO_PARABEGIN_ALTKEY1: - case NANO_PARABEGIN_ALTKEY2: - do_para_begin(); - resetstatuspos = TRUE; - break; - case NANO_PARAEND_KEY: - case NANO_PARAEND_ALTKEY1: - case NANO_PARAEND_ALTKEY2: - do_para_end(); - resetstatuspos = TRUE; - break; - case NANO_FULLJUSTIFY_KEY: - case NANO_FULLJUSTIFY_ALTKEY: - if (!ISSET(VIEW_MODE)) - do_full_justify(); - resetstatuspos = TRUE; - break; -#endif - case NANO_CANCEL_KEY: - ret = -1; - resetstatuspos = TRUE; - break; - case NANO_ENTER_KEY: - ret = (answer[0] == '\0') ? -2 : 0; - resetstatuspos = TRUE; - break; - } - blank_statusbar(); - -#ifdef DEBUG - fprintf(stderr, "I got \"%s\"\n", answer); -#endif - -#ifndef DISABLE_TABCOMP - /* if we've done tab completion, there might be a list of - filename matches on the edit window at this point; make sure - they're cleared off. */ - if (list) - edit_refresh(); -#endif - - return ret; -} - /* Ask a simple yes/no question, specified in msg, on the statusbar. * Return 1 for Y, 0 for N, 2 for All (if all is TRUE when passed in) * and -1 for abort (^C). */ -int do_yesno(int all, const char *msg) +int do_yesno(bool all, const char *msg) { int ok = -2, width = 16; const char *yesstr; /* String of yes characters accepted. */