diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2017-11-27 00:35:09 +0100 | 
|---|---|---|
| committer | Justin M. Keyes <justinkz@gmail.com> | 2017-12-05 01:45:39 +0100 | 
| commit | 3aa24042a8f7d591b8091b437fc9cdb03497bc7a (patch) | |
| tree | 42aa095f3500f6337cc406a948846823e014a357 /src | |
| parent | a494c999189200c36786f7c453c5c316244da0d1 (diff) | |
| download | rneovim-3aa24042a8f7d591b8091b437fc9cdb03497bc7a.tar.gz rneovim-3aa24042a8f7d591b8091b437fc9cdb03497bc7a.tar.bz2 rneovim-3aa24042a8f7d591b8091b437fc9cdb03497bc7a.zip  | |
tui: dump termcap info if -V3 ('verbose' >= 3)
Get terminal debugging info by starting Nvim with 'verbose' level 3:
    nvim -V3log
This is like Vim's `:set termcap`, which was removed in Nvim (and would
be very awkward to restore because of the decoupled UI).
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/README.md | 35 | ||||
| -rw-r--r-- | src/nvim/option.c | 11 | ||||
| -rw-r--r-- | src/nvim/tui/terminfo.c | 87 | ||||
| -rw-r--r-- | src/nvim/tui/tui.c | 21 | ||||
| -rw-r--r-- | src/nvim/ui_bridge.c | 3 | 
5 files changed, 147 insertions, 10 deletions
diff --git a/src/nvim/README.md b/src/nvim/README.md index 0caf71e2c5..da87a0208e 100644 --- a/src/nvim/README.md +++ b/src/nvim/README.md @@ -32,6 +32,39 @@ The source files use extensions to hint about their purpose.  - `*.h.generated.h` - exported functions’ declarations.  - `*.c.generated.h` - static functions’ declarations. +TUI debugging +------------- + +### TUI troubleshoot + +Nvim logs its internal terminfo state at 'verbose' level 3.  This makes it +possible to see exactly what terminfo values Nvim is using on any system. + +    nvim -V3log + +### TUI trace + +The ancient `script` command is still the "state of the art" for tracing +terminal behavior. The libvterm `vterm-dump` utility formats the result for +human-readability. + +Record a Nvim terminal session and format it with `vterm-dump`: + +    script foo +    ./build/bin/nvim -u NONE +    # Exit the script session with CTRL-d + +    # Use `vterm-dump` utility to format the result. +    ./.deps/usr/bin/vterm-dump foo > bar + +Then you can compare `bar` with another session, to debug TUI behavior. + +### Terminal reference + +- `man terminfo` +- http://bazaar.launchpad.net/~libvterm/libvterm/trunk/view/head:/doc/seqs.txt +- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html +  Nvim lifecycle  -------------- @@ -39,7 +72,7 @@ Following describes how Nvim processes input.  Consider a typical Vim-like editing session: -01. Vim dispays the welcome screen +01. Vim displays the welcome screen  02. User types: `:`  03. Vim enters command-line mode  04. User types: `edit README.txt<CR>` diff --git a/src/nvim/option.c b/src/nvim/option.c index 913d27d508..37c4233142 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4906,15 +4906,14 @@ showoptions (    vimoption_T **items = xmalloc(sizeof(vimoption_T *) * PARAM_COUNT); -  /* Highlight title */ -  if (all == 2) -    MSG_PUTS_TITLE(_("\n--- Terminal codes ---")); -  else if (opt_flags & OPT_GLOBAL) +  // Highlight title +  if (opt_flags & OPT_GLOBAL) {      MSG_PUTS_TITLE(_("\n--- Global option values ---")); -  else if (opt_flags & OPT_LOCAL) +  } else if (opt_flags & OPT_LOCAL) {      MSG_PUTS_TITLE(_("\n--- Local option values ---")); -  else +  } else {      MSG_PUTS_TITLE(_("\n--- Options ---")); +  }    /*     * do the loop two times: diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index fdc33f0a77..492c1c5e9c 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -9,7 +9,10 @@  #include <unibilium.h>  #include "nvim/log.h" +#include "nvim/globals.h"  #include "nvim/memory.h" +#include "nvim/message.h" +#include "nvim/option.h"  #include "nvim/tui/terminfo.h"  #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -166,3 +169,87 @@ unibi_term *terminfo_from_builtin(const char *term, char **termname)    unibi_set_bool(ut, unibi_back_color_erase, false);    return ut;  } + +/// Dumps termcap info to the messages area. +/// Serves a similar purpose as Vim `:set termcap` (removed in Nvim). +/// +/// @note adapted from unibilium unibi-dump.c +void terminfo_info_msg(const unibi_term *const ut) +{ +  if (exiting) { +    return; +  } +  msg_puts_title("\n\n--- Terminal info --- {{{\n"); + +  char *term; +  get_tty_option("term", &term); +  msg_printf_attr(0, "&term: %s\n", term); +  msg_printf_attr(0, "Description: %s\n", unibi_get_name(ut)); +  const char **a = unibi_get_aliases(ut); +  if (*a) { +    msg_puts("Aliases: "); +    do { +      msg_printf_attr(0, "%s%s\n", *a, a[1] ? " | " : ""); +      a++; +    } while (*a); +  } + +  msg_puts("Boolean capabilities:\n"); +  for (enum unibi_boolean i = unibi_boolean_begin_ + 1; +       i < unibi_boolean_end_; i++) { +    msg_printf_attr(0, "  %-25s %-10s = %s\n", unibi_name_bool(i), +                    unibi_short_name_bool(i), +                    unibi_get_bool(ut, i) ? "true" : "false"); +  } + +  msg_puts("Numeric capabilities:\n"); +  for (enum unibi_numeric i = unibi_numeric_begin_ + 1; +       i < unibi_numeric_end_; i++) { +    int n = unibi_get_num(ut, i);  // -1 means "empty" +    msg_printf_attr(0, "  %-25s %-10s = %hd\n", unibi_name_num(i), +                    unibi_short_name_num(i), n); +  } + +  msg_puts("String capabilities:\n"); +  for (enum unibi_string i = unibi_string_begin_ + 1; +       i < unibi_string_end_; i++) { +    const char *s = unibi_get_str(ut, i); +    if (s) { +      msg_printf_attr(0, "  %-25s %-10s = ", unibi_name_str(i), +                      unibi_short_name_str(i)); +      // Most of these strings will contain escape sequences. +      msg_outtrans_special((char_u *)s, false); +      msg_putchar('\n'); +    } +  } + +  if (unibi_count_ext_bool(ut)) { +    msg_puts("Extended boolean capabilities:\n"); +    for (size_t i = 0; i < unibi_count_ext_bool(ut); i++) { +      msg_printf_attr(0, "  %-25s = %s\n", +                      unibi_get_ext_bool_name(ut, i), +                      unibi_get_ext_bool(ut, i) ? "true" : "false"); +    } +  } + +  if (unibi_count_ext_num(ut)) { +    msg_puts("Extended numeric capabilities:\n"); +    for (size_t i = 0; i < unibi_count_ext_num(ut); i++) { +      msg_printf_attr(0, "  %-25s = %hd\n", +                      unibi_get_ext_num_name(ut, i), +                      unibi_get_ext_num(ut, i)); +    } +  } + +  if (unibi_count_ext_str(ut)) { +    msg_puts("Extended string capabilities:\n"); +    for (size_t i = 0; i < unibi_count_ext_str(ut); i++) { +      msg_printf_attr(0, "  %-25s = ", unibi_get_ext_str_name(ut, i)); +      msg_outtrans_special((char_u *)unibi_get_ext_str(ut, i), false); +      msg_putchar('\n'); +    } +  } + +  msg_puts("}}}\n"); +  xfree(term); +} diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 2436295ad4..739f3d18d2 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -354,10 +354,12 @@ static void tui_main(UIBridgeData *bridge, UI *ui)    tui_terminal_start(ui);    data->stop = false; -  // allow the main thread to continue, we are ready to start handling UI -  // callbacks +  // Allow main thread to continue, we are ready to handle UI callbacks.    CONTINUE(bridge); +  loop_schedule_deferred(&main_loop, +                         event_create(show_termcap_event, 1, data->ut)); +    while (!data->stop) {      loop_poll_events(&tui_loop, -1);  // tui_loop.events is never processed    } @@ -1061,6 +1063,21 @@ static void tui_flush(UI *ui)    flush_buf(ui, true);  } +/// Dumps termcap info to the messages area, if 'verbose' >= 3. +static void show_termcap_event(void **argv) +{ +  if (p_verbose < 3) { +    return; +  } +  const unibi_term *const ut = argv[0]; +  if (!ut) { +    abort(); +  } +  // XXX: (future) if unibi_term is modified (e.g. after a terminal +  // query-response) this is a race condition. +  terminfo_info_msg(ut); +} +  #ifdef UNIX  static void suspend_event(void **argv)  { diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 5585886612..7573fa1653 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -82,6 +82,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)      abort();    } +  // Suspend the main thread until CONTINUE is called by the UI thread.    while (!rv->ready) {      uv_cond_wait(&rv->cond, &rv->mutex);    } @@ -149,7 +150,7 @@ static void ui_bridge_suspend(UI *b)    uv_mutex_lock(&data->mutex);    UI_BRIDGE_CALL(b, suspend, 1, b);    data->ready = false; -  // suspend the main thread until CONTINUE is called by the UI thread +  // Suspend the main thread until CONTINUE is called by the UI thread.    while (!data->ready) {      uv_cond_wait(&data->cond, &data->mutex);    }  | 
