init: pipe detected terminal through to heuristics #1761

This commit is contained in:
nick black 2021-06-14 18:15:47 -04:00 committed by Nick Black
parent c13c613f32
commit 9cbcc6c273
4 changed files with 44 additions and 34 deletions

View File

@ -1023,7 +1023,7 @@ pump_control_read(init_state* inits, unsigned char c){
// complete the terminal detection process // complete the terminal detection process
static int static int
control_read(tinfo* tcache, int ttyfd){ control_read(tinfo* tcache, int ttyfd, queried_terminals_e* detected){
init_state inits = { init_state inits = {
.tcache = tcache, .tcache = tcache,
.state = STATE_NULL, .state = STATE_NULL,
@ -1032,6 +1032,7 @@ control_read(tinfo* tcache, int ttyfd){
unsigned char* buf; unsigned char* buf;
ssize_t s; ssize_t s;
*detected = TERMINAL_UNKNOWN;
if((buf = malloc(BUFSIZ)) == NULL){ if((buf = malloc(BUFSIZ)) == NULL){
return -1; return -1;
} }
@ -1040,6 +1041,7 @@ control_read(tinfo* tcache, int ttyfd){
int r = pump_control_read(&inits, buf[idx]); int r = pump_control_read(&inits, buf[idx]);
if(r == 1){ // success! if(r == 1){ // success!
free(buf); free(buf);
*detected = inits.qterm;
//fprintf(stderr, "at end, derived terminal %d\n", inits.qterm); //fprintf(stderr, "at end, derived terminal %d\n", inits.qterm);
return 0; return 0;
}else if(r < 0){ }else if(r < 0){
@ -1053,7 +1055,7 @@ err:
return -1; return -1;
} }
int ncinputlayer_init(tinfo* tcache, FILE* infp){ int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected){
ncinputlayer* nilayer = &tcache->input; ncinputlayer* nilayer = &tcache->input;
setbuffer(infp, NULL, 0); setbuffer(infp, NULL, 0);
nilayer->inputescapes = NULL; nilayer->inputescapes = NULL;
@ -1068,7 +1070,7 @@ int ncinputlayer_init(tinfo* tcache, FILE* infp){
nilayer->input_events = 0; nilayer->input_events = 0;
int csifd = nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd; int csifd = nilayer->ttyfd >= 0 ? nilayer->ttyfd : nilayer->infd;
if(isatty(csifd)){ if(isatty(csifd)){
if(control_read(tcache, csifd)){ if(control_read(tcache, csifd, detected)){
input_free_esctrie(&nilayer->inputescapes); input_free_esctrie(&nilayer->inputescapes);
return -1; return -1;
} }

View File

@ -1496,8 +1496,9 @@ cellcmp_and_dupfar(egcpool* dampool, nccell* damcell,
// sets up the input layer, building a trie of escape sequences and their // sets up the input layer, building a trie of escape sequences and their
// nckey equivalents. if we are connected to a tty, this also completes the // nckey equivalents. if we are connected to a tty, this also completes the
// terminal detection sequence (we ought have already written our initial // terminal detection sequence (we ought have already written our initial
// queries, ideally as early as possible). // queries, ideally as early as possible). if we are able to determine the
int ncinputlayer_init(tinfo* tcache, FILE* infp); // terminal conclusively, it will be written to |detected|.
int ncinputlayer_init(tinfo* tcache, FILE* infp, queried_terminals_e* detected);
void ncinputlayer_stop(ncinputlayer* nilayer); void ncinputlayer_stop(ncinputlayer* nilayer);

View File

@ -74,15 +74,31 @@ terminfostr(char** gseq, const char* name){
return 0; return 0;
} }
// we couldn't get a terminal from interrogation, so let's see if the TERM
// matches any of our known terminals. this can only be as accurate as the
// TERM setting is (and as up-to-date and complete as we are).
static int
match_termname(const char* termname, queried_terminals_e* qterm){
if(strstr(termname, "alacritty")){
*qterm = TERMINAL_ALACRITTY;
}
return 0;
}
// Qui si convien lasciare ogne sospetto; ogne viltà convien che qui sia morta. // Qui si convien lasciare ogne sospetto; ogne viltà convien che qui sia morta.
static int static int
apply_term_heuristics(tinfo* ti, const char* termname, int fd){ apply_term_heuristics(tinfo* ti, const char* termname, int fd,
queried_terminals_e qterm){
if(!termname){ if(!termname){
// setupterm interprets a missing/empty TERM variable as the special value “unknown”. // setupterm interprets a missing/empty TERM variable as the special value “unknown”.
termname = "unknown"; termname = "unknown";
} }
if(qterm == TERMINAL_UNKNOWN){
match_termname(termname, &qterm);
}
// st had neithersextants nor quadrants last i checked (0.8.4)
ti->braille = true; // most everyone has working braille, even from fonts ti->braille = true; // most everyone has working braille, even from fonts
if(strstr(termname, "kitty")){ // kitty (https://sw.kovidgoyal.net/kitty/) if(qterm == TERMINAL_KITTY){ // kitty (https://sw.kovidgoyal.net/kitty/)
termname = "Kitty"; termname = "Kitty";
// see https://sw.kovidgoyal.net/kitty/protocol-extensions.html // see https://sw.kovidgoyal.net/kitty/protocol-extensions.html
// FIXME detect the actual default background color; this assumes it to // FIXME detect the actual default background color; this assumes it to
@ -92,45 +108,33 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd){
ti->quadrants = true; ti->quadrants = true;
ti->RGBflag = true; ti->RGBflag = true;
setup_kitty_bitmaps(ti, fd); setup_kitty_bitmaps(ti, fd);
}else if(strstr(termname, "alacritty")){ }else if(qterm == TERMINAL_ALACRITTY){
termname = "Alacritty"; termname = "Alacritty";
ti->quadrants = true; ti->quadrants = true;
// ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */ // ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */
ti->RGBflag = true; ti->RGBflag = true;
}else if(strstr(termname, "vte") || strstr(termname, "gnome") || strstr(termname, "xfce")){ }else if(qterm == TERMINAL_VTE){
termname = "VTE"; termname = "VTE";
ti->sextants = true; // VTE has long enjoyed good sextant support
ti->quadrants = true; ti->quadrants = true;
}else if(strncmp(termname, "foot", 4) == 0){ ti->sextants = true; // VTE has long enjoyed good sextant support
}else if(qterm == TERMINAL_FOOT){
termname = "foot"; termname = "foot";
ti->sextants = true; ti->sextants = true;
ti->quadrants = true; ti->quadrants = true;
ti->RGBflag = true; ti->RGBflag = true;
}else if(strncmp(termname, "st", 2) == 0){ }else if(qterm == TERMINAL_MLTERM){
termname = "simple terminal";
// st had neithersextants nor quadrants last i checked (0.8.4)
}else if(strstr(termname, "mlterm")){
termname = "MLterm"; termname = "MLterm";
ti->quadrants = true; // good quadrants, no sextants as of 3.9.0 ti->quadrants = true; // good quadrants, no sextants as of 3.9.0
ti->sprixel_cursor_hack = true; ti->sprixel_cursor_hack = true;
}else if(strstr(termname, "xterm")){ }else if(qterm == TERMINAL_WEZTERM){
// xterm has nothing beyond halfblocks. this is going to catch all kinds
// of people using xterm when they shouldn't be, or even real database
// entries like "xterm-kitty" (if we don't catch them above), giving a
// pretty minimal (but safe) experience. set your TERM correctly!
// wezterm wants a TERM of xterm-256color, and identifies itself based
// off TERM_PROGRAM and TERM_PROGRAM_VERSION.
const char* term_program = getenv("TERM_PROGRAM");
if(term_program && strcmp(term_program, "WezTerm") == 0){
termname = "WezTerm"; termname = "WezTerm";
ti->quadrants = true; ti->quadrants = true;
const char* termver = getenv("TERM_PROGRAM_VERSION"); const char* termver = getenv("TERM_PROGRAM_VERSION");
if(termver && strcmp(termver, "20210610") >= 0){ if(termver && strcmp(termver, "20210610") >= 0){
ti->sextants = true; // good sextants as of 2021-06-10 ti->sextants = true; // good sextants as of 2021-06-10
} }
}else{ }else if(qterm == TERMINAL_XTERM){
termname = "XTerm"; termname = "XTerm";
}
}else if(strcmp(termname, "linux") == 0){ }else if(strcmp(termname, "linux") == 0){
termname = "Linux console"; termname = "Linux console";
ti->braille = false; // no braille, no sextants in linux console ti->braille = false; // no braille, no sextants in linux console
@ -399,7 +403,8 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
goto err; goto err;
} }
} }
if(ncinputlayer_init(ti, stdin)){ queried_terminals_e detected;
if(ncinputlayer_init(ti, stdin, &detected)){
goto err; goto err;
} }
// our current sixel quantization algorithm requires at least 64 color // our current sixel quantization algorithm requires at least 64 color
@ -415,7 +420,8 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
} }
} }
} }
if(apply_term_heuristics(ti, termname, fd)){ //fprintf(stderr, "DETECTED TERM: %d\n", detected);
if(apply_term_heuristics(ti, termname, fd, detected)){
ncinputlayer_stop(&ti->input); ncinputlayer_stop(&ti->input);
goto err; goto err;
} }

View File

@ -176,6 +176,7 @@ typedef enum {
TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\" TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\"
TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm' TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm'
TERMINAL_WEZTERM, TERMINAL_WEZTERM,
TERMINAL_ALACRITTY, // can't be detected; match TERM
} queried_terminals_e; } queried_terminals_e;
#ifdef __cplusplus #ifdef __cplusplus