diff options
Diffstat (limited to 'libbb/lineedit.c')
-rw-r--r-- | libbb/lineedit.c | 153 |
1 files changed, 148 insertions, 5 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index e8d721e61..7c46fa5db 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -371,7 +371,7 @@ int adjust_width_and_validate_wc(unsigned *width_adj, int wc); | |||
371 | /* Put 'command_ps[cursor]', cursor++. | 371 | /* Put 'command_ps[cursor]', cursor++. |
372 | * Advance cursor on screen. If we reached right margin, scroll text up | 372 | * Advance cursor on screen. If we reached right margin, scroll text up |
373 | * and remove terminal margin effect by printing 'next_char' */ | 373 | * and remove terminal margin effect by printing 'next_char' */ |
374 | #define HACK_FOR_WRONG_WIDTH 1 | 374 | #define HACK_FOR_WRONG_WIDTH 1 && !ENABLE_PLATFORM_MINGW32 |
375 | static void put_cur_glyph_and_inc_cursor(void) | 375 | static void put_cur_glyph_and_inc_cursor(void) |
376 | { | 376 | { |
377 | CHAR_T c = command_ps[cursor]; | 377 | CHAR_T c = command_ps[cursor]; |
@@ -434,6 +434,42 @@ static void put_cur_glyph_and_inc_cursor(void) | |||
434 | } | 434 | } |
435 | } | 435 | } |
436 | 436 | ||
437 | #if ENABLE_PLATFORM_MINGW32 | ||
438 | static void inc_cursor(void) | ||
439 | { | ||
440 | CHAR_T c = command_ps[cursor]; | ||
441 | unsigned width = 0; | ||
442 | int ofs_to_right; | ||
443 | |||
444 | /* advance cursor */ | ||
445 | cursor++; | ||
446 | if (unicode_status == UNICODE_ON) { | ||
447 | IF_UNICODE_WIDE_WCHARS(width = cmdedit_x;) | ||
448 | c = adjust_width_and_validate_wc(&cmdedit_x, c); | ||
449 | IF_UNICODE_WIDE_WCHARS(width = cmdedit_x - width;) | ||
450 | } else { | ||
451 | cmdedit_x++; | ||
452 | } | ||
453 | |||
454 | ofs_to_right = cmdedit_x - cmdedit_termw; | ||
455 | if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right <= 0) { | ||
456 | /* cursor remains on this line */ | ||
457 | printf(ESC"[1C"); | ||
458 | } | ||
459 | |||
460 | if (ofs_to_right >= 0) { | ||
461 | /* we go to the next line */ | ||
462 | printf(ESC"[1B"); | ||
463 | bb_putchar('\r'); | ||
464 | cmdedit_y++; | ||
465 | if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right == 0) { | ||
466 | width = 0; | ||
467 | } | ||
468 | cmdedit_x = width; | ||
469 | } | ||
470 | } | ||
471 | #endif | ||
472 | |||
437 | /* Move to end of line (by printing all chars till the end) */ | 473 | /* Move to end of line (by printing all chars till the end) */ |
438 | static void put_till_end_and_adv_cursor(void) | 474 | static void put_till_end_and_adv_cursor(void) |
439 | { | 475 | { |
@@ -493,6 +529,7 @@ static void input_backward(unsigned num) | |||
493 | 529 | ||
494 | if (cmdedit_x >= num) { | 530 | if (cmdedit_x >= num) { |
495 | cmdedit_x -= num; | 531 | cmdedit_x -= num; |
532 | #if !ENABLE_PLATFORM_MINGW32 | ||
496 | if (num <= 4) { | 533 | if (num <= 4) { |
497 | /* This is longer by 5 bytes on x86. | 534 | /* This is longer by 5 bytes on x86. |
498 | * Also gets miscompiled for ARM users | 535 | * Also gets miscompiled for ARM users |
@@ -505,6 +542,7 @@ static void input_backward(unsigned num) | |||
505 | } while (--num); | 542 | } while (--num); |
506 | return; | 543 | return; |
507 | } | 544 | } |
545 | #endif | ||
508 | printf(ESC"[%uD", num); | 546 | printf(ESC"[%uD", num); |
509 | return; | 547 | return; |
510 | } | 548 | } |
@@ -643,7 +681,11 @@ static void input_backspace(void) | |||
643 | static void input_forward(void) | 681 | static void input_forward(void) |
644 | { | 682 | { |
645 | if (cursor < command_len) | 683 | if (cursor < command_len) |
684 | #if !ENABLE_PLATFORM_MINGW32 | ||
646 | put_cur_glyph_and_inc_cursor(); | 685 | put_cur_glyph_and_inc_cursor(); |
686 | #else | ||
687 | inc_cursor(); | ||
688 | #endif | ||
647 | } | 689 | } |
648 | 690 | ||
649 | #if ENABLE_FEATURE_TAB_COMPLETION | 691 | #if ENABLE_FEATURE_TAB_COMPLETION |
@@ -654,6 +696,14 @@ static void input_forward(void) | |||
654 | //Also, perhaps "foo b<TAB> needs to complete to "foo bar" <cursor>, | 696 | //Also, perhaps "foo b<TAB> needs to complete to "foo bar" <cursor>, |
655 | //not "foo bar <cursor>... | 697 | //not "foo bar <cursor>... |
656 | 698 | ||
699 | # if ENABLE_PLATFORM_MINGW32 | ||
700 | /* use case-insensitive comparisons for filenames */ | ||
701 | # define is_prefixed_with(s, k) is_prefixed_with_case(s, k) | ||
702 | # define qsort_string_vector(s, c) qsort_string_vector_case(s, c) | ||
703 | # define strcmp(s, t) strcasecmp(s, t) | ||
704 | # define strncmp(s, t, n) strncasecmp(s, t, n) | ||
705 | # endif | ||
706 | |||
657 | static void free_tab_completion_data(void) | 707 | static void free_tab_completion_data(void) |
658 | { | 708 | { |
659 | if (matches) { | 709 | if (matches) { |
@@ -670,8 +720,12 @@ static void add_match(char *matched) | |||
670 | while (*p) { | 720 | while (*p) { |
671 | /* ESC attack fix: drop any string with control chars */ | 721 | /* ESC attack fix: drop any string with control chars */ |
672 | if (*p < ' ' | 722 | if (*p < ' ' |
723 | # if !ENABLE_PLATFORM_MINGW32 | ||
673 | || (!ENABLE_UNICODE_SUPPORT && *p >= 0x7f) | 724 | || (!ENABLE_UNICODE_SUPPORT && *p >= 0x7f) |
674 | || (ENABLE_UNICODE_SUPPORT && *p == 0x7f) | 725 | || (ENABLE_UNICODE_SUPPORT && *p == 0x7f) |
726 | # else | ||
727 | || *p == 0x7f | ||
728 | # endif | ||
675 | ) { | 729 | ) { |
676 | free(matched); | 730 | free(matched); |
677 | return; | 731 | return; |
@@ -690,13 +744,16 @@ static void add_match(char *matched) | |||
690 | */ | 744 | */ |
691 | static char *username_path_completion(char *ud) | 745 | static char *username_path_completion(char *ud) |
692 | { | 746 | { |
747 | # if !ENABLE_PLATFORM_MINGW32 | ||
693 | struct passwd *entry; | 748 | struct passwd *entry; |
749 | #endif | ||
694 | char *tilde_name = ud; | 750 | char *tilde_name = ud; |
695 | char *home = NULL; | 751 | char *home = NULL; |
696 | 752 | ||
697 | ud++; /* skip ~ */ | 753 | ud++; /* skip ~ */ |
698 | if (*ud == '/') { /* "~/..." */ | 754 | if (*ud == '/') { /* "~/..." */ |
699 | home = home_pwd_buf; | 755 | home = home_pwd_buf; |
756 | # if !ENABLE_PLATFORM_MINGW32 | ||
700 | } else { | 757 | } else { |
701 | /* "~user/..." */ | 758 | /* "~user/..." */ |
702 | ud = strchr(ud, '/'); | 759 | ud = strchr(ud, '/'); |
@@ -705,6 +762,7 @@ static char *username_path_completion(char *ud) | |||
705 | *ud = '/'; /* restore "~user/..." */ | 762 | *ud = '/'; /* restore "~user/..." */ |
706 | if (entry) | 763 | if (entry) |
707 | home = entry->pw_dir; | 764 | home = entry->pw_dir; |
765 | # endif | ||
708 | } | 766 | } |
709 | if (home) { | 767 | if (home) { |
710 | ud = concat_path_file(home, ud); | 768 | ud = concat_path_file(home, ud); |
@@ -714,6 +772,7 @@ static char *username_path_completion(char *ud) | |||
714 | return tilde_name; | 772 | return tilde_name; |
715 | } | 773 | } |
716 | 774 | ||
775 | # if !ENABLE_PLATFORM_MINGW32 | ||
717 | /* ~use<tab> - find all users with this prefix. | 776 | /* ~use<tab> - find all users with this prefix. |
718 | * Return the length of the prefix used for matching. | 777 | * Return the length of the prefix used for matching. |
719 | */ | 778 | */ |
@@ -736,6 +795,7 @@ static NOINLINE unsigned complete_username(const char *ud) | |||
736 | 795 | ||
737 | return 1 + userlen; | 796 | return 1 + userlen; |
738 | } | 797 | } |
798 | # endif | ||
739 | # endif /* FEATURE_USERNAME_COMPLETION */ | 799 | # endif /* FEATURE_USERNAME_COMPLETION */ |
740 | 800 | ||
741 | enum { | 801 | enum { |
@@ -765,7 +825,7 @@ static unsigned path_parse(char ***p) | |||
765 | tmp = (char*)pth; | 825 | tmp = (char*)pth; |
766 | npth = 1; /* path component count */ | 826 | npth = 1; /* path component count */ |
767 | while (1) { | 827 | while (1) { |
768 | tmp = strchr(tmp, ':'); | 828 | tmp = strchr(tmp, PATH_SEP); |
769 | if (!tmp) | 829 | if (!tmp) |
770 | break; | 830 | break; |
771 | tmp++; | 831 | tmp++; |
@@ -776,7 +836,7 @@ static unsigned path_parse(char ***p) | |||
776 | res[0] = tmp = xstrdup(pth); | 836 | res[0] = tmp = xstrdup(pth); |
777 | npth = 1; | 837 | npth = 1; |
778 | while (1) { | 838 | while (1) { |
779 | tmp = strchr(tmp, ':'); | 839 | tmp = strchr(tmp, PATH_SEP); |
780 | if (!tmp) | 840 | if (!tmp) |
781 | break; | 841 | break; |
782 | *tmp++ = '\0'; /* ':' -> '\0' */ | 842 | *tmp++ = '\0'; /* ':' -> '\0' */ |
@@ -804,6 +864,17 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
804 | path1[0] = (char*)"."; | 864 | path1[0] = (char*)"."; |
805 | 865 | ||
806 | basecmd = strrchr(command, '/'); | 866 | basecmd = strrchr(command, '/'); |
867 | #if ENABLE_PLATFORM_MINGW32 | ||
868 | if (!basecmd && has_dos_drive_prefix(command) && command[2] != '\0') { | ||
869 | char buffer[PATH_MAX]; | ||
870 | |||
871 | /* path is of form c:path with no '/' */ | ||
872 | if (get_drive_cwd(command, buffer, PATH_MAX)) { | ||
873 | basecmd = command + 2; | ||
874 | path1[0] = dirbuf = xstrdup(buffer); | ||
875 | } | ||
876 | } else | ||
877 | #endif | ||
807 | if (!basecmd) { | 878 | if (!basecmd) { |
808 | if (type == FIND_EXE_ONLY) | 879 | if (type == FIND_EXE_ONLY) |
809 | npaths = path_parse(&paths); | 880 | npaths = path_parse(&paths); |
@@ -861,6 +932,9 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
861 | } | 932 | } |
862 | 933 | ||
863 | lpath = *paths[i] ? paths[i] : "."; | 934 | lpath = *paths[i] ? paths[i] : "."; |
935 | #if ENABLE_PLATFORM_MINGW32 | ||
936 | lpath = auto_string(alloc_system_drive(lpath)); | ||
937 | #endif | ||
864 | dir = opendir(lpath); | 938 | dir = opendir(lpath); |
865 | if (!dir) | 939 | if (!dir) |
866 | continue; /* don't print an error */ | 940 | continue; /* don't print an error */ |
@@ -883,6 +957,12 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
883 | if (stat(found, &st) && lstat(found, &st)) | 957 | if (stat(found, &st) && lstat(found, &st)) |
884 | goto cont; /* hmm, remove in progress? */ | 958 | goto cont; /* hmm, remove in progress? */ |
885 | 959 | ||
960 | # if ENABLE_PLATFORM_MINGW32 | ||
961 | if (type == FIND_EXE_ONLY && S_ISREG(st.st_mode) && | ||
962 | !(st.st_mode & S_IXUSR)) | ||
963 | goto cont; | ||
964 | # endif | ||
965 | |||
886 | /* Save only name */ | 966 | /* Save only name */ |
887 | len = strlen(name_found); | 967 | len = strlen(name_found); |
888 | found = xrealloc(found, len + 2); /* +2: for slash and NUL */ | 968 | found = xrealloc(found, len + 2); /* +2: for slash and NUL */ |
@@ -966,7 +1046,13 @@ static NOINLINE int build_match_prefix(char *match_buf) | |||
966 | 1046 | ||
967 | /* Mark every \c as "quoted c" */ | 1047 | /* Mark every \c as "quoted c" */ |
968 | for (i = 0; int_buf[i]; i++) { | 1048 | for (i = 0; int_buf[i]; i++) { |
1049 | #if ENABLE_PLATFORM_MINGW32 | ||
1050 | /* Trailing backslash is effectively removed which confuses | ||
1051 | * the code to display case-preserved filenames. */ | ||
1052 | if (int_buf[i] == '\\' && int_buf[i+1] != '\0') { | ||
1053 | #else | ||
969 | if (int_buf[i] == '\\') { | 1054 | if (int_buf[i] == '\\') { |
1055 | #endif | ||
970 | remove_chunk(int_buf, i, i + 1); | 1056 | remove_chunk(int_buf, i, i + 1); |
971 | int_buf[i] |= QUOT; | 1057 | int_buf[i] |= QUOT; |
972 | } | 1058 | } |
@@ -1167,6 +1253,11 @@ static NOINLINE void input_tab(smallint *lastWasTab) | |||
1167 | size_t len_found; | 1253 | size_t len_found; |
1168 | /* Length of string used for matching */ | 1254 | /* Length of string used for matching */ |
1169 | unsigned match_pfx_len = match_pfx_len; | 1255 | unsigned match_pfx_len = match_pfx_len; |
1256 | #if ENABLE_PLATFORM_MINGW32 | ||
1257 | unsigned orig_pfx_len; | ||
1258 | char *target; | ||
1259 | const char *source; | ||
1260 | #endif | ||
1170 | int find_type; | 1261 | int find_type; |
1171 | # if ENABLE_UNICODE_SUPPORT | 1262 | # if ENABLE_UNICODE_SUPPORT |
1172 | /* cursor pos in command converted to multibyte form */ | 1263 | /* cursor pos in command converted to multibyte form */ |
@@ -1214,7 +1305,7 @@ static NOINLINE void input_tab(smallint *lastWasTab) | |||
1214 | /* Free up any memory already allocated */ | 1305 | /* Free up any memory already allocated */ |
1215 | free_tab_completion_data(); | 1306 | free_tab_completion_data(); |
1216 | 1307 | ||
1217 | # if ENABLE_FEATURE_USERNAME_COMPLETION | 1308 | # if ENABLE_FEATURE_USERNAME_COMPLETION && !ENABLE_PLATFORM_MINGW32 |
1218 | /* If the word starts with ~ and there is no slash in the word, | 1309 | /* If the word starts with ~ and there is no slash in the word, |
1219 | * then try completing this word as a username. */ | 1310 | * then try completing this word as a username. */ |
1220 | if (state->flags & USERNAME_COMPLETION) | 1311 | if (state->flags & USERNAME_COMPLETION) |
@@ -1231,6 +1322,9 @@ static NOINLINE void input_tab(smallint *lastWasTab) | |||
1231 | { | 1322 | { |
1232 | const char *e = match_buf + strlen(match_buf); | 1323 | const char *e = match_buf + strlen(match_buf); |
1233 | const char *s = e - match_pfx_len; | 1324 | const char *s = e - match_pfx_len; |
1325 | #if ENABLE_PLATFORM_MINGW32 | ||
1326 | orig_pfx_len = match_pfx_len; | ||
1327 | #endif | ||
1234 | while (s < e) | 1328 | while (s < e) |
1235 | if (is_special_char(*s++)) | 1329 | if (is_special_char(*s++)) |
1236 | match_pfx_len++; | 1330 | match_pfx_len++; |
@@ -1265,7 +1359,11 @@ static NOINLINE void input_tab(smallint *lastWasTab) | |||
1265 | for (cp = chosen_match; *cp; cp++) { | 1359 | for (cp = chosen_match; *cp; cp++) { |
1266 | unsigned n; | 1360 | unsigned n; |
1267 | for (n = 1; n < num_matches; n++) { | 1361 | for (n = 1; n < num_matches; n++) { |
1362 | # if !ENABLE_PLATFORM_MINGW32 | ||
1268 | if (matches[n][cp - chosen_match] != *cp) { | 1363 | if (matches[n][cp - chosen_match] != *cp) { |
1364 | # else | ||
1365 | if (tolower(matches[n][cp - chosen_match]) != tolower(*cp)) { | ||
1366 | # endif | ||
1269 | goto stop; | 1367 | goto stop; |
1270 | } | 1368 | } |
1271 | } | 1369 | } |
@@ -1301,7 +1399,21 @@ static NOINLINE void input_tab(smallint *lastWasTab) | |||
1301 | /* save tail */ | 1399 | /* save tail */ |
1302 | strcpy(match_buf, &command_ps[cursor]); | 1400 | strcpy(match_buf, &command_ps[cursor]); |
1303 | /* add match and tail */ | 1401 | /* add match and tail */ |
1402 | # if ENABLE_PLATFORM_MINGW32 | ||
1403 | if (match_pfx_len == orig_pfx_len) { | ||
1404 | /* replace match prefix to allow for altered case */ | ||
1405 | target = &command_ps[cursor-match_pfx_len]; | ||
1406 | source = chosen_match; | ||
1407 | } | ||
1408 | else { | ||
1409 | /* only replace tail of match if special characters are quoted */ | ||
1410 | target = &command_ps[cursor]; | ||
1411 | source = chosen_match + match_pfx_len; | ||
1412 | } | ||
1413 | strcpy(stpcpy(target, source), match_buf); | ||
1414 | # else | ||
1304 | sprintf(&command_ps[cursor], "%s%s", chosen_match + match_pfx_len, match_buf); | 1415 | sprintf(&command_ps[cursor], "%s%s", chosen_match + match_pfx_len, match_buf); |
1416 | # endif | ||
1305 | command_len = strlen(command_ps); | 1417 | command_len = strlen(command_ps); |
1306 | /* new pos */ | 1418 | /* new pos */ |
1307 | pos = cursor + len_found - match_pfx_len; | 1419 | pos = cursor + len_found - match_pfx_len; |
@@ -1338,6 +1450,13 @@ static NOINLINE void input_tab(smallint *lastWasTab) | |||
1338 | free(match_buf); | 1450 | free(match_buf); |
1339 | } | 1451 | } |
1340 | 1452 | ||
1453 | # if ENABLE_PLATFORM_MINGW32 | ||
1454 | # undef is_prefixed_with | ||
1455 | # undef qsort_string_vector | ||
1456 | # undef strcmp | ||
1457 | # undef strncmp | ||
1458 | # endif | ||
1459 | |||
1341 | #endif /* FEATURE_TAB_COMPLETION */ | 1460 | #endif /* FEATURE_TAB_COMPLETION */ |
1342 | 1461 | ||
1343 | 1462 | ||
@@ -2383,7 +2502,7 @@ static void sigaction2(int sig, struct sigaction *act) | |||
2383 | */ | 2502 | */ |
2384 | int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) | 2503 | int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) |
2385 | { | 2504 | { |
2386 | int len, n; | 2505 | int len IF_NOT_PLATFORM_MINGW32(, n); |
2387 | int timeout; | 2506 | int timeout; |
2388 | #if ENABLE_FEATURE_TAB_COMPLETION | 2507 | #if ENABLE_FEATURE_TAB_COMPLETION |
2389 | smallint lastWasTab = 0; | 2508 | smallint lastWasTab = 0; |
@@ -2393,7 +2512,9 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2393 | smallint vi_cmdmode = 0; | 2512 | smallint vi_cmdmode = 0; |
2394 | #endif | 2513 | #endif |
2395 | struct termios initial_settings; | 2514 | struct termios initial_settings; |
2515 | #if !ENABLE_PLATFORM_MINGW32 | ||
2396 | struct termios new_settings; | 2516 | struct termios new_settings; |
2517 | #endif | ||
2397 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; | 2518 | char read_key_buffer[KEYCODE_BUFFER_SIZE]; |
2398 | 2519 | ||
2399 | INIT_S(); | 2520 | INIT_S(); |
@@ -2403,10 +2524,16 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2403 | IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) | 2524 | IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) |
2404 | IF_FEATURE_EDITING_VI(delptr = delbuf;) | 2525 | IF_FEATURE_EDITING_VI(delptr = delbuf;) |
2405 | 2526 | ||
2527 | #if !ENABLE_PLATFORM_MINGW32 | ||
2406 | n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0 | 2528 | n = get_termios_and_make_raw(STDIN_FILENO, &new_settings, &initial_settings, 0 |
2407 | | TERMIOS_CLEAR_ISIG /* turn off INTR (ctrl-C), QUIT, SUSP */ | 2529 | | TERMIOS_CLEAR_ISIG /* turn off INTR (ctrl-C), QUIT, SUSP */ |
2408 | ); | 2530 | ); |
2409 | if (n != 0 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON) { | 2531 | if (n != 0 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON) { |
2532 | #else | ||
2533 | initial_settings.c_cc[VINTR] = CTRL('C'); | ||
2534 | initial_settings.c_cc[VEOF] = CTRL('D'); | ||
2535 | if (!isatty(0) || !isatty(1)) { | ||
2536 | #endif | ||
2410 | /* Happens when e.g. stty -echo was run before. | 2537 | /* Happens when e.g. stty -echo was run before. |
2411 | * But if ICANON is not set, we don't come here. | 2538 | * But if ICANON is not set, we don't come here. |
2412 | * (example: interactive python ^Z-backgrounded, | 2539 | * (example: interactive python ^Z-backgrounded, |
@@ -2458,7 +2585,9 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2458 | #endif | 2585 | #endif |
2459 | #define command command_must_not_be_used | 2586 | #define command command_must_not_be_used |
2460 | 2587 | ||
2588 | #if !ENABLE_PLATFORM_MINGW32 | ||
2461 | tcsetattr_stdin_TCSANOW(&new_settings); | 2589 | tcsetattr_stdin_TCSANOW(&new_settings); |
2590 | #endif | ||
2462 | 2591 | ||
2463 | #if ENABLE_USERNAME_OR_HOMEDIR | 2592 | #if ENABLE_USERNAME_OR_HOMEDIR |
2464 | { | 2593 | { |
@@ -2511,6 +2640,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2511 | } | 2640 | } |
2512 | #endif | 2641 | #endif |
2513 | ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); | 2642 | ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); |
2643 | #if ENABLE_PLATFORM_MINGW32 | ||
2644 | /* scroll to cursor position on any keypress */ | ||
2645 | if (isatty(fileno(stdin)) && isatty(fileno(stdout))) | ||
2646 | move_cursor_row(0); | ||
2647 | #endif | ||
2514 | 2648 | ||
2515 | #if ENABLE_FEATURE_REVERSE_SEARCH | 2649 | #if ENABLE_FEATURE_REVERSE_SEARCH |
2516 | again: | 2650 | again: |
@@ -2572,6 +2706,13 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2572 | input_tab(&lastWasTab); | 2706 | input_tab(&lastWasTab); |
2573 | break; | 2707 | break; |
2574 | #endif | 2708 | #endif |
2709 | #if ENABLE_PLATFORM_MINGW32 | ||
2710 | case CTRL('Z'): | ||
2711 | command_ps[command_len] = '\0'; | ||
2712 | bs_to_slash(command_ps); | ||
2713 | redraw(cmdedit_y, 0); | ||
2714 | break; | ||
2715 | #endif | ||
2575 | case CTRL('K'): | 2716 | case CTRL('K'): |
2576 | /* Control-k -- clear to end of line */ | 2717 | /* Control-k -- clear to end of line */ |
2577 | command_ps[cursor] = BB_NUL; | 2718 | command_ps[cursor] = BB_NUL; |
@@ -2945,8 +3086,10 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2945 | free_tab_completion_data(); | 3086 | free_tab_completion_data(); |
2946 | #endif | 3087 | #endif |
2947 | 3088 | ||
3089 | #if !ENABLE_PLATFORM_MINGW32 | ||
2948 | /* restore initial_settings */ | 3090 | /* restore initial_settings */ |
2949 | tcsetattr_stdin_TCSANOW(&initial_settings); | 3091 | tcsetattr_stdin_TCSANOW(&initial_settings); |
3092 | #endif | ||
2950 | #if ENABLE_FEATURE_EDITING_WINCH | 3093 | #if ENABLE_FEATURE_EDITING_WINCH |
2951 | /* restore SIGWINCH handler */ | 3094 | /* restore SIGWINCH handler */ |
2952 | sigaction_set(SIGWINCH, &S.SIGWINCH_handler); | 3095 | sigaction_set(SIGWINCH, &S.SIGWINCH_handler); |