Patch 9.0.0980
Problem:    The keyboard state response may end up in a shell command.
Solution:   Only request the keyboard protocol state when the typeahead is
            empty, no more commands are following and not exiting.  Add the
            t_RK termcap entry for this.
Files:      runtime/doc/term.txt, runtime/doc/map.txt, src/term.c,
            src/proto/term.pro, src/termdefs.h, src/edit.c, src/normal.c,
            src/os_unix.c, src/main.c, src/proto/main.pro, src/ex_getln.c


*** ../vim-9.0.0979/runtime/doc/term.txt        2022-11-25 15:09:30.710402884 
+0000
--- runtime/doc/term.txt        2022-12-01 11:09:35.145283059 +0000
***************
*** 90,95 ****
--- 90,100 ----
  alternate screen.  This may slightly change what happens when executing a
  shell command or exiting Vim.  To avoid this use 't_TI' and 't_TE'.
  
+ Vim will try to detect what keyboard protocol the terminal is using with the
+ 't_RK' termcap entry.  This is sent after 't_TI', but only when there is no
+ work to do (no typeahead and no pending commands).  That is to avoid the
+ response to end up in a shell command or arrive after Vim exits.
+ 
                                                *xterm-bracketed-paste*
  When the 't_BE' option is set then 't_BE' will be sent to the
  terminal when entering "raw" mode and 't_BD' when leaving "raw" mode.  The
***************
*** 388,393 ****
--- 393,400 ----
                xterm and other terminal emulators)  The
                response is stored in |v:termresponse| |xterm-8bit|
                |'ttymouse'| |xterm-codes|
+       t_RK    request terminal keyboard protocol state;       *t_RK* *'t_RK'*
+               sent after |t_TI|
        t_u7    request cursor position (for xterm)             *t_u7* *'t_u7'*
                see |'ambiwidth'|
                The response is stored in |v:termu7resp|
