mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
optimize determining if can set term title
Decide if the terminal supports setting its title only when necessary (e.g., when TERM changes) rather than everytime we're about to write the prompt.
This commit is contained in:
parent
e9de674bbd
commit
11dccccdcc
3 changed files with 45 additions and 29 deletions
42
src/env.cpp
42
src/env.cpp
|
@ -238,6 +238,47 @@ static bool var_is_curses(const wcstring &key) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// True if we think we can set the terminal title else false.
|
||||
static bool can_set_term_title = false;
|
||||
|
||||
/// Returns true if we think the terminal supports setting its title.
|
||||
bool term_supports_setting_title() {
|
||||
return can_set_term_title;
|
||||
}
|
||||
|
||||
/// This is a pretty lame heuristic for detecting terminals that do not support setting the
|
||||
/// title. If we recognise the terminal name as that of a virtual terminal, we assume it supports
|
||||
/// setting the title. If we recognise it as that of a console, we assume it does not support
|
||||
/// setting the title. Otherwise we check the ttyname and see if we believe it is a virtual
|
||||
/// terminal.
|
||||
///
|
||||
/// One situation in which this breaks down is with screen, since screen supports setting the
|
||||
/// terminal title if the underlying terminal does so, but will print garbage on terminals that
|
||||
/// don't. Since we can't see the underlying terminal below screen there is no way to fix this.
|
||||
static bool does_term_support_setting_title() {
|
||||
const env_var_t term_str = env_get_string(L"TERM");
|
||||
if (term_str.missing()) return false;
|
||||
|
||||
const wchar_t *term = term_str.c_str();
|
||||
bool recognized = contains(term, L"xterm", L"screen", L"tmux", L"nxterm", L"rxvt");
|
||||
if (!recognized) recognized = !wcsncmp(term, L"xterm-", wcslen(L"xterm-"));
|
||||
if (!recognized) recognized = !wcsncmp(term, L"screen-", wcslen(L"screen-"));
|
||||
if (!recognized) recognized = !wcsncmp(term, L"tmux-", wcslen(L"tmux-"));
|
||||
if (!recognized) {
|
||||
if (contains(term, L"linux", L"dumb")) return false;
|
||||
|
||||
char *n = ttyname(STDIN_FILENO);
|
||||
if (!n || strstr(n, "tty") || strstr(n, "/vc/")) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Handle changes to the TERM env var that do not involves the curses subsystem.
|
||||
static void handle_term() {
|
||||
can_set_term_title = does_term_support_setting_title();
|
||||
}
|
||||
|
||||
/// Push all curses/terminfo env vars into the global environment where they can be found by those
|
||||
/// libraries.
|
||||
static void handle_curses(const wchar_t *env_var_name) {
|
||||
|
@ -264,6 +305,7 @@ static void react_to_variable_change(const wcstring &key) {
|
|||
handle_locale(key.c_str());
|
||||
} else if (var_is_curses(key)) {
|
||||
handle_curses(key.c_str());
|
||||
if (key == L"TERM") handle_term();
|
||||
} else if (var_is_timezone(key)) {
|
||||
handle_timezone(key.c_str());
|
||||
} else if (key == L"fish_term256" || key == L"fish_term24bit") {
|
||||
|
|
|
@ -186,4 +186,7 @@ struct var_entry_t {
|
|||
typedef std::map<wcstring, var_entry_t> var_table_t;
|
||||
|
||||
extern bool term_has_xn; // does the terminal have the "eat_newline_glitch"
|
||||
|
||||
/// Returns true if we think the terminal supports setting its title.
|
||||
bool term_supports_setting_title();
|
||||
#endif
|
||||
|
|
|
@ -660,35 +660,6 @@ bool reader_thread_job_is_stale() {
|
|||
return (void *)(uintptr_t)s_generation_count != pthread_getspecific(generation_count_key);
|
||||
}
|
||||
|
||||
|
||||
/// This is a pretty lame heuristic for detecting terminals that do not support setting the
|
||||
/// title. If we recognise the terminal name as that of a virtual terminal, we assume it supports
|
||||
/// setting the title. If we recognise it as that of a console, we assume it does not support
|
||||
/// setting the title. Otherwise we check the ttyname and see if we believe it is a virtual
|
||||
/// terminal.
|
||||
///
|
||||
/// One situation in which this breaks down is with screen, since screen supports setting the
|
||||
/// terminal title if the underlying terminal does so, but will print garbage on terminals that
|
||||
/// don't. Since we can't see the underlying terminal below screen there is no way to fix this.
|
||||
static bool term_supports_setting_title() {
|
||||
const env_var_t term_str = env_get_string(L"TERM");
|
||||
if (term_str.missing()) return false;
|
||||
|
||||
const wchar_t *term = term_str.c_str();
|
||||
bool recognized = contains(term, L"xterm", L"screen", L"tmux", L"nxterm", L"rxvt");
|
||||
if (!recognized) recognized = !wcsncmp(term, L"xterm-", wcslen(L"xterm-"));
|
||||
if (!recognized) recognized = !wcsncmp(term, L"screen-", wcslen(L"screen-"));
|
||||
if (!recognized) recognized = !wcsncmp(term, L"tmux-", wcslen(L"tmux-"));
|
||||
if (!recognized) {
|
||||
if (contains(term, L"linux", L"dumb")) return false;
|
||||
|
||||
char *n = ttyname(STDIN_FILENO);
|
||||
if (!n || strstr(n, "tty") || strstr(n, "/vc/")) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void reader_write_title(const wcstring &cmd, bool reset_cursor_position) {
|
||||
if (!term_supports_setting_title()) return;
|
||||
|
||||
|
|
Loading…
Reference in a new issue