Patch 8.2.4748
Problem:    Cannot use an imported function in a mapping.
Solution:   Recognize <SID>name.Func.
Files:      runtime/doc/vim9.txt, src/term.c, src/vim9execute.c,
            src/proto/vim9execute.pro, src/scriptfile.c,
            src/testdir/test_vim9_import.vim


*** ../vim-8.2.4747/runtime/doc/vim9.txt        2022-04-10 11:26:00.941539608 
+0100
--- runtime/doc/vim9.txt        2022-04-14 12:55:06.633007990 +0100
***************
*** 1542,1548 ****
                name   # Error!
        echo that
                .name  # Error!
! <                                                     *:import-cycle*
  The `import` commands are executed when encountered.  If script A imports
  script B, and B (directly or indirectly) imports A, this will be skipped over.
  At this point items in A after "import B" will not have been processed and
--- 1720,1734 ----
                name   # Error!
        echo that
                .name  # Error!
! 
! To refer to a function in an imported script in a mapping, |<SID>| can be
! used: >
!       noremap <silent> ,a :call <SID>name.Function()<CR>
! 
! When the mapping is defined "<SID>name." will be replaced with <SNR> and the
! script ID of the imported script.
! 
!                                                       *:import-cycle*
  The `import` commands are executed when encountered.  If script A imports
  script B, and B (directly or indirectly) imports A, this will be skipped over.
  At this point items in A after "import B" will not have been processed and
