Patch 9.0.0387
Problem:    repeating a <ScriptCmd> mapping does not use the right script
            context.
Solution:   When using a mapping put <SID>{sid}; in the redo buffer.
            (closes #11049)
Files:      src/getchar.c, src/proto/getchar.pro, src/keymap.h, src/normal.c,
            src/testdir/test_mapping.vim


*** ../vim-9.0.0386/src/getchar.c       2022-09-05 13:05:26.034229996 +0100
--- src/getchar.c       2022-09-05 16:50:04.679709793 +0100
***************
*** 85,90 ****
--- 85,91 ----
  
  #ifdef FEAT_EVAL
  mapblock_T    *last_used_map = NULL;
+ int           last_used_sid = -1;
  #endif
  
  static int    read_readbuf(buffheader_T *buf, int advance);
***************
*** 837,842 ****
--- 838,859 ----
  
      c = read_redo(FALSE, old_redo);
  
+ #ifdef FEAT_EVAL
+     if (c == K_SID)
+     {
+       // Copy the <SID>{sid}; sequence
+       add_char_buff(&readbuf2, c);
+       for (;;)
+       {
+           c = read_redo(FALSE, old_redo);
+           add_char_buff(&readbuf2, c);
+           if (!isdigit(c))
+               break;
+       }
+       c = read_redo(FALSE, old_redo);
+     }
+ #endif
+ 
      // copy the buffer name, if present
      if (c == '"')
      {
***************
*** 876,882 ****
        add_num_buff(&readbuf2, count);
      }
  
!     // copy from the redo buffer into the stuff buffer
      add_char_buff(&readbuf2, c);
      copy_redo(old_redo);
      return OK;
--- 893,899 ----
        add_num_buff(&readbuf2, count);
      }
  
!     // copy the rest from the redo buffer into the stuff buffer
      add_char_buff(&readbuf2, c);
      copy_redo(old_redo);
      return OK;
***************
*** 1796,1802 ****
--- 1813,1833 ----
                if (c == K_CSI)
                    c = CSI;
  #endif
+ #ifdef FEAT_EVAL
+               if (c == K_SID)
+               {
+                   int     j;
+ 
+                   // Handle <SID>{sid};  Do up to 20 digits for safety.
+                   last_used_sid = 0;
+                   for (j = 0; j < 20 && isdigit(c = vgetorpeek(TRUE)); ++j)
+                       last_used_sid = last_used_sid * 10 + (c - '0');
+                   last_used_map = NULL;
+                   continue;
+               }
+ #endif
            }
+ 
            // a keypad or special function key was not mapped, use it like
            // its ASCII equivalent
            switch (c)
***************
*** 2922,2927 ****
--- 2953,2962 ----
        {
            int noremap;
  
+ #ifdef FEAT_EVAL
+           last_used_map = mp;
+           last_used_sid = -1;
+ #endif
            if (save_m_noremap != REMAP_YES)
                noremap = save_m_noremap;
            else if (
***************
*** 2940,2946 ****
  #ifdef FEAT_EVAL
            if (save_m_expr)
                vim_free(map_str);
-           last_used_map = mp;
  #endif
        }
  #ifdef FEAT_EVAL
--- 2975,2980 ----
***************
*** 3896,3901 ****
--- 3930,3958 ----
      return (char_u *)line_ga.ga_data;
  }
  
