diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-07-25 15:18:20 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-07-25 15:18:20 +0200 |
| commit | 4e552a70ec00e4eb9bb0bcde95688ddb3c4fcefe (patch) | |
| tree | f39123cd092c53644788dea0636cfe155d4e8cb3 /miscutils | |
| parent | be391e759675b23ccf6e19cb6ea5b819840f3026 (diff) | |
| download | busybox-w32-4e552a70ec00e4eb9bb0bcde95688ddb3c4fcefe.tar.gz busybox-w32-4e552a70ec00e4eb9bb0bcde95688ddb3c4fcefe.tar.bz2 busybox-w32-4e552a70ec00e4eb9bb0bcde95688ddb3c4fcefe.zip | |
less: optionally query terminal size via "ESC [ 6 n". Closes bug 2659.
+7 bytes is not selected, +100 if selected.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/Config.src | 66 | ||||
| -rw-r--r-- | miscutils/less.c | 132 |
2 files changed, 117 insertions, 81 deletions
diff --git a/miscutils/Config.src b/miscutils/Config.src index 61529141d..b9fc196d8 100644 --- a/miscutils/Config.src +++ b/miscutils/Config.src | |||
| @@ -360,72 +360,6 @@ config FEATURE_LAST_FANCY | |||
| 360 | logged into the system (mimics sysvinit last). +900 bytes. | 360 | logged into the system (mimics sysvinit last). +900 bytes. |
| 361 | endchoice | 361 | endchoice |
| 362 | 362 | ||
| 363 | config LESS | ||
| 364 | bool "less" | ||
| 365 | default y | ||
| 366 | help | ||
| 367 | 'less' is a pager, meaning that it displays text files. It possesses | ||
| 368 | a wide array of features, and is an improvement over 'more'. | ||
| 369 | |||
| 370 | config FEATURE_LESS_MAXLINES | ||
| 371 | int "Max number of input lines less will try to eat" | ||
| 372 | default 9999999 | ||
| 373 | depends on LESS | ||
| 374 | |||
| 375 | config FEATURE_LESS_BRACKETS | ||
| 376 | bool "Enable bracket searching" | ||
| 377 | default y | ||
| 378 | depends on LESS | ||
| 379 | help | ||
| 380 | This option adds the capability to search for matching left and right | ||
| 381 | brackets, facilitating programming. | ||
| 382 | |||
| 383 | config FEATURE_LESS_FLAGS | ||
| 384 | bool "Enable extra flags" | ||
| 385 | default y | ||
| 386 | depends on LESS | ||
| 387 | help | ||
| 388 | The extra flags provided do the following: | ||
| 389 | |||
| 390 | The -M flag enables a more sophisticated status line. | ||
| 391 | The -m flag enables a simpler status line with a percentage. | ||
| 392 | |||
| 393 | config FEATURE_LESS_MARKS | ||
| 394 | bool "Enable marks" | ||
| 395 | default y | ||
| 396 | depends on LESS | ||
| 397 | help | ||
| 398 | Marks enable positions in a file to be stored for easy reference. | ||
| 399 | |||
| 400 | config FEATURE_LESS_REGEXP | ||
| 401 | bool "Enable regular expressions" | ||
| 402 | default y | ||
| 403 | depends on LESS | ||
| 404 | help | ||
| 405 | Enable regular expressions, allowing complex file searches. | ||
| 406 | |||
| 407 | config FEATURE_LESS_WINCH | ||
| 408 | bool "Enable automatic resizing on window size changes" | ||
| 409 | default y | ||
| 410 | depends on LESS | ||
| 411 | help | ||
| 412 | Makes less track window size changes. | ||
| 413 | |||
| 414 | config FEATURE_LESS_DASHCMD | ||
| 415 | bool "Enable flag changes ('-' command)" | ||
| 416 | default y | ||
| 417 | depends on LESS | ||
| 418 | help | ||
| 419 | This enables the ability to change command-line flags within | ||
| 420 | less itself ('-' keyboard command). | ||
| 421 | |||
| 422 | config FEATURE_LESS_LINENUMS | ||
| 423 | bool "Enable dynamic switching of line numbers" | ||
| 424 | default y | ||
| 425 | depends on FEATURE_LESS_DASHCMD | ||
| 426 | help | ||
| 427 | Enables "-N" command. | ||
| 428 | |||
| 429 | config HDPARM | 363 | config HDPARM |
| 430 | bool "hdparm" | 364 | bool "hdparm" |
| 431 | default y | 365 | default y |
diff --git a/miscutils/less.c b/miscutils/less.c index 46024f9f7..16eb95d56 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
| @@ -21,6 +21,85 @@ | |||
| 21 | * redirected input has been read from stdin | 21 | * redirected input has been read from stdin |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | //config:config LESS | ||
| 25 | //config: bool "less" | ||
| 26 | //config: default y | ||
| 27 | //config: help | ||
| 28 | //config: 'less' is a pager, meaning that it displays text files. It possesses | ||
| 29 | //config: a wide array of features, and is an improvement over 'more'. | ||
| 30 | //config: | ||
| 31 | //config:config FEATURE_LESS_MAXLINES | ||
| 32 | //config: int "Max number of input lines less will try to eat" | ||
| 33 | //config: default 9999999 | ||
| 34 | //config: depends on LESS | ||
| 35 | //config: | ||
| 36 | //config:config FEATURE_LESS_BRACKETS | ||
| 37 | //config: bool "Enable bracket searching" | ||
| 38 | //config: default y | ||
| 39 | //config: depends on LESS | ||
| 40 | //config: help | ||
| 41 | //config: This option adds the capability to search for matching left and right | ||
| 42 | //config: brackets, facilitating programming. | ||
| 43 | //config: | ||
| 44 | //config:config FEATURE_LESS_FLAGS | ||
| 45 | //config: bool "Enable extra flags" | ||
| 46 | //config: default y | ||
| 47 | //config: depends on LESS | ||
| 48 | //config: help | ||
| 49 | //config: The extra flags provided do the following: | ||
| 50 | //config: | ||
| 51 | //config: The -M flag enables a more sophisticated status line. | ||
| 52 | //config: The -m flag enables a simpler status line with a percentage. | ||
| 53 | //config: | ||
| 54 | //config:config FEATURE_LESS_MARKS | ||
| 55 | //config: bool "Enable marks" | ||
| 56 | //config: default y | ||
| 57 | //config: depends on LESS | ||
| 58 | //config: help | ||
| 59 | //config: Marks enable positions in a file to be stored for easy reference. | ||
| 60 | //config: | ||
| 61 | //config:config FEATURE_LESS_REGEXP | ||
| 62 | //config: bool "Enable regular expressions" | ||
| 63 | //config: default y | ||
| 64 | //config: depends on LESS | ||
| 65 | //config: help | ||
| 66 | //config: Enable regular expressions, allowing complex file searches. | ||
| 67 | //config: | ||
| 68 | //config:config FEATURE_LESS_WINCH | ||
| 69 | //config: bool "Enable automatic resizing on window size changes" | ||
| 70 | //config: default y | ||
| 71 | //config: depends on LESS | ||
| 72 | //config: help | ||
| 73 | //config: Makes less track window size changes. | ||
| 74 | //config: | ||
| 75 | //config:config FEATURE_LESS_ASK_TERMINAL | ||
| 76 | //config: bool "Use 'tell me cursor position' ESC sequence to measure window" | ||
| 77 | //config: default y | ||
| 78 | //config: depends on FEATURE_LESS_WINCH | ||
| 79 | //config: help | ||
| 80 | //config: Makes less track window size changes. | ||
| 81 | //config: If terminal size can't be retrieved and $LINES/$COLUMNS are not set, | ||
| 82 | //config: this option makes less perform a last-ditch effort to find it: | ||
| 83 | //config: position cursor to 999,999 and ask terminal to report real | ||
| 84 | //config: cursor position using "ESC [ 6 n" escape sequence, then read stdin. | ||
| 85 | //config: | ||
| 86 | //config: This is not clean but helps a lot on serial lines and such. | ||
| 87 | //config: | ||
| 88 | //config:config FEATURE_LESS_DASHCMD | ||
| 89 | //config: bool "Enable flag changes ('-' command)" | ||
| 90 | //config: default y | ||
| 91 | //config: depends on LESS | ||
| 92 | //config: help | ||
| 93 | //config: This enables the ability to change command-line flags within | ||
| 94 | //config: less itself ('-' keyboard command). | ||
| 95 | //config: | ||
| 96 | //config:config FEATURE_LESS_LINENUMS | ||
| 97 | //config: bool "Enable dynamic switching of line numbers" | ||
| 98 | //config: default y | ||
| 99 | //config: depends on FEATURE_LESS_DASHCMD | ||
| 100 | //config: help | ||
| 101 | //config: Enables "-N" command. | ||
| 102 | |||
| 24 | //usage:#define less_trivial_usage | 103 | //usage:#define less_trivial_usage |
| 25 | //usage: "[-EMNmh~I?] [FILE]..." | 104 | //usage: "[-EMNmh~I?] [FILE]..." |
| 26 | //usage:#define less_full_usage "\n\n" | 105 | //usage:#define less_full_usage "\n\n" |
| @@ -108,6 +187,9 @@ struct globals { | |||
| 108 | regex_t pattern; | 187 | regex_t pattern; |
| 109 | smallint pattern_valid; | 188 | smallint pattern_valid; |
| 110 | #endif | 189 | #endif |
| 190 | #if ENABLE_FEATURE_LESS_ASK_TERMINAL | ||
| 191 | smallint winsize_err; | ||
| 192 | #endif | ||
| 111 | smallint terminated; | 193 | smallint terminated; |
| 112 | struct termios term_orig, term_less; | 194 | struct termios term_orig, term_less; |
| 113 | char kbd_input[KEYCODE_BUFFER_SIZE]; | 195 | char kbd_input[KEYCODE_BUFFER_SIZE]; |
| @@ -815,12 +897,17 @@ static void reinitialize(void) | |||
| 815 | cur_fline = 0; | 897 | cur_fline = 0; |
| 816 | max_lineno = 0; | 898 | max_lineno = 0; |
| 817 | open_file_and_read_lines(); | 899 | open_file_and_read_lines(); |
| 900 | #if ENABLE_FEATURE_LESS_ASK_TERMINAL | ||
| 901 | if (G.winsize_err) | ||
| 902 | printf("\033[999;999H" "\033[6n"); | ||
| 903 | #endif | ||
| 818 | buffer_fill_and_print(); | 904 | buffer_fill_and_print(); |
| 819 | } | 905 | } |
| 820 | 906 | ||
| 821 | static int getch_nowait(void) | 907 | static int64_t getch_nowait(void) |
| 822 | { | 908 | { |
| 823 | int rd; | 909 | int rd; |
| 910 | int64_t key64; | ||
| 824 | struct pollfd pfd[2]; | 911 | struct pollfd pfd[2]; |
| 825 | 912 | ||
| 826 | pfd[0].fd = STDIN_FILENO; | 913 | pfd[0].fd = STDIN_FILENO; |
| @@ -868,8 +955,8 @@ static int getch_nowait(void) | |||
| 868 | 955 | ||
| 869 | /* We have kbd_fd in O_NONBLOCK mode, read inside read_key() | 956 | /* We have kbd_fd in O_NONBLOCK mode, read inside read_key() |
| 870 | * would not block even if there is no input available */ | 957 | * would not block even if there is no input available */ |
| 871 | rd = read_key(kbd_fd, kbd_input, /*timeout off:*/ -2); | 958 | key64 = read_key(kbd_fd, kbd_input, /*timeout off:*/ -2); |
| 872 | if (rd == -1) { | 959 | if ((int)key64 == -1) { |
| 873 | if (errno == EAGAIN) { | 960 | if (errno == EAGAIN) { |
| 874 | /* No keyboard input available. Since poll() did return, | 961 | /* No keyboard input available. Since poll() did return, |
| 875 | * we should have input on stdin */ | 962 | * we should have input on stdin */ |
| @@ -881,25 +968,29 @@ static int getch_nowait(void) | |||
| 881 | less_exit(0); | 968 | less_exit(0); |
| 882 | } | 969 | } |
| 883 | set_tty_cooked(); | 970 | set_tty_cooked(); |
| 884 | return rd; | 971 | return key64; |
| 885 | } | 972 | } |
| 886 | 973 | ||
| 887 | /* Grab a character from input without requiring the return key. | 974 | /* Grab a character from input without requiring the return key. |
| 888 | * May return KEYCODE_xxx values. | 975 | * May return KEYCODE_xxx values. |
| 889 | * Note that this function works best with raw input. */ | 976 | * Note that this function works best with raw input. */ |
| 890 | static int less_getch(int pos) | 977 | static int64_t less_getch(int pos) |
| 891 | { | 978 | { |
| 892 | int i; | 979 | int64_t key64; |
| 980 | int key; | ||
| 893 | 981 | ||
| 894 | again: | 982 | again: |
| 895 | less_gets_pos = pos; | 983 | less_gets_pos = pos; |
| 896 | i = getch_nowait(); | 984 | key = key64 = getch_nowait(); |
| 897 | less_gets_pos = -1; | 985 | less_gets_pos = -1; |
| 898 | 986 | ||
| 899 | /* Discard Ctrl-something chars */ | 987 | /* Discard Ctrl-something chars. |
| 900 | if (i >= 0 && i < ' ' && i != 0x0d && i != 8) | 988 | * (checking only lower 32 bits is a size optimization: |
| 989 | * upper 32 bits are used only by KEYCODE_CURSOR_POS) | ||
| 990 | */ | ||
| 991 | if (key >= 0 && key < ' ' && key != 0x0d && key != 8) | ||
| 901 | goto again; | 992 | goto again; |
| 902 | return i; | 993 | return key; |
| 903 | } | 994 | } |
| 904 | 995 | ||
| 905 | static char* less_gets(int sz) | 996 | static char* less_gets(int sz) |
| @@ -1514,8 +1605,6 @@ static void sigwinch_handler(int sig UNUSED_PARAM) | |||
| 1514 | int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1605 | int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 1515 | int less_main(int argc, char **argv) | 1606 | int less_main(int argc, char **argv) |
| 1516 | { | 1607 | { |
| 1517 | int keypress; | ||
| 1518 | |||
| 1519 | INIT_G(); | 1608 | INIT_G(); |
| 1520 | 1609 | ||
| 1521 | /* TODO: -x: do not interpret backspace, -xx: tab also */ | 1610 | /* TODO: -x: do not interpret backspace, -xx: tab also */ |
| @@ -1558,7 +1647,7 @@ int less_main(int argc, char **argv) | |||
| 1558 | term_less.c_cc[VMIN] = 1; | 1647 | term_less.c_cc[VMIN] = 1; |
| 1559 | term_less.c_cc[VTIME] = 0; | 1648 | term_less.c_cc[VTIME] = 0; |
| 1560 | 1649 | ||
| 1561 | get_terminal_width_height(kbd_fd, &width, &max_displayed_line); | 1650 | IF_FEATURE_LESS_ASK_TERMINAL(G.winsize_err =) get_terminal_width_height(kbd_fd, &width, &max_displayed_line); |
| 1562 | /* 20: two tabstops + 4 */ | 1651 | /* 20: two tabstops + 4 */ |
| 1563 | if (width < 20 || max_displayed_line < 3) | 1652 | if (width < 20 || max_displayed_line < 3) |
| 1564 | return bb_cat(argv); | 1653 | return bb_cat(argv); |
| @@ -1573,11 +1662,14 @@ int less_main(int argc, char **argv) | |||
| 1573 | buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); | 1662 | buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); |
| 1574 | reinitialize(); | 1663 | reinitialize(); |
| 1575 | while (1) { | 1664 | while (1) { |
| 1665 | int64_t keypress; | ||
| 1666 | |||
| 1576 | #if ENABLE_FEATURE_LESS_WINCH | 1667 | #if ENABLE_FEATURE_LESS_WINCH |
| 1577 | while (WINCH_COUNTER) { | 1668 | while (WINCH_COUNTER) { |
| 1578 | again: | 1669 | again: |
| 1579 | winch_counter--; | 1670 | winch_counter--; |
| 1580 | get_terminal_width_height(kbd_fd, &width, &max_displayed_line); | 1671 | IF_FEATURE_LESS_ASK_TERMINAL(G.winsize_err =) get_terminal_width_height(kbd_fd, &width, &max_displayed_line); |
| 1672 | IF_FEATURE_LESS_ASK_TERMINAL(got_size:) | ||
| 1581 | /* 20: two tabstops + 4 */ | 1673 | /* 20: two tabstops + 4 */ |
| 1582 | if (width < 20) | 1674 | if (width < 20) |
| 1583 | width = 20; | 1675 | width = 20; |
| @@ -1597,8 +1689,18 @@ int less_main(int argc, char **argv) | |||
| 1597 | /* This took some time. Loop back and check, | 1689 | /* This took some time. Loop back and check, |
| 1598 | * were there another SIGWINCH? */ | 1690 | * were there another SIGWINCH? */ |
| 1599 | } | 1691 | } |
| 1600 | #endif | ||
| 1601 | keypress = less_getch(-1); /* -1: do not position cursor */ | 1692 | keypress = less_getch(-1); /* -1: do not position cursor */ |
| 1693 | # if ENABLE_FEATURE_LESS_ASK_TERMINAL | ||
| 1694 | if ((int32_t)keypress == KEYCODE_CURSOR_POS) { | ||
| 1695 | uint32_t rc = (keypress >> 32); | ||
| 1696 | width = (rc & 0x7fff); | ||
| 1697 | max_displayed_line = ((rc >> 16) & 0x7fff); | ||
| 1698 | goto got_size; | ||
| 1699 | } | ||
| 1700 | # endif | ||
| 1701 | #else | ||
| 1702 | keypress = less_getch(-1); /* -1: do not position cursor */ | ||
| 1703 | #endif | ||
| 1602 | keypress_process(keypress); | 1704 | keypress_process(keypress); |
| 1603 | } | 1705 | } |
| 1604 | } | 1706 | } |
