To: vim_dev@googlegroups.com Subject: Patch 8.2.0941 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0941 Problem: Detecting terminal properties is unstructured. Solution: Add a table with terminal properties. Set properties when a terminal is detected. Files: src/term.c *** ../vim-8.2.0940/src/term.c 2020-06-09 21:35:32.546431760 +0200 --- src/term.c 2020-06-10 12:11:48.124913593 +0200 *************** *** 1431,1438 **** static char_u termleader[256 + 1]; // for check_termcode() #ifdef FEAT_TERMRESPONSE static int check_for_codes = FALSE; // check for key code response ! static int is_not_xterm = FALSE; // recognized not-really-xterm ! static int xcc_test_failed = FALSE; // xcc_status check failed #endif static struct builtin_term * --- 1431,1493 ---- static char_u termleader[256 + 1]; // for check_termcode() #ifdef FEAT_TERMRESPONSE static int check_for_codes = FALSE; // check for key code response ! ! /* ! * Structure and table to store terminal features that can be detected by ! * querying the terminal. Either by inspecting the termresponse or a more ! * specific request. Besides this there are: ! * t_colors - number of colors supported ! */ ! typedef struct { ! char *tpr_name; ! int tpr_set_by_termresponse; ! int tpr_status; ! } termprop_T; ! ! // Values for tpr_status. ! #define TPR_UNKNOWN 'u' ! #define TPR_YES 'y' ! #define TPR_NO 'n' ! #define TPR_MOUSE_XTERM 'x' // use "xterm" for 'ttymouse' ! #define TPR_MOUSE_XTERM2 '2' // use "xterm2" for 'ttymouse' ! #define TPR_MOUSE_SGR 's' // use "sgr" for 'ttymouse' ! ! // can request the cursor style without messing up the display ! #define TPR_CURSOR_STYLE 0 ! // can request the cursor blink mode without messing up the display ! #define TPR_CURSOR_BLINK 1 ! // can set the underline color with t_8u without resetting other colors ! #define TPR_UNDERLINE_RGB 2 ! // mouse support - TPR_MOUSE_XTERM, TPR_MOUSE_XTERM2 or TPR_MOUSE_SGR ! #define TPR_MOUSE 3 ! // table size ! #define TPR_COUNT 4 ! ! static termprop_T term_props[TPR_COUNT]; ! ! /* ! * Initialize the term_props table. ! * When "all" is FALSE only set those that are detected from the version ! * response. ! */ ! static void ! init_term_props(int all) ! { ! int i; ! ! term_props[TPR_CURSOR_STYLE].tpr_name = "cursor_style"; ! term_props[TPR_CURSOR_STYLE].tpr_set_by_termresponse = FALSE; ! term_props[TPR_CURSOR_BLINK].tpr_name = "cursor_blink_mode"; ! term_props[TPR_CURSOR_BLINK].tpr_set_by_termresponse = FALSE; ! term_props[TPR_UNDERLINE_RGB].tpr_name = "underline_rgb"; ! term_props[TPR_UNDERLINE_RGB].tpr_set_by_termresponse = TRUE; ! term_props[TPR_MOUSE].tpr_name = "mouse"; ! term_props[TPR_MOUSE].tpr_set_by_termresponse = TRUE; ! ! for (i = 0; i < TPR_COUNT; ++i) ! if (all || term_props[i].tpr_set_by_termresponse) ! term_props[i].tpr_status = TPR_UNKNOWN; ! } #endif static struct builtin_term * *************** *** 1958,1965 **** term_is_xterm = vim_is_xterm(term); #endif #ifdef FEAT_TERMRESPONSE ! is_not_xterm = FALSE; ! is_mac_terminal = FALSE; #endif #if defined(UNIX) || defined(VMS) --- 2013,2021 ---- term_is_xterm = vim_is_xterm(term); #endif #ifdef FEAT_TERMRESPONSE ! // Reset terminal properties that are set based on the termresponse, which ! // will be sent out soon. ! init_term_props(FALSE); #endif #if defined(UNIX) || defined(VMS) *************** *** 3612,3623 **** --- 3668,3683 ---- /* * Send sequences to the terminal and check with t_u7 how the cursor moves, to * find out properties of the terminal. + * Note that this goes out before T_CRV, so that the result can be used when + * the termresponse arrives. */ void check_terminal_behavior(void) { int did_send = FALSE; + init_term_props(TRUE); + if (!can_get_termresponse() || starting != 0 || *T_U7 == NUL) return; *************** *** 4424,4451 **** } else if (arg[0] == 3) { LOG_TR(("Received compatibility test result: %s", tp)); - // Third row: xterm compatibility test. - // If the cursor is not on the first column then the - // terminal is not xterm compatible. - if (arg[1] != 1) - xcc_test_failed = TRUE; xcc_status.tr_progress = STATUS_GOT; } } /* ! * Handle a response to T_CRV. */ static void handle_version_response(int first, int *arg, int argc, char_u *tp) { int version = arg[1]; LOG_TR(("Received CRV response: %s", tp)); crv_status.tr_progress = STATUS_GOT; did_cursorhold = TRUE; // If this code starts with CSI, you can bet that the // terminal uses 8-bit codes. if (tp[0] == CSI) --- 4484,4523 ---- } else if (arg[0] == 3) { + int value; + LOG_TR(("Received compatibility test result: %s", tp)); xcc_status.tr_progress = STATUS_GOT; + + // Third row: xterm compatibility test. + // If the cursor is on the first column then the terminal can handle + // the request for cursor style and blinking. + value = arg[1] == 1 ? TPR_YES : TPR_NO; + term_props[TPR_CURSOR_STYLE].tpr_status = value; + term_props[TPR_CURSOR_BLINK].tpr_status = value; } } /* ! * Handle a response to T_CRV: {lead}{first}{x};{vers};{y}c ! * Xterm and alikes use '>' for {first}. ! * Rxvt sends "{lead}?1;2c". */ static void handle_version_response(int first, int *arg, int argc, char_u *tp) { + // The xterm version. It is set to zero when it can't be an actual xterm + // version. int version = arg[1]; LOG_TR(("Received CRV response: %s", tp)); crv_status.tr_progress = STATUS_GOT; did_cursorhold = TRUE; + // Reset terminal properties that are set based on the termresponse. + // Mainly useful for tests that send the termresponse multiple times. + init_term_props(FALSE); + // If this code starts with CSI, you can bet that the // terminal uses 8-bit codes. if (tp[0] == CSI) *************** *** 4458,4476 **** if (version > 20000) version = 0; if (first == '>' && argc == 3) { int need_flush = FALSE; - int is_iterm2 = FALSE; - int is_mintty = FALSE; - int is_screen = FALSE; // mintty 2.9.5 sends 77;20905;0c. // (77 is ASCII 'M' for mintty.) if (arg[0] == 77) ! is_mintty = TRUE; ! // if xterm version >= 141 try to get termcap codes if (version >= 141) { LOG_TR(("Enable checking for XT codes")); --- 4530,4550 ---- if (version > 20000) version = 0; + // Figure out more if the reeponse is CSI > 99 ; 99 ; 99 c if (first == '>' && argc == 3) { int need_flush = FALSE; // mintty 2.9.5 sends 77;20905;0c. // (77 is ASCII 'M' for mintty.) if (arg[0] == 77) ! { ! // mintty can do SGR mouse reporting ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; ! } ! // If xterm version >= 141 try to get termcap codes. For other ! // terminals the request should be ignored. if (version >= 141) { LOG_TR(("Enable checking for XT codes")); *************** *** 4488,4496 **** if (mch_getenv((char_u *)"COLORS") == NULL) may_adjust_color_count(256); // Libvterm can handle SGR mouse reporting. ! if (!option_was_set((char_u *)"ttym")) ! set_option_value((char_u *)"ttym", 0L, ! (char_u *)"sgr", 0); } if (version == 95) --- 4562,4568 ---- if (mch_getenv((char_u *)"COLORS") == NULL) may_adjust_color_count(256); // Libvterm can handle SGR mouse reporting. ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; } if (version == 95) *************** *** 4498,4596 **** // Mac Terminal.app sends 1;95;0 if (arg[0] == 1 && arg[2] == 0) { ! is_not_xterm = TRUE; ! is_mac_terminal = TRUE; } // iTerm2 sends 0;95;0 else if (arg[0] == 0 && arg[2] == 0) ! is_iterm2 = TRUE; // old iTerm2 sends 0;95; else if (arg[0] == 0 && arg[2] == -1) ! is_not_xterm = TRUE; } // screen sends 83;40500;0 83 is 'S' in ASCII. if (arg[0] == 83) ! is_screen = TRUE; ! // Only set 'ttymouse' automatically if it was not set ! // by the user already. ! if (!option_was_set((char_u *)"ttym")) { ! // Xterm version 277 supports SGR. Also support ! // Terminal.app, iTerm2, mintty, and screen 4.7+. ! if ((!is_screen && version >= 277) ! || is_iterm2 ! || is_mac_terminal ! || is_mintty ! || (is_screen && arg[1] >= 40700)) ! set_option_value((char_u *)"ttym", 0L, ! (char_u *)"sgr", 0); ! // For xterm version >= 95 mouse dragging works. else if (version >= 95) ! set_option_value((char_u *)"ttym", 0L, ! (char_u *)"xterm2", 0); } // Detect terminals that set $TERM to something like // "xterm-256color" but are not fully xterm compatible. ! // Gnome terminal sends 1;3801;0, 1;4402;0 or 1;2501;0. // xfce4-terminal sends 1;2802;0. // screen sends 83;40500;0 // Assuming any version number over 2500 is not an // xterm (without the limit for rxvt and screen). if (arg[1] >= 2500) ! is_not_xterm = TRUE; - // PuTTY sends 0;136;0 - // vandyke SecureCRT sends 1;136;0 else if (version == 136 && arg[2] == 0) { ! is_not_xterm = TRUE; ! // PuTTY supports sgr-like mouse reporting, but ! // only set 'ttymouse' if it was not set by the ! // user already. ! if (arg[0] == 0 ! && !option_was_set((char_u *)"ttym")) ! set_option_value((char_u *)"ttym", 0L, ! (char_u *)"sgr", 0); } // Konsole sends 0;115;0 else if (version == 115 && arg[0] == 0 && arg[2] == 0) ! is_not_xterm = TRUE; // GNU screen sends 83;30600;0, 83;40500;0, etc. ! // 30600/40500 is a version number of GNU screen. DA2 ! // support is added on 3.6. DCS string has a special ! // meaning to GNU screen, but xterm compatibility ! // checking does not detect GNU screen. ! if (version >= 30600 && arg[0] == 83) ! xcc_test_failed = TRUE; // Xterm first responded to this request at patch level ! // 95, so assume anything below 95 is not xterm. if (version < 95) ! is_not_xterm = TRUE; ! // With the real Xterm setting the underline RGB color ! // clears the background color, disable "t_8u". ! if (!is_not_xterm && *T_8U != NUL) T_8U = empty_option; // Only request the cursor style if t_SH and t_RS are // set. Only supported properly by xterm since version // 279 (otherwise it returns 0x18). ! // Only when the xcc_status was set, the test finished, ! // and xcc_test_failed is FALSE; // Not for Terminal.app, it can't handle t_RS, it // echoes the characters to the screen. if (rcs_status.tr_progress == STATUS_GET ! && xcc_status.tr_progress == STATUS_GOT ! && !xcc_test_failed ! && version >= 279 && *T_CSH != NUL && *T_CRS != NUL) { --- 4570,4687 ---- // Mac Terminal.app sends 1;95;0 if (arg[0] == 1 && arg[2] == 0) { ! term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; } // iTerm2 sends 0;95;0 else if (arg[0] == 0 && arg[2] == 0) ! { ! // iTerm2 can do SGR mouse reporting ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; ! } // old iTerm2 sends 0;95; else if (arg[0] == 0 && arg[2] == -1) ! term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; } // screen sends 83;40500;0 83 is 'S' in ASCII. if (arg[0] == 83) ! { ! // screen supports SGR mouse codes since 4.7.0 ! if (arg[1] >= 40700) ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; ! else ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_XTERM; ! } ! // If no recognized terminal has set mouse behavior, assume xterm. ! if (term_props[TPR_MOUSE].tpr_status == TPR_UNKNOWN) { ! // Xterm version 277 supports SGR. ! // Xterm version >= 95 supports mouse dragging. ! if (version >= 277) ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; else if (version >= 95) ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_XTERM2; } // Detect terminals that set $TERM to something like // "xterm-256color" but are not fully xterm compatible. ! // // Gnome terminal sends 1;3801;0, 1;4402;0 or 1;2501;0. // xfce4-terminal sends 1;2802;0. // screen sends 83;40500;0 // Assuming any version number over 2500 is not an // xterm (without the limit for rxvt and screen). if (arg[1] >= 2500) ! term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; else if (version == 136 && arg[2] == 0) { ! term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; ! // PuTTY sends 0;136;0 ! if (arg[0] == 0) ! { ! // supports sgr-like mouse reporting. ! term_props[TPR_MOUSE].tpr_status = TPR_MOUSE_SGR; ! } ! // vandyke SecureCRT sends 1;136;0 } // Konsole sends 0;115;0 else if (version == 115 && arg[0] == 0 && arg[2] == 0) ! term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; // GNU screen sends 83;30600;0, 83;40500;0, etc. ! // 30600/40500 is a version number of GNU screen. DA2 support is added ! // on 3.6. DCS string has a special meaning to GNU screen, but xterm ! // compatibility checking does not detect GNU screen. ! if (arg[0] == 83 && arg[1] >= 30600) ! { ! term_props[TPR_CURSOR_STYLE].tpr_status = TPR_NO; ! term_props[TPR_CURSOR_BLINK].tpr_status = TPR_NO; ! } // Xterm first responded to this request at patch level ! // 95, so assume anything below 95 is not xterm and hopefully supports ! // the underline RGB color sequence. if (version < 95) ! term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES; ! // Getting the cursor style is only supported properly by xterm since ! // version 279 (otherwise it returns 0x18). ! if (version < 279) ! term_props[TPR_CURSOR_STYLE].tpr_status = TPR_NO; ! ! /* ! * Take action on the detected properties. ! */ ! ! // Unless the underline RGB color is expected to work, disable "t_8u". ! // It does not work for the real Xterm, it resets the background color. ! if (term_props[TPR_UNDERLINE_RGB].tpr_status == TPR_YES && *T_8U != NUL) T_8U = empty_option; + // Only set 'ttymouse' automatically if it was not set + // by the user already. + if (!option_was_set((char_u *)"ttym") + && (term_props[TPR_MOUSE].tpr_status == TPR_MOUSE_XTERM2 + || term_props[TPR_MOUSE].tpr_status == TPR_MOUSE_SGR)) + { + set_option_value((char_u *)"ttym", 0L, + term_props[TPR_MOUSE].tpr_status == TPR_MOUSE_SGR + ? (char_u *)"sgr" : (char_u *)"xterm2", 0); + } + // Only request the cursor style if t_SH and t_RS are // set. Only supported properly by xterm since version // 279 (otherwise it returns 0x18). ! // Only when getting the cursor style was detected to work. // Not for Terminal.app, it can't handle t_RS, it // echoes the characters to the screen. if (rcs_status.tr_progress == STATUS_GET ! && term_props[TPR_CURSOR_STYLE].tpr_status == TPR_YES && *T_CSH != NUL && *T_CRS != NUL) { *************** *** 4603,4613 **** // Only request the cursor blink mode if t_RC set. Not // for Gnome terminal, it can't handle t_RC, it // echoes the characters to the screen. ! // Only when the xcc_status was set, the test finished, ! // and xcc_test_failed is FALSE; if (rbm_status.tr_progress == STATUS_GET ! && xcc_status.tr_progress == STATUS_GOT ! && !xcc_test_failed && *T_CRC != NUL) { LOG_TR(("Sending cursor blink mode request")); --- 4694,4702 ---- // Only request the cursor blink mode if t_RC set. Not // for Gnome terminal, it can't handle t_RC, it // echoes the characters to the screen. ! // Only when getting the cursor style was detected to work. if (rbm_status.tr_progress == STATUS_GET ! && term_props[TPR_CURSOR_BLINK].tpr_status == TPR_YES && *T_CRC != NUL) { LOG_TR(("Sending cursor blink mode request")); *************** *** 4681,4689 **** /* * Handle a CSI escape sequence. ! * - Xterm version string: {lead}>{x};{vers};{y}c ! * Also eat other possible responses to t_RV, rxvt returns ! * "{lead}?1;2c". * * - Cursor position report: {lead}{row};{col}R * The final byte must be 'R'. It is used for checking the --- 4770,4776 ---- /* * Handle a CSI escape sequence. ! * - Xterm version string. * * - Cursor position report: {lead}{row};{col}R * The final byte must be 'R'. It is used for checking the *** ../vim-8.2.0940/src/version.c 2020-06-09 21:35:32.546431760 +0200 --- src/version.c 2020-06-10 12:15:29.307991901 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 941, /**/ -- LAUNCELOT leaps into SHOT with a mighty cry and runs the GUARD through and hacks him to the floor. Blood. Swashbuckling music (perhaps). LAUNCELOT races through into the castle screaming. SECOND SENTRY: Hey! "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///