Make fish_key_reader's output simpler (#8467)

* fish_key_reader: Simplify default output

It now only prints the bind statement. Timing information and such is
relegated to a separate "verbose" mode.

* Adjust fish_key_reader docs

* Adjust tests
This commit is contained in:
Fabian Homborg 2021-11-22 17:22:22 +01:00 committed by GitHub
parent 084458bc47
commit f2fd30df03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 24 deletions

View File

@ -13,14 +13,16 @@ Synopsis
Description
-----------
``fish_key_reader`` is used to study input received from the terminal and can help with key binds. The program is interactive and works on standard input. Individual characters themselves and their hexadecimal values are displayed.
``fish_key_reader`` is used to explain how you would bind a certain key sequence. By default, it prints the :ref:`bind <cmd-bind>` command for one key sequence read interactively over standard input.
The tool will write an example :ref:`bind <cmd-bind>` command matching the character sequence captured to stdout. If the character sequence matches a special key name (see ``bind --key-names``), both ``bind CHARS ...`` and ``bind -k KEYNAME ...`` usage will be shown. Additional details about the characters received, such as the delay between chars, are written to stderr.
If the character sequence matches a special key name (see ``bind --key-names``), both ``bind CHARS ...`` and ``bind -k KEYNAME ...`` usage will be shown. In verbose mode (enabled by passing ``--verbose``), additional details about the characters received, such as the delay between chars, are written to stderr.
The following options are available:
- ``-c`` or ``--continuous`` begins a session where multiple key sequences can be inspected. By default the program exits after capturing a single key sequence.
- ``-V`` or ``--verbose`` tells fish_key_reader to output timing information and explain the sequence in more detail.
- ``-h`` or ``--help`` prints usage information.
- ``-v`` or ``--version`` prints fish_key_reader's version and exits.
@ -28,7 +30,7 @@ The following options are available:
Usage Notes
-----------
The delay in milliseconds since the previous character was received is included in the diagnostic information written to stderr. This information may be useful to determine the optimal ``fish_escape_delay_ms`` setting or learn the amount of lag introduced by tools like ``ssh``, ``mosh`` or ``tmux``.
In verbose mode, the delay in milliseconds since the previous character was received is included in the diagnostic information written to stderr. This information may be useful to determine the optimal ``fish_escape_delay_ms`` setting or learn the amount of lag introduced by tools like ``ssh``, ``mosh`` or ``tmux``.
``fish_key_reader`` intentionally disables handling of many signals. To terminate ``fish_key_reader`` in ``--continuous`` mode do:
@ -36,3 +38,21 @@ The delay in milliseconds since the previous character was received is included
- press :kbd:`Control`\ +\ :kbd:`D` twice, or
- type ``exit``, or
- type ``quit``
Example
-------
::
> fish_key_reader
Press a key:
# press up-arrow
bind \e\[A 'do something'
> fish_key_reader --verbose
Press a key:
# press alt+enter
hex: 1B char: \c[ (or \e)
( 0.027 ms) hex: D char: \cM (or \r)
bind \e\r 'do something'

View File

@ -487,15 +487,11 @@ The key sequence (the ``\cc``) here depends on your setup, in particular the ter
> fish_key_reader # pressing control-c
Press a key:
hex: 3 char: \cC
Press [ctrl-C] again to exit
bind \cC 'do something'
> fish_key_reader # pressing the right-arrow
Press a key:
hex: 1B char: \c[ (or \e)
( 0.077 ms) hex: 5B char: [
( 0.037 ms) hex: 43 char: C
bind \e\[C 'do something'
Note that some key combinations are indistinguishable or unbindable. For instance control-i *is the same* as the tab key. This is a terminal limitation that fish can't do anything about.

View File

@ -205,23 +205,25 @@ static bool output_matching_key_name(wchar_t wc) {
return false;
}
static double output_elapsed_time(double prev_tstamp, bool first_char_seen) {
static double output_elapsed_time(double prev_tstamp, bool first_char_seen, bool verbose) {
// How much time has passed since the previous char was received in microseconds.
double now = timef();
long long int delta_tstamp_us = 1000000 * (now - prev_tstamp);
if (delta_tstamp_us >= 200000 && first_char_seen) std::fputwc(L'\n', stderr);
if (delta_tstamp_us >= 1000000) {
std::fwprintf(stderr, L" ");
} else {
std::fwprintf(stderr, L"(%3lld.%03lld ms) ", delta_tstamp_us / 1000,
delta_tstamp_us % 1000);
if (verbose) {
if (delta_tstamp_us >= 200000 && first_char_seen) std::fputwc(L'\n', stderr);
if (delta_tstamp_us >= 1000000) {
std::fwprintf(stderr, L" ");
} else {
std::fwprintf(stderr, L"(%3lld.%03lld ms) ", delta_tstamp_us / 1000,
delta_tstamp_us % 1000);
}
}
return now;
}
/// Process the characters we receive as the user presses keys.
static void process_input(bool continuous_mode) {
static void process_input(bool continuous_mode, bool verbose) {
bool first_char_seen = false;
double prev_tstamp = 0.0;
input_event_queue_t queue;
@ -244,14 +246,16 @@ static void process_input(bool continuous_mode) {
}
wchar_t wc = evt->get_char();
prev_tstamp = output_elapsed_time(prev_tstamp, first_char_seen);
prev_tstamp = output_elapsed_time(prev_tstamp, first_char_seen, verbose);
// Hack for #3189. Do not suggest \c@ as the binding for nul, because a string containing
// nul cannot be passed to builtin_bind since it uses C strings. We'll output the name of
// this key (nul) elsewhere.
if (wc) {
add_char_to_bind_command(wc, bind_chars);
}
output_info_about_char(wc);
if (verbose) {
output_info_about_char(wc);
}
if (output_matching_key_name(wc)) {
output_bind_command(bind_chars);
}
@ -266,7 +270,7 @@ static void process_input(bool continuous_mode) {
}
/// Setup our environment (e.g., tty modes), process key strokes, then reset the environment.
[[noreturn]] static void setup_and_process_keys(bool continuous_mode) {
[[noreturn]] static void setup_and_process_keys(bool continuous_mode, bool verbose) {
set_interactive_session(true);
set_main_thread();
setup_fork_guards();
@ -288,16 +292,17 @@ static void process_input(bool continuous_mode) {
std::fwprintf(stderr, L"\n");
}
process_input(continuous_mode);
process_input(continuous_mode, verbose);
restore_term_mode();
_exit(0);
}
static bool parse_flags(int argc, char **argv, bool *continuous_mode) {
const char *short_opts = "+chv";
static bool parse_flags(int argc, char **argv, bool *continuous_mode, bool *verbose) {
const char *short_opts = "+chvV";
const struct option long_opts[] = {{"continuous", no_argument, nullptr, 'c'},
{"help", no_argument, nullptr, 'h'},
{"version", no_argument, nullptr, 'v'},
{"verbose", no_argument, nullptr, 'V'},
{nullptr, 0, nullptr, 0}};
int opt;
bool error = false;
@ -315,6 +320,10 @@ static bool parse_flags(int argc, char **argv, bool *continuous_mode) {
std::fwprintf(stdout, _(L"%ls, version %s\n"), program_name, get_fish_version());
exit(0);
}
case 'V': {
*verbose = true;
break;
}
default: {
// We assume getopt_long() has already emitted a diagnostic msg.
error = true;
@ -337,15 +346,16 @@ static bool parse_flags(int argc, char **argv, bool *continuous_mode) {
int main(int argc, char **argv) {
program_name = L"fish_key_reader";
bool continuous_mode = false;
bool verbose = false;
if (!parse_flags(argc, argv, &continuous_mode)) return 1;
if (!parse_flags(argc, argv, &continuous_mode, &verbose)) return 1;
if (!isatty(STDIN_FILENO)) {
std::fwprintf(stderr, L"Stdin must be attached to a tty.\n");
return 1;
}
setup_and_process_keys(continuous_mode);
setup_and_process_keys(continuous_mode, verbose);
exit_without_destructors(0);
return EXIT_FAILURE; // above should exit
}

View File

@ -18,7 +18,7 @@ send, sendline, sleep, expect_prompt, expect_re, expect_str = (
)
expect_prompt()
sendline("exec $fish_key_reader -c")
sendline("exec $fish_key_reader -c -V")
# Do we get the expected startup prompt?
expect_str("Press a key:")