*** ../vim-9.0.0979/runtime/doc/map.txt 2022-11-24 13:27:32.385881078 +0000
--- runtime/doc/map.txt 2022-12-01 11:53:45.407249388 +0000
***************
*** 993,1002 ****
  WARNING: if you map <C-[> you may very well break any key codes that start
  with Esc.  Make sure it comes AFTER other mappings.
  
! Vim automatically detects if the modifyOtherKeys mode was enabled when it
! spots an escape sequence that must have been created by it.  To see if Vim
! detected such an escape sequence use `:verbose map`, the first line will then
! show "Seen modifyOtherKeys: true" (possibly translated).
  
  This automatic detection depends on receiving an escape code starting with 
  "<1b>[27;".  This is the normal way xterm sends these key codes.  However, if
--- 1001,1015 ----
  WARNING: if you map <C-[> you may very well break any key codes that start
  with Esc.  Make sure it comes AFTER other mappings.
  
! Starting with xterm version 377 Vim can detect the modifyOtherKeys state by
! requesting it.  For this the 't_RK' termcap entry is used.  When the response
! is found then Vim will know whether modifyOtherKeys level 2 is enabled, and
! handle mappings accordingly.
! 
! Before version 377 Vim automatically detects if the modifyOtherKeys mode was
! enabled when it spots an escape sequence that must have been created by it.
! To see if Vim detected such an escape sequence use `:verbose map`, the first
! line will then show "Seen modifyOtherKeys: true" (possibly translated).
  
  This automatic detection depends on receiving an escape code starting with 
  "<1b>[27;".  This is the normal way xterm sends these key codes.  However, if
***************
*** 1008,1013 ****
--- 1021,1029 ----
  enabled: In Insert mode type CTRL-SHIFT-V CTRL-V, if you get one byte then
  modifyOtherKeys is off, if you get <1b>[27;5;118~ then it is on.
  
+ Note that xterm up to version 376 has a bug that makes Shift-Esc send a
+ regular Esc code, the Shift modifier is dropped.
+ 
  When the 'esckeys' option is off, then modifyOtherKeys will be disabled in
  Insert mode to avoid every key with a modifier causing Insert mode to end.
  
*** ../vim-9.0.0979/src/term.c  2022-11-30 18:11:52.694904295 +0000
--- src/term.c  2022-12-01 11:32:08.563300766 +0000
***************
*** 452,458 ****
      {(int)KS_TI,      "\0337\033[?47h"},
      {(int)KS_TE,      "\033[?47l\0338"},
  #  endif
!     {(int)KS_CTI,     "\033[>4;2m\033[?4m"},  // see "builtin_mok2"
      {(int)KS_CTE,     "\033[>4;m"},
      {(int)KS_CIS,     "\033]1;"},
      {(int)KS_CIE,     "\007"},
--- 452,459 ----
      {(int)KS_TI,      "\0337\033[?47h"},
      {(int)KS_TE,      "\033[?47l\0338"},
  #  endif
!     {(int)KS_CTI,     "\033[>4;2m"},
!     {(int)KS_CRK,     "\033[?4m"},  // see "builtin_mok2"
      {(int)KS_CTE,     "\033[>4;m"},
      {(int)KS_CIS,     "\033]1;"},
      {(int)KS_CIE,     "\007"},
***************
*** 593,602 ****
   * xterm.
   */
  static tcap_entry_T builtin_mok2[] = {
      // XTQMODKEYS was added in xterm version 377: "CSI ? 4 m" which should
      // return "{lead} > 4 ; Pv m".  Before version 377 we expect it to have no
      // effect.
!     {(int)KS_CTI,     "\033[>4;2m\033[?4m"},
      {(int)KS_CTE,     "\033[>4;m"},
  
      {(int)KS_NAME,    NULL}  // end marker
--- 594,608 ----
   * xterm.
   */
  static tcap_entry_T builtin_mok2[] = {
+     // t_TI enables modifyOtherKeys level 2
+     {(int)KS_CTI,     "\033[>4;2m"},
+ 
      // XTQMODKEYS was added in xterm version 377: "CSI ? 4 m" which should
      // return "{lead} > 4 ; Pv m".  Before version 377 we expect it to have no
      // effect.
!     {(int)KS_CRK,     "\033[?4m"},
! 
!     // t_TE disables modifyOtherKeys
      {(int)KS_CTE,     "\033[>4;m"},
  
      {(int)KS_NAME,    NULL}  // end marker
***************
*** 606,616 ****
   * Additions for using the Kitty keyboard protocol.
   */
  static tcap_entry_T builtin_kitty[] = {
!     // t_TI enables the kitty keyboard protocol, requests the kitty keyboard
!     // protocol state and requests the version response.
!     {(int)KS_CTI,     "\033[=1;1u\033[?u\033[>c"},
  
!     // t_TE also disabled modifyOtherKeys, because t_TI from xterm may already
      // have been used.
      {(int)KS_CTE,     "\033[>4;m\033[=0;1u"},
  
--- 612,624 ----
   * Additions for using the Kitty keyboard protocol.
   */
  static tcap_entry_T builtin_kitty[] = {
!     // t_TI enables the kitty keyboard protocol.
!     {(int)KS_CTI,     "\033[=1;1u"},
! 
!     // t_RK requests the kitty keyboard protocol state
!     {(int)KS_CRK,     "\033[?u"},
  
!     // t_TE also disables modifyOtherKeys, because t_TI from xterm may already
      // have been used.
      {(int)KS_CTE,     "\033[>4;m\033[=0;1u"},
  
***************
*** 1685,1691 ****
                        {KS_CM, "cm"}, {KS_SR, "sr"},
                        {KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
                        {KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
!                       {KS_CTI, "TI"}, {KS_CTE, "TE"},
                        {KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
                        {KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_CAU,"AU"},
                        {KS_LE, "le"},
--- 1693,1699 ----
                        {KS_CM, "cm"}, {KS_SR, "sr"},
                        {KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
                        {KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
!                       {KS_CTI, "TI"}, {KS_CRK, "RK"}, {KS_CTE, "TE"},
                        {KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
                        {KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_CAU,"AU"},
                        {KS_LE, "le"},
***************
*** 3693,3698 ****
--- 3701,3740 ----
        kitty_protocol_state = KKPS_AFTER_T_KE;
  }
  
+ static int send_t_RK = FALSE;
+ 
+ /*
+  * Output T_TI and setup for what follows.
+  */
+     void
+ out_str_t_TI(void)
+ {
+     out_str(T_CTI);
+ 
+     // Send t_RK when there is no more work to do.
+     send_t_RK = TRUE;
+ }
+ 
+ /*
+  * If t_TI was recently sent and there is no typeahead or work to do, now send
+  * t_RK.  This is postponed to avoid the response arriving in a shell command
+  * or after Vim exits.
+  */
+     void
+ may_send_t_RK(void)
+ {
+     if (send_t_RK
+           && !work_pending()
+           && !ex_normal_busy
+           && !in_feedkeys
+           && !exiting)
+     {
+       send_t_RK = FALSE;
+       out_str(T_CRK);
+       out_flush();
+     }
+ }
+ 
  /*
   * Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
   * commands and Ex mode).
***************
*** 3751,3757 ****
                {
                    out_str(T_BE);      // enable bracketed paste mode (should
                                        // be before mch_settmode().
!                   out_str(T_CTI);     // possibly enables modifyOtherKeys
                }
            }
            out_flush();
--- 3793,3799 ----
                {
                    out_str(T_BE);      // enable bracketed paste mode (should
                                        // be before mch_settmode().
!                   out_str_t_TI();     // possibly enables modifyOtherKeys
                }
            }
            out_flush();
***************
*** 3775,3781 ****
        MAY_WANT_TO_LOG_THIS;
  
        out_str(T_TI);                  // start termcap mode
!       out_str(T_CTI);                 // start "raw" mode
        out_str(T_KS);                  // start "keypad transmit" mode
        out_str(T_BE);                  // enable bracketed paste mode
  
--- 3817,3823 ----
        MAY_WANT_TO_LOG_THIS;
  
        out_str(T_TI);                  // start termcap mode
!       out_str_t_TI();                 // start "raw" mode
        out_str(T_KS);                  // start "keypad transmit" mode
        out_str(T_BE);                  // enable bracketed paste mode
  
*** ../vim-9.0.0979/src/proto/term.pro  2022-11-23 20:19:17.129682462 +0000
--- src/proto/term.pro  2022-12-01 11:38:39.243456607 +0000
***************
*** 48,53 ****
--- 48,55 ----
  void shell_resized_check(void);
  void set_shellsize(int width, int height, int mustset);
  void out_str_t_TE(void);
+ void out_str_t_TI(void);
+ void may_send_t_RK(void);
  void settmode(tmode_T tmode);
  void starttermcap(void);
  void stoptermcap(void);
*** ../vim-9.0.0979/src/termdefs.h      2022-06-29 18:39:05.011841452 +0100
--- src/termdefs.h      2022-12-01 11:23:24.078950857 +0000
***************
*** 69,74 ****
--- 69,75 ----
      KS_KE,    // out of "keypad transmit" mode
      KS_TI,    // put terminal in termcap mode
      KS_CTI,   // put terminal in "raw" mode
+     KS_CRK,   // request keyboard protocol state
      KS_TE,    // end of termcap mode
      KS_CTE,   // end of "raw" mode
      KS_BC,    // backspace character (cursor left)
***************
*** 177,182 ****
--- 178,184 ----
  #define T_KE  (TERM_STR(KS_KE))       // out of "keypad transmit" mode
  #define T_TI  (TERM_STR(KS_TI))       // put terminal in termcap mode
  #define T_CTI (TERM_STR(KS_CTI))      // put terminal in "raw" mode
+ #define T_CRK (TERM_STR(KS_CRK))      // request keyboard protocol status
  #define T_TE  (TERM_STR(KS_TE))       // end of termcap mode
  #define T_CTE (TERM_STR(KS_CTE))      // end of "raw" mode
  #define T_BC  (TERM_STR(KS_BC))       // backspace character
*** ../vim-9.0.0979/src/edit.c  2022-11-23 20:19:17.129682462 +0000
--- src/edit.c  2022-12-01 11:36:12.163404016 +0000
***************
*** 571,576 ****
--- 571,578 ----
  #ifdef USE_ON_FLY_SCROLL
        dont_scroll = FALSE;            // allow scrolling here
  #endif
+       // May request the keyboard protocol state now.
+       may_send_t_RK();
  
        /*
         * Get a character for Insert mode.  Ignore K_IGNORE and K_NOP.
***************
*** 1479,1485 ****
        aco_save_T      aco;
        varnumber_T     tick = CHANGEDTICK(curbuf);
  
!       // save and restore curwin and curbuf, in case the autocmd changes them
        aucmd_prepbuf(&aco, curbuf);
        apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
        aucmd_restbuf(&aco);
--- 1481,1488 ----
        aco_save_T      aco;
        varnumber_T     tick = CHANGEDTICK(curbuf);
  
!       // Save and restore curwin and curbuf, in case the autocmd changes
!       // them.
        aucmd_prepbuf(&aco, curbuf);
        apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
        aucmd_restbuf(&aco);
***************
*** 1499,1505 ****
        aco_save_T      aco;
        varnumber_T     tick = CHANGEDTICK(curbuf);
  
!       // save and restore curwin and curbuf, in case the autocmd changes them
        aucmd_prepbuf(&aco, curbuf);
        apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
        aucmd_restbuf(&aco);
--- 1502,1509 ----
        aco_save_T      aco;
        varnumber_T     tick = CHANGEDTICK(curbuf);
  
!       // Save and restore curwin and curbuf, in case the autocmd changes
!       // them.
        aucmd_prepbuf(&aco, curbuf);
        apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
        aucmd_restbuf(&aco);
***************
*** 3706,3712 ****
        out_str(T_BE);
  
        // Re-enable modifyOtherKeys.
!       out_str(T_CTI);
      }
  #ifdef FEAT_CONCEAL
      // Check if the cursor line needs redrawing after changing State.  If
--- 3710,3716 ----
        out_str(T_BE);
  
        // Re-enable modifyOtherKeys.
!       out_str_t_TI();
      }
  #ifdef FEAT_CONCEAL
      // Check if the cursor line needs redrawing after changing State.  If
***************
*** 4384,4389 ****
--- 4388,4394 ----
        do
            c = vgetc();
        while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
+ 
        if (c == NUL || got_int || (ex_normal_busy > 0 && c == Ctrl_C))
            // When CTRL-C was encountered the typeahead will be flushed and we
            // won't get the end sequence.  Except when using ":normal".
*** ../vim-9.0.0979/src/normal.c        2022-11-25 13:03:28.200437332 +0000
--- src/normal.c        2022-12-01 11:16:03.034352695 +0000
***************
*** 455,461 ****
  
            // Re-enable bracketed paste mode and modifyOtherKeys
            out_str(T_BE);
!           out_str(T_CTI);
        }
  
        if (langmap_active)
--- 455,461 ----
  
            // Re-enable bracketed paste mode and modifyOtherKeys
            out_str(T_BE);
!           out_str_t_TI();
        }
  
        if (langmap_active)
*** ../vim-9.0.0979/src/os_unix.c       2022-11-30 18:11:52.690904297 +0000
--- src/os_unix.c       2022-12-01 11:16:20.714386050 +0000
***************
*** 5379,5385 ****
  
                if (tmode == TMODE_RAW)
                    // possibly enables modifyOtherKeys again
!                   out_str(T_CTI);
            }
  # endif
  
--- 5379,5385 ----
  
                if (tmode == TMODE_RAW)
                    // possibly enables modifyOtherKeys again
!                   out_str_t_TI();
            }
  # endif
  
*** ../vim-9.0.0979/src/main.c  2022-11-30 18:11:52.690904297 +0000
--- src/main.c  2022-12-01 11:38:13.243447838 +0000
***************
*** 1133,1146 ****
        // of calling feedkeys(), we check if it's now safe again (all keys
        // were consumed).
        was_safe = is_safe_now();
! #ifdef FEAT_EVAL
        if (was_safe)
            ch_log(NULL, "SafeState: undo reset");
! #endif
      }
      if (was_safe)
      {
! #ifdef FEAT_EVAL
        // Only do this message when another message was given, otherwise we
        // get lots of them.
        if ((did_repeated_msg & REPEATED_MSG_SAFESTATE) == 0)
--- 1133,1146 ----
        // of calling feedkeys(), we check if it's now safe again (all keys
        // were consumed).
        was_safe = is_safe_now();
! # ifdef FEAT_EVAL
        if (was_safe)
            ch_log(NULL, "SafeState: undo reset");
! # endif
      }
      if (was_safe)
      {
! # ifdef FEAT_EVAL
        // Only do this message when another message was given, otherwise we
        // get lots of them.
        if ((did_repeated_msg & REPEATED_MSG_SAFESTATE) == 0)
***************
*** 1151,1167 ****
                      "SafeState: back to waiting, triggering SafeStateAgain");
            did_repeated_msg = did | REPEATED_MSG_SAFESTATE;
        }
! #endif
        apply_autocmds(EVENT_SAFESTATEAGAIN, NULL, NULL, FALSE, curbuf);
      }
! #ifdef FEAT_EVAL
      else
        ch_log(NULL,
                  "SafeState: back to waiting, not triggering SafeStateAgain");
! #endif
  }
  #endif
  
  
  /*
   * Main loop: Execute Normal mode commands until exiting Vim.
--- 1151,1176 ----
                      "SafeState: back to waiting, triggering SafeStateAgain");
            did_repeated_msg = did | REPEATED_MSG_SAFESTATE;
        }
! # endif
        apply_autocmds(EVENT_SAFESTATEAGAIN, NULL, NULL, FALSE, curbuf);
      }
! # ifdef FEAT_EVAL
      else
        ch_log(NULL,
                  "SafeState: back to waiting, not triggering SafeStateAgain");
! # endif
  }
  #endif
  
+ /*
+  * Return TRUE if there is any typeahead, pending operator or command.
+  */
+     int
+ work_pending(void)
+ {
+     return op_pending() || !is_safe_now();
+ }
+ 
  
  /*
   * Main loop: Execute Normal mode commands until exiting Vim.
***************
*** 1477,1486 ****
            gui_mouse_correct();
  #endif
  
!       /*
!        * Update w_curswant if w_set_curswant has been set.
!        * Postponed until here to avoid computing w_virtcol too often.
!        */
        update_curswant();
  
  #ifdef FEAT_EVAL
--- 1486,1496 ----
            gui_mouse_correct();
  #endif
  
!       // May request the keyboard protocol state now.
!       may_send_t_RK();
! 
!       // Update w_curswant if w_set_curswant has been set.
!       // Postponed until here to avoid computing w_virtcol too often.
        update_curswant();
  
  #ifdef FEAT_EVAL
*** ../vim-9.0.0979/src/proto/main.pro  2022-09-24 13:10:00.739938625 +0100
--- src/proto/main.pro  2022-12-01 11:38:34.719455102 +0000
***************
*** 9,14 ****
--- 9,15 ----
  void state_no_longer_safe(char *reason);
  int get_was_safe_state(void);
  void may_trigger_safestateagain(void);
+ int work_pending(void);
  void main_loop(int cmdwin, int noexmode);
  void getout_preserve_modified(int exitval);
  void getout(int exitval);
*** ../vim-9.0.0979/src/ex_getln.c      2022-11-17 11:34:33.333726348 +0000
--- src/ex_getln.c      2022-12-01 11:37:11.083425840 +0000
***************
*** 2908,2913 ****
--- 2908,2916 ----
        long    sw;
        char_u *s;
  
+       // May request the keyboard protocol state now.
+       may_send_t_RK();
+ 
        if (ga_grow(&line_ga, 40) == FAIL)
            break;
  
*** ../vim-9.0.0979/src/version.c       2022-12-01 11:02:19.288680405 +0000
--- src/version.c       2022-12-01 11:07:10.764647255 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     980,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
191. You rate eating establishments not by the quality of the food,
     but by the availability of electrical outlets for your PowerBook.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221201120418.B759F1C06AE%40moolenaar.net.

Raspunde prin e-mail lui