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: help
|
||||||
//config: If terminal size can't be retrieved and $LINES/$COLUMNS are not set,
|
//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: 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: position cursor to 999,999 and ask terminal to report real
|
||||||
//config: cursor position using "ESC [ 6 n" escape sequence, then reads stdin.
|
//config: cursor position using "ESC [ 6 n" escape sequence, then read stdin.
|
||||||
//config:
|
//config:
|
||||||
//config: This is not clean but helps a lot on serial lines and such.
|
//config: This is not clean but helps a lot on serial lines and such.
|
||||||
//config:
|
//config:
|
||||||
|
@ -214,7 +214,10 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
|
|||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
/* Try to decipher "ESC [ NNN ; NNN R" sequence */
|
/* 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
|
&& n >= 5
|
||||||
&& buffer[0] == '['
|
&& buffer[0] == '['
|
||||||
&& buffer[n-1] == 'R'
|
&& buffer[n-1] == 'R'
|
||||||
|
@ -360,72 +360,6 @@ config FEATURE_LAST_FANCY
|
|||||||
logged into the system (mimics sysvinit last). +900 bytes.
|
logged into the system (mimics sysvinit last). +900 bytes.
|
||||||
endchoice
|
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
|
config HDPARM
|
||||||
bool "hdparm"
|
bool "hdparm"
|
||||||
default y
|
default y
|
||||||
|
132
miscutils/less.c
132
miscutils/less.c
@ -21,6 +21,85 @@
|
|||||||
* redirected input has been read from stdin
|
* 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:#define less_trivial_usage
|
||||||
//usage: "[-EMNmh~I?] [FILE]..."
|
//usage: "[-EMNmh~I?] [FILE]..."
|
||||||
//usage:#define less_full_usage "\n\n"
|
//usage:#define less_full_usage "\n\n"
|
||||||
@ -107,6 +186,9 @@ struct globals {
|
|||||||
int num_matches;
|
int num_matches;
|
||||||
regex_t pattern;
|
regex_t pattern;
|
||||||
smallint pattern_valid;
|
smallint pattern_valid;
|
||||||
|
#endif
|
||||||
|
#if ENABLE_FEATURE_LESS_ASK_TERMINAL
|
||||||
|
smallint winsize_err;
|
||||||
#endif
|
#endif
|
||||||
smallint terminated;
|
smallint terminated;
|
||||||
struct termios term_orig, term_less;
|
struct termios term_orig, term_less;
|
||||||
@ -815,12 +897,17 @@ static void reinitialize(void)
|
|||||||
cur_fline = 0;
|
cur_fline = 0;
|
||||||
max_lineno = 0;
|
max_lineno = 0;
|
||||||
open_file_and_read_lines();
|
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();
|
buffer_fill_and_print();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getch_nowait(void)
|
static int64_t getch_nowait(void)
|
||||||
{
|
{
|
||||||
int rd;
|
int rd;
|
||||||
|
int64_t key64;
|
||||||
struct pollfd pfd[2];
|
struct pollfd pfd[2];
|
||||||
|
|
||||||
pfd[0].fd = STDIN_FILENO;
|
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()
|
/* We have kbd_fd in O_NONBLOCK mode, read inside read_key()
|
||||||
* would not block even if there is no input available */
|
* would not block even if there is no input available */
|
||||||
rd = read_key(kbd_fd, kbd_input, /*timeout off:*/ -2);
|
key64 = read_key(kbd_fd, kbd_input, /*timeout off:*/ -2);
|
||||||
if (rd == -1) {
|
if ((int)key64 == -1) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
/* No keyboard input available. Since poll() did return,
|
/* No keyboard input available. Since poll() did return,
|
||||||
* we should have input on stdin */
|
* we should have input on stdin */
|
||||||
@ -881,25 +968,29 @@ static int getch_nowait(void)
|
|||||||
less_exit(0);
|
less_exit(0);
|
||||||
}
|
}
|
||||||
set_tty_cooked();
|
set_tty_cooked();
|
||||||
return rd;
|
return key64;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grab a character from input without requiring the return key.
|
/* Grab a character from input without requiring the return key.
|
||||||
* May return KEYCODE_xxx values.
|
* May return KEYCODE_xxx values.
|
||||||
* Note that this function works best with raw input. */
|
* 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:
|
again:
|
||||||
less_gets_pos = pos;
|
less_gets_pos = pos;
|
||||||
i = getch_nowait();
|
key = key64 = getch_nowait();
|
||||||
less_gets_pos = -1;
|
less_gets_pos = -1;
|
||||||
|
|
||||||
/* Discard Ctrl-something chars */
|
/* Discard Ctrl-something chars.
|
||||||
if (i >= 0 && i < ' ' && i != 0x0d && i != 8)
|
* (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;
|
goto again;
|
||||||
return i;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* less_gets(int sz)
|
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) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int less_main(int argc, char **argv)
|
int less_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int keypress;
|
|
||||||
|
|
||||||
INIT_G();
|
INIT_G();
|
||||||
|
|
||||||
/* TODO: -x: do not interpret backspace, -xx: tab also */
|
/* 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[VMIN] = 1;
|
||||||
term_less.c_cc[VTIME] = 0;
|
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 */
|
/* 20: two tabstops + 4 */
|
||||||
if (width < 20 || max_displayed_line < 3)
|
if (width < 20 || max_displayed_line < 3)
|
||||||
return bb_cat(argv);
|
return bb_cat(argv);
|
||||||
@ -1573,11 +1662,14 @@ int less_main(int argc, char **argv)
|
|||||||
buffer = xmalloc((max_displayed_line+1) * sizeof(char *));
|
buffer = xmalloc((max_displayed_line+1) * sizeof(char *));
|
||||||
reinitialize();
|
reinitialize();
|
||||||
while (1) {
|
while (1) {
|
||||||
|
int64_t keypress;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_LESS_WINCH
|
#if ENABLE_FEATURE_LESS_WINCH
|
||||||
while (WINCH_COUNTER) {
|
while (WINCH_COUNTER) {
|
||||||
again:
|
again:
|
||||||
winch_counter--;
|
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 */
|
/* 20: two tabstops + 4 */
|
||||||
if (width < 20)
|
if (width < 20)
|
||||||
width = 20;
|
width = 20;
|
||||||
@ -1597,8 +1689,18 @@ int less_main(int argc, char **argv)
|
|||||||
/* This took some time. Loop back and check,
|
/* This took some time. Loop back and check,
|
||||||
* were there another SIGWINCH? */
|
* were there another SIGWINCH? */
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
keypress = less_getch(-1); /* -1: do not position cursor */
|
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);
|
keypress_process(keypress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user