Patch 8.2.4171
Problem:    Cannot invoke option function using autoload import.
Solution:   Expand the import to an autoload function name. (closes #9578)
Files:      src/userfunc.c, src/evalvars.c, src/proto/evalvars.pro,
            src/option.c, src/testdir/test_vim9_import.vim


*** ../vim-8.2.4170/src/userfunc.c      2022-01-21 10:32:53.948494252 +0000
--- src/userfunc.c      2022-01-21 12:37:06.220819776 +0000
***************
*** 3262,3268 ****
      typval_T  rettv;
      varnumber_T       retval;
  
!     if (call_callback(callback, 0, &rettv, argcount, argvars) == FAIL)
        return -2;
  
      retval = tv_get_number_chk(&rettv, NULL);
--- 3262,3268 ----
      typval_T  rettv;
      varnumber_T       retval;
  
!     if (call_callback(callback, -1, &rettv, argcount, argvars) == FAIL)
        return -2;
  
      retval = tv_get_number_chk(&rettv, NULL);
*** ../vim-8.2.4170/src/evalvars.c      2022-01-20 21:32:50.331303977 +0000
--- src/evalvars.c      2022-01-21 13:28:32.905469173 +0000
***************
*** 3382,3403 ****
      }
      else
      {
!       if (in_vim9script() && SCRIPT_ID_VALID(current_sctx.sc_sid)
!               && SCRIPT_ITEM(current_sctx.sc_sid)->sn_autoload_prefix != NULL
!               && is_export)
!       {
!           scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
!           size_t       len = STRLEN(name) + STRLEN(si->sn_autoload_prefix) + 
1;
  
            // In a vim9 autoload script an exported variable is put in the
            // global namespace with the autoload prefix.
            var_in_autoload = TRUE;
!           varname = alloc(len);
            if (varname == NULL)
                goto failed;
            name_tofree = varname;
-           vim_snprintf((char *)varname, len, "%s%s",
-                                                si->sn_autoload_prefix, name);
            ht = &globvarht;
        }
        else
--- 3382,3401 ----
      }
      else
      {
!       scriptitem_T *si;
  
+       if (in_vim9script() && is_export
+               && SCRIPT_ID_VALID(current_sctx.sc_sid)
+               && (si = SCRIPT_ITEM(current_sctx.sc_sid))
+                                                  ->sn_autoload_prefix != NULL)
+       {
            // In a vim9 autoload script an exported variable is put in the
            // global namespace with the autoload prefix.
            var_in_autoload = TRUE;
!           varname = concat_str(si->sn_autoload_prefix, name);
            if (varname == NULL)
                goto failed;
            name_tofree = varname;
            ht = &globvarht;
        }
        else
***************
*** 4630,4635 ****
--- 4628,4667 ----
      }
  }
  
+ /*
+  * When a callback refers to an autoload import, change the function name to
+  * the "path#name" form.  Uses the current script context.
+  * Only works when the name is allocated.
+  */
+     void
+ expand_autload_callback(callback_T *cb)
+ {
+     char_u    *p;
+     imported_T        *import;
+ 
+     if (!in_vim9script() || cb->cb_name == NULL || !cb->cb_free_name)
+       return;
+     p = vim_strchr(cb->cb_name, '.');
+     if (p == NULL)
+       return;
+     import = find_imported(cb->cb_name, p - cb->cb_name, FALSE, NULL);
+     if (import != NULL && SCRIPT_ID_VALID(import->imp_sid))
+     {
+       scriptitem_T *si = SCRIPT_ITEM(import->imp_sid);
+ 
+       if (si->sn_autoload_prefix != NULL)
+       {
+           char_u *name = concat_str(si->sn_autoload_prefix, p + 1);
+ 
+           if (name != NULL)
+           {
+               vim_free(cb->cb_name);
+               cb->cb_name = name;
+           }
+       }
+     }
+ }
+ 
  /*
   * Unref/free "callback" returned by get_callback() or set_callback().
   */
