aboutsummaryrefslogtreecommitdiff
path: root/libbb/lineedit.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-23 11:13:23 +0000
committerRon Yorston <rmy@pobox.com>2012-03-23 11:13:23 +0000
commit40514a0309939f2446f0d4ed9600cad5de396e7f (patch)
tree0f5f4a57d4bb7893418b5bb11d482858eb17ba8b /libbb/lineedit.c
parent9db164d6e39050d09f38288c6045cd2a2cbf6d63 (diff)
parentc0cae52662ccced9df19f19ec94238d1b1e3bd71 (diff)
downloadbusybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.tar.gz
busybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.tar.bz2
busybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.zip
Merge commit 'c0cae52662ccced9df19f19ec94238d1b1e3bd71' into merge
Conflicts: Makefile.flags scripts/basic/fixdep.c
Diffstat (limited to 'libbb/lineedit.c')
-rw-r--r--libbb/lineedit.c110
1 files changed, 102 insertions, 8 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 1b97e8609..c89c829ed 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1359,7 +1359,9 @@ static void load_history(line_input_t *st_parm)
1359 1359
1360 /* fill temp_h[], retaining only last MAX_HISTORY lines */ 1360 /* fill temp_h[], retaining only last MAX_HISTORY lines */
1361 memset(temp_h, 0, sizeof(temp_h)); 1361 memset(temp_h, 0, sizeof(temp_h));
1362 st_parm->cnt_history_in_file = idx = 0; 1362 idx = 0;
1363 if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
1364 st_parm->cnt_history_in_file = 0;
1363 while ((line = xmalloc_fgetline(fp)) != NULL) { 1365 while ((line = xmalloc_fgetline(fp)) != NULL) {
1364 if (line[0] == '\0') { 1366 if (line[0] == '\0') {
1365 free(line); 1367 free(line);
@@ -1367,7 +1369,8 @@ static void load_history(line_input_t *st_parm)
1367 } 1369 }
1368 free(temp_h[idx]); 1370 free(temp_h[idx]);
1369 temp_h[idx] = line; 1371 temp_h[idx] = line;
1370 st_parm->cnt_history_in_file++; 1372 if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
1373 st_parm->cnt_history_in_file++;
1371 idx++; 1374 idx++;
1372 if (idx == st_parm->max_history) 1375 if (idx == st_parm->max_history)
1373 idx = 0; 1376 idx = 0;
@@ -1397,15 +1400,62 @@ static void load_history(line_input_t *st_parm)
1397 st_parm->history[i++] = line; 1400 st_parm->history[i++] = line;
1398 } 1401 }
1399 st_parm->cnt_history = i; 1402 st_parm->cnt_history = i;
1403 if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
1404 st_parm->cnt_history_in_file = i;
1400 } 1405 }
1401} 1406}
1402 1407
1403/* state->flags is already checked to be nonzero */ 1408# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1409void save_history(line_input_t *st)
1410{
1411 FILE *fp;
1412
1413 if (!st->hist_file)
1414 return;
1415 if (st->cnt_history <= st->cnt_history_in_file)
1416 return;
1417
1418 fp = fopen(st->hist_file, "a");
1419 if (fp) {
1420 int i, fd;
1421 char *new_name;
1422 line_input_t *st_temp;
1423
1424 for (i = st->cnt_history_in_file; i < st->cnt_history; i++)
1425 fprintf(fp, "%s\n", st->history[i]);
1426 fclose(fp);
1427
1428 /* we may have concurrently written entries from others.
1429 * load them */
1430 st_temp = new_line_input_t(st->flags);
1431 st_temp->hist_file = st->hist_file;
1432 st_temp->max_history = st->max_history;
1433 load_history(st_temp);
1434
1435 /* write out temp file and replace hist_file atomically */
1436 new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid());
1437 fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1438 if (fd >= 0) {
1439 fp = xfdopen_for_write(fd);
1440 for (i = 0; i < st_temp->cnt_history; i++)
1441 fprintf(fp, "%s\n", st_temp->history[i]);
1442 fclose(fp);
1443 if (rename(new_name, st->hist_file) == 0)
1444 st->cnt_history_in_file = st_temp->cnt_history;
1445 }
1446 free(new_name);
1447 free_line_input_t(st_temp);
1448 }
1449}
1450# else
1404static void save_history(char *str) 1451static void save_history(char *str)
1405{ 1452{
1406 int fd; 1453 int fd;
1407 int len, len2; 1454 int len, len2;
1408 1455
1456 if (!state->hist_file)
1457 return;
1458
1409 fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); 1459 fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600);
1410 if (fd < 0) 1460 if (fd < 0)
1411 return; 1461 return;
@@ -1433,7 +1483,7 @@ static void save_history(char *str)
1433 1483
1434 /* write out temp file and replace hist_file atomically */ 1484 /* write out temp file and replace hist_file atomically */
1435 new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid()); 1485 new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid());
1436 fd = open(state->hist_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1486 fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1437 if (fd >= 0) { 1487 if (fd >= 0) {
1438 FILE *fp; 1488 FILE *fp;
1439 int i; 1489 int i;
@@ -1449,6 +1499,7 @@ static void save_history(char *str)
1449 free_line_input_t(st_temp); 1499 free_line_input_t(st_temp);
1450 } 1500 }
1451} 1501}
1502# endif
1452# else 1503# else
1453# define load_history(a) ((void)0) 1504# define load_history(a) ((void)0)
1454# define save_history(a) ((void)0) 1505# define save_history(a) ((void)0)
@@ -1477,15 +1528,18 @@ static void remember_in_history(char *str)
1477 for (i = 0; i < state->max_history-1; i++) 1528 for (i = 0; i < state->max_history-1; i++)
1478 state->history[i] = state->history[i+1]; 1529 state->history[i] = state->history[i+1];
1479 /* i == state->max_history-1 */ 1530 /* i == state->max_history-1 */
1531# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1532 if (state->cnt_history_in_file)
1533 state->cnt_history_in_file--;
1534# endif
1480 } 1535 }
1481 /* i <= state->max_history-1 */ 1536 /* i <= state->max_history-1 */
1482 state->history[i++] = xstrdup(str); 1537 state->history[i++] = xstrdup(str);
1483 /* i <= state->max_history */ 1538 /* i <= state->max_history */
1484 state->cur_history = i; 1539 state->cur_history = i;
1485 state->cnt_history = i; 1540 state->cnt_history = i;
1486# if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY 1541# if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1487 if ((state->flags & SAVE_HISTORY) && state->hist_file) 1542 save_history(str);
1488 save_history(str);
1489# endif 1543# endif
1490 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) 1544 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
1491} 1545}
@@ -2147,7 +2201,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2147 state = st ? st : (line_input_t*) &const_int_0; 2201 state = st ? st : (line_input_t*) &const_int_0;
2148#if MAX_HISTORY > 0 2202#if MAX_HISTORY > 0
2149# if ENABLE_FEATURE_EDITING_SAVEHISTORY 2203# if ENABLE_FEATURE_EDITING_SAVEHISTORY
2150 if ((state->flags & SAVE_HISTORY) && state->hist_file) 2204 if (state->hist_file)
2151 if (state->cnt_history == 0) 2205 if (state->cnt_history == 0)
2152 load_history(state); 2206 load_history(state);
2153# endif 2207# endif
@@ -2467,6 +2521,44 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2467 vi_cmdmode = 1; 2521 vi_cmdmode = 1;
2468 input_backward(1); 2522 input_backward(1);
2469 } 2523 }
2524 /* Handle a few ESC-<key> combinations the same way
2525 * standard readline bindings (IOW: bash) do.
2526 * Often, Alt-<key> generates ESC-<key>.
2527 */
2528 ic = lineedit_read_key(read_key_buffer, timeout);
2529 switch (ic) {
2530 //case KEYCODE_LEFT: - bash doesn't do this
2531 case 'b':
2532 ctrl_left();
2533 break;
2534 //case KEYCODE_RIGHT: - bash doesn't do this
2535 case 'f':
2536 ctrl_right();
2537 break;
2538 //case KEYCODE_DELETE: - bash doesn't do this
2539 case 'd': /* Alt-D */
2540 {
2541 /* Delete word forward */
2542 int nc, sc = cursor;
2543 ctrl_right();
2544 nc = cursor;
2545 input_backward(cursor - sc);
2546 while (--nc >= cursor)
2547 input_delete(1);
2548 break;
2549 }
2550 case '\b': /* Alt-Backspace(?) */
2551 case '\x7f': /* Alt-Backspace(?) */
2552 //case 'w': - bash doesn't do this
2553 {
2554 /* Delete word backward */
2555 int sc = cursor;
2556 ctrl_left();
2557 while (sc-- > cursor)
2558 input_delete(1);
2559 break;
2560 }
2561 }
2470 break; 2562 break;
2471#endif /* FEATURE_COMMAND_EDITING_VI */ 2563#endif /* FEATURE_COMMAND_EDITING_VI */
2472 2564
@@ -2495,9 +2587,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2495 input_backward(1); 2587 input_backward(1);
2496 break; 2588 break;
2497 case KEYCODE_CTRL_LEFT: 2589 case KEYCODE_CTRL_LEFT:
2590 case KEYCODE_ALT_LEFT: /* bash doesn't do it */
2498 ctrl_left(); 2591 ctrl_left();
2499 break; 2592 break;
2500 case KEYCODE_CTRL_RIGHT: 2593 case KEYCODE_CTRL_RIGHT:
2594 case KEYCODE_ALT_RIGHT: /* bash doesn't do it */
2501 ctrl_right(); 2595 ctrl_right();
2502 break; 2596 break;
2503 case KEYCODE_HOME: 2597 case KEYCODE_HOME: