diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2017-11-26 23:15:17 +0100 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2017-11-27 09:45:32 +0100 |
commit | 944e3c06193f6d10baa9ba3021e01626337dd884 (patch) | |
tree | 949c05f0259f1d746f68b932139b4573225e179b /src | |
parent | a043899ba255524b7421579b9bd6112801f09247 (diff) | |
download | rneovim-944e3c06193f6d10baa9ba3021e01626337dd884.tar.gz rneovim-944e3c06193f6d10baa9ba3021e01626337dd884.tar.bz2 rneovim-944e3c06193f6d10baa9ba3021e01626337dd884.zip |
tui: expose terminal type in 'term' option
Since "builtin" terminfo definitions were implemented (7cbf52db1bdf),
the decisions made by tui.c and terminfo.c are more relevant. Exposing
that decision in the 'term' option helps with troubleshooting.
Also: remove code that allowed setting t_Co. `:set t_Co=…` has never
worked; the highlight_spec test asserting that nvim_set_option('t_Co')
_does_ work makes no sense, and should not have worked.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/option.c | 73 | ||||
-rw-r--r-- | src/nvim/tui/terminfo.c | 28 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 22 |
3 files changed, 86 insertions, 37 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c index 65ab7a54a6..07114c9507 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -105,6 +105,9 @@ typedef enum { */ #define VAR_WIN ((char_u *)-1) +static char *p_term = NULL; +static char *p_ttytype = NULL; + /* * These are the global values for options which are also local to a buffer. * Only to be used in option.c! @@ -4530,13 +4533,17 @@ int findoption_len(const char *const arg, const size_t len) bool is_tty_option(const char *name) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - return (name[0] == 't' && name[1] == '_') || strcmp(name, "term") == 0; + return (name[0] == 't' && name[1] == '_') + || strequal(name, "term") + || strequal(name, "ttytype"); } #define TCO_BUFFER_SIZE 8 +/// @param name TUI-related option +/// @param[out,allocated] value option string value bool get_tty_option(char *name, char **value) { - if (!strcmp(name, "t_Co")) { + if (strequal(name, "t_Co")) { if (value) { if (t_colors <= 1) { *value = xstrdup(""); @@ -4548,9 +4555,16 @@ bool get_tty_option(char *name, char **value) return true; } - if (!strcmp(name, "term") || !strcmp(name, "ttytype")) { + if (strequal(name, "term")) { if (value) { - *value = xstrdup("nvim"); + *value = p_term ? xstrdup(p_term) : xstrdup("nvim"); + } + return true; + } + + if (strequal(name, "ttytype")) { + if (value) { + *value = p_ttytype ? xstrdup(p_ttytype) : xstrdup("nvim"); } return true; } @@ -4566,25 +4580,25 @@ bool get_tty_option(char *name, char **value) return false; } -bool set_tty_option(const char *name, const char *value) +bool set_tty_option(const char *name, char *value) { - if (!strcmp(name, "t_Co")) { - int colors = atoi(value); - - // Only reinitialize colors if t_Co value has really changed to - // avoid expensive reload of colorscheme if t_Co is set to the - // same value multiple times - if (colors != t_colors) { - t_colors = colors; - // We now have a different color setup, initialize it again. - init_highlight(true, false); + if (strequal(name, "term")) { + if (p_term) { + xfree(p_term); } + p_term = value; + return true; + } + if (strequal(name, "ttytype")) { + if (p_ttytype) { + xfree(p_ttytype); + } + p_ttytype = value; return true; } - return (is_tty_option(name) || !strcmp(name, "term") - || !strcmp(name, "ttytype")); + return false; } /// Find index for an option @@ -4597,18 +4611,15 @@ static int findoption(const char *const arg) return findoption_len(arg, strlen(arg)); } -/* - * Get the value for an option. - * - * Returns: - * Number or Toggle option: 1, *numval gets value. - * String option: 0, *stringval gets allocated string. - * Hidden Number or Toggle option: -1. - * hidden String option: -2. - * unknown option: -3. - */ -int -get_option_value ( +/// Gets the value for an option. +/// +/// @returns: +/// Number or Toggle option: 1, *numval gets value. +/// String option: 0, *stringval gets allocated string. +/// Hidden Number or Toggle option: -1. +/// hidden String option: -2. +/// unknown option: -3. +int get_option_value ( char_u *name, long *numval, char_u **stringval, /* NULL when only checking existence */ @@ -4791,8 +4802,8 @@ char *set_option_value(const char *const name, const long number, const char *const string, const int opt_flags) FUNC_ATTR_NONNULL_ARG(1) { - if (set_tty_option(name, string)) { - return NULL; + if (is_tty_option(name)) { + return NULL; // Fail silently; many old vimrcs set t_xx options. } int opt_idx; diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index 75e9a2d8da..fdc33f0a77 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -9,6 +9,7 @@ #include <unibilium.h> #include "nvim/log.h" +#include "nvim/memory.h" #include "nvim/tui/terminfo.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -94,51 +95,72 @@ bool terminfo_is_term_family(const char *term, const char *family) /// Loads a built-in terminfo db when we (unibilium) failed to load a terminfo /// record from the environment (termcap systems, unrecognized $TERM, …). /// We do not attempt to detect xterm pretenders here. -static unibi_term *terminfo_builtin(const char *term) +/// +/// @param term $TERM value +/// @param[out,allocated] termname decided builtin 'term' name +/// @return [allocated] terminfo structure +static unibi_term *terminfo_builtin(const char *term, char **termname) { if (terminfo_is_term_family(term, "xterm")) { + *termname = xstrdup("builtin_xterm"); return unibi_from_mem((const char *)xterm_256colour_terminfo, sizeof xterm_256colour_terminfo); } else if (terminfo_is_term_family(term, "screen")) { + *termname = xstrdup("builtin_screen"); return unibi_from_mem((const char *)screen_256colour_terminfo, sizeof screen_256colour_terminfo); } else if (terminfo_is_term_family(term, "tmux")) { + *termname = xstrdup("builtin_tmux"); return unibi_from_mem((const char *)tmux_256colour_terminfo, sizeof tmux_256colour_terminfo); } else if (terminfo_is_term_family(term, "rxvt")) { + *termname = xstrdup("builtin_rxvt"); return unibi_from_mem((const char *)rxvt_256colour_terminfo, sizeof rxvt_256colour_terminfo); } else if (terminfo_is_term_family(term, "putty")) { + *termname = xstrdup("builtin_putty"); return unibi_from_mem((const char *)putty_256colour_terminfo, sizeof putty_256colour_terminfo); } else if (terminfo_is_term_family(term, "linux")) { + *termname = xstrdup("builtin_linux"); return unibi_from_mem((const char *)linux_16colour_terminfo, sizeof linux_16colour_terminfo); } else if (terminfo_is_term_family(term, "interix")) { + *termname = xstrdup("builtin_interix"); return unibi_from_mem((const char *)interix_8colour_terminfo, sizeof interix_8colour_terminfo); } else if (terminfo_is_term_family(term, "iterm") || terminfo_is_term_family(term, "iterm2") || terminfo_is_term_family(term, "iTerm.app") || terminfo_is_term_family(term, "iTerm2.app")) { + *termname = xstrdup("builtin_iterm"); return unibi_from_mem((const char *)iterm_256colour_terminfo, sizeof iterm_256colour_terminfo); } else if (terminfo_is_term_family(term, "st")) { + *termname = xstrdup("builtin_st"); return unibi_from_mem((const char *)st_256colour_terminfo, sizeof st_256colour_terminfo); } else if (terminfo_is_term_family(term, "gnome") || terminfo_is_term_family(term, "vte")) { + *termname = xstrdup("builtin_vte"); return unibi_from_mem((const char *)vte_256colour_terminfo, sizeof vte_256colour_terminfo); } else { + *termname = xstrdup("builtin_ansi"); return unibi_from_mem((const char *)ansi_terminfo, sizeof ansi_terminfo); } } -unibi_term *terminfo_from_builtin(const char *term) +/// @param term $TERM value +/// @param[out,allocated] termname decided builtin 'term' name +/// @return [allocated] terminfo structure +unibi_term *terminfo_from_builtin(const char *term, char **termname) { - unibi_term *ut = terminfo_builtin(term); + unibi_term *ut = terminfo_builtin(term, termname); + if (*termname == NULL) { + *termname = xstrdup("builtin_?"); + } // Disable BCE by default (for built-in terminfos). #7624 // https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545 unibi_set_bool(ut, unibi_back_color_erase, false); diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index c2e597c36c..732a86d0fb 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -23,6 +23,7 @@ #include "nvim/map.h" #include "nvim/main.h" #include "nvim/memory.h" +#include "nvim/option.h" #include "nvim/api/vim.h" #include "nvim/api/private/helpers.h" #include "nvim/event/loop.h" @@ -166,6 +167,13 @@ static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, return unibi_run(str, data->params, buf, len); } +static void termname_set_event(void **argv) +{ + char *termname = argv[0]; + set_tty_option("term", termname); + // Do not free termname, it is freed by set_tty_option. +} + static void terminfo_start(UI *ui) { TUIData *data = ui->data; @@ -190,12 +198,20 @@ static void terminfo_start(UI *ui) data->unibi_ext.reset_cursor_style = -1; data->out_fd = 1; data->out_isatty = os_isatty(data->out_fd); - // setup unibilium + + // Set up unibilium/terminfo. const char *term = os_getenv("TERM"); data->ut = unibi_from_env(); + char *termname = NULL; if (!data->ut) { - data->ut = terminfo_from_builtin(term); + data->ut = terminfo_from_builtin(term, &termname); + } else { + termname = xstrdup(term); } + // Update 'term' option. + loop_schedule_deferred(&main_loop, + event_create(termname_set_event, 1, termname)); + // None of the following work over SSH; see :help TERM . const char *colorterm = os_getenv("COLORTERM"); const char *termprg = os_getenv("TERM_PROGRAM"); @@ -344,7 +360,7 @@ static void tui_scheduler(Event event, void *d) { UI *ui = d; TUIData *data = ui->data; - loop_schedule(data->loop, event); + loop_schedule(data->loop, event); // `tui_loop` local to tui_main(). } #ifdef UNIX |