Patch 8.2.4059
Problem:    Vim9: an expression of a map cannot access script-local items.
            (Maxim Kim)
Solution:   Use the script ID of where the map was defined.
Files:      src/getchar.c, src/map.c, src/proto/map.pro,
            src/testdir/test_vim9_import.vim


*** ../vim-8.2.4058/src/getchar.c       2022-01-04 18:01:17.889123524 +0000
--- src/getchar.c       2022-01-11 11:28:26.060819006 +0000
***************
*** 2785,2791 ****
        int     save_m_noremap;
        int     save_m_silent;
        char_u  *save_m_keys;
-       char_u  *save_m_str;
  #else
  # define save_m_noremap mp->m_noremap
  # define save_m_silent mp->m_silent
--- 2785,2790 ----
***************
*** 2834,2840 ****
        save_m_noremap = mp->m_noremap;
        save_m_silent = mp->m_silent;
        save_m_keys = NULL;  // only saved when needed
-       save_m_str = NULL;  // only saved when needed
  
        /*
         * Handle ":map <expr>": evaluate the {rhs} as an expression.  Also
--- 2833,2838 ----
***************
*** 2851,2858 ****
            may_garbage_collect = FALSE;
  
            save_m_keys = vim_strsave(mp->m_keys);
!           save_m_str = vim_strsave(mp->m_str);
!           map_str = eval_map_expr(save_m_str, NUL);
  
            // The mapping may do anything, but we expect it to take care of
            // redrawing.  Do put the cursor back where it was.
--- 2849,2855 ----
            may_garbage_collect = FALSE;
  
            save_m_keys = vim_strsave(mp->m_keys);
!           map_str = eval_map_expr(mp, NUL);
  
            // The mapping may do anything, but we expect it to take care of
            // redrawing.  Do put the cursor back where it was.
***************
*** 2900,2906 ****
        }
  #ifdef FEAT_EVAL
        vim_free(save_m_keys);
-       vim_free(save_m_str);
  #endif
        *keylenp = keylen;
        if (i == FAIL)
--- 2897,2902 ----
*** ../vim-8.2.4058/src/map.c   2022-01-02 20:20:41.377033186 +0000
--- src/map.c   2022-01-11 11:40:09.263727756 +0000
***************
*** 260,265 ****
--- 260,266 ----
      {
        mp->m_script_ctx.sc_sid = sid;
        mp->m_script_ctx.sc_lnum = lnum;
+       mp->m_script_ctx.sc_version = in_vim9script() ? SCRIPT_VERSION_VIM9 : 0;
      }
      else
      {
***************
*** 1565,1571 ****
            }
  #ifdef FEAT_EVAL
            if (mp->m_expr)
!               s = eval_map_expr(mp->m_str, c);
            else
  #endif
                s = mp->m_str;
--- 1566,1572 ----
            }
  #ifdef FEAT_EVAL
            if (mp->m_expr)
!               s = eval_map_expr(mp, c);
            else
  #endif
                s = mp->m_str;
***************
*** 1600,1606 ****
   */
      char_u *
  eval_map_expr(
!     char_u    *str,
      int               c)          // NUL or typed character for abbreviation
  {
      char_u    *res;
--- 1601,1607 ----
   */
      char_u *
  eval_map_expr(
!     mapblock_T        *mp,
      int               c)          // NUL or typed character for abbreviation
  {
      char_u    *res;
***************
*** 1609,1618 ****
      pos_T     save_cursor;
      int               save_msg_col;
      int               save_msg_row;
  
      // Remove escaping of CSI, because "str" is in a format to be used as
      // typeahead.
!     expr = vim_strsave(str);
      if (expr == NULL)
        return NULL;
      vim_unescape_csi(expr);
--- 1610,1621 ----
      pos_T     save_cursor;
      int               save_msg_col;
      int               save_msg_row;
+     scid_T    save_sctx_sid = current_sctx.sc_sid;
+     int               save_sctx_version = current_sctx.sc_version;
  
      // Remove escaping of CSI, because "str" is in a format to be used as
      // typeahead.
!     expr = vim_strsave(mp->m_str);
      if (expr == NULL)
        return NULL;
      vim_unescape_csi(expr);
***************
*** 1625,1636 ****
--- 1628,1649 ----
      save_cursor = curwin->w_cursor;
      save_msg_col = msg_col;
      save_msg_row = msg_row;
+     if (mp->m_script_ctx.sc_version == SCRIPT_VERSION_VIM9)
+     {
+       current_sctx.sc_sid = mp->m_script_ctx.sc_sid;
+       current_sctx.sc_version = SCRIPT_VERSION_VIM9;
+     }
+ 
+     // Note: the evaluation may make "mp" invalid.
      p = eval_to_string(expr, FALSE);
+ 
      --textwinlock;
      --ex_normal_lock;
      curwin->w_cursor = save_cursor;
      msg_col = save_msg_col;
      msg_row = save_msg_row;
+     current_sctx.sc_sid = save_sctx_sid;
+     current_sctx.sc_version = save_sctx_version;
  
      vim_free(expr);
  
*** ../vim-8.2.4058/src/proto/map.pro   2021-07-30 20:32:41.448722501 +0100
--- src/proto/map.pro   2022-01-11 11:28:31.184817355 +0000
***************
*** 10,16 ****
  char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, int 
forceit, int isabbrev, int isunmap, cmdidx_T cmdidx);
  int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file);
  int check_abbr(int c, char_u *ptr, int col, int mincol);
