Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/libbb/lineedit.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/libbb/lineedit.c
r2725 r3232 42 42 #include "libbb.h" 43 43 #include "unicode.h" 44 #ifndef _POSIX_VDISABLE 45 # define _POSIX_VDISABLE '\0' 46 #endif 47 44 48 45 49 #ifdef TEST … … 185 189 IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \ 186 190 } while (0) 191 187 192 static void deinit_S(void) 188 193 { … … 203 208 204 209 #if ENABLE_UNICODE_SUPPORT 205 static size_t load_string(const char *src, int maxsize) 206 { 207 ssize_t len = mbstowcs(command_ps, src, maxsize - 1); 208 if (len < 0) 209 len = 0; 210 command_ps[len] = BB_NUL; 211 return len; 210 static size_t load_string(const char *src) 211 { 212 if (unicode_status == UNICODE_ON) { 213 ssize_t len = mbstowcs(command_ps, src, S.maxsize - 1); 214 if (len < 0) 215 len = 0; 216 command_ps[len] = BB_NUL; 217 return len; 218 } else { 219 unsigned i = 0; 220 while (src[i] && i < S.maxsize - 1) { 221 command_ps[i] = src[i]; 222 i++; 223 } 224 command_ps[i] = BB_NUL; 225 return i; 226 } 212 227 } 213 228 static unsigned save_string(char *dst, unsigned maxsize) 214 229 { 230 if (unicode_status == UNICODE_ON) { 215 231 # if !ENABLE_UNICODE_PRESERVE_BROKEN 216 ssize_t len = wcstombs(dst, command_ps, maxsize - 1);217 if (len < 0)218 len = 0;219 dst[len] = '\0';220 return len;232 ssize_t len = wcstombs(dst, command_ps, maxsize - 1); 233 if (len < 0) 234 len = 0; 235 dst[len] = '\0'; 236 return len; 221 237 # else 222 unsigned dstpos = 0; 223 unsigned srcpos = 0; 224 225 maxsize--; 226 while (dstpos < maxsize) { 227 wchar_t wc; 228 int n = srcpos; 229 230 /* Convert up to 1st invalid byte (or up to end) */ 231 while ((wc = command_ps[srcpos]) != BB_NUL 232 && !unicode_is_raw_byte(wc) 233 ) { 238 unsigned dstpos = 0; 239 unsigned srcpos = 0; 240 241 maxsize--; 242 while (dstpos < maxsize) { 243 wchar_t wc; 244 int n = srcpos; 245 246 /* Convert up to 1st invalid byte (or up to end) */ 247 while ((wc = command_ps[srcpos]) != BB_NUL 248 && !unicode_is_raw_byte(wc) 249 ) { 250 srcpos++; 251 } 252 command_ps[srcpos] = BB_NUL; 253 n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); 254 if (n < 0) /* should not happen */ 255 break; 256 dstpos += n; 257 if (wc == BB_NUL) /* usually is */ 258 break; 259 260 /* We do have invalid byte here! */ 261 command_ps[srcpos] = wc; /* restore it */ 234 262 srcpos++; 235 } 236 command_ps[srcpos] = BB_NUL; 237 n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); 238 if (n < 0) /* should not happen */ 239 break; 240 dstpos += n; 241 if (wc == BB_NUL) /* usually is */ 242 break; 243 244 /* We do have invalid byte here! */ 245 command_ps[srcpos] = wc; /* restore it */ 246 srcpos++; 247 if (dstpos == maxsize) 248 break; 249 dst[dstpos++] = (char) wc; 250 } 251 dst[dstpos] = '\0'; 252 return dstpos; 263 if (dstpos == maxsize) 264 break; 265 dst[dstpos++] = (char) wc; 266 } 267 dst[dstpos] = '\0'; 268 return dstpos; 253 269 # endif 270 } else { 271 unsigned i = 0; 272 while ((dst[i] = command_ps[i]) != 0) 273 i++; 274 return i; 275 } 254 276 } 255 277 /* I thought just fputwc(c, stdout) would work. But no... */ 256 278 static void BB_PUTCHAR(wchar_t c) 257 279 { 258 char buf[MB_CUR_MAX + 1]; 259 mbstate_t mbst = { 0 }; 260 ssize_t len; 261 262 len = wcrtomb(buf, c, &mbst); 263 if (len > 0) { 264 buf[len] = '\0'; 265 fputs(buf, stdout); 280 if (unicode_status == UNICODE_ON) { 281 char buf[MB_CUR_MAX + 1]; 282 mbstate_t mbst = { 0 }; 283 ssize_t len = wcrtomb(buf, c, &mbst); 284 if (len > 0) { 285 buf[len] = '\0'; 286 fputs(buf, stdout); 287 } 288 } else { 289 /* In this case, c is always one byte */ 290 putchar(c); 266 291 } 267 292 } … … 298 323 } 299 324 #else /* !UNICODE */ 300 static size_t load_string(const char *src , int maxsize)301 { 302 safe_strncpy(command_ps, src, maxsize);325 static size_t load_string(const char *src) 326 { 327 safe_strncpy(command_ps, src, S.maxsize); 303 328 return strlen(command_ps); 304 329 } … … 1203 1228 /* where do we want to have cursor after all? */ 1204 1229 strcpy(&command[cursor_mb], chosen_match + match_pfx_len); 1205 len = load_string(command , S.maxsize);1230 len = load_string(command); 1206 1231 /* add match and tail */ 1207 1232 sprintf(&command[cursor_mb], "%s%s", chosen_match + match_pfx_len, match_buf); 1208 command_len = load_string(command , S.maxsize);1233 command_len = load_string(command); 1209 1234 /* write out the matched command */ 1210 1235 /* paranoia: load_string can return 0 on conv error, … … 1227 1252 line_input_t *n = xzalloc(sizeof(*n)); 1228 1253 n->flags = flags; 1254 n->max_history = MAX_HISTORY; 1229 1255 return n; 1230 1256 } … … 1232 1258 1233 1259 #if MAX_HISTORY > 0 1260 1261 unsigned size_from_HISTFILESIZE(const char *hp) 1262 { 1263 int size = MAX_HISTORY; 1264 if (hp) { 1265 size = atoi(hp); 1266 if (size <= 0) 1267 return 1; 1268 if (size > MAX_HISTORY) 1269 return MAX_HISTORY; 1270 } 1271 return size; 1272 } 1234 1273 1235 1274 static void save_command_ps_at_cur_history(void) … … 1313 1352 /* fill temp_h[], retaining only last MAX_HISTORY lines */ 1314 1353 memset(temp_h, 0, sizeof(temp_h)); 1315 st_parm->cnt_history_in_file = idx = 0; 1354 idx = 0; 1355 st_parm->cnt_history_in_file = 0; 1316 1356 while ((line = xmalloc_fgetline(fp)) != NULL) { 1317 1357 if (line[0] == '\0') { … … 1323 1363 st_parm->cnt_history_in_file++; 1324 1364 idx++; 1325 if (idx == MAX_HISTORY)1365 if (idx == st_parm->max_history) 1326 1366 idx = 0; 1327 1367 } … … 1332 1372 while (temp_h[idx] == NULL) { 1333 1373 idx++; 1334 if (idx == MAX_HISTORY)1374 if (idx == st_parm->max_history) 1335 1375 idx = 0; 1336 1376 } … … 1338 1378 1339 1379 /* copy temp_h[] to st_parm->history[] */ 1340 for (i = 0; i < MAX_HISTORY;) {1380 for (i = 0; i < st_parm->max_history;) { 1341 1381 line = temp_h[idx]; 1342 1382 if (!line) 1343 1383 break; 1344 1384 idx++; 1345 if (idx == MAX_HISTORY)1385 if (idx == st_parm->max_history) 1346 1386 idx = 0; 1347 1387 line_len = strlen(line); … … 1351 1391 } 1352 1392 st_parm->cnt_history = i; 1353 } 1354 } 1355 1356 /* state->flags is already checked to be nonzero */ 1393 if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) 1394 st_parm->cnt_history_in_file = i; 1395 } 1396 } 1397 1398 # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 1399 void save_history(line_input_t *st) 1400 { 1401 FILE *fp; 1402 1403 if (!st->hist_file) 1404 return; 1405 if (st->cnt_history <= st->cnt_history_in_file) 1406 return; 1407 1408 fp = fopen(st->hist_file, "a"); 1409 if (fp) { 1410 int i, fd; 1411 char *new_name; 1412 line_input_t *st_temp; 1413 1414 for (i = st->cnt_history_in_file; i < st->cnt_history; i++) 1415 fprintf(fp, "%s\n", st->history[i]); 1416 fclose(fp); 1417 1418 /* we may have concurrently written entries from others. 1419 * load them */ 1420 st_temp = new_line_input_t(st->flags); 1421 st_temp->hist_file = st->hist_file; 1422 st_temp->max_history = st->max_history; 1423 load_history(st_temp); 1424 1425 /* write out temp file and replace hist_file atomically */ 1426 new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid()); 1427 fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1428 if (fd >= 0) { 1429 fp = xfdopen_for_write(fd); 1430 for (i = 0; i < st_temp->cnt_history; i++) 1431 fprintf(fp, "%s\n", st_temp->history[i]); 1432 fclose(fp); 1433 if (rename(new_name, st->hist_file) == 0) 1434 st->cnt_history_in_file = st_temp->cnt_history; 1435 } 1436 free(new_name); 1437 free_line_input_t(st_temp); 1438 } 1439 } 1440 # else 1357 1441 static void save_history(char *str) 1358 1442 { 1359 1443 int fd; 1360 1444 int len, len2; 1445 1446 if (!state->hist_file) 1447 return; 1361 1448 1362 1449 fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); … … 1374 1461 /* did we write so much that history file needs trimming? */ 1375 1462 state->cnt_history_in_file++; 1376 if (state->cnt_history_in_file > MAX_HISTORY* 4) {1463 if (state->cnt_history_in_file > state->max_history * 4) { 1377 1464 char *new_name; 1378 1465 line_input_t *st_temp; … … 1382 1469 st_temp = new_line_input_t(state->flags); 1383 1470 st_temp->hist_file = state->hist_file; 1471 st_temp->max_history = state->max_history; 1384 1472 load_history(st_temp); 1385 1473 1386 1474 /* write out temp file and replace hist_file atomically */ 1387 1475 new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid()); 1388 fd = open( state->hist_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);1476 fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1389 1477 if (fd >= 0) { 1390 1478 FILE *fp; … … 1402 1490 } 1403 1491 } 1492 # endif 1404 1493 # else 1405 1494 # define load_history(a) ((void)0) … … 1420 1509 return; 1421 1510 1422 free(state->history[ MAX_HISTORY]); /* redundant, paranoia */1423 state->history[ MAX_HISTORY] = NULL; /* redundant, paranoia */1511 free(state->history[state->max_history]); /* redundant, paranoia */ 1512 state->history[state->max_history] = NULL; /* redundant, paranoia */ 1424 1513 1425 1514 /* If history[] is full, remove the oldest command */ 1426 /* we need to keep history[ MAX_HISTORY] empty, hence >=, not > */1427 if (i >= MAX_HISTORY) {1515 /* we need to keep history[state->max_history] empty, hence >=, not > */ 1516 if (i >= state->max_history) { 1428 1517 free(state->history[0]); 1429 for (i = 0; i < MAX_HISTORY-1; i++)1518 for (i = 0; i < state->max_history-1; i++) 1430 1519 state->history[i] = state->history[i+1]; 1431 /* i == MAX_HISTORY-1 */ 1432 } 1433 /* i <= MAX_HISTORY-1 */ 1520 /* i == state->max_history-1 */ 1521 # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 1522 if (state->cnt_history_in_file) 1523 state->cnt_history_in_file--; 1524 # endif 1525 } 1526 /* i <= state->max_history-1 */ 1434 1527 state->history[i++] = xstrdup(str); 1435 /* i <= MAX_HISTORY*/1528 /* i <= state->max_history */ 1436 1529 state->cur_history = i; 1437 1530 state->cnt_history = i; 1438 # if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY 1439 if ((state->flags & SAVE_HISTORY) && state->hist_file) 1440 save_history(str); 1531 # if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 1532 save_history(str); 1441 1533 # endif 1442 1534 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) … … 1645 1737 * poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout) <-- no input exists 1646 1738 * write(1, "\33[6n", 4) = 4 <-- send the ESC sequence, quick! 1647 * poll([{fd=0, events=POLLIN}], 1, 4294967295) = 1 ([{fd=0, revents=POLLIN}])1739 * poll([{fd=0, events=POLLIN}], 1, -1) = 1 ([{fd=0, revents=POLLIN}]) 1648 1740 * read(0, "\n", 1) = 1 <-- oh crap, user's input got in first 1649 1741 */ … … 1803 1895 int sv_errno = errno; 1804 1896 unsigned width; 1897 1805 1898 get_terminal_width_height(0, &width, NULL); 1806 cmdedit_setwidth(width, nsig /* - just a yes/no flag */); 1807 if (nsig == SIGWINCH)1808 signal(SIGWINCH, win_changed); /* rearm ourself */ 1899 //FIXME: cmdedit_setwidth() -> redraw() -> printf() -> KABOOM! (we are in signal handler!) 1900 cmdedit_setwidth(width, /*redraw_flg:*/ nsig); 1901 1809 1902 errno = sv_errno; 1810 1903 } 1811 1904 1812 static int lineedit_read_key(char *read_key_buffer )1905 static int lineedit_read_key(char *read_key_buffer, int timeout) 1813 1906 { 1814 1907 int64_t ic; 1815 int timeout = -1;1816 1908 #if ENABLE_UNICODE_SUPPORT 1817 1909 char unicode_buf[MB_CUR_MAX + 1]; … … 1912 2004 #define CTRL(a) ((a) & ~0x40) 1913 2005 2006 enum { 2007 VI_CMDMODE_BIT = 0x40000000, 2008 /* 0x80000000 bit flags KEYCODE_xxx */ 2009 }; 2010 2011 #if ENABLE_FEATURE_REVERSE_SEARCH 2012 /* Mimic readline Ctrl-R reverse history search. 2013 * When invoked, it shows the following prompt: 2014 * (reverse-i-search)'': user_input [cursor pos unchanged by Ctrl-R] 2015 * and typing results in search being performed: 2016 * (reverse-i-search)'tmp': cd /tmp [cursor under t in /tmp] 2017 * Search is performed by looking at progressively older lines in history. 2018 * Ctrl-R again searches for the next match in history. 2019 * Backspace deletes last matched char. 2020 * Control keys exit search and return to normal editing (at current history line). 2021 */ 2022 static int32_t reverse_i_search(void) 2023 { 2024 char match_buf[128]; /* for user input */ 2025 char read_key_buffer[KEYCODE_BUFFER_SIZE]; 2026 const char *matched_history_line; 2027 const char *saved_prompt; 2028 int32_t ic; 2029 2030 matched_history_line = NULL; 2031 read_key_buffer[0] = 0; 2032 match_buf[0] = '\0'; 2033 2034 /* Save and replace the prompt */ 2035 saved_prompt = cmdedit_prompt; 2036 goto set_prompt; 2037 2038 while (1) { 2039 int h; 2040 unsigned match_buf_len = strlen(match_buf); 2041 2042 fflush_all(); 2043 //FIXME: correct timeout? 2044 ic = lineedit_read_key(read_key_buffer, -1); 2045 2046 switch (ic) { 2047 case CTRL('R'): /* searching for the next match */ 2048 break; 2049 2050 case '\b': 2051 case '\x7f': 2052 /* Backspace */ 2053 if (unicode_status == UNICODE_ON) { 2054 while (match_buf_len != 0) { 2055 uint8_t c = match_buf[--match_buf_len]; 2056 if ((c & 0xc0) != 0x80) /* start of UTF-8 char? */ 2057 break; /* yes */ 2058 } 2059 } else { 2060 if (match_buf_len != 0) 2061 match_buf_len--; 2062 } 2063 match_buf[match_buf_len] = '\0'; 2064 break; 2065 2066 default: 2067 if (ic < ' ' 2068 || (!ENABLE_UNICODE_SUPPORT && ic >= 256) 2069 || (ENABLE_UNICODE_SUPPORT && ic >= VI_CMDMODE_BIT) 2070 ) { 2071 goto ret; 2072 } 2073 2074 /* Append this char */ 2075 #if ENABLE_UNICODE_SUPPORT 2076 if (unicode_status == UNICODE_ON) { 2077 mbstate_t mbstate = { 0 }; 2078 char buf[MB_CUR_MAX + 1]; 2079 int len = wcrtomb(buf, ic, &mbstate); 2080 if (len > 0) { 2081 buf[len] = '\0'; 2082 if (match_buf_len + len < sizeof(match_buf)) 2083 strcpy(match_buf + match_buf_len, buf); 2084 } 2085 } else 2086 #endif 2087 if (match_buf_len < sizeof(match_buf) - 1) { 2088 match_buf[match_buf_len] = ic; 2089 match_buf[match_buf_len + 1] = '\0'; 2090 } 2091 break; 2092 } /* switch (ic) */ 2093 2094 /* Search in history for match_buf */ 2095 h = state->cur_history; 2096 if (ic == CTRL('R')) 2097 h--; 2098 while (h >= 0) { 2099 if (state->history[h]) { 2100 char *match = strstr(state->history[h], match_buf); 2101 if (match) { 2102 state->cur_history = h; 2103 matched_history_line = state->history[h]; 2104 command_len = load_string(matched_history_line); 2105 cursor = match - matched_history_line; 2106 //FIXME: cursor position for Unicode case 2107 2108 free((char*)cmdedit_prompt); 2109 set_prompt: 2110 cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf); 2111 cmdedit_prmt_len = strlen(cmdedit_prompt); 2112 goto do_redraw; 2113 } 2114 } 2115 h--; 2116 } 2117 2118 /* Not found */ 2119 match_buf[match_buf_len] = '\0'; 2120 beep(); 2121 continue; 2122 2123 do_redraw: 2124 redraw(cmdedit_y, command_len - cursor); 2125 } /* while (1) */ 2126 2127 ret: 2128 if (matched_history_line) 2129 command_len = load_string(matched_history_line); 2130 2131 free((char*)cmdedit_prompt); 2132 cmdedit_prompt = saved_prompt; 2133 cmdedit_prmt_len = strlen(cmdedit_prompt); 2134 redraw(cmdedit_y, command_len - cursor); 2135 2136 return ic; 2137 } 2138 #endif 2139 1914 2140 /* maxsize must be >= 2. 1915 2141 * Returns: … … 1918 2144 * >0 length of input string, including terminating '\n' 1919 2145 */ 1920 int FAST_FUNC read_line_input( const char *prompt, char *command, int maxsize, line_input_t *st)2146 int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) 1921 2147 { 1922 2148 int len; … … 1955 2181 S.maxsize = maxsize; 1956 2182 1957 /* With nullflags, no other fields are ever used */2183 /* With zero flags, no other fields are ever used */ 1958 2184 state = st ? st : (line_input_t*) &const_int_0; 1959 2185 #if MAX_HISTORY > 0 1960 2186 # if ENABLE_FEATURE_EDITING_SAVEHISTORY 1961 if ( (state->flags & SAVE_HISTORY) &&state->hist_file)2187 if (state->hist_file) 1962 2188 if (state->cnt_history == 0) 1963 2189 load_history(state); … … 1979 2205 1980 2206 new_settings = initial_settings; 1981 new_settings.c_lflag &= ~ICANON; /* unbuffered input */ 1982 /* Turn off echoing and CTRL-C, so we can trap it */ 1983 new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); 1984 /* Hmm, in linux c_cc[] is not parsed if ICANON is off */ 2207 /* ~ICANON: unbuffered input (most c_cc[] are disabled, VMIN/VTIME are enabled) */ 2208 /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ 2209 /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ 2210 new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); 2211 /* reads would block only if < 1 char is available */ 1985 2212 new_settings.c_cc[VMIN] = 1; 2213 /* no timeout (reads block forever) */ 1986 2214 new_settings.c_cc[VTIME] = 0; 1987 /* Turn off CTRL-C, so we can trap it */ 1988 #ifndef _POSIX_VDISABLE 1989 # define _POSIX_VDISABLE '\0' 1990 #endif 1991 new_settings.c_cc[VINTR] = _POSIX_VDISABLE; 2215 /* Should be not needed if ISIG is off: */ 2216 /* Turn off CTRL-C */ 2217 /* new_settings.c_cc[VINTR] = _POSIX_VDISABLE; */ 1992 2218 tcsetattr_stdin_TCSANOW(&new_settings); 1993 2219 1994 /* Now initialize things */1995 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);1996 win_changed(0); /* do initial resizing */1997 2220 #if ENABLE_USERNAME_OR_HOMEDIR 1998 2221 { … … 2008 2231 2009 2232 #if 0 2010 for (i = 0; i <= MAX_HISTORY; i++)2233 for (i = 0; i <= state->max_history; i++) 2011 2234 bb_error_msg("history[%d]:'%s'", i, state->history[i]); 2012 2235 bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history); … … 2016 2239 parse_and_put_prompt(prompt); 2017 2240 ask_terminal(); 2241 2242 /* Install window resize handler (NB: after *all* init is complete) */ 2243 //FIXME: save entire sigaction! 2244 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); 2245 win_changed(0); /* get initial window size */ 2018 2246 2019 2247 read_key_buffer[0] = 0; … … 2027 2255 * in one place. 2028 2256 */ 2029 enum {2030 VI_CMDMODE_BIT = 0x40000000,2031 /* 0x80000000 bit flags KEYCODE_xxx */2032 };2033 2257 int32_t ic, ic_raw; 2034 2258 2035 2259 fflush_all(); 2036 ic = ic_raw = lineedit_read_key(read_key_buffer); 2037 2260 ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); 2261 2262 #if ENABLE_FEATURE_REVERSE_SEARCH 2263 again: 2264 #endif 2038 2265 #if ENABLE_FEATURE_EDITING_VI 2039 2266 newdelflag = 1; … … 2139 2366 input_backspace(); 2140 2367 break; 2368 #if ENABLE_FEATURE_REVERSE_SEARCH 2369 case CTRL('R'): 2370 ic = ic_raw = reverse_i_search(); 2371 goto again; 2372 #endif 2141 2373 2142 2374 #if ENABLE_FEATURE_EDITING_VI … … 2195 2427 int nc, sc; 2196 2428 2197 ic = lineedit_read_key(read_key_buffer );2429 ic = lineedit_read_key(read_key_buffer, timeout); 2198 2430 if (errno) /* error */ 2199 2431 goto return_error_indicator; … … 2259 2491 case 'r'|VI_CMDMODE_BIT: 2260 2492 //FIXME: unicode case? 2261 ic = lineedit_read_key(read_key_buffer );2493 ic = lineedit_read_key(read_key_buffer, timeout); 2262 2494 if (errno) /* error */ 2263 2495 goto return_error_indicator; … … 2276 2508 input_backward(1); 2277 2509 } 2510 /* Handle a few ESC-<key> combinations the same way 2511 * standard readline bindings (IOW: bash) do. 2512 * Often, Alt-<key> generates ESC-<key>. 2513 */ 2514 ic = lineedit_read_key(read_key_buffer, timeout); 2515 switch (ic) { 2516 //case KEYCODE_LEFT: - bash doesn't do this 2517 case 'b': 2518 ctrl_left(); 2519 break; 2520 //case KEYCODE_RIGHT: - bash doesn't do this 2521 case 'f': 2522 ctrl_right(); 2523 break; 2524 //case KEYCODE_DELETE: - bash doesn't do this 2525 case 'd': /* Alt-D */ 2526 { 2527 /* Delete word forward */ 2528 int nc, sc = cursor; 2529 ctrl_right(); 2530 nc = cursor - sc; 2531 input_backward(nc); 2532 while (--nc >= 0) 2533 input_delete(1); 2534 break; 2535 } 2536 case '\b': /* Alt-Backspace(?) */ 2537 case '\x7f': /* Alt-Backspace(?) */ 2538 //case 'w': - bash doesn't do this 2539 { 2540 /* Delete word backward */ 2541 int sc = cursor; 2542 ctrl_left(); 2543 while (sc-- > cursor) 2544 input_delete(1); 2545 break; 2546 } 2547 } 2278 2548 break; 2279 2549 #endif /* FEATURE_COMMAND_EDITING_VI */ … … 2292 2562 /* change command */ 2293 2563 command_len = load_string(state->history[state->cur_history] ? 2294 state->history[state->cur_history] : "" , maxsize);2564 state->history[state->cur_history] : ""); 2295 2565 /* redraw and go to eol (bol, in vi) */ 2296 2566 redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); … … 2304 2574 break; 2305 2575 case KEYCODE_CTRL_LEFT: 2576 case KEYCODE_ALT_LEFT: /* bash doesn't do it */ 2306 2577 ctrl_left(); 2307 2578 break; 2308 2579 case KEYCODE_CTRL_RIGHT: 2580 case KEYCODE_ALT_RIGHT: /* bash doesn't do it */ 2309 2581 ctrl_right(); 2310 2582 break; … … 2458 2730 fputs(prompt, stdout); 2459 2731 fflush_all(); 2460 fgets(command, maxsize, stdin); 2732 if (!fgets(command, maxsize, stdin)) 2733 return -1; 2461 2734 return strlen(command); 2462 2735 }
Note:
See TracChangeset
for help on using the changeset viewer.