*** ../vim-8.2.4170/src/proto/evalvars.pro      2022-01-07 18:20:48.370967086 
+0000
--- src/proto/evalvars.pro      2022-01-21 12:52:47.849249627 +0000
***************
*** 103,107 ****
--- 103,108 ----
  void put_callback(callback_T *cb, typval_T *tv);
  void set_callback(callback_T *dest, callback_T *src);
  void copy_callback(callback_T *dest, callback_T *src);
+ void expand_autload_callback(callback_T *cb);
  void free_callback(callback_T *callback);
  /* vim: set ft=c : */
*** ../vim-8.2.4170/src/option.c        2022-01-15 18:31:37.720587407 +0000
--- src/option.c        2022-01-21 13:07:40.482595858 +0000
***************
*** 7238,7243 ****
--- 7238,7248 ----
      free_callback(optcb);
      set_callback(optcb, &cb);
      free_tv(tv);
+ 
+     // when using Vim9 style "import.funcname" it needs to be expanded to
+     // "import#funcname".
+     expand_autload_callback(optcb);
+ 
      return OK;
  #else
      return FAIL;
*** ../vim-8.2.4170/src/testdir/test_vim9_import.vim    2022-01-20 
21:32:50.331303977 +0000
--- src/testdir/test_vim9_import.vim    2022-01-21 13:05:43.356993080 +0000
***************
*** 609,615 ****
    nunmap <F3>
  enddef
  
! def Test_use_import_in_completion()
    var lines =<< trim END
        vim9script
        export def Complete(..._): list<string>
--- 609,615 ----
    nunmap <F3>
  enddef
  
! def Test_use_import_in_command_completion()
    var lines =<< trim END
        vim9script
        export def Complete(..._): list<string>
***************
*** 632,637 ****
--- 632,678 ----
    delete('Xscript.vim')
  enddef
  
+ def Test_use_autoload_import_in_insert_completion()
+   mkdir('Xdir/autoload', 'p')
+   var save_rtp = &rtp
+   exe 'set rtp^=' .. getcwd() .. '/Xdir'
+ 
+   var lines =<< trim END
+       vim9script
+       export def ThesaurusFunc(findbase: bool, _): any
+         if findbase
+           return 1
+         endif
+         return [
+           'check',
+           'experiment',
+           'test',
+           'verification'
+           ]
+       enddef
+       g:completion_loaded = 'yes'
+   END
+   writefile(lines, 'Xdir/autoload/completion.vim')
+ 
+   new
+   lines =<< trim END
+       vim9script
+       g:completion_loaded = 'no'
+       import autoload 'completion.vim'
+       set thesaurusfunc=completion.ThesaurusFunc
+       assert_equal('no', g:completion_loaded)
+       feedkeys("i\<C-X>\<C-T>\<C-N>\<Esc>", 'xt')
+       assert_equal('experiment', getline(1))
+       assert_equal('yes', g:completion_loaded)
+   END
+   CheckScriptSuccess(lines)
+ 
+   set thesaurusfunc=
+   bwipe!
+   delete('Xdir', 'rf')
+   &rtp = save_rtp
+ enddef
+ 
  def Test_export_fails()
    CheckScriptFailure(['export var some = 123'], 'E1042:')
    CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
*** ../vim-8.2.4170/src/version.c       2022-01-21 11:37:03.640642885 +0000
--- src/version.c       2022-01-21 12:43:28.905328975 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4171,
  /**/

-- 
The Law of VIM:
For each member b of the possible behaviour space B of program P, there exists
a finite time t before which at least one user u in the total user space U of
program P will request b becomes a member of the allowed behaviour space B'
(B' <= B).
In other words: Sooner or later everyone wants everything as an option.
                                        -- Vince Negri

 /// 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/20220121133027.4C6821C0202%40moolenaar.net.

Raspunde prin e-mail lui