diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-23 11:13:23 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-23 11:13:23 +0000 |
commit | 40514a0309939f2446f0d4ed9600cad5de396e7f (patch) | |
tree | 0f5f4a57d4bb7893418b5bb11d482858eb17ba8b /libbb/lineedit.c | |
parent | 9db164d6e39050d09f38288c6045cd2a2cbf6d63 (diff) | |
parent | c0cae52662ccced9df19f19ec94238d1b1e3bd71 (diff) | |
download | busybox-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.c | 110 |
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 |
1409 | void 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 | ||
1404 | static void save_history(char *str) | 1451 | static 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: |