! char_u *eval_map_expr(char_u *str, int c);
  char_u *vim_strsave_escape_csi(char_u *p);
  void vim_unescape_csi(char_u *p);
  int makemap(FILE *fd, buf_T *buf);
--- 10,16 ----
  char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, int 
forceit, int isabbrev, int isunmap, cmdidx_T cmdidx);
  int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file);
  int check_abbr(int c, char_u *ptr, int col, int mincol);
! char_u *eval_map_expr(mapblock_T *mp, int c);
  char_u *vim_strsave_escape_csi(char_u *p);
  void vim_unescape_csi(char_u *p);
  int makemap(FILE *fd, buf_T *buf);
*** ../vim-8.2.4058/src/testdir/test_vim9_import.vim    2022-01-10 
21:38:59.635224879 +0000
--- src/testdir/test_vim9_import.vim    2022-01-11 11:48:24.502444638 +0000
***************
*** 1184,1189 ****
--- 1184,1227 ----
    &rtp = save_rtp
  enddef
  
+ def Test_autoload_mapping()
+   mkdir('Xdir/autoload', 'p')
+   var save_rtp = &rtp
+   exe 'set rtp^=' .. getcwd() .. '/Xdir'
+ 
+   var lines =<< trim END
+       vim9script autoload
+ 
+       g:toggle_loaded = 'yes'
+ 
+       export def Toggle(): string
+         return ":g:toggle_called = 'yes'\<CR>"
+       enddef
+   END
+   writefile(lines, 'Xdir/autoload/toggle.vim')
+ 
+   lines =<< trim END
+       vim9script
+ 
+       import autoload 'toggle.vim'
+ 
+       nnoremap <silent> <expr> tt toggle.Toggle() 
+   END
+   CheckScriptSuccess(lines)
+   assert_false(exists("g:toggle_loaded"))
+   assert_false(exists("g:toggle_called"))
+ 
+   feedkeys("tt", 'xt')
+   assert_equal('yes', g:toggle_loaded)
+   assert_equal('yes', g:toggle_called)
+ 
+   nunmap tt
+   unlet g:toggle_loaded
+   unlet g:toggle_called
+   delete('Xdir', 'rf')
+   &rtp = save_rtp
+ enddef
+ 
  def Test_vim9script_autoload_fails()
    var lines =<< trim END
        vim9script autoload
*** ../vim-8.2.4058/src/version.c       2022-01-10 21:38:59.635224879 +0000
--- src/version.c       2022-01-11 11:49:27.846268104 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4059,
  /**/

-- 
In his lifetime van Gogh painted 486 oil paintings. Oddly enough, 8975
of them are to be found in the United States.

 /// 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/20220111115936.975ED1C04D4%40moolenaar.net.

Raspunde prin e-mail lui