Migrate the "Apple Term hacks" from set_color to init_curses

Apple's terminfo has missing support for enter_italics_mode,
exit_italics_mode, and enter_dim_mode. Previously we would hack in such
support in set_color; migrate that to init_curses so we do it up-front
instead of opportunistically.
This commit is contained in:
ridiculousfish 2022-04-16 13:00:14 -07:00
parent 4b96dd9908
commit 1da952450f
2 changed files with 34 additions and 22 deletions

View file

@ -99,32 +99,11 @@ static const struct woption long_options[] = {{L"background", required_argument,
{L"print-colors", no_argument, nullptr, 'c'},
{}};
#ifdef __APPLE__
static char sitm_esc[] = "\x1B[3m";
static char ritm_esc[] = "\x1B[23m";
static char dim_esc[] = "\x1B[2m";
#endif
/// set_color builtin.
maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, const wchar_t **argv) {
// By the time this is called we should have initialized the curses subsystem.
assert(curses_initialized);
#ifdef __APPLE__
// Hack in missing italics and dim capabilities omitted from MacOS xterm-256color terminfo
// Helps Terminal.app/iTerm
const auto term_prog = parser.vars().get(L"TERM_PROGRAM");
if (!term_prog.missing_or_empty() && (term_prog->as_string() == L"Apple_Terminal" ||
term_prog->as_string() == L"iTerm.app")) {
const auto term = parser.vars().get(L"TERM");
if (!term.missing_or_empty() && (term->as_string() == L"xterm-256color")) {
enter_italics_mode = sitm_esc;
exit_italics_mode = ritm_esc;
enter_dim_mode = dim_esc;
}
}
#endif
// Variables used for parsing the argument list.
int argc = builtin_count_args(argv);

View file

@ -488,6 +488,37 @@ static void initialize_curses_using_fallbacks(const environment_t &vars) {
}
}
// Apply any platform-specific hacks to cur_term/
static void apply_term_hacks(const environment_t &vars) {
UNUSED(vars);
#ifdef __APPLE__
// Hack in missing italics and dim capabilities omitted from MacOS xterm-256color terminfo
// Helps Terminal.app/iTerm
wcstring term_prog;
if (auto var = vars.get(L"TERM_PROGRAM")) {
term_prog = var->as_string();
}
if (term_prog == L"Apple_Terminal" || term_prog == L"iTerm.app") {
const auto term = vars.get(L"TERM");
if (term && term->as_string() == L"xterm-256color") {
static char sitm_esc[] = "\x1B[3m";
static char ritm_esc[] = "\x1B[23m";
static char dim_esc[] = "\x1B[2m";
if (!enter_italics_mode) {
enter_italics_mode = sitm_esc;
}
if (!exit_italics_mode) {
exit_italics_mode = ritm_esc;
}
if (!enter_dim_mode) {
enter_dim_mode = dim_esc;
}
}
}
#endif
}
/// 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
@ -539,7 +570,7 @@ static void init_curses(const environment_t &vars) {
}
}
int err_ret;
int err_ret{0};
if (setupterm(nullptr, STDOUT_FILENO, &err_ret) == ERR) {
if (is_interactive_session()) {
auto term = vars.get(L"TERM");
@ -556,6 +587,8 @@ static void init_curses(const environment_t &vars) {
initialize_curses_using_fallbacks(vars);
}
apply_term_hacks(vars);
can_set_term_title = does_term_support_setting_title(vars);
term_has_xn =
tigetflag(const_cast<char *>("xenl")) == 1; // does terminal have the eat_newline_glitch