+ #if defined(FEAT_EVAL) || defined(PROTO)
+ /*
+  * If there was a mapping put info about it in the redo buffer, so that "."
+  * will use the same script context.  We only need the SID.
+  */
+     void
+ may_add_last_used_map_to_redobuff(void)
+ {
+     char_u buf[3 + 20];
+ 
+     if (last_used_map == NULL || last_used_map->m_script_ctx.sc_sid < 0)
+       return;
+ 
+     // <K_SID>{nr};
+     buf[0] = K_SPECIAL;
+     buf[1] = KS_EXTRA;
+     buf[2] = KE_SID;
+     vim_snprintf((char *)buf + 3, 20, "%d;",
+                                          last_used_map->m_script_ctx.sc_sid);
+     add_buff(&redobuff, buf, -1L);
+ }
+ #endif
+ 
      int
  do_cmdkey_command(int key UNUSED, int flags)
  {
***************
*** 3903,3912 ****
  #ifdef FEAT_EVAL
      sctx_T  save_current_sctx = {-1, 0, 0, 0};
  
!     if (key == K_SCRIPT_COMMAND && last_used_map != NULL)
      {
        save_current_sctx = current_sctx;
!       current_sctx = last_used_map->m_script_ctx;
      }
  #endif
  
--- 3960,3977 ----
  #ifdef FEAT_EVAL
      sctx_T  save_current_sctx = {-1, 0, 0, 0};
  
!     if (key == K_SCRIPT_COMMAND
!                 && (last_used_map != NULL || SCRIPT_ID_VALID(last_used_sid)))
      {
        save_current_sctx = current_sctx;
!       if (last_used_map != NULL)
!           current_sctx = last_used_map->m_script_ctx;
!       else
!       {
!           current_sctx.sc_sid = last_used_sid;
!           current_sctx.sc_lnum = 0;
!           current_sctx.sc_version = SCRIPT_ITEM(last_used_sid)->sn_version;
!       }
      }
  #endif
  
***************
*** 3925,3930 ****
--- 3990,3998 ----
  reset_last_used_map(mapblock_T *mp)
  {
      if (last_used_map == mp)
+     {
        last_used_map = NULL;
+       last_used_sid = -1;
+     }
  }
  #endif
*** ../vim-9.0.0386/src/proto/getchar.pro       2022-06-27 23:15:07.000000000 
+0100
--- src/proto/getchar.pro       2022-09-05 15:48:38.243636493 +0100
***************
*** 52,57 ****
--- 52,58 ----
  void vungetc(int c);
  int fix_input_buffer(char_u *buf, int len);
  int input_available(void);
+ void may_add_last_used_map_to_redobuff(void);
  int do_cmdkey_command(int key, int flags);
  void reset_last_used_map(mapblock_T *mp);
  /* vim: set ft=c : */
*** ../vim-9.0.0386/src/keymap.h        2022-05-09 19:16:21.000000000 +0100
--- src/keymap.h        2022-09-05 15:11:28.574604295 +0100
***************
*** 277,282 ****
--- 277,283 ----
      , KE_COMMAND = 103                // <Cmd> special key
      , KE_SCRIPT_COMMAND = 104 // <ScriptCmd> special key
      , KE_S_BS = 105           // shift + <BS>
+     , KE_SID = 106            // <SID> special key, followed by {nr};
  };
  
  /*
***************
*** 483,488 ****
--- 484,490 ----
  
  #define K_COMMAND     TERMCAP2KEY(KS_EXTRA, KE_COMMAND)
  #define K_SCRIPT_COMMAND TERMCAP2KEY(KS_EXTRA, KE_SCRIPT_COMMAND)
+ #define K_SID         TERMCAP2KEY(KS_EXTRA, KE_SID)
  
  // Bits for modifier mask
  // 0x01 cannot be used, because the modifier must be 0x02 or higher
*** ../vim-9.0.0386/src/normal.c        2022-08-31 14:46:07.907016957 +0100
--- src/normal.c        2022-09-05 15:48:22.403657169 +0100
***************
*** 1466,1471 ****
--- 1466,1478 ----
      int           cmd5)
  {
      ResetRedobuff();
+ 
+ #ifdef FEAT_EVAL
+     // Put info about a mapping in the redo buffer, so that "." will use the
+     // same script context.
+     may_add_last_used_map_to_redobuff();
+ #endif
+ 
      if (regname != 0) // yank from specified buffer
      {
        AppendCharToRedobuff('"');
*** ../vim-9.0.0386/src/testdir/test_mapping.vim        2022-07-01 
16:35:38.406031649 +0100
--- src/testdir/test_mapping.vim        2022-09-05 16:39:55.404396060 +0100
***************
*** 1529,1534 ****
--- 1529,1563 ----
    autocmd! CmdlineEnter
  endfunc
  
+ func Test_map_script_cmd_redo()
+   call mkdir('Xmapcmd')
+   let lines =<< trim END
+       vim9script
+       import autoload './script.vim'
+       onoremap <F3> <ScriptCmd>script.Func()<CR>
+   END
+   call writefile(lines, 'Xmapcmd/plugin.vim')
+ 
+   let lines =<< trim END
+       vim9script
+       export def Func()
+         normal! dd
+       enddef
+   END
+   call writefile(lines, 'Xmapcmd/script.vim')
+   new
+   call setline(1, ['one', 'two', 'three', 'four'])
+   nnoremap j j
+   source Xmapcmd/plugin.vim
+   call feedkeys("d\<F3>j.", 'xt')
+   call assert_equal(['two', 'four'], getline(1, '$'))
+ 
+   ounmap <F3>
+   nunmap j
+   call delete('Xmapcmd', 'rf')
+   bwipe!
+ endfunc
+ 
  " Test for using <script> with a map to remap characters in rhs
  func Test_script_local_remap()
    new
*** ../vim-9.0.0386/src/version.c       2022-09-05 14:33:42.202419990 +0100
--- src/version.c       2022-09-05 16:51:56.031577969 +0100
***************
*** 705,706 ****
--- 705,708 ----
  {   /* Add new patch number below this line */
+ /**/
+     387,
  /**/

-- 
Everybody wants to go to heaven, but nobody wants to die.

 /// 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/20220905155407.0B9C81C0CE4%40moolenaar.net.

Raspunde prin e-mail lui