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>
This commit is contained in:
parent
be391e7596
commit
4e552a70ec
@ -132,8 +132,8 @@
|
||||
//config: help
|
||||
//config: If terminal size can't be retrieved and $LINES/$COLUMNS are not set,
|
||||
//config: this option makes vi perform a last-ditch effort to find it:
|
||||
//config: vi positions cursor to 999,999 and asks terminal to report real
|
||||
//config: cursor position using "ESC [ 6 n" escape sequence, then reads stdin.
|
||||
//config: position cursor to 999,999 and ask terminal to report real
|
||||
//config: cursor position using "ESC [ 6 n" escape sequence, then read stdin.
|
||||
//config:
|
||||
//config: This is not clean but helps a lot on serial lines and such.
|
||||
//config:
|
||||
|
@ -214,7 +214,10 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
|
||||
}
|
||||
n++;
|
||||
/* Try to decipher "ESC [ NNN ; NNN R" sequence */
|
||||
if ((ENABLE_FEATURE_EDITING_ASK_TERMINAL || ENABLE_FEATURE_VI_ASK_TERMINAL)
|
||||
if ((ENABLE_FEATURE_EDITING_ASK_TERMINAL
|
||||
|| ENABLE_FEATURE_VI_ASK_TERMINAL
|
||||
|| ENABLE_FEATURE_LESS_ASK_TERMINAL
|
||||
)
|
||||
&& n >= 5
|
||||
&& buffer[0] == '['
|
||||
&& buffer[n-1] == 'R'
|
||||
|
@ -360,72 +360,6 @@ config FEATURE_LAST_FANCY
|
||||
logged into the system (mimics sysvinit last). +900 bytes.
|
||||
endchoice
|
||||
|
||||
config LESS
|
||||
bool "less"
|
||||
default y
|
||||
help
|
||||
'less' is a pager, meaning that it displays text files. It possesses
|
||||
a wide array of features, and is an improvement over 'more'.
|
||||
|
||||
config FEATURE_LESS_MAXLINES
|
||||
int "Max number of input lines less will try to eat"
|
||||
default 9999999
|
||||
depends on LESS
|
||||
|
||||
config FEATURE_LESS_BRACKETS
|
||||
bool "Enable bracket searching"
|
||||
default y
|
||||
depends on LESS
|
||||
help
|
||||
This option adds the capability to search for matching left and right
|
||||
brackets, facilitating programming.
|
||||
|
||||
config FEATURE_LESS_FLAGS
|
||||
bool "Enable extra flags"
|
||||
default y
|
||||
depends on LESS
|
||||
help
|
||||
The extra flags provided do the following:
|
||||
|
||||
The -M flag enables a more sophisticated status line.
|
||||
The -m flag enables a simpler status line with a percentage.
|
||||
|
||||
config FEATURE_LESS_MARKS
|
||||
bool "Enable marks"
|
||||
default y
|
||||
depends on LESS
|
||||
help
|
||||
Marks enable positions in a file to be stored for easy reference.
|
||||
|
||||
config FEATURE_LESS_REGEXP
|
||||
bool "Enable regular expressions"
|
||||
default y
|
||||
depends on LESS
|
||||
help
|
||||
Enable regular expressions, allowing complex file searches.
|
||||
|
||||
config FEATURE_LESS_WINCH
|
||||
bool "Enable automatic resizing on window size changes"
|
||||
default y
|
||||
depends on LESS
|
||||
help
|
||||
Makes less track window size changes.
|
||||
|
||||
config FEATURE_LESS_DASHCMD
|
||||
bool "Enable flag changes ('-' command)"
|
||||
default y
|
||||
depends on LESS
|
||||
help
|
||||
This enables the ability to change command-line flags within
|
||||
less itself ('-' keyboard command).
|
||||
|
||||
config FEATURE_LESS_LINENUMS
|
||||
bool "Enable dynamic switching of line numbers"
|
||||
default y
|
||||
depends on FEATURE_LESS_DASHCMD
|
||||
help
|
||||
Enables "-N" command.
|
||||
|
||||
config HDPARM
|
||||
bool "hdparm"
|
||||
default y
|
||||
|
132
miscutils/less.c
132
miscutils/less.c
@ -21,6 +21,85 @@
|
||||
* redirected input has been read from stdin
|
||||
*/
|
||||
|
||||
//config:config LESS
|
||||
//config: bool "less"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: 'less' is a pager, meaning that it displays text files. It possesses
|
||||
//config: a wide array of features, and is an improvement over 'more'.
|
||||
//config:
|
||||
//config:config FEATURE_LESS_MAXLINES
|
||||
//config: int "Max number of input lines less will try to eat"
|
||||
//config: default 9999999
|
||||
//config: depends on LESS
|
||||
//config:
|
||||
//config:config FEATURE_LESS_BRACKETS
|
||||
//config: bool "Enable bracket searching"
|
||||
//config: default y
|
||||
//config: depends on LESS
|
||||
//config: help
|
||||
//config: This option adds the capability to search for matching left and right
|
||||
//config: brackets, facilitating programming.
|
||||
//config:
|
||||
//config:config FEATURE_LESS_FLAGS
|
||||
//config: bool "Enable extra flags"
|
||||
//config: default y
|
||||
//config: depends on LESS
|
||||
//config: help
|
||||
//config: The extra flags provided do the following:
|
||||
//config:
|
||||
//config: The -M flag enables a more sophisticated status line.
|
||||
//config: The -m flag enables a simpler status line with a percentage.
|
||||
//config:
|
||||
//config:config FEATURE_LESS_MARKS
|
||||
//config: bool "Enable marks"
|
||||
//config: default y
|
||||
//config: depends on LESS
|
||||
//config: help
|
||||
//config: Marks enable positions in a file to be stored for easy reference.
|
||||
//config:
|
||||
//config:config FEATURE_LESS_REGEXP
|
||||
//config: bool "Enable regular expressions"
|
||||
//config: default y
|
||||
//config: depends on LESS
|
||||
//config: help
|
||||
//config: Enable regular expressions, allowing complex file searches.
|
||||
//config:
|
||||
//config:config FEATURE_LESS_WINCH
|
||||
//config: bool "Enable automatic resizing on window size changes"
|
||||
//config: default y
|
||||
//config: depends on LESS
|
||||
//config: help
|
||||
//config: Makes less track window size changes.
|
||||
//config:
|
||||
//config:config FEATURE_LESS_ASK_TERMINAL
|
||||
//config: bool "Use 'tell me cursor position' ESC sequence to measure window"
|
||||
//config: default y
|
||||
//config: depends on FEATURE_LESS_WINCH
|
||||
//config: help
|
||||
//config: Makes less track window size changes.
|
||||
//config: If terminal size can't be retrieved and $LINES/$COLUMNS are not set,
|
||||
//config: this option makes less perform a last-ditch effort to find it:
|
||||
//config: position cursor to 999,999 and ask terminal to report real
|
||||
//config: cursor position using "ESC [ 6 n" escape sequence, then read stdin.
|
||||
//config:
|
||||
//config: This is not clean but helps a lot on serial lines and such.
|
||||
//config:
|
||||
//config:config FEATURE_LESS_DASHCMD
|
||||
//config: bool "Enable flag changes ('-' command)"
|
||||
//config: default y
|
||||
//config: depends on LESS
|
||||
//config: help
|
||||
//config: This enables the ability to change command-line flags within
|
||||
//config: less itself ('-' keyboard command).
|
||||
//config:
|
||||
//config:config FEATURE_LESS_LINENUMS
|
||||
//config: bool "Enable dynamic switching of line numbers"
|
||||
//config: default y
|
||||
//config: depends on FEATURE_LESS_DASHCMD
|
||||
//config: help
|
||||
//config: Enables "-N" command.
|
||||
|
||||
//usage:#define less_trivial_usage
|
||||
//usage: "[-EMNmh~I?] [FILE]..."
|
||||
//usage:#define less_full_usage "\n\n"
|
||||
@ -107,6 +186,9 @@ struct globals {
|
||||
int num_matches;
|
||||
regex_t pattern;
|
||||
smallint pattern_valid;
|
||||
#endif
|
||||
#if ENABLE_FEATURE_LESS_ASK_TERMINAL
|
||||
smallint winsize_err;
|
||||
#endif
|
||||
smallint terminated;
|
||||
struct termios term_orig, term_less;
|
||||
@ -815,12 +897,17 @@ static void reinitialize(void)
|
||||
cur_fline = 0;
|
||||
max_lineno = 0;
|
||||
open_file_and_read_lines();
|
||||
#if ENABLE_FEATURE_LESS_ASK_TERMINAL
|
||||
if (G.winsize_err)
|
||||
printf("\033[999;999H" "\033[6n");
|
||||
#endif
|
||||
buffer_fill_and_print();
|
||||
}
|
||||
|
||||
static int getch_nowait(void)
|
||||
static int64_t getch_nowait(void)
|
||||
{
|
||||
int rd;
|
||||
int64_t key64;
|
||||
struct pollfd pfd[2];
|
||||
|
||||
pfd[0].fd = STDIN_FILENO;
|
||||
@ -868,8 +955,8 @@ static int getch_nowait(void)
|
||||
|
||||
/* We have kbd_fd in O_NONBLOCK mode, read inside read_key()
|
||||
* would not block even if there is no input available */
|
||||
rd = read_key(kbd_fd, kbd_input, /*timeout off:*/ -2);
|
||||
if (rd == -1) {
|
||||
key64 = read_key(kbd_fd, kbd_input, /*timeout off:*/ -2);
|
||||
if ((int)key64 == -1) {
|
||||
if (errno == EAGAIN) {
|
||||
/* No keyboard input available. Since poll() did return,
|
||||
* we should have input on stdin */
|
||||
@ -881,25 +968,29 @@ static int getch_nowait(void)
|
||||
less_exit(0);
|
||||
}
|
||||
set_tty_cooked();
|
||||
return rd;
|
||||
return key64;
|
||||
}
|
||||
|
||||
/* Grab a character from input without requiring the return key.
|
||||
* May return KEYCODE_xxx values.
|
||||
* Note that this function works best with raw input. */
|
||||
static int less_getch(int pos)
|
||||
static int64_t less_getch(int pos)
|
||||
{
|
||||
int i;
|
||||
int64_t key64;
|
||||
int key;
|
||||
|
||||
again:
|
||||
less_gets_pos = pos;
|
||||
i = getch_nowait();
|
||||
key = key64 = getch_nowait();
|
||||
less_gets_pos = -1;
|
||||
|
||||
/* Discard Ctrl-something chars */
|
||||
if (i >= 0 && i < ' ' && i != 0x0d && i != 8)
|
||||
/* Discard Ctrl-something chars.
|
||||
* (checking only lower 32 bits is a size optimization:
|
||||
* upper 32 bits are used only by KEYCODE_CURSOR_POS)
|
||||
*/
|
||||
if (key >= 0 && key < ' ' && key != 0x0d && key != 8)
|
||||
goto again;
|
||||
return i;
|
||||
return key;
|
||||
}
|
||||
|
||||
static char* less_gets(int sz)
|
||||
@ -1514,8 +1605,6 @@ static void sigwinch_handler(int sig UNUSED_PARAM)
|
||||
int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int less_main(int argc, char **argv)
|
||||
{
|
||||
int keypress;
|
||||
|
||||
INIT_G();
|
||||
|
||||
/* TODO: -x: do not interpret backspace, -xx: tab also */
|
||||
@ -1558,7 +1647,7 @@ int less_main(int argc, char **argv)
|
||||
term_less.c_cc[VMIN] = 1;
|
||||
term_less.c_cc[VTIME] = 0;
|
||||
|
||||
get_terminal_width_height(kbd_fd, &width, &max_displayed_line);
|
||||
IF_FEATURE_LESS_ASK_TERMINAL(G.winsize_err =) get_terminal_width_height(kbd_fd, &width, &max_displayed_line);
|
||||
/* 20: two tabstops + 4 */
|
||||
if (width < 20 || max_displayed_line < 3)
|
||||
return bb_cat(argv);
|
||||
@ -1573,11 +1662,14 @@ int less_main(int argc, char **argv)
|
||||
buffer = xmalloc((max_displayed_line+1) * sizeof(char *));
|
||||
reinitialize();
|
||||
while (1) {
|
||||
int64_t keypress;
|
||||
|
||||
#if ENABLE_FEATURE_LESS_WINCH
|
||||
while (WINCH_COUNTER) {
|
||||
again:
|
||||
winch_counter--;
|
||||
get_terminal_width_height(kbd_fd, &width, &max_displayed_line);
|
||||
IF_FEATURE_LESS_ASK_TERMINAL(G.winsize_err =) get_terminal_width_height(kbd_fd, &width, &max_displayed_line);
|
||||
IF_FEATURE_LESS_ASK_TERMINAL(got_size:)
|
||||
/* 20: two tabstops + 4 */
|
||||
if (width < 20)
|
||||
width = 20;
|
||||
@ -1597,8 +1689,18 @@ int less_main(int argc, char **argv)
|
||||
/* This took some time. Loop back and check,
|
||||
* were there another SIGWINCH? */
|
||||
}
|
||||
#endif
|
||||
keypress = less_getch(-1); /* -1: do not position cursor */
|
||||
# if ENABLE_FEATURE_LESS_ASK_TERMINAL
|
||||
if ((int32_t)keypress == KEYCODE_CURSOR_POS) {
|
||||
uint32_t rc = (keypress >> 32);
|
||||
width = (rc & 0x7fff);
|
||||
max_displayed_line = ((rc >> 16) & 0x7fff);
|
||||
goto got_size;
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
keypress = less_getch(-1); /* -1: do not position cursor */
|
||||
#endif
|
||||
keypress_process(keypress);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user