*** ../vim-8.2.4747/src/term.c  2022-03-09 13:00:50.776824777 +0000
--- src/term.c  2022-04-14 12:07:46.058053594 +0100
***************
*** 6010,6017 ****
        {
  #ifdef FEAT_EVAL
            /*
!            * Replace <SID> by K_SNR <script-nr> _.
             * (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
             */
            if (STRNICMP(src, "<SID>", 5) == 0)
            {
--- 6010,6020 ----
        {
  #ifdef FEAT_EVAL
            /*
!            * Change <SID>Func to K_SNR <script-nr> _Func.  This name is used
!            * for script-locla user functions.
             * (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
+            * Also change <SID>name.Func to K_SNR <import-script-nr> _Func.
+            * Only if "name" is recognized as an import.
             */
            if (STRNICMP(src, "<SID>", 5) == 0)
            {
***************
*** 6019,6030 ****
                    emsg(_(e_using_sid_not_in_script_context));
                else
                {
                    src += 5;
                    result[dlen++] = K_SPECIAL;
                    result[dlen++] = (int)KS_EXTRA;
                    result[dlen++] = (int)KE_SNR;
!                   sprintf((char *)result + dlen, "%ld",
!                                                   (long)current_sctx.sc_sid);
                    dlen += (int)STRLEN(result + dlen);
                    result[dlen++] = '_';
                    continue;
--- 6022,6047 ----
                    emsg(_(e_using_sid_not_in_script_context));
                else
                {
+                   char_u  *dot;
+                   long    sid = current_sctx.sc_sid;
+ 
                    src += 5;
+                   if (in_vim9script()
+                                      && (dot = vim_strchr(src, '.')) != NULL)
+                   {
+                       imported_T *imp = find_imported(src, dot - src, FALSE);
+ 
+                       if (imp != NULL)
+                       {
+                           sid = imp->imp_sid;
+                           src = dot + 1;
+                       }
+                   }
+ 
                    result[dlen++] = K_SPECIAL;
                    result[dlen++] = (int)KS_EXTRA;
                    result[dlen++] = (int)KE_SNR;
!                   sprintf((char *)result + dlen, "%ld", sid);
                    dlen += (int)STRLEN(result + dlen);
                    result[dlen++] = '_';
                    continue;
*** ../vim-8.2.4747/src/vim9execute.c   2022-04-05 21:40:32.107458262 +0100
--- src/vim9execute.c   2022-04-14 12:39:01.904659075 +0100
***************
*** 1658,1663 ****
--- 1658,1686 ----
      return OK;
  }
  
+ /*
+  * If script "sid" is not loaded yet then load it now.
+  * Caller must make sure "sid" is a valid script ID.
+  * "loaded" is set to TRUE if the script had to be loaded.
+  * Returns FAIL if loading fails, OK if already loaded or loaded now.
+  */
+     int
+ may_load_script(int sid, int *loaded)
+ {
+     scriptitem_T *si = SCRIPT_ITEM(sid);
+ 
+     if (si->sn_state == SN_STATE_NOT_LOADED)
+     {
+       *loaded = TRUE;
+       if (do_source(si->sn_name, FALSE, DOSO_NONE, NULL) == FAIL)
+       {
+           semsg(_(e_cant_open_file_str), si->sn_name);
+           return FAIL;
+       }
+     }
+     return OK;
+ }
+ 
  // used for v_instr of typval of VAR_INSTR
  struct instr_S {
      ectx_T    *instr_ectx;
***************
*** 2632,2649 ****
  
            case ISN_SOURCE:
                {
!                   scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.number);
! 
!                   if (si->sn_state == SN_STATE_NOT_LOADED)
!                   {
!                       SOURCING_LNUM = iptr->isn_lnum;
!                       if (do_source(si->sn_name, FALSE, DOSO_NONE, NULL)
                                                                       == FAIL)
!                       {
!                           semsg(_(e_cant_open_file_str), si->sn_name);
!                           goto on_error;
!                       }
!                   }
                }
                break;
  
--- 2655,2665 ----
  
            case ISN_SOURCE:
                {
!                   int notused;
!                   SOURCING_LNUM = iptr->isn_lnum;
!                   if (may_load_script((int)iptr->isn_arg.number, &notused)
                                                                       == FAIL)
!                       goto on_error;
                }
                break;
  
*** ../vim-8.2.4747/src/proto/vim9execute.pro   2022-03-15 15:57:00.426428445 
+0000
--- src/proto/vim9execute.pro   2022-04-14 12:38:23.248578404 +0100
***************
*** 6,11 ****
--- 6,12 ----
  char_u *char_from_string(char_u *str, varnumber_T index);
  char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int 
exclusive);
  int fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, ectx_T *ectx);
+ int may_load_script(int sid, int *loaded);
  typval_T *lookup_debug_var(char_u *name);
  int may_break_in_function(ufunc_T *ufunc);
  int exe_typval_instr(typval_T *tv, typval_T *rettv);
*** ../vim-8.2.4747/src/scriptfile.c    2022-04-09 21:41:22.266689586 +0100
--- src/scriptfile.c    2022-04-14 12:39:08.148671284 +0100
***************
*** 117,123 ****
  }
  
  /*
!  * Get the current value for <sfile> in allocated memory.
   * "which" is ESTACK_SFILE for <sfile>, ESTACK_STACK for <stack> or
   * ESTACK_SCRIPT for <script>.
   */
--- 117,123 ----
  }
  
  /*
!  * Get the current value for "which" in allocated memory.
   * "which" is ESTACK_SFILE for <sfile>, ESTACK_STACK for <stack> or
   * ESTACK_SCRIPT for <script>.
   */
***************
*** 2468,2473 ****
--- 2468,2485 ----
      int               i;
      int               ret_sid;
  
+     // If the name starts with "<SNR>123_" then "123" is the script ID.
+     if (name[0] == K_SPECIAL && name[1] == KS_EXTRA && name[2] == KE_SNR)
+     {
+       p = name + 3;
+       ret_sid = (int)getdigits(&p);
+       if (*p == '_' && SCRIPT_ID_VALID(ret_sid))
+       {
+           may_load_script(ret_sid, &ret);
+           return ret;
+       }
+     }
+ 
      // If there is no '#' after name[0] there is no package name.
      p = vim_strchr(name, AUTOLOAD_CHAR);
      if (p == NULL || p == name)
*** ../vim-8.2.4747/src/testdir/test_vim9_import.vim    2022-04-03 
21:52:47.770067812 +0100
--- src/testdir/test_vim9_import.vim    2022-04-14 12:49:06.077119932 +0100
***************
*** 642,649 ****
  def Test_use_import_in_mapping()
    var lines =<< trim END
        vim9script
!       export def Funcx()
!         g:result = 42
        enddef
    END
    writefile(lines, 'XsomeExport.vim')
--- 642,649 ----
  def Test_use_import_in_mapping()
    var lines =<< trim END
        vim9script
!       export def Funcx(nr: number)
!         g:result = nr
        enddef
    END
    writefile(lines, 'XsomeExport.vim')
***************
*** 651,668 ****
        vim9script
        import './XsomeExport.vim' as some
        var Funcy = some.Funcx
!       nnoremap <F3> :call <sid>Funcy()<cr>
    END
    writefile(lines, 'Xmapscript.vim')
  
    source Xmapscript.vim
    feedkeys("\<F3>", "xt")
    assert_equal(42, g:result)
  
    unlet g:result
    delete('XsomeExport.vim')
    delete('Xmapscript.vim')
    nunmap <F3>
  enddef
  
  def Test_use_import_in_command_completion()
--- 651,698 ----
        vim9script
        import './XsomeExport.vim' as some
        var Funcy = some.Funcx
!       nnoremap <F3> :call <sid>Funcy(42)<cr>
!       nnoremap <F4> :call <sid>some.Funcx(44)<cr>
    END
    writefile(lines, 'Xmapscript.vim')
  
    source Xmapscript.vim
    feedkeys("\<F3>", "xt")
    assert_equal(42, g:result)
+   feedkeys("\<F4>", "xt")
+   assert_equal(44, g:result)
  
    unlet g:result
    delete('XsomeExport.vim')
    delete('Xmapscript.vim')
    nunmap <F3>
+   nunmap <F4>
+ enddef
+ 
+ def Test_use_autoload_import_in_mapping()
+   var lines =<< trim END
+       vim9script
+       export def Func()
+         g:result = 42
+       enddef
+   END
+   writefile(lines, 'XautoloadExport.vim')
+   lines =<< trim END
+       vim9script
+       import autoload './XautoloadExport.vim' as some
+       nnoremap <F3> :call <SID>some.Func()<CR>
+   END
+   writefile(lines, 'Xmapscript.vim')
+ 
+   source Xmapscript.vim
+   assert_match('\d\+ A: .*XautoloadExport.vim', 
execute('scriptnames')->split("\n")[-1])
+   feedkeys("\<F3>", "xt")
+   assert_equal(42, g:result)
+ 
+   unlet g:result
+   delete('XautoloadExport.vim')
+   delete('Xmapscript.vim')
+   nunmap <F3>
  enddef
  
  def Test_use_import_in_command_completion()
*** ../vim-8.2.4747/src/version.c       2022-04-13 20:45:33.343510618 +0100
--- src/version.c       2022-04-14 12:06:20.474252051 +0100
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     4748,
  /**/

-- 
The only way the average employee can speak to an executive is by taking a
second job as a golf caddie.
                                (Scott Adams - The Dilbert principle)

 /// 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/20220414115925.BBA2A1C0EA0%40moolenaar.net.

Raspunde prin e-mail lui