mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-28 13:53:10 +00:00
Add xterm-256color fallback
And use it if $TERM is xterm-256color and could not be found, *without* warning. These barely change, especially in the parts we use.
This commit is contained in:
parent
8c86336109
commit
75f7cda6ab
2 changed files with 97 additions and 2 deletions
|
@ -41,6 +41,7 @@ pub fn term() -> Option<Arc<Term>> {
|
||||||
///
|
///
|
||||||
/// An extant `Term` instance means the curses `TERMINAL *cur_term` pointer is non-null. Any
|
/// An extant `Term` instance means the curses `TERMINAL *cur_term` pointer is non-null. Any
|
||||||
/// functionality that is normally performed using `cur_term` should be done via `Term` instead.
|
/// functionality that is normally performed using `cur_term` should be done via `Term` instead.
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Term {
|
pub struct Term {
|
||||||
// String capabilities. Any Some value is confirmed non-empty.
|
// String capabilities. Any Some value is confirmed non-empty.
|
||||||
pub enter_bold_mode: Option<CString>,
|
pub enter_bold_mode: Option<CString>,
|
||||||
|
@ -394,6 +395,79 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setup_fallback_term() -> Arc<Term> {
|
||||||
|
let mut global_term = TERM.lock().expect("Mutex poisoned!");
|
||||||
|
// These values extracted from xterm-256color from ncurses 6.4
|
||||||
|
let term = Term {
|
||||||
|
enter_bold_mode: Some(CString::new("\x1b[1m").unwrap()),
|
||||||
|
enter_italics_mode: Some(CString::new("\x1b[3m").unwrap()),
|
||||||
|
exit_italics_mode: Some(CString::new("\x1b[23m").unwrap()),
|
||||||
|
enter_dim_mode: Some(CString::new("\x1b[2m").unwrap()),
|
||||||
|
enter_underline_mode: Some(CString::new("\x1b[4m").unwrap()),
|
||||||
|
exit_underline_mode: Some(CString::new("\x1b[24m").unwrap()),
|
||||||
|
enter_reverse_mode: Some(CString::new("\x1b[7m").unwrap()),
|
||||||
|
enter_standout_mode: Some(CString::new("\x1b[7m").unwrap()),
|
||||||
|
exit_standout_mode: Some(CString::new("\x1b[27m").unwrap()),
|
||||||
|
enter_blink_mode: Some(CString::new("\x1b[5m").unwrap()),
|
||||||
|
enter_secure_mode: Some(CString::new("\x1b[8m").unwrap()),
|
||||||
|
enter_alt_charset_mode: Some(CString::new("\x1b(0").unwrap()),
|
||||||
|
exit_alt_charset_mode: Some(CString::new("\x1b(B").unwrap()),
|
||||||
|
set_a_foreground: Some(
|
||||||
|
CString::new("\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m")
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
set_a_background: Some(
|
||||||
|
CString::new("\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m")
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
exit_attribute_mode: Some(CString::new("\x1b(B\x1b[m").unwrap()),
|
||||||
|
clear_screen: Some(CString::new("\x1b[H\x1b[2J").unwrap()),
|
||||||
|
cursor_up: Some(CString::new("\x1b[A").unwrap()),
|
||||||
|
cursor_down: Some(CString::new("\n").unwrap()),
|
||||||
|
cursor_left: Some(CString::new("\x08").unwrap()),
|
||||||
|
cursor_right: Some(CString::new("\x1b[C").unwrap()),
|
||||||
|
parm_left_cursor: Some(CString::new("\x1b[%p1%dD").unwrap()),
|
||||||
|
parm_right_cursor: Some(CString::new("\x1b[%p1%dC").unwrap()),
|
||||||
|
clr_eol: Some(CString::new("\x1b[K").unwrap()),
|
||||||
|
clr_eos: Some(CString::new("\x1b[J").unwrap()),
|
||||||
|
max_colors: Some(256),
|
||||||
|
init_tabs: Some(8),
|
||||||
|
eat_newline_glitch: true,
|
||||||
|
auto_right_margin: true,
|
||||||
|
key_a1: Some(CString::new("\x1bOw").unwrap()),
|
||||||
|
key_a3: Some(CString::new("\x1bOy").unwrap()),
|
||||||
|
key_b2: Some(CString::new("\x1bOu").unwrap()),
|
||||||
|
key_backspace: Some(CString::new("\x7f").unwrap()),
|
||||||
|
key_btab: Some(CString::new("\x1b[Z").unwrap()),
|
||||||
|
key_c1: Some(CString::new("\x1bOq").unwrap()),
|
||||||
|
key_c3: Some(CString::new("\x1bOs").unwrap()),
|
||||||
|
key_dc: Some(CString::new("\x1b[3~").unwrap()),
|
||||||
|
key_down: Some(CString::new("\x1bOB").unwrap()),
|
||||||
|
key_f1: Some(CString::new("\x1bOP").unwrap()),
|
||||||
|
key_home: Some(CString::new("\x1bOH").unwrap()),
|
||||||
|
key_ic: Some(CString::new("\x1b[2~").unwrap()),
|
||||||
|
key_left: Some(CString::new("\x1bOD").unwrap()),
|
||||||
|
key_npage: Some(CString::new("\x1b[6~").unwrap()),
|
||||||
|
key_ppage: Some(CString::new("\x1b[5~").unwrap()),
|
||||||
|
key_right: Some(CString::new("\x1bOC").unwrap()),
|
||||||
|
key_sdc: Some(CString::new("\x1b[3;2~").unwrap()),
|
||||||
|
key_send: Some(CString::new("\x1b[1;2F").unwrap()),
|
||||||
|
key_sf: Some(CString::new("\x1b[1;2B").unwrap()),
|
||||||
|
key_shome: Some(CString::new("\x1b[1;2H").unwrap()),
|
||||||
|
key_sic: Some(CString::new("\x1b[2;2~").unwrap()),
|
||||||
|
key_sleft: Some(CString::new("\x1b[1;2D").unwrap()),
|
||||||
|
key_snext: Some(CString::new("\x1b[6;2~").unwrap()),
|
||||||
|
key_sprevious: Some(CString::new("\x1b[5;2~").unwrap()),
|
||||||
|
key_sr: Some(CString::new("\x1b[1;2A").unwrap()),
|
||||||
|
key_sright: Some(CString::new("\x1b[1;2C").unwrap()),
|
||||||
|
key_up: Some(CString::new("\x1bOA").unwrap()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let term = Arc::new(term);
|
||||||
|
*global_term = Some(term.clone());
|
||||||
|
term
|
||||||
|
}
|
||||||
|
|
||||||
/// Return a nonempty String capability from termcap, or None if missing or empty.
|
/// Return a nonempty String capability from termcap, or None if missing or empty.
|
||||||
/// Panics if the given code string does not contain exactly two bytes.
|
/// Panics if the given code string does not contain exactly two bytes.
|
||||||
fn get_str_cap(db: &terminfo::Database, code: &str) -> Option<CString> {
|
fn get_str_cap(db: &terminfo::Database, code: &str) -> Option<CString> {
|
||||||
|
|
|
@ -496,6 +496,19 @@ fn initialize_curses_using_fallbacks(vars: &EnvStack) {
|
||||||
.map(|v| v.as_string())
|
.map(|v| v.as_string())
|
||||||
.unwrap_or(Default::default());
|
.unwrap_or(Default::default());
|
||||||
|
|
||||||
|
let mut success = false;
|
||||||
|
if current_term == "xterm-256color" {
|
||||||
|
// If we have xterm-256color, let's just use our hard-coded version
|
||||||
|
// instead of trying to read xterm or "ansi".
|
||||||
|
// It's almost certain we can't find terminfo.
|
||||||
|
FLOG!(
|
||||||
|
term_support,
|
||||||
|
"Could not read xterm-256color. Using fallback."
|
||||||
|
);
|
||||||
|
curses::setup_fallback_term();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for term in FALLBACKS {
|
for term in FALLBACKS {
|
||||||
// If $TERM is already set to the fallback name we're about to use, there's no point in
|
// If $TERM is already set to the fallback name we're about to use, there's no point in
|
||||||
// seeing if the fallback name can be used.
|
// seeing if the fallback name can be used.
|
||||||
|
@ -505,8 +518,7 @@ fn initialize_curses_using_fallbacks(vars: &EnvStack) {
|
||||||
|
|
||||||
// `term` here is one of our hard-coded strings above; we can unwrap because we can
|
// `term` here is one of our hard-coded strings above; we can unwrap because we can
|
||||||
// guarantee it doesn't contain any interior NULs.
|
// guarantee it doesn't contain any interior NULs.
|
||||||
let success =
|
success = curses::setup(Some(&term), |term| apply_term_hacks(vars, term)).is_some();
|
||||||
curses::setup(Some(&term), |term| apply_term_hacks(vars, term)).is_some();
|
|
||||||
if is_interactive_session() {
|
if is_interactive_session() {
|
||||||
if success {
|
if success {
|
||||||
FLOG!(warning, wgettext!("Using fallback terminal type"), term);
|
FLOG!(warning, wgettext!("Using fallback terminal type"), term);
|
||||||
|
@ -523,6 +535,15 @@ fn initialize_curses_using_fallbacks(vars: &EnvStack) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !success {
|
||||||
|
if is_interactive_session() {
|
||||||
|
FLOG!(
|
||||||
|
warning,
|
||||||
|
wgettext!("Could not get any terminfo database, falling back to hardcoded xterm-256color values"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
curses::setup_fallback_term();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply any platform- or environment-specific hacks to our curses [`Term`] instance.
|
/// Apply any platform- or environment-specific hacks to our curses [`Term`] instance.
|
||||||
|
|
Loading…
Reference in a new issue