David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 1 | /************************************************************************** |
Benno Schulenberg | 514cd9a | 2016-08-29 17:10:49 +0200 | [diff] [blame] | 2 | * prompt.c -- This file is part of GNU nano. * |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 3 | * * |
Chris Allegretta | 8a07a96 | 2009-12-02 03:36:22 +0000 | [diff] [blame] | 4 | * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * |
Benno Schulenberg | 7a9f4a4 | 2014-04-30 20:18:26 +0000 | [diff] [blame] | 5 | * 2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc. * |
Benno Schulenberg | 406e524 | 2016-08-29 15:14:18 +0200 | [diff] [blame] | 6 | * Copyright (C) 2016 Benno Schulenberg * |
| 7 | * * |
Benno Schulenberg | 514cd9a | 2016-08-29 17:10:49 +0200 | [diff] [blame] | 8 | * GNU nano is free software: you can redistribute it and/or modify * |
| 9 | * it under the terms of the GNU General Public License as published * |
| 10 | * by the Free Software Foundation, either version 3 of the License, * |
| 11 | * or (at your option) any later version. * |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 12 | * * |
Benno Schulenberg | 514cd9a | 2016-08-29 17:10:49 +0200 | [diff] [blame] | 13 | * GNU nano is distributed in the hope that it will be useful, * |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty * |
| 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * |
| 16 | * See the GNU General Public License for more details. * |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 17 | * * |
| 18 | * You should have received a copy of the GNU General Public License * |
Benno Schulenberg | 514cd9a | 2016-08-29 17:10:49 +0200 | [diff] [blame] | 19 | * along with this program. If not, see http://www.gnu.org/licenses/. * |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 20 | * * |
| 21 | **************************************************************************/ |
| 22 | |
David Lawrence Ramsey | 034b994 | 2005-12-08 02:47:10 +0000 | [diff] [blame] | 23 | #include "proto.h" |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 24 | |
David Lawrence Ramsey | 143b8c7 | 2005-11-01 18:35:47 +0000 | [diff] [blame] | 25 | #include <stdio.h> |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 26 | #include <stdarg.h> |
| 27 | #include <string.h> |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 28 | |
| 29 | static char *prompt = NULL; |
David Lawrence Ramsey | 6335fb5 | 2007-01-01 05:15:32 +0000 | [diff] [blame] | 30 | /* The prompt string used for statusbar questions. */ |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 31 | static size_t statusbar_x = HIGHEST_POSITIVE; |
David Lawrence Ramsey | c1c818e | 2006-05-14 18:22:01 +0000 | [diff] [blame] | 32 | /* The cursor position in answer. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 33 | |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 34 | /* Read in a keystroke, interpret it if it is a shortcut or toggle, and |
| 35 | * return it. Set ran_func to TRUE if we ran a function associated with |
| 36 | * a shortcut key, and set finished to TRUE if we're done after running |
Benno Schulenberg | 379b155 | 2016-12-03 20:37:30 +0100 | [diff] [blame] | 37 | * or trying to run a function associated with a shortcut key. */ |
| 38 | int do_statusbar_input(bool *ran_func, bool *finished) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 39 | { |
| 40 | int input; |
| 41 | /* The character we read in. */ |
| 42 | static int *kbinput = NULL; |
| 43 | /* The input buffer. */ |
| 44 | static size_t kbinput_len = 0; |
| 45 | /* The length of the input buffer. */ |
Chris Allegretta | 79a33bb | 2008-03-05 07:34:01 +0000 | [diff] [blame] | 46 | const sc *s; |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 47 | bool have_shortcut = FALSE; |
Chris Allegretta | 79a33bb | 2008-03-05 07:34:01 +0000 | [diff] [blame] | 48 | const subnfunc *f; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 49 | |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 50 | *ran_func = FALSE; |
| 51 | *finished = FALSE; |
| 52 | |
| 53 | /* Read in a character. */ |
Benno Schulenberg | 7e5324d | 2014-06-30 18:04:33 +0000 | [diff] [blame] | 54 | input = get_kbinput(bottomwin); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 55 | |
Benno Schulenberg | 75d64e6 | 2015-05-28 13:02:29 +0000 | [diff] [blame] | 56 | #ifndef NANO_TINY |
| 57 | if (input == KEY_WINCH) |
| 58 | return KEY_WINCH; |
| 59 | #endif |
| 60 | |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 61 | #ifndef DISABLE_MOUSE |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 62 | /* If we got a mouse click and it was on a shortcut, read in the |
| 63 | * shortcut character. */ |
Benno Schulenberg | cb10b2b | 2016-07-13 16:22:56 +0200 | [diff] [blame] | 64 | if (input == KEY_MOUSE) { |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 65 | if (do_statusbar_mouse() == 1) |
Benno Schulenberg | 7e5324d | 2014-06-30 18:04:33 +0000 | [diff] [blame] | 66 | input = get_kbinput(bottomwin); |
Benno Schulenberg | 9cd30d4 | 2016-07-15 21:59:38 +0200 | [diff] [blame] | 67 | else |
Benno Schulenberg | 6ad3700 | 2016-08-27 11:11:00 +0200 | [diff] [blame] | 68 | return ERR; |
David Lawrence Ramsey | 8992d0a | 2006-05-10 12:48:47 +0000 | [diff] [blame] | 69 | } |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 70 | #endif |
| 71 | |
| 72 | /* Check for a shortcut in the current list. */ |
Benno Schulenberg | 49816fe | 2014-07-01 10:41:10 +0000 | [diff] [blame] | 73 | s = get_shortcut(&input); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 74 | |
| 75 | /* If we got a shortcut from the current list, or a "universal" |
| 76 | * statusbar prompt shortcut, set have_shortcut to TRUE. */ |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 77 | have_shortcut = (s != NULL); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 78 | |
David Lawrence Ramsey | d6eb175 | 2006-05-25 21:39:25 +0000 | [diff] [blame] | 79 | /* If we got a non-high-bit control key, a meta key sequence, or a |
| 80 | * function key, and it's not a shortcut or toggle, throw it out. */ |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 81 | if (!have_shortcut) { |
Benno Schulenberg | cb10b2b | 2016-07-13 16:22:56 +0200 | [diff] [blame] | 82 | if (is_ascii_cntrl_char(input) || meta_key || !is_byte(input)) { |
David Lawrence Ramsey | 106c1bf | 2006-06-03 19:36:02 +0000 | [diff] [blame] | 83 | beep(); |
David Lawrence Ramsey | 305d889 | 2006-05-24 19:48:03 +0000 | [diff] [blame] | 84 | input = ERR; |
David Lawrence Ramsey | 8e341e1 | 2006-05-24 17:36:00 +0000 | [diff] [blame] | 85 | } |
| 86 | } |
| 87 | |
Benno Schulenberg | bd1fcc5 | 2016-08-06 12:15:03 +0200 | [diff] [blame] | 88 | /* If the keystroke isn't a shortcut nor a toggle, it's a normal text |
| 89 | * character: add the it to the input buffer, when allowed. */ |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 90 | if (input != ERR && !have_shortcut) { |
Benno Schulenberg | bd1fcc5 | 2016-08-06 12:15:03 +0200 | [diff] [blame] | 91 | /* Only accept input when not in restricted mode, or when not at |
| 92 | * the "Write File" prompt, or when there is no filename yet. */ |
| 93 | if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE || |
| 94 | openfile->filename[0] == '\0') { |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 95 | kbinput_len++; |
| 96 | kbinput = (int *)nrealloc(kbinput, kbinput_len * sizeof(int)); |
| 97 | kbinput[kbinput_len - 1] = input; |
| 98 | } |
| 99 | } |
| 100 | |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 101 | /* If we got a shortcut, or if there aren't any other keystrokes waiting |
| 102 | * after the one we read in, we need to insert all the characters in the |
| 103 | * input buffer (if not empty) into the answer. */ |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 104 | if ((have_shortcut || get_key_buffer_len() == 0) && kbinput != NULL) { |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 105 | /* Inject all characters in the input buffer at once, filtering out |
| 106 | * control characters. */ |
Benno Schulenberg | 908663e | 2016-12-27 12:20:20 +0100 | [diff] [blame] | 107 | do_statusbar_output(kbinput, kbinput_len, TRUE); |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 108 | |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 109 | /* Empty the input buffer. */ |
| 110 | kbinput_len = 0; |
| 111 | free(kbinput); |
| 112 | kbinput = NULL; |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 113 | } |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 114 | |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 115 | if (have_shortcut) { |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 116 | if (s->scfunc == do_tab || s->scfunc == do_enter) |
| 117 | ; |
Benno Schulenberg | 379b155 | 2016-12-03 20:37:30 +0100 | [diff] [blame] | 118 | else if (s->scfunc == do_left) |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 119 | do_statusbar_left(); |
| 120 | else if (s->scfunc == do_right) |
| 121 | do_statusbar_right(); |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 122 | #ifndef NANO_TINY |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 123 | else if (s->scfunc == do_prev_word_void) |
| 124 | do_statusbar_prev_word(); |
| 125 | else if (s->scfunc == do_next_word_void) |
| 126 | do_statusbar_next_word(); |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 127 | #endif |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 128 | else if (s->scfunc == do_home) |
| 129 | do_statusbar_home(); |
| 130 | else if (s->scfunc == do_end) |
| 131 | do_statusbar_end(); |
| 132 | /* When in restricted mode at the "Write File" prompt and the |
| 133 | * filename isn't blank, disallow any input and deletion. */ |
| 134 | else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE && |
Benno Schulenberg | aefe26d | 2016-07-25 12:31:40 +0200 | [diff] [blame] | 135 | openfile->filename[0] != '\0' && |
| 136 | (s->scfunc == do_verbatim_input || |
| 137 | s->scfunc == do_cut_text_void || |
| 138 | s->scfunc == do_delete || |
| 139 | s->scfunc == do_backspace)) |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 140 | ; |
| 141 | else if (s->scfunc == do_verbatim_input) { |
Benno Schulenberg | 908663e | 2016-12-27 12:20:20 +0100 | [diff] [blame] | 142 | do_statusbar_verbatim_input(); |
Benno Schulenberg | 2f9232a | 2016-08-22 14:05:25 +0200 | [diff] [blame] | 143 | } else if (s->scfunc == do_cut_text_void) |
| 144 | do_statusbar_cut_text(); |
| 145 | else if (s->scfunc == do_delete) |
| 146 | do_statusbar_delete(); |
| 147 | else if (s->scfunc == do_backspace) |
| 148 | do_statusbar_backspace(); |
| 149 | else { |
| 150 | /* Handle any other shortcut in the current menu, setting |
| 151 | * ran_func to TRUE if we try to run their associated functions, |
| 152 | * and setting finished to TRUE to indicatethat we're done after |
| 153 | * running or trying to run their associated functions. */ |
| 154 | f = sctofunc(s); |
| 155 | if (s->scfunc != NULL) { |
| 156 | *ran_func = TRUE; |
| 157 | if (f && (!ISSET(VIEW_MODE) || f->viewok) && |
| 158 | f->scfunc != do_gotolinecolumn_void) |
| 159 | f->scfunc(); |
| 160 | } |
| 161 | *finished = TRUE; |
| 162 | } |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | return input; |
| 166 | } |
| 167 | |
| 168 | #ifndef DISABLE_MOUSE |
David Lawrence Ramsey | 6d6a36c | 2005-12-08 07:09:08 +0000 | [diff] [blame] | 169 | /* Handle a mouse click on the statusbar prompt or the shortcut list. */ |
David Lawrence Ramsey | 3a5eaeb | 2007-05-20 23:41:56 +0000 | [diff] [blame] | 170 | int do_statusbar_mouse(void) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 171 | { |
| 172 | int mouse_x, mouse_y; |
David Lawrence Ramsey | 3a5eaeb | 2007-05-20 23:41:56 +0000 | [diff] [blame] | 173 | int retval = get_mouseinput(&mouse_x, &mouse_y, TRUE); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 174 | |
David Lawrence Ramsey | ebc38fd | 2007-06-28 16:00:50 +0000 | [diff] [blame] | 175 | /* We can click on the statusbar window text to move the cursor. */ |
Benno Schulenberg | 22a01ca | 2016-02-06 12:12:08 +0000 | [diff] [blame] | 176 | if (retval == 0 && wmouse_trafo(bottomwin, &mouse_y, &mouse_x, FALSE)) { |
David Lawrence Ramsey | ebc38fd | 2007-06-28 16:00:50 +0000 | [diff] [blame] | 177 | size_t start_col; |
David Lawrence Ramsey | 143b8c7 | 2005-11-01 18:35:47 +0000 | [diff] [blame] | 178 | |
David Lawrence Ramsey | 281a469 | 2007-12-08 07:00:27 +0000 | [diff] [blame] | 179 | start_col = strlenpt(prompt) + 2; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 180 | |
David Lawrence Ramsey | ebc38fd | 2007-06-28 16:00:50 +0000 | [diff] [blame] | 181 | /* Move to where the click occurred. */ |
David Lawrence Ramsey | 281a469 | 2007-12-08 07:00:27 +0000 | [diff] [blame] | 182 | if (mouse_x >= start_col && mouse_y == 0) { |
David Lawrence Ramsey | ebc38fd | 2007-06-28 16:00:50 +0000 | [diff] [blame] | 183 | statusbar_x = actual_x(answer, |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 184 | get_statusbar_page_start(start_col, start_col + |
David Lawrence Ramsey | 281a469 | 2007-12-08 07:00:27 +0000 | [diff] [blame] | 185 | statusbar_xplustabs()) + mouse_x - start_col); |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 186 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 187 | } |
| 188 | } |
| 189 | |
| 190 | return retval; |
| 191 | } |
| 192 | #endif |
| 193 | |
Benno Schulenberg | 908663e | 2016-12-27 12:20:20 +0100 | [diff] [blame] | 194 | /* The user typed input_len multibyte characters. Add them to the answer, |
| 195 | * filtering out ASCII control characters if filtering is TRUE. */ |
Benno Schulenberg | e540053 | 2016-02-14 12:03:47 +0000 | [diff] [blame] | 196 | void do_statusbar_output(int *the_input, size_t input_len, |
Benno Schulenberg | 908663e | 2016-12-27 12:20:20 +0100 | [diff] [blame] | 197 | bool filtering) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 198 | { |
Benno Schulenberg | e540053 | 2016-02-14 12:03:47 +0000 | [diff] [blame] | 199 | char *output = charalloc(input_len + 1); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 200 | char *char_buf = charalloc(mb_cur_max()); |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 201 | int i, char_len; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 202 | |
Benno Schulenberg | ef16a2a | 2016-02-14 11:16:54 +0000 | [diff] [blame] | 203 | /* Copy the typed stuff so it can be treated. */ |
Benno Schulenberg | e540053 | 2016-02-14 12:03:47 +0000 | [diff] [blame] | 204 | for (i = 0; i < input_len; i++) |
Benno Schulenberg | ef16a2a | 2016-02-14 11:16:54 +0000 | [diff] [blame] | 205 | output[i] = (char)the_input[i]; |
| 206 | output[i] = '\0'; |
| 207 | |
Benno Schulenberg | ef16a2a | 2016-02-14 11:16:54 +0000 | [diff] [blame] | 208 | i = 0; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 209 | |
Benno Schulenberg | e540053 | 2016-02-14 12:03:47 +0000 | [diff] [blame] | 210 | while (i < input_len) { |
Benno Schulenberg | 908663e | 2016-12-27 12:20:20 +0100 | [diff] [blame] | 211 | /* Encode any NUL byte as 0x0A. */ |
| 212 | if (output[i] == '\0') |
| 213 | output[i] = '\n'; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 214 | |
| 215 | /* Interpret the next multibyte character. */ |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 216 | char_len = parse_mbchar(output + i, char_buf, NULL); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 217 | |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 218 | i += char_len; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 219 | |
Benno Schulenberg | e540053 | 2016-02-14 12:03:47 +0000 | [diff] [blame] | 220 | /* When filtering, skip any ASCII control character. */ |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 221 | if (filtering && is_ascii_cntrl_char(*(output + i - char_len))) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 222 | continue; |
| 223 | |
Benno Schulenberg | 3ed08c5 | 2016-02-22 14:26:05 +0000 | [diff] [blame] | 224 | /* Insert the typed character into the existing answer string. */ |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 225 | answer = charealloc(answer, strlen(answer) + char_len + 1); |
| 226 | charmove(answer + statusbar_x + char_len, answer + statusbar_x, |
Benno Schulenberg | 3ed08c5 | 2016-02-22 14:26:05 +0000 | [diff] [blame] | 227 | strlen(answer) - statusbar_x + 1); |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 228 | strncpy(answer + statusbar_x, char_buf, char_len); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 229 | |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 230 | statusbar_x += char_len; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 231 | } |
| 232 | |
| 233 | free(char_buf); |
Benno Schulenberg | ef16a2a | 2016-02-14 11:16:54 +0000 | [diff] [blame] | 234 | free(output); |
David Lawrence Ramsey | af3314c | 2005-11-07 06:32:07 +0000 | [diff] [blame] | 235 | |
Benno Schulenberg | d844f05 | 2016-02-06 11:40:15 +0000 | [diff] [blame] | 236 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 237 | } |
| 238 | |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 239 | /* Move to the beginning of the answer. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 240 | void do_statusbar_home(void) |
| 241 | { |
Benno Schulenberg | 7ade5de | 2016-01-31 13:26:15 +0000 | [diff] [blame] | 242 | statusbar_x = 0; |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 243 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 244 | } |
| 245 | |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 246 | /* Move to the end of the answer. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 247 | void do_statusbar_end(void) |
| 248 | { |
| 249 | statusbar_x = strlen(answer); |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 250 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 251 | } |
| 252 | |
David Lawrence Ramsey | 6d6a36c | 2005-12-08 07:09:08 +0000 | [diff] [blame] | 253 | /* Move left one character. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 254 | void do_statusbar_left(void) |
| 255 | { |
David Lawrence Ramsey | af3314c | 2005-11-07 06:32:07 +0000 | [diff] [blame] | 256 | if (statusbar_x > 0) { |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 257 | statusbar_x = move_mbleft(answer, statusbar_x); |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 258 | update_the_statusbar(); |
David Lawrence Ramsey | af3314c | 2005-11-07 06:32:07 +0000 | [diff] [blame] | 259 | } |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 260 | } |
| 261 | |
David Lawrence Ramsey | 6d6a36c | 2005-12-08 07:09:08 +0000 | [diff] [blame] | 262 | /* Move right one character. */ |
| 263 | void do_statusbar_right(void) |
| 264 | { |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 265 | if (answer[statusbar_x] != '\0') { |
David Lawrence Ramsey | 6d6a36c | 2005-12-08 07:09:08 +0000 | [diff] [blame] | 266 | statusbar_x = move_mbright(answer, statusbar_x); |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 267 | update_the_statusbar(); |
David Lawrence Ramsey | 6d6a36c | 2005-12-08 07:09:08 +0000 | [diff] [blame] | 268 | } |
| 269 | } |
| 270 | |
| 271 | /* Backspace over one character. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 272 | void do_statusbar_backspace(void) |
| 273 | { |
| 274 | if (statusbar_x > 0) { |
Benno Schulenberg | 8585bf2 | 2016-02-06 11:50:57 +0000 | [diff] [blame] | 275 | statusbar_x = move_mbleft(answer, statusbar_x); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 276 | do_statusbar_delete(); |
| 277 | } |
| 278 | } |
| 279 | |
David Lawrence Ramsey | 6d6a36c | 2005-12-08 07:09:08 +0000 | [diff] [blame] | 280 | /* Delete one character. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 281 | void do_statusbar_delete(void) |
| 282 | { |
| 283 | if (answer[statusbar_x] != '\0') { |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 284 | int char_len = parse_mbchar(answer + statusbar_x, NULL, NULL); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 285 | |
Benno Schulenberg | 8a2dd97 | 2016-02-23 08:31:57 +0000 | [diff] [blame] | 286 | charmove(answer + statusbar_x, answer + statusbar_x + char_len, |
| 287 | strlen(answer) - statusbar_x - char_len + 1); |
David Lawrence Ramsey | e19449e | 2005-11-07 21:45:44 +0000 | [diff] [blame] | 288 | |
Benno Schulenberg | d844f05 | 2016-02-06 11:40:15 +0000 | [diff] [blame] | 289 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 290 | } |
| 291 | } |
| 292 | |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 293 | /* Zap some or all text from the answer. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 294 | void do_statusbar_cut_text(void) |
| 295 | { |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 296 | if (!ISSET(CUT_TO_END)) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 297 | statusbar_x = 0; |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 298 | |
| 299 | null_at(&answer, statusbar_x); |
David Lawrence Ramsey | af3314c | 2005-11-07 06:32:07 +0000 | [diff] [blame] | 300 | |
Benno Schulenberg | d844f05 | 2016-02-06 11:40:15 +0000 | [diff] [blame] | 301 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 302 | } |
| 303 | |
David Lawrence Ramsey | ebe3425 | 2005-11-15 03:17:35 +0000 | [diff] [blame] | 304 | #ifndef NANO_TINY |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 305 | /* Move to the next word in the answer. */ |
Benno Schulenberg | eed1aab | 2016-01-24 15:42:45 +0000 | [diff] [blame] | 306 | void do_statusbar_next_word(void) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 307 | { |
Benno Schulenberg | a93a11e | 2016-01-26 10:31:16 +0000 | [diff] [blame] | 308 | bool seen_space = !is_word_mbchar(answer + statusbar_x, FALSE); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 309 | |
Benno Schulenberg | a93a11e | 2016-01-26 10:31:16 +0000 | [diff] [blame] | 310 | /* Move forward until we reach the start of a word. */ |
| 311 | while (answer[statusbar_x] != '\0') { |
| 312 | statusbar_x = move_mbright(answer, statusbar_x); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 313 | |
Benno Schulenberg | a93a11e | 2016-01-26 10:31:16 +0000 | [diff] [blame] | 314 | /* If this is not a word character, then it's a separator; else |
| 315 | * if we've already seen a separator, then it's a word start. */ |
| 316 | if (!is_word_mbchar(answer + statusbar_x, FALSE)) |
| 317 | seen_space = TRUE; |
| 318 | else if (seen_space) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 319 | break; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 320 | } |
| 321 | |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 322 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 323 | } |
| 324 | |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 325 | /* Move to the previous word in the answer. */ |
Benno Schulenberg | eed1aab | 2016-01-24 15:42:45 +0000 | [diff] [blame] | 326 | void do_statusbar_prev_word(void) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 327 | { |
Benno Schulenberg | 5688c16 | 2016-01-26 10:10:20 +0000 | [diff] [blame] | 328 | bool seen_a_word = FALSE, step_forward = FALSE; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 329 | |
Benno Schulenberg | 5688c16 | 2016-01-26 10:10:20 +0000 | [diff] [blame] | 330 | /* Move backward until we pass over the start of a word. */ |
| 331 | while (statusbar_x != 0) { |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 332 | statusbar_x = move_mbleft(answer, statusbar_x); |
| 333 | |
Benno Schulenberg | 5688c16 | 2016-01-26 10:10:20 +0000 | [diff] [blame] | 334 | if (is_word_mbchar(answer + statusbar_x, FALSE)) |
| 335 | seen_a_word = TRUE; |
| 336 | else if (seen_a_word) { |
| 337 | /* This is space now: we've overshot the start of the word. */ |
| 338 | step_forward = TRUE; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 339 | break; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 340 | } |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 341 | } |
| 342 | |
Benno Schulenberg | 5688c16 | 2016-01-26 10:10:20 +0000 | [diff] [blame] | 343 | if (step_forward) |
| 344 | /* Move one character forward again to sit on the start of the word. */ |
| 345 | statusbar_x = move_mbright(answer, statusbar_x); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 346 | |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 347 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 348 | } |
David Lawrence Ramsey | ebe3425 | 2005-11-15 03:17:35 +0000 | [diff] [blame] | 349 | #endif /* !NANO_TINY */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 350 | |
Benno Schulenberg | 908663e | 2016-12-27 12:20:20 +0100 | [diff] [blame] | 351 | /* Get verbatim input and inject it into the answer, without filtering. */ |
| 352 | void do_statusbar_verbatim_input(void) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 353 | { |
| 354 | int *kbinput; |
Benno Schulenberg | ef16a2a | 2016-02-14 11:16:54 +0000 | [diff] [blame] | 355 | size_t kbinput_len; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 356 | |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 357 | kbinput = get_verbatim_kbinput(bottomwin, &kbinput_len); |
| 358 | |
Benno Schulenberg | 908663e | 2016-12-27 12:20:20 +0100 | [diff] [blame] | 359 | do_statusbar_output(kbinput, kbinput_len, FALSE); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 360 | } |
| 361 | |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 362 | /* Return the zero-based column position of the cursor in the answer. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 363 | size_t statusbar_xplustabs(void) |
| 364 | { |
| 365 | return strnlenpt(answer, statusbar_x); |
| 366 | } |
| 367 | |
Benno Schulenberg | da2fce9 | 2016-08-26 22:46:01 +0200 | [diff] [blame] | 368 | /* Return the column number of the first character of the answer that is |
| 369 | * displayed in the statusbar when the cursor is at the given column, |
| 370 | * with the available room for the answer starting at base. Note that |
| 371 | * (0 <= column - get_statusbar_page_start(column) < COLS). */ |
| 372 | size_t get_statusbar_page_start(size_t base, size_t column) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 373 | { |
Benno Schulenberg | da2fce9 | 2016-08-26 22:46:01 +0200 | [diff] [blame] | 374 | if (column == base || column < COLS - 1) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 375 | return 0; |
Benno Schulenberg | da2fce9 | 2016-08-26 22:46:01 +0200 | [diff] [blame] | 376 | else if (COLS > base + 2) |
| 377 | return column - base - 1 - (column - base - 1) % (COLS - base - 2); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 378 | else |
Benno Schulenberg | 92c97c7 | 2016-08-26 21:29:53 +0200 | [diff] [blame] | 379 | return column - 2; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 380 | } |
| 381 | |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 382 | /* Reinitialize the cursor position in the answer. */ |
Benno Schulenberg | 34a20f8 | 2016-04-17 15:24:05 +0200 | [diff] [blame] | 383 | void reinit_statusbar_x(void) |
| 384 | { |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 385 | statusbar_x = HIGHEST_POSITIVE; |
Benno Schulenberg | 34a20f8 | 2016-04-17 15:24:05 +0200 | [diff] [blame] | 386 | } |
| 387 | |
Benno Schulenberg | 7275e11 | 2016-08-28 18:15:20 +0200 | [diff] [blame] | 388 | /* Put the cursor in the answer at statusbar_x. */ |
David Lawrence Ramsey | 60edb0a | 2006-05-15 15:17:50 +0000 | [diff] [blame] | 389 | void reset_statusbar_cursor(void) |
| 390 | { |
David Lawrence Ramsey | 281a469 | 2007-12-08 07:00:27 +0000 | [diff] [blame] | 391 | size_t start_col = strlenpt(prompt) + 2; |
David Lawrence Ramsey | 60edb0a | 2006-05-15 15:17:50 +0000 | [diff] [blame] | 392 | size_t xpt = statusbar_xplustabs(); |
| 393 | |
Benno Schulenberg | c22cd03 | 2016-08-25 10:42:46 +0200 | [diff] [blame] | 394 | /* Work around a cursor-misplacement bug in VTEs. */ |
| 395 | wmove(bottomwin, 0, 0); |
| 396 | wnoutrefresh(bottomwin); |
| 397 | doupdate(); |
| 398 | |
David Lawrence Ramsey | 281a469 | 2007-12-08 07:00:27 +0000 | [diff] [blame] | 399 | wmove(bottomwin, 0, start_col + xpt - |
Benno Schulenberg | da2fce9 | 2016-08-26 22:46:01 +0200 | [diff] [blame] | 400 | get_statusbar_page_start(start_col, start_col + xpt)); |
Benno Schulenberg | c22cd03 | 2016-08-25 10:42:46 +0200 | [diff] [blame] | 401 | |
| 402 | wnoutrefresh(bottomwin); |
David Lawrence Ramsey | 60edb0a | 2006-05-15 15:17:50 +0000 | [diff] [blame] | 403 | } |
| 404 | |
Benno Schulenberg | d844f05 | 2016-02-06 11:40:15 +0000 | [diff] [blame] | 405 | /* Repaint the statusbar. */ |
| 406 | void update_the_statusbar(void) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 407 | { |
Benno Schulenberg | da2fce9 | 2016-08-26 22:46:01 +0200 | [diff] [blame] | 408 | size_t base, the_page, end_page; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 409 | char *expanded; |
| 410 | |
Benno Schulenberg | da2fce9 | 2016-08-26 22:46:01 +0200 | [diff] [blame] | 411 | base = strlenpt(prompt) + 2; |
| 412 | the_page = get_statusbar_page_start(base, base + strnlenpt(answer, statusbar_x)); |
| 413 | end_page = get_statusbar_page_start(base, base + strlenpt(answer) - 1); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 414 | |
Benno Schulenberg | 960e848 | 2016-07-12 09:35:48 +0200 | [diff] [blame] | 415 | wattron(bottomwin, interface_color_pair[TITLE_BAR]); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 416 | |
| 417 | blank_statusbar(); |
| 418 | |
Benno Schulenberg | 77d1407 | 2016-08-28 17:53:44 +0200 | [diff] [blame] | 419 | mvwaddstr(bottomwin, 0, 0, prompt); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 420 | waddch(bottomwin, ':'); |
Benno Schulenberg | 6142ef8 | 2016-08-27 09:29:09 +0200 | [diff] [blame] | 421 | waddch(bottomwin, (the_page == 0) ? ' ' : '<'); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 422 | |
Benno Schulenberg | da2fce9 | 2016-08-26 22:46:01 +0200 | [diff] [blame] | 423 | expanded = display_string(answer, the_page, COLS - base - 1, FALSE); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 424 | waddstr(bottomwin, expanded); |
| 425 | free(expanded); |
| 426 | |
Benno Schulenberg | 6142ef8 | 2016-08-27 09:29:09 +0200 | [diff] [blame] | 427 | waddch(bottomwin, (the_page >= end_page) ? ' ' : '>'); |
Benno Schulenberg | 1e3cffb | 2016-08-26 21:42:23 +0200 | [diff] [blame] | 428 | |
Benno Schulenberg | 960e848 | 2016-07-12 09:35:48 +0200 | [diff] [blame] | 429 | wattroff(bottomwin, interface_color_pair[TITLE_BAR]); |
Benno Schulenberg | 22a01ca | 2016-02-06 12:12:08 +0000 | [diff] [blame] | 430 | |
David Lawrence Ramsey | a9c0000 | 2007-12-03 20:14:18 +0000 | [diff] [blame] | 431 | reset_statusbar_cursor(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 432 | } |
| 433 | |
Benno Schulenberg | 65c7c81 | 2016-01-26 09:16:09 +0000 | [diff] [blame] | 434 | /* Get a string of input at the statusbar prompt. */ |
Benno Schulenberg | 7e0c4e5 | 2016-08-25 20:20:50 +0200 | [diff] [blame] | 435 | functionptrtype acquire_an_answer(int *actual, bool allow_tabs, |
Benno Schulenberg | 30f3c53 | 2016-04-26 17:50:25 +0200 | [diff] [blame] | 436 | bool allow_files, bool *listed, |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 437 | #ifndef DISABLE_HISTORIES |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 438 | filestruct **history_list, |
| 439 | #endif |
Benno Schulenberg | ebcc68f | 2014-07-01 11:50:35 +0000 | [diff] [blame] | 440 | void (*refresh_func)(void)) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 441 | { |
David Lawrence Ramsey | 591c409 | 2006-02-08 20:14:49 +0000 | [diff] [blame] | 442 | int kbinput = ERR; |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 443 | bool ran_func, finished; |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 444 | functionptrtype func; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 445 | #ifndef DISABLE_TABCOMP |
| 446 | bool tabbed = FALSE; |
| 447 | /* Whether we've pressed Tab. */ |
| 448 | #endif |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 449 | #ifndef DISABLE_HISTORIES |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 450 | char *history = NULL; |
| 451 | /* The current history string. */ |
| 452 | char *magichistory = NULL; |
| 453 | /* The temporary string typed at the bottom of the history, if |
| 454 | * any. */ |
| 455 | #ifndef DISABLE_TABCOMP |
| 456 | int last_kbinput = ERR; |
| 457 | /* The key we pressed before the current key. */ |
| 458 | size_t complete_len = 0; |
| 459 | /* The length of the original string that we're trying to |
| 460 | * tab complete, if any. */ |
| 461 | #endif |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 462 | #endif /* !DISABLE_HISTORIES */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 463 | |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 464 | if (statusbar_x > strlen(answer)) |
Benno Schulenberg | a443760 | 2016-01-21 18:29:39 +0000 | [diff] [blame] | 465 | statusbar_x = strlen(answer); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 466 | |
Chris Allegretta | 79a33bb | 2008-03-05 07:34:01 +0000 | [diff] [blame] | 467 | #ifdef DEBUG |
Benno Schulenberg | b77b139 | 2016-08-26 12:18:04 +0200 | [diff] [blame] | 468 | fprintf(stderr, "acquiring: answer = \"%s\", statusbar_x = %lu\n", answer, (unsigned long) statusbar_x); |
Chris Allegretta | 79a33bb | 2008-03-05 07:34:01 +0000 | [diff] [blame] | 469 | #endif |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 470 | |
Benno Schulenberg | d844f05 | 2016-02-06 11:40:15 +0000 | [diff] [blame] | 471 | update_the_statusbar(); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 472 | |
Benno Schulenberg | 22a01ca | 2016-02-06 12:12:08 +0000 | [diff] [blame] | 473 | /* Refresh edit window and statusbar before getting input. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 474 | wnoutrefresh(edit); |
| 475 | wnoutrefresh(bottomwin); |
| 476 | |
Benno Schulenberg | b5895f0 | 2014-06-28 08:29:18 +0000 | [diff] [blame] | 477 | while (TRUE) { |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 478 | /* Ensure the cursor is shown when waiting for input. */ |
Benno Schulenberg | 568d2a3 | 2016-02-13 19:41:12 +0000 | [diff] [blame] | 479 | curs_set(1); |
| 480 | |
Benno Schulenberg | 379b155 | 2016-12-03 20:37:30 +0100 | [diff] [blame] | 481 | kbinput = do_statusbar_input(&ran_func, &finished); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 482 | |
Benno Schulenberg | 75d64e6 | 2015-05-28 13:02:29 +0000 | [diff] [blame] | 483 | #ifndef NANO_TINY |
Benno Schulenberg | 5061614 | 2016-08-25 20:02:35 +0200 | [diff] [blame] | 484 | /* If the window size changed, go reformat the prompt string. */ |
Benno Schulenberg | 65c7c81 | 2016-01-26 09:16:09 +0000 | [diff] [blame] | 485 | if (kbinput == KEY_WINCH) { |
| 486 | refresh_func(); |
Benno Schulenberg | 5061614 | 2016-08-25 20:02:35 +0200 | [diff] [blame] | 487 | *actual = KEY_WINCH; |
Benno Schulenberg | 2dffcf1 | 2016-08-30 11:14:19 +0200 | [diff] [blame] | 488 | #ifndef DISABLE_HISTORIES |
Benno Schulenberg | 5061614 | 2016-08-25 20:02:35 +0200 | [diff] [blame] | 489 | free(magichistory); |
Benno Schulenberg | 2dffcf1 | 2016-08-30 11:14:19 +0200 | [diff] [blame] | 490 | #endif |
Benno Schulenberg | 5061614 | 2016-08-25 20:02:35 +0200 | [diff] [blame] | 491 | return NULL; |
Benno Schulenberg | 65c7c81 | 2016-01-26 09:16:09 +0000 | [diff] [blame] | 492 | } |
Benno Schulenberg | 2dffcf1 | 2016-08-30 11:14:19 +0200 | [diff] [blame] | 493 | #endif /* !NANO_TINY */ |
| 494 | |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 495 | func = func_from_key(&kbinput); |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 496 | |
Benno Schulenberg | bde996d | 2015-11-11 19:56:35 +0000 | [diff] [blame] | 497 | if (func == do_cancel || func == do_enter) |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 498 | break; |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 499 | |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 500 | #ifndef DISABLE_TABCOMP |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 501 | if (func != do_tab) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 502 | tabbed = FALSE; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 503 | |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 504 | if (func == do_tab) { |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 505 | #ifndef DISABLE_HISTORIES |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 506 | if (history_list != NULL) { |
Benno Schulenberg | a9b5a0e | 2016-12-22 12:02:11 +0100 | [diff] [blame] | 507 | if (last_kbinput != the_code_for(do_tab, TAB_CODE)) |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 508 | complete_len = strlen(answer); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 509 | |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 510 | if (complete_len > 0) { |
Benno Schulenberg | e86dc03 | 2016-02-20 12:16:43 +0000 | [diff] [blame] | 511 | answer = get_history_completion(history_list, |
| 512 | answer, complete_len); |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 513 | statusbar_x = strlen(answer); |
| 514 | } |
| 515 | } else |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 516 | #endif |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 517 | if (allow_tabs) |
| 518 | answer = input_tab(answer, allow_files, &statusbar_x, |
Benno Schulenberg | 17cf833 | 2016-05-30 09:09:36 +0200 | [diff] [blame] | 519 | &tabbed, refresh_func, listed); |
Chris Allegretta | 637daa8 | 2011-02-07 14:45:56 +0000 | [diff] [blame] | 520 | } else |
David Lawrence Ramsey | ad07401 | 2005-11-16 21:34:46 +0000 | [diff] [blame] | 521 | #endif /* !DISABLE_TABCOMP */ |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 522 | #ifndef DISABLE_HISTORIES |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 523 | if (func == get_history_older_void) { |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 524 | if (history_list != NULL) { |
| 525 | /* If we're scrolling up at the bottom of the history list |
| 526 | * and answer isn't blank, save answer in magichistory. */ |
Benno Schulenberg | 1d3d307 | 2016-05-27 21:31:55 +0200 | [diff] [blame] | 527 | if ((*history_list)->next == NULL && *answer != '\0') |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 528 | magichistory = mallocstrcpy(magichistory, answer); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 529 | |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 530 | /* Get the older search from the history list and save it in |
| 531 | * answer. If there is no older search, don't do anything. */ |
| 532 | if ((history = get_history_older(history_list)) != NULL) { |
| 533 | answer = mallocstrcpy(answer, history); |
| 534 | statusbar_x = strlen(answer); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 535 | } |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 536 | |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 537 | /* This key has a shortcut-list entry when it's used to |
| 538 | * move to an older search, which means that finished has |
| 539 | * been set to TRUE. Set it back to FALSE here, so that |
| 540 | * we aren't kicked out of the statusbar prompt. */ |
Benno Schulenberg | a8a23ab | 2014-06-10 19:12:14 +0000 | [diff] [blame] | 541 | finished = FALSE; |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 542 | } |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 543 | } else if (func == get_history_newer_void) { |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 544 | if (history_list != NULL) { |
| 545 | /* Get the newer search from the history list and save it in |
| 546 | * answer. If there is no newer search, don't do anything. */ |
| 547 | if ((history = get_history_newer(history_list)) != NULL) { |
| 548 | answer = mallocstrcpy(answer, history); |
| 549 | statusbar_x = strlen(answer); |
| 550 | } |
| 551 | |
| 552 | /* If, after scrolling down, we're at the bottom of the |
| 553 | * history list, answer is blank, and magichistory is set, |
| 554 | * save magichistory in answer. */ |
| 555 | if ((*history_list)->next == NULL && |
Benno Schulenberg | 65c7c81 | 2016-01-26 09:16:09 +0000 | [diff] [blame] | 556 | *answer == '\0' && magichistory != NULL) { |
| 557 | answer = mallocstrcpy(answer, magichistory); |
| 558 | statusbar_x = strlen(answer); |
| 559 | } |
David Lawrence Ramsey | ea9d03f | 2005-11-08 01:49:14 +0000 | [diff] [blame] | 560 | |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 561 | /* This key has a shortcut-list entry when it's used to |
| 562 | * move to a newer search, which means that finished has |
| 563 | * been set to TRUE. Set it back to FALSE here, so that |
| 564 | * we aren't kicked out of the statusbar prompt. */ |
| 565 | finished = FALSE; |
| 566 | } |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 567 | } else |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 568 | #endif /* !DISABLE_HISTORIES */ |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 569 | if (func == do_help_void) { |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 570 | /* This key has a shortcut-list entry when it's used to go to |
| 571 | * the help browser or display a message indicating that help |
| 572 | * is disabled, which means that finished has been set to TRUE. |
| 573 | * Set it back to FALSE here, so that we aren't kicked out of |
| 574 | * the statusbar prompt. */ |
| 575 | finished = FALSE; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 576 | } |
| 577 | |
Benno Schulenberg | 96c95cd | 2014-04-04 19:26:08 +0000 | [diff] [blame] | 578 | /* If we have a shortcut with an associated function, break out if |
| 579 | * we're finished after running or trying to run the function. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 580 | if (finished) |
| 581 | break; |
| 582 | |
Benno Schulenberg | 0242d84 | 2016-08-28 18:32:56 +0200 | [diff] [blame] | 583 | update_the_statusbar(); |
| 584 | |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 585 | #if !defined(DISABLE_HISTORIES) && !defined(DISABLE_TABCOMP) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 586 | last_kbinput = kbinput; |
| 587 | #endif |
David Lawrence Ramsey | 8326254 | 2006-02-09 22:42:14 +0000 | [diff] [blame] | 588 | } |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 589 | |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 590 | #ifndef DISABLE_HISTORIES |
Benno Schulenberg | 22a01ca | 2016-02-06 12:12:08 +0000 | [diff] [blame] | 591 | /* Set the current position in the history list to the bottom. */ |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 592 | if (history_list != NULL) { |
| 593 | history_reset(*history_list); |
Benno Schulenberg | c32a58a | 2015-06-14 19:14:41 +0000 | [diff] [blame] | 594 | free(magichistory); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 595 | } |
| 596 | #endif |
| 597 | |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 598 | *actual = kbinput; |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 599 | |
| 600 | return func; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 601 | } |
| 602 | |
David Lawrence Ramsey | e19449e | 2005-11-07 21:45:44 +0000 | [diff] [blame] | 603 | /* Ask a question on the statusbar. The prompt will be stored in the |
| 604 | * static prompt, which should be NULL initially, and the answer will be |
| 605 | * stored in the answer global. Returns -1 on aborted enter, -2 on a |
| 606 | * blank string, and 0 otherwise, the valid shortcut key caught. |
David Lawrence Ramsey | 6816007 | 2006-02-18 21:32:29 +0000 | [diff] [blame] | 607 | * curranswer is any editable text that we want to put up by default, |
| 608 | * and refresh_func is the function we want to call to refresh the edit |
| 609 | * window. |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 610 | * |
| 611 | * The allow_tabs parameter indicates whether we should allow tabs to be |
David Lawrence Ramsey | 9d8c284 | 2006-02-07 21:11:05 +0000 | [diff] [blame] | 612 | * interpreted. The allow_files parameter indicates whether we should |
Benno Schulenberg | 34fbb1f | 2016-01-13 20:32:40 +0000 | [diff] [blame] | 613 | * allow all files (as opposed to just directories) to be tab completed. */ |
Benno Schulenberg | fd0589d | 2017-01-02 21:12:44 +0100 | [diff] [blame] | 614 | int do_prompt(bool allow_tabs, bool allow_files, |
Chris Allegretta | 79a33bb | 2008-03-05 07:34:01 +0000 | [diff] [blame] | 615 | int menu, const char *curranswer, |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 616 | #ifndef DISABLE_HISTORIES |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 617 | filestruct **history_list, |
| 618 | #endif |
David Lawrence Ramsey | 6816007 | 2006-02-18 21:32:29 +0000 | [diff] [blame] | 619 | void (*refresh_func)(void), const char *msg, ...) |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 620 | { |
| 621 | va_list ap; |
Benno Schulenberg | c11c688 | 2016-08-30 09:11:33 +0200 | [diff] [blame] | 622 | int retval; |
Benno Schulenberg | b77b139 | 2016-08-26 12:18:04 +0200 | [diff] [blame] | 623 | functionptrtype func = NULL; |
Benno Schulenberg | 30f3c53 | 2016-04-26 17:50:25 +0200 | [diff] [blame] | 624 | bool listed = FALSE; |
Benno Schulenberg | 34a20f8 | 2016-04-17 15:24:05 +0200 | [diff] [blame] | 625 | /* Save a possible current statusbar x position. */ |
| 626 | size_t was_statusbar_x = statusbar_x; |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 627 | |
Chris Allegretta | 79a33bb | 2008-03-05 07:34:01 +0000 | [diff] [blame] | 628 | bottombars(menu); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 629 | |
Benno Schulenberg | 4f156aa | 2016-08-27 10:48:20 +0200 | [diff] [blame] | 630 | answer = mallocstrcpy(answer, curranswer); |
| 631 | |
Benno Schulenberg | c11c688 | 2016-08-30 09:11:33 +0200 | [diff] [blame] | 632 | #ifndef NANO_TINY |
| 633 | redo_theprompt: |
| 634 | #endif |
| 635 | prompt = charalloc((COLS * mb_cur_max()) + 1); |
| 636 | va_start(ap, msg); |
| 637 | vsnprintf(prompt, COLS * mb_cur_max(), msg, ap); |
| 638 | va_end(ap); |
| 639 | /* Reserve five columns for colon plus angles plus answer, ":<aa>". */ |
| 640 | null_at(&prompt, actual_x(prompt, (COLS < 5) ? 0 : COLS - 5)); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 641 | |
Benno Schulenberg | fd0589d | 2017-01-02 21:12:44 +0100 | [diff] [blame] | 642 | func = acquire_an_answer(&retval, allow_tabs, allow_files, &listed, |
Benno Schulenberg | b341f29 | 2014-06-19 20:05:24 +0000 | [diff] [blame] | 643 | #ifndef DISABLE_HISTORIES |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 644 | history_list, |
David Lawrence Ramsey | 9d8c284 | 2006-02-07 21:11:05 +0000 | [diff] [blame] | 645 | #endif |
Benno Schulenberg | 0d5fbfb | 2016-08-22 13:54:55 +0200 | [diff] [blame] | 646 | refresh_func); |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 647 | |
Benno Schulenberg | c11c688 | 2016-08-30 09:11:33 +0200 | [diff] [blame] | 648 | free(prompt); |
| 649 | prompt = NULL; |
| 650 | |
| 651 | #ifndef NANO_TINY |
| 652 | if (retval == KEY_WINCH) |
| 653 | goto redo_theprompt; |
| 654 | #endif |
David Lawrence Ramsey | 143b8c7 | 2005-11-01 18:35:47 +0000 | [diff] [blame] | 655 | |
Benno Schulenberg | 34a20f8 | 2016-04-17 15:24:05 +0200 | [diff] [blame] | 656 | /* If we're done with this prompt, restore the x position to what |
| 657 | * it was at a possible previous prompt. */ |
Benno Schulenberg | 4d2ada6 | 2016-08-28 17:37:25 +0200 | [diff] [blame] | 658 | if (func == do_cancel || func == do_enter) |
Benno Schulenberg | 34a20f8 | 2016-04-17 15:24:05 +0200 | [diff] [blame] | 659 | statusbar_x = was_statusbar_x; |
David Lawrence Ramsey | 98332d4 | 2006-08-26 15:14:55 +0000 | [diff] [blame] | 660 | |
David Lawrence Ramsey | e1e2cb7 | 2006-08-26 16:42:12 +0000 | [diff] [blame] | 661 | /* If we left the prompt via Cancel or Enter, set the return value |
| 662 | * properly. */ |
Benno Schulenberg | 3933a30 | 2014-07-02 08:47:09 +0000 | [diff] [blame] | 663 | if (func == do_cancel) |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 664 | retval = -1; |
Benno Schulenberg | bde996d | 2015-11-11 19:56:35 +0000 | [diff] [blame] | 665 | else if (func == do_enter) |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 666 | retval = (*answer == '\0') ? -2 : 0; |
Chris Allegretta | 79a33bb | 2008-03-05 07:34:01 +0000 | [diff] [blame] | 667 | |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 668 | blank_statusbar(); |
| 669 | wnoutrefresh(bottomwin); |
| 670 | |
| 671 | #ifdef DEBUG |
| 672 | fprintf(stderr, "answer = \"%s\"\n", answer); |
| 673 | #endif |
| 674 | |
Benno Schulenberg | 30f3c53 | 2016-04-26 17:50:25 +0200 | [diff] [blame] | 675 | #ifndef DISABLE_TABCOMP |
| 676 | /* If we've done tab completion, there might still be a list of |
| 677 | * filename matches on the edit window. Clear them off. */ |
| 678 | if (listed) |
| 679 | refresh_func(); |
| 680 | #endif |
| 681 | |
David Lawrence Ramsey | d24d0a4 | 2005-11-01 17:37:44 +0000 | [diff] [blame] | 682 | return retval; |
| 683 | } |
| 684 | |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 685 | /* Ask a simple Yes/No (and optionally All) question, specified in msg, |
| 686 | * on the statusbar. Return 1 for Yes, 0 for No, 2 for All (if all is |
| 687 | * TRUE when passed in), and -1 for Cancel. */ |
David Lawrence Ramsey | e19449e | 2005-11-07 21:45:44 +0000 | [diff] [blame] | 688 | int do_yesno_prompt(bool all, const char *msg) |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 689 | { |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 690 | int response = -2, width = 16; |
Benno Schulenberg | 9973366 | 2016-12-26 17:31:27 +0100 | [diff] [blame] | 691 | char *message = display_string(msg, 0, COLS, FALSE); |
| 692 | |
David Lawrence Ramsey | cde9039 | 2006-04-09 18:27:42 +0000 | [diff] [blame] | 693 | /* TRANSLATORS: For the next three strings, if possible, specify |
David Lawrence Ramsey | be7fd8a | 2006-04-09 18:24:54 +0000 | [diff] [blame] | 694 | * the single-byte shortcuts for both your language and English. |
Benno Schulenberg | 8f95f9b | 2016-12-01 15:25:35 +0100 | [diff] [blame] | 695 | * For example, in French: "OoYy", for both "Oui" and "Yes". */ |
| 696 | const char *yesstr = _("Yy"); |
| 697 | const char *nostr = _("Nn"); |
| 698 | const char *allstr = _("Aa"); |
| 699 | |
| 700 | /* The above three variables consist of all the single-byte characters |
| 701 | * that are accepted for the corresponding answer. Of each variable, |
| 702 | * the first character is displayed in the help lines. */ |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 703 | |
Benno Schulenberg | 1fb8203 | 2016-12-26 20:20:03 +0100 | [diff] [blame] | 704 | while (response == -2) { |
Benno Schulenberg | 75d64e6 | 2015-05-28 13:02:29 +0000 | [diff] [blame] | 705 | int kbinput; |
| 706 | functionptrtype func; |
Benno Schulenberg | 75d64e6 | 2015-05-28 13:02:29 +0000 | [diff] [blame] | 707 | |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 708 | if (!ISSET(NO_HELP)) { |
| 709 | char shortstr[3]; |
Benno Schulenberg | 2661d6d | 2015-05-28 13:51:03 +0000 | [diff] [blame] | 710 | /* Temporary string for (translated) " Y", " N" and " A". */ |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 711 | |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 712 | if (COLS < 32) |
| 713 | width = COLS / 2; |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 714 | |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 715 | /* Clear the shortcut list from the bottom of the screen. */ |
| 716 | blank_bottombars(); |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 717 | |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 718 | /* Now show the ones for "Yes", "No", "Cancel" and maybe "All". */ |
| 719 | sprintf(shortstr, " %c", yesstr[0]); |
| 720 | wmove(bottomwin, 1, 0); |
| 721 | onekey(shortstr, _("Yes"), width); |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 722 | |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 723 | if (all) { |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 724 | shortstr[1] = allstr[0]; |
Benno Schulenberg | 2661d6d | 2015-05-28 13:51:03 +0000 | [diff] [blame] | 725 | wmove(bottomwin, 1, width); |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 726 | onekey(shortstr, _("All"), width); |
| 727 | } |
| 728 | |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 729 | shortstr[1] = nostr[0]; |
Benno Schulenberg | 2661d6d | 2015-05-28 13:51:03 +0000 | [diff] [blame] | 730 | wmove(bottomwin, 2, 0); |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 731 | onekey(shortstr, _("No"), width); |
| 732 | |
Benno Schulenberg | 2661d6d | 2015-05-28 13:51:03 +0000 | [diff] [blame] | 733 | wmove(bottomwin, 2, width); |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 734 | onekey("^C", _("Cancel"), width); |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 735 | } |
| 736 | |
Benno Schulenberg | c6512a9 | 2016-12-01 15:14:41 +0100 | [diff] [blame] | 737 | /* Color the statusbar over its full width and display the question. */ |
Benno Schulenberg | 960e848 | 2016-07-12 09:35:48 +0200 | [diff] [blame] | 738 | wattron(bottomwin, interface_color_pair[TITLE_BAR]); |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 739 | blank_statusbar(); |
Benno Schulenberg | 9973366 | 2016-12-26 17:31:27 +0100 | [diff] [blame] | 740 | mvwaddnstr(bottomwin, 0, 0, message, actual_x(message, COLS - 1)); |
Benno Schulenberg | 960e848 | 2016-07-12 09:35:48 +0200 | [diff] [blame] | 741 | wattroff(bottomwin, interface_color_pair[TITLE_BAR]); |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 742 | |
Benno Schulenberg | 59187b8 | 2015-05-28 13:28:37 +0000 | [diff] [blame] | 743 | wnoutrefresh(bottomwin); |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 744 | |
Benno Schulenberg | 86121cf | 2016-12-05 15:43:58 +0100 | [diff] [blame] | 745 | /* When not replacing, show the cursor. */ |
| 746 | if (!all) |
| 747 | curs_set(1); |
| 748 | |
Chris Allegretta | cc59383 | 2008-03-19 02:32:48 +0000 | [diff] [blame] | 749 | currmenu = MYESNO; |
Benno Schulenberg | 7e5324d | 2014-06-30 18:04:33 +0000 | [diff] [blame] | 750 | kbinput = get_kbinput(bottomwin); |
Benno Schulenberg | 75d64e6 | 2015-05-28 13:02:29 +0000 | [diff] [blame] | 751 | |
Benno Schulenberg | 266e049 | 2014-07-27 19:32:03 +0000 | [diff] [blame] | 752 | func = func_from_key(&kbinput); |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 753 | |
Benno Schulenberg | 266e049 | 2014-07-27 19:32:03 +0000 | [diff] [blame] | 754 | if (func == do_cancel) |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 755 | response = -1; |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 756 | #ifndef DISABLE_MOUSE |
Chris Allegretta | eb64314 | 2008-03-12 04:44:14 +0000 | [diff] [blame] | 757 | else if (kbinput == KEY_MOUSE) { |
Benno Schulenberg | 1fb8203 | 2016-12-26 20:20:03 +0100 | [diff] [blame] | 758 | int mouse_x, mouse_y; |
Benno Schulenberg | e5fee7e | 2016-02-07 13:37:16 +0000 | [diff] [blame] | 759 | /* We can click on the Yes/No/All shortcuts to select an answer. */ |
| 760 | if (get_mouseinput(&mouse_x, &mouse_y, FALSE) == 0 && |
| 761 | wmouse_trafo(bottomwin, &mouse_y, &mouse_x, FALSE) && |
| 762 | mouse_x < (width * 2) && mouse_y > 0) { |
| 763 | int x = mouse_x / width; |
| 764 | /* The x-coordinate among the Yes/No/All shortcuts. */ |
| 765 | int y = mouse_y - 1; |
| 766 | /* The y-coordinate among the Yes/No/All shortcuts. */ |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 767 | |
Benno Schulenberg | e5fee7e | 2016-02-07 13:37:16 +0000 | [diff] [blame] | 768 | assert(0 <= x && x <= 1 && 0 <= y && y <= 1); |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 769 | |
Benno Schulenberg | e5fee7e | 2016-02-07 13:37:16 +0000 | [diff] [blame] | 770 | /* x == 0 means they clicked Yes or No. |
| 771 | * y == 0 means Yes or All. */ |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 772 | response = -2 * x * y + x - y + 1; |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 773 | |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 774 | if (response == 2 && !all) |
| 775 | response = -2; |
Benno Schulenberg | e5fee7e | 2016-02-07 13:37:16 +0000 | [diff] [blame] | 776 | } |
Chris Allegretta | 0018d8e | 2008-03-13 08:23:52 +0000 | [diff] [blame] | 777 | } |
David Lawrence Ramsey | bc80cb1 | 2006-04-24 23:03:21 +0000 | [diff] [blame] | 778 | #endif /* !DISABLE_MOUSE */ |
Benno Schulenberg | 379b155 | 2016-12-03 20:37:30 +0100 | [diff] [blame] | 779 | else { |
Benno Schulenberg | e5fee7e | 2016-02-07 13:37:16 +0000 | [diff] [blame] | 780 | /* Look for the kbinput in the Yes, No (and All) strings. */ |
| 781 | if (strchr(yesstr, kbinput) != NULL) |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 782 | response = 1; |
Benno Schulenberg | e5fee7e | 2016-02-07 13:37:16 +0000 | [diff] [blame] | 783 | else if (strchr(nostr, kbinput) != NULL) |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 784 | response = 0; |
Benno Schulenberg | e5fee7e | 2016-02-07 13:37:16 +0000 | [diff] [blame] | 785 | else if (all && strchr(allstr, kbinput) != NULL) |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 786 | response = 2; |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 787 | } |
Benno Schulenberg | 1fb8203 | 2016-12-26 20:20:03 +0100 | [diff] [blame] | 788 | } |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 789 | |
Benno Schulenberg | 9973366 | 2016-12-26 17:31:27 +0100 | [diff] [blame] | 790 | free(message); |
| 791 | |
Benno Schulenberg | e853c1e | 2016-02-07 13:41:46 +0000 | [diff] [blame] | 792 | return response; |
David Lawrence Ramsey | 38ebba1 | 2005-11-03 21:07:24 +0000 | [diff] [blame] | 793 | } |