Patch 8.2.3994

2022-01-03 Fir de Conversatie Bram Moolenaar


Patch 8.2.3994
Problem:Vim9: extend() complains about the type even when it was not
declared.
Solution:   Only check the list or dict type when it was declared.
Files:  src/list.c, src/testdir/test_vim9_builtin.vim


*** ../vim-8.2.3993/src/list.c  2022-01-03 12:27:59.359039951 +
--- src/list.c  2022-01-03 15:01:35.340002252 +
***
*** 2758,2782 
  extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new)
  {
  type_T*type = NULL;
- garray_T  type_list;
  char  *func_name = is_new ? "extendnew()" : "extend()";
  
- if (!is_new && in_vim9script())
- {
-   // Check that extend() does not change the type of the dict.
-   ga_init2(&type_list, sizeof(type_T *), 10);
-   type = typval2type(argvars, get_copyID(), &type_list, TVTT_DO_MEMBER);
- }
- 
  if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
list_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv);
  else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
dict_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv);
  else
semsg(_(e_argument_of_str_must_be_list_or_dictionary), func_name);
- 
- if (type != NULL)
-   clear_type_list(&type_list);
  }
  
  /*
--- 2758,2783 
  extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new)
  {
  type_T*type = NULL;
  char  *func_name = is_new ? "extendnew()" : "extend()";
  
  if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
+ {
+   // Check that extend() does not change the type of the list if it was
+   // declared.
+   if (!is_new && in_vim9script() && argvars[0].vval.v_list != NULL)
+   type = argvars[0].vval.v_list->lv_type;
list_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv);
+ }
  else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
+ {
+   // Check that extend() does not change the type of the list if it was
+   // declared.
+   if (!is_new && in_vim9script() && argvars[0].vval.v_dict != NULL)
+   type = argvars[0].vval.v_dict->dv_type;
dict_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv);
+ }
  else
semsg(_(e_argument_of_str_must_be_list_or_dictionary), func_name);
  }
  
  /*
*** ../vim-8.2.3993/src/testdir/test_vim9_builtin.vim   2022-01-03 
12:27:59.359039951 +
--- src/testdir/test_vim9_builtin.vim   2022-01-03 16:46:52.361229193 +
***
*** 974,988 
assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, 'keep'))
assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, g:string_keep))
  
var res: list>
extend(res, mapnew([1, 2], (_, v) => ({})))
assert_equal([{}, {}], res)
END
CheckDefAndScriptSuccess(lines)
  
CheckDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type 
mismatch, expected list but got string', 'E712: Argument of extend() must 
be a List or Dictionary'])
CheckDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type 
mismatch, expected list but got number', 'E712: Argument of extend() 
must be a List or Dictionary'])
!   CheckDefAndScriptFailure(['extend([1, 2], ["x"])'], ['E1013: Argument 2: 
type mismatch, expected list but got list', 'E1013: Argument 2: 
type mismatch, expected list but got list'])
CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type 
mismatch, expected number but got string')
  
CheckDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, 
expected dict but got number')
--- 974,998 
assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, 'keep'))
assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, g:string_keep))
  
+   # mix of types is OK without a declaration
+ 
var res: list>
extend(res, mapnew([1, 2], (_, v) => ({})))
assert_equal([{}, {}], res)
END
CheckDefAndScriptSuccess(lines)
  
+   # FIXME: this should not fail when compiled
+   lines =<< trim END
+   vim9script
+   assert_equal([1, 2, "x"], extend([1, 2], ["x"]))
+   assert_equal([1, "b", 1], extend([1], ["b", 1]))
+   END
+   CheckScriptSuccess(lines)
+ 
CheckDefAndScriptFailure(['extend("a", 1)'], ['E1013: Argument 1: type 
mismatch, expected list but got string', 'E712: Argument of extend() must 
be a List or Dictionary'])
CheckDefAndScriptFailure(['extend([1, 2], 3)'], ['E1013: Argument 2: type 
mismatch, expected list but got number', 'E712: Argument of extend() 
must be a List or Dictionary'])
!   CheckDefAndScriptFailure(['var ll = [1, 2]', 'extend(ll, ["x"])'], ['E1013: 
Argument 2: type mismatch, expected list but got list', 'E1013: 
Argument 2: type mismatch, expected list but got list'])
CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type 
mismatch, expe

Patch 8.2.3995

2022-01-03 Fir de Conversatie Bram Moolenaar


Patch 8.2.3995
Problem:Not all sshconfig files are detected as such.
Solution:   Adjust the patterns used for sshconfig detection. (David Auer,
closes #9322)
Files:  runtime/filetype.vim, src/testdir/test_filetype.vim


*** ../vim-8.2.3994/runtime/filetype.vim2022-01-01 11:38:32.412349129 
+
--- runtime/filetype.vim2022-01-03 17:27:57.756431896 +
***
*** 1778,1785 
  au BufNewFile,BufRead *.nut   setf squirrel
  
  " OpenSSH configuration
! au BufNewFile,BufRead ssh_config,*/.ssh/configsetf sshconfig
! au BufNewFile,BufRead */etc/ssh/ssh_config.d/*.conf   setf sshconfig
  
  " OpenSSH server configuration
  au BufNewFile,BufRead sshd_config setf sshdconfig
--- 1778,1785 
  au BufNewFile,BufRead *.nut   setf squirrel
  
  " OpenSSH configuration
! au BufNewFile,BufRead ssh_config,*/.ssh/config,*/.ssh/*.conf  setf sshconfig
! au BufNewFile,BufRead */etc/ssh/ssh_config.d/*.conf   setf sshconfig
  
  " OpenSSH server configuration
  au BufNewFile,BufRead sshd_config setf sshdconfig
*** ../vim-8.2.3994/src/testdir/test_filetype.vim   2022-01-01 
11:38:32.412349129 +
--- src/testdir/test_filetype.vim   2022-01-03 17:27:57.756431896 +
***
*** 482,488 
  \ 'squid': ['squid.conf'],
  \ 'squirrel': ['file.nut'],
  \ 'srec': ['file.s19', 'file.s28', 'file.s37', 'file.mot', 'file.srec'],
! \ 'sshconfig': ['ssh_config', '/.ssh/config', 
'/etc/ssh/ssh_config.d/file.conf', 'any/etc/ssh/ssh_config.d/file.conf', 
'any/.ssh/config'],
  \ 'sshdconfig': ['sshd_config', '/etc/ssh/sshd_config.d/file.conf', 
'any/etc/ssh/sshd_config.d/file.conf'],
  \ 'st': ['file.st'],
  \ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'],
--- 482,488 
  \ 'squid': ['squid.conf'],
  \ 'squirrel': ['file.nut'],
  \ 'srec': ['file.s19', 'file.s28', 'file.s37', 'file.mot', 'file.srec'],
! \ 'sshconfig': ['ssh_config', '/.ssh/config', 
'/etc/ssh/ssh_config.d/file.conf', 'any/etc/ssh/ssh_config.d/file.conf', 
'any/.ssh/config', 'any/.ssh/file.conf'],
  \ 'sshdconfig': ['sshd_config', '/etc/ssh/sshd_config.d/file.conf', 
'any/etc/ssh/sshd_config.d/file.conf'],
  \ 'st': ['file.st'],
  \ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'],
*** ../vim-8.2.3994/src/version.c   2022-01-03 16:52:24.616533342 +
--- src/version.c   2022-01-03 17:32:26.644007367 +
***
*** 752,753 
--- 752,755 
  {   /* Add new patch number below this line */
+ /**/
+ 3995,
  /**/

-- 
Your mouse has moved.  Windows must be restarted for the change
to take effect.  Reboot now?

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220103173324.ABE501C1181%40moolenaar.net.


Re: Vim9 import [was Vim9 script feature-complete]

2022-01-03 Fir de Conversatie Bram Moolenaar


> On 2022-01-03, Marvin Renich  wrote:
> > Don't bother with the
> 
> >   import MyClass from "myclass.vim"
> >   import {someValue, MyClass} from "thatscript.vim"
> >
> > syntax, and only provide
> >
> >   import "myclass.vim"
> >   import "myclass.vim" as Other
> >
> > and require use of the namespace prefix:
> >
> >   Other.MyClass
> >
> > The first case, without the "as" would default to the file name, with
> > leading directories and trailing ".vim" removed
> 
> I do not think that using a filename as an identifier is a good idea.
> For instance, calling a script 1.vim would automatically make it
> non-importable (without "as").

Since a script needs to use "export" to be able to be imported, having
to use a nice name for the script is clearly needed.  The only thing is
that it may be a long name to avoid name collisions, but then the "as
{name}" form can be used to shorten the name.

> I personally find that using an imported name without a prefix (as it is
> currently possible) makes my code terse, and I think that in the limited
> scope a plugin that works well. But I understand that Vim9 scripts might
> have a broader use, such as generic libraries of functions that can be
> used by many scripts. In that context, stricter scoping rules, such as
> in Go, are likely a cleaner approach.
> 
> How about always requiring a prefix, but allowing explicit namespace
> pollution? As in
> 
> import "myclass.vim" as Other
> use Other  # Makes Other.F() available as just F()

Throwing everything from "Other" into the current namespace is going to
cause trouble, because someone may add an item to myclass.vim that
conflicts with what is in your script.  Thus extending one script may
break another script, that is bad.

A kind of an alias mechanism would work.  Since most of the items are
going to be functions, might as well use a function reference:

final Func = Other.Func

That's an existing mechanism, thus keeps things simple.

It also works for constants and read-only variables:

const MAX = Other.MAX_VALUE

This does not work for variables that can be set, but you should
probably use a setter function for that anyway.

I'm just pointing out what valid pro's and con's are, I'm not suggesting
this means the alternate import syntax is best.

-- 
hundred-and-one symptoms of being an internet addict:
208. Your goals for the future are obtaining a second Gbit connection
and upgrade your NAS to all SSD

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220103173324.A57551C110C%40moolenaar.net.


Re: Vim9 import [was Vim9 script feature-complete]

2022-01-03 Fir de Conversatie Bram Moolenaar


Marvin Renich wrote:

> * Bram Moolenaar  [220103 07:07]:
> > 
> > > On 2021-12-30, Bram Moolenaar  wrote:
> > > > If you have remarks on something in Vim9 script that you think should be
> > > > different, speak up now!  Soon we'll only make backwards compatible
> > > > changes to avoid breaking existing plugins.
> > > 
> > > There was a thread about this on HN a few days ago, and one of the
> > > comments suggested to reverse the import syntax so that the imported
> > > script is named first and the imported entities next. A rationale for
> > > this is that it would help automatic completion.
> > 
> > Is there another language that works like this?  The current syntax
> > resembles Javascript, which hopefully some users are familiar with.
> 
> I have to agree that putting the file being imported first is much
> better.
> 
> In Go, by default every imported identifier must be prefixed by the
> package name, much like the current Vim9 "as" clause.  Requiring an "as"
> clause (or defaulting to some form of the script name for the value of
> the "as" clause), and requiring that all imported identifiers be
> prefixed by this identifier make the code _much_ clearer and easier to
> follow.
> 
> I very much dislike the JavaScript style where importing, by default,
> places the imported names in the current namespace rather than in a
> separate namespace (identified by the "as" clause in Vim9).
> 
> Given that even when you are only importing one identifier from a
> script, the whole script must be read and executed, I think the Go way
> is better.  Don't bother with the
> 
>   import MyClass from "myclass.vim"
>   import {someValue, MyClass} from "thatscript.vim"
> 
> syntax, and only provide
> 
>   import "myclass.vim"
>   import "myclass.vim" as Other
> 
> and require use of the namespace prefix:
> 
>   Other.MyClass
> 
> The first case, without the "as" would default to the file name, with
> leading directories and trailing ".vim" removed, and with the first
> letter capitalized.  Non-identifier characters and leading digits would
> be removed as well.  In the case without "as" above, you would reference
> the imported MyClass identifier as
> 
>   Myclass.MyClass
> 
> With this, every use of an imported identifier is clear and explicit.

I have to agree that the Javascript way is a bit complicated and
verbose.  Especially the "* as SomeName" part is not optimal:
import * as funcs from "./subdir/myfunctioncollection.vim"
Now "funcs" is somewhere in the middle of the line.
This form might actually be the most common use.

Not mentioning the items being imported has the disadvantage that it's
harder to find out what is used from the imported script.  But that
might not be very important.  You can always use "*" on the name to see
what's being used.

File names are often longer, thus the "import as" style can be expected
to be used quite a lot.  Example:

import "./subdir/myfunctioncollection.vim" as funcs
funcs.DoSomething()

The main disadvantage is that the prefix must always be used, there is
no way to use an imported item without it.  But as you mention, this can
also be seen as an advantage, that it's clear it is not defined in this
script file.

I hope others give there opinion, this is an important choice.

-- 
$ echo pizza > /dev/oven

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220103141413.36CB01C0A5B%40moolenaar.net.


Patch 8.2.3993

2022-01-03 Fir de Conversatie Bram Moolenaar


Patch 8.2.3993
Problem:When recording a change in Select mode the first typed character
appears twice.
Solution:   When putting the character back into typeahead remove it from
recorded characters. (closes #9462)
Files:  src/getchar.c, src/proto/getchar.pro, src/normal.c,
src/testdir/test_registers.vim


*** ../vim-8.2.3992/src/getchar.c   2022-01-01 14:19:44.040353857 +
--- src/getchar.c   2022-01-03 13:34:38.078133995 +
***
*** 242,247 
--- 242,263 
  }
  
  /*
+  * Delete "slen" bytes from the end of "buf".
+  * Only works when it was just added.
+  */
+ static void
+ delete_buff_tail(buffheader_T *buf, int slen)
+ {
+ int len = (int)STRLEN(buf->bh_curr->b_str);
+ 
+ if (len >= slen)
+ {
+   buf->bh_curr->b_str[len - slen] = NUL;
+   buf->bh_space += slen;
+ }
+ }
+ 
+ /*
   * Add number "n" to buffer "buf".
   */
  static void
***
*** 1100, 
   * Can be used for a character obtained by vgetc() that needs to be put back.
   * Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
   * the char.
   */
! void
  ins_char_typebuf(int c, int modifier)
  {
  char_ubuf[MB_MAXBYTES + 4];
! int   idx = 0;
  
  if (modifier != 0)
  {
--- 1116,1128 
   * Can be used for a character obtained by vgetc() that needs to be put back.
   * Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
   * the char.
+  * Returns the length of what was inserted.
   */
! int
  ins_char_typebuf(int c, int modifier)
  {
  char_ubuf[MB_MAXBYTES + 4];
! int   len = 0;
  
  if (modifier != 0)
  {
***
*** 1113,1131 
buf[1] = KS_MODIFIER;
buf[2] = modifier;
buf[3] = NUL;
!   idx = 3;
  }
  if (IS_SPECIAL(c))
  {
!   buf[idx] = K_SPECIAL;
!   buf[idx + 1] = K_SECOND(c);
!   buf[idx + 2] = K_THIRD(c);
!   buf[idx + 3] = NUL;
!   idx += 3;
  }
  else
!   buf[(*mb_char2bytes)(c, buf + idx) + idx] = NUL;
  (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
  }
  
  /*
--- 1130,1152 
buf[1] = KS_MODIFIER;
buf[2] = modifier;
buf[3] = NUL;
!   len = 3;
  }
  if (IS_SPECIAL(c))
  {
!   buf[len] = K_SPECIAL;
!   buf[len + 1] = K_SECOND(c);
!   buf[len + 2] = K_THIRD(c);
!   buf[len + 3] = NUL;
!   len += 3;
  }
  else
! {
!   len += (*mb_char2bytes)(c, buf + len);
!   buf[len] = NUL;
! }
  (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
+ return len;
  }
  
  /*
***
*** 1302,1307 
--- 1323,1344 
  }
  
  /*
+  * Undo the last gotchars() for "len" bytes.  To be used when putting a typed
+  * character back into the typeahead buffer, thus gotchars() will be called
+  * again.
+  * Only affects recorded characters.
+  */
+ void
+ ungetchars(int len)
+ {
+ if (reg_recording != 0)
+ {
+   delete_buff_tail(&recordbuff, len);
+   last_recorded_len -= len;
+ }
+ }
+ 
+ /*
   * Sync undo.  Called when typed characters are obtained from the typeahead
   * buffer, or when a menu is used.
   * Do not sync:
*** ../vim-8.2.3992/src/proto/getchar.pro   2021-08-09 18:59:01.442811242 
+0100
--- src/proto/getchar.pro   2022-01-03 13:34:37.050135970 +
***
*** 24,34 
  void stop_redo_ins(void);
  int noremap_keys(void);
  int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, int 
silent);
! void ins_char_typebuf(int c, int modifier);
  int typebuf_changed(int tb_change_cnt);
  int typebuf_typed(void);
  int typebuf_maplen(void);
  void del_typebuf(int len, int offset);
  int save_typebuf(void);
  void save_typeahead(tasave_T *tp);
  void restore_typeahead(tasave_T *tp, int overwrite);
--- 24,35 
  void stop_redo_ins(void);
  int noremap_keys(void);
  int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, int 
silent);
! int ins_char_typebuf(int c, int modifier);
  int typebuf_changed(int tb_change_cnt);
  int typebuf_typed(void);
  int typebuf_maplen(void);
  void del_typebuf(int len, int offset);
+ void ungetchars(int len);
  int save_typebuf(void);
  void save_typeahead(tasave_T *tp);
  void restore_typeahead(tasave_T *tp, int overwrite);
*** ../vim-8.2.3992/src/normal.c2022-01-02 19:25:22.846078499 +
--- src/normal.c2022-01-03 13:46:07.401043973 +
***
*** 592,603 
&& VIsual_select
&& (vim_isprintc(c) || c == NL || c == CAR || c == K_KENTER))
  {
// Fake a "c"hange command.  When "restart_edit" is set (e.g., because
// 'insertmode' is set) fake a "d"elete command, Insert mode will
// restart automatically.
// Insert the typed character in the typeahead buffer, so that it can
// be mapped in Insert mode. 

Re: Vim9 import [was Vim9 script feature-complete]

2022-01-03 Fir de Conversatie Marvin Renich
* Bram Moolenaar  [220103 07:07]:
> 
> > On 2021-12-30, Bram Moolenaar  wrote:
> > > If you have remarks on something in Vim9 script that you think should be
> > > different, speak up now!  Soon we'll only make backwards compatible
> > > changes to avoid breaking existing plugins.
> > 
> > There was a thread about this on HN a few days ago, and one of the
> > comments suggested to reverse the import syntax so that the imported
> > script is named first and the imported entities next. A rationale for
> > this is that it would help automatic completion.
> 
> Is there another language that works like this?  The current syntax
> resembles Javascript, which hopefully some users are familiar with.

I have to agree that putting the file being imported first is much
better.

In Go, by default every imported identifier must be prefixed by the
package name, much like the current Vim9 "as" clause.  Requiring an "as"
clause (or defaulting to some form of the script name for the value of
the "as" clause), and requiring that all imported identifiers be
prefixed by this identifier make the code _much_ clearer and easier to
follow.

I very much dislike the JavaScript style where importing, by default,
places the imported names in the current namespace rather than in a
separate namespace (identified by the "as" clause in Vim9).

Given that even when you are only importing one identifier from a
script, the whole script must be read and executed, I think the Go way
is better.  Don't bother with the

  import MyClass from "myclass.vim"
  import {someValue, MyClass} from "thatscript.vim"

syntax, and only provide

  import "myclass.vim"
  import "myclass.vim" as Other

and require use of the namespace prefix:

  Other.MyClass

The first case, without the "as" would default to the file name, with
leading directories and trailing ".vim" removed, and with the first
letter capitalized.  Non-identifier characters and leading digits would
be removed as well.  In the case without "as" above, you would reference
the imported MyClass identifier as

  Myclass.MyClass

With this, every use of an imported identifier is clear and explicit.

...Marvin

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/YdL35xfbRHlaYZU5%40basil.wdw.


Patch 8.2.3992

2022-01-03 Fir de Conversatie Bram Moolenaar


Patch 8.2.3992
Problem:Wrong local-additions in the help with language mix.
Solution:   Adjust how the local additions list is generated. (Hirohito
Higashi, closes #9464)
Files:  src/help.c, src/testdir/test_help.vim


*** ../vim-8.2.3991/src/help.c  2022-01-02 20:20:41.377033186 +
--- src/help.c  2022-01-03 12:52:12.158852025 +
***
*** 818,849 
// the same directory.
for (i1 = 0; i1 < fcount; ++i1)
{
!   for (i2 = 0; i2 < fcount; ++i2)
{
-   if (i1 == i2)
-   continue;
-   if (fnames[i1] == NULL || fnames[i2] == NULL)
-   continue;
-   f1 = fnames[i1];
f2 = fnames[i2];
!   t1 = gettail(f1);
t2 = gettail(f2);
-   e1 = vim_strrchr(t1, '.');
e2 = vim_strrchr(t2, '.');
if (e1 == NULL || e2 == NULL)
continue;
-   if (fnamecmp(e1, ".txt") != 0
-   && fnamecmp(e1, fname + 4) != 0)
-   {
-   // Not .txt and not .abx, remove it.
-   VIM_CLEAR(fnames[i1]);
-   continue;
-   }
if (e1 - f1 != e2 - f2
|| fnamencmp(f1, f2, e1 - f1) != 0)
continue;
if (fnamecmp(e1, ".txt") == 0
!   && fnamecmp(e2, fname + 4) == 0)
// use .abx instead of .txt
VIM_CLEAR(fnames[i1]);
}
--- 818,848 
// the same directory.
for (i1 = 0; i1 < fcount; ++i1)
{
!   f1 = fnames[i1];
!   t1 = gettail(f1);
!   e1 = vim_strrchr(t1, '.');
!   if (fnamecmp(e1, ".txt") != 0
!  && fnamecmp(e1, fname + 4) != 0)
!   {
!   // Not .txt and not .abx, remove it.
!   VIM_CLEAR(fnames[i1]);
!   continue;
!   }
! 
!   for (i2 = i1 + 1; i2 < fcount; ++i2)
{
f2 = fnames[i2];
!   if (f2 == NULL)
!   continue;
t2 = gettail(f2);
e2 = vim_strrchr(t2, '.');
if (e1 == NULL || e2 == NULL)
continue;
if (e1 - f1 != e2 - f2
|| fnamencmp(f1, f2, e1 - f1) != 0)
continue;
if (fnamecmp(e1, ".txt") == 0
!  && fnamecmp(e2, fname + 4) == 0)
// use .abx instead of .txt
VIM_CLEAR(fnames[i1]);
}
*** ../vim-8.2.3991/src/testdir/test_help.vim   2021-11-25 10:50:09.178844306 
+
--- src/testdir/test_help.vim   2022-01-03 12:48:51.651396534 +
***
*** 57,72 
call writefile(['*mydoc-ext.txt* my extended awesome doc'], 
'Xruntime/doc/mydoc-ext.txt')
let rtp_save = &rtp
set rtp+=./Xruntime
!   help
!   1
!   call search('mydoc.txt')
!   call assert_equal('|mydoc.txt| my awesome doc', getline('.'))
!   1
!   call search('mydoc-ext.txt')
!   call assert_equal('|mydoc-ext.txt| my extended awesome doc', getline('.'))
close
  
call delete('Xruntime', 'rf')
let &rtp = rtp_save
  endfunc
  
--- 57,98 
call writefile(['*mydoc-ext.txt* my extended awesome doc'], 
'Xruntime/doc/mydoc-ext.txt')
let rtp_save = &rtp
set rtp+=./Xruntime
!   help local-additions
!   let lines = getline(line(".") + 1, search("^$") - 1)
!   call assert_equal([
!   \ '|mydoc-ext.txt| my extended awesome doc',
!   \ '|mydoc.txt| my awesome doc'
!   \ ], lines)
!   call delete('Xruntime/doc/mydoc-ext.txt')
!   close
! 
!   call mkdir('Xruntime-ja/doc', 'p')
!   call writefile(["local-additions\thelp.jax\t/*local-additions*"], 
'Xruntime-ja/doc/tags-ja')
!   call writefile(['*help.txt* This is jax file', '',
!   \ 'LOCAL ADDITIONS: *local-additions*', ''], 'Xruntime-j

Patch 8.2.3991

2022-01-03 Fir de Conversatie Bram Moolenaar


Patch 8.2.3991
Problem:Vim9: error when extending dict with another type that it was
initialized with.
Solution:   Also set the type for dict if the initializer has a more
specific type. (closes #9461)
Files:  src/vim9compile.c, src/vim9type.c, src/vim9.h, src/eval.c,
src/list.c, src/vim9script.c, src/testdir/test_vim9_assign.vim,
src/testdir/test_vim9_builtin.vim, src/testdir/test_vim9_func.vim


*** ../vim-8.2.3990/src/vim9compile.c   2022-01-01 15:58:19.122486356 +
--- src/vim9compile.c   2022-01-03 11:34:36.005461730 +
***
*** 2286,2296 
&& (lhs.lhs_type->tt_type == VAR_DICT
  || lhs.lhs_type->tt_type == VAR_LIST)
&& lhs.lhs_type->tt_member != NULL
-   && !(lhs.lhs_type->tt_member == &t_any
-   && oplen > 0
-   && rhs_type != NULL
-   && rhs_type->tt_type == lhs.lhs_type->tt_type
-   && rhs_type->tt_member != &t_unknown)
&& lhs.lhs_type->tt_member != &t_unknown)
// Set the type in the list or dict, so that it can be checked,
// also in legacy script.  Not for "list = val", then the
--- 2286,2291 
*** ../vim-8.2.3990/src/vim9type.c  2021-12-30 13:59:17.038036582 +
--- src/vim9type.c  2022-01-03 12:21:04.425371033 +
***
*** 252,261 
  /*
   * Get a type_T for a typval_T.
   * "type_gap" is used to temporarily create types in.
!  * When "do_member" is TRUE also get the member type, otherwise use "any".
   */
  static type_T *
! typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
  {
  type_T  *type;
  type_T  *member_type = NULL;
--- 252,264 
  /*
   * Get a type_T for a typval_T.
   * "type_gap" is used to temporarily create types in.
!  * When "flags" has TVTT_DO_MEMBER also get the member type, otherwise use
!  * "any".
!  * When "flags" has TVTT_MORE_SPECIFIC get the more specific member type if it
!  * is "any".
   */
  static type_T *
! typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags)
  {
  type_T  *type;
  type_T  *member_type = NULL;
***
*** 278,286 
  
if (l == NULL || (l->lv_first == NULL && l->lv_type == NULL))
return &t_list_empty;
!   if (!do_member)
return &t_list_any;
!   if (l->lv_type != NULL)
return l->lv_type;
if (l->lv_first == &range_list_item)
return &t_list_number;
--- 281,293 
  
if (l == NULL || (l->lv_first == NULL && l->lv_type == NULL))
return &t_list_empty;
!   if ((flags & TVTT_DO_MEMBER) == 0)
return &t_list_any;
!   // If the type is list go through the members, it may end up a
!   // more specific type.
!   if (l->lv_type != NULL && (l->lv_first == NULL
!  || (flags & TVTT_MORE_SPECIFIC) == 0
!  || l->lv_type->tt_member != &t_any))
return l->lv_type;
if (l->lv_first == &range_list_item)
return &t_list_number;
***
*** 290,298 
l->lv_copyID = copyID;
  
// Use the common type of all members.
!   member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap, TRUE);
for (li = l->lv_first->li_next; li != NULL; li = li->li_next)
!   common_type(typval2type(&li->li_tv, copyID, type_gap, TRUE),
  member_type, &member_type, type_gap);
return get_list_type(member_type, type_gap);
  }
--- 297,307 
l->lv_copyID = copyID;
  
// Use the common type of all members.
!   member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap,
!  TVTT_DO_MEMBER);
for (li = l->lv_first->li_next; li != NULL; li = li->li_next)
!   common_type(typval2type(&li->li_tv, copyID, type_gap,
!  TVTT_DO_MEMBER),
  member_type, &member_type, type_gap);
return get_list_type(member_type, type_gap);
  }
***
*** 305,313 
  
if (d == NULL || (d->dv_hashtab.ht_used == 0 && d->dv_type == NULL))
return &t_dict_empty;
!   if (!do_member)
return &t_dict_any;
!   if (d->dv_type != NULL)
return d->dv_type;
if (d->dv_copyID == copyID)
// avoid recursion
--- 314,326 
  
if (d == NULL || (d->dv_hashtab.ht_used == 0 && d->dv_type == NULL))
return &t_dict_empty;
!   if ((flags & TVTT_DO_MEMBER) == 0)
return &t_dict_any;
!   // If the type is dict go through the members, it may end up a
!   // more specifi

Patch 8.2.3990

2022-01-03 Fir de Conversatie Bram Moolenaar


Patch 8.2.3990
Problem:Testing wrong operator.
Solution:   Test "g@" instead of "r_". (Naohiro Ono, closes #9463)
Files:  src/testdir/test_normal.vim


*** ../vim-8.2.3989/src/testdir/test_normal.vim 2022-01-02 13:05:41.992274960 
+
--- src/testdir/test_normal.vim 2022-01-03 11:14:12.640957197 +
***
*** 486,492 
set operatorfunc=Underscorize
new
call setline(1, ['first', 'first', 'third', 'third', 'second'])
!   normal! 1GVjr_
normal! 5G.
normal! 3G.
call assert_equal(['_', '_', '_', '_', '__'], 
getline(1, '$'))
--- 486,492 
set operatorfunc=Underscorize
new
call setline(1, ['first', 'first', 'third', 'third', 'second'])
!   normal! 1GVjg@
normal! 5G.
normal! 3G.
call assert_equal(['_', '_', '_', '_', '__'], 
getline(1, '$'))
*** ../vim-8.2.3989/src/version.c   2022-01-03 11:03:42.538752401 +
--- src/version.c   2022-01-03 11:14:36.740888412 +
***
*** 752,753 
--- 752,755 
  {   /* Add new patch number below this line */
+ /**/
+ 3990,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
200. You really believe in the concept of a "paperless" office.

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220103111620.2C7DB1C0A5B%40moolenaar.net.


Re: Vim9 script feature-complete

2022-01-03 Fir de Conversatie Bram Moolenaar


> ["Followup-To:" header set to gmane.editors.vim.]
> On 2021-12-30, Bram Moolenaar  wrote:
> > The work on Vim9 script is coming to a point where the syntax and
> > semantics are practially done.  There might be some more tests
> > uncovering problems that need to be fixed and perhaps some tiny tweaks,
> > but otherwise it has been quite stable for the past months.
> >
> > If you have remarks on something in Vim9 script that you think should be
> > different, speak up now!  Soon we'll only make backwards compatible
> > changes to avoid breaking existing plugins.
> 
> There was a thread about this on HN a few days ago, and one of the
> comments suggested to reverse the import syntax so that the imported
> script is named first and the imported entities next. A rationale for
> this is that it would help automatic completion.

Is there another language that works like this?  The current syntax
resembles Javascript, which hopefully some users are familiar with.

> Personally, the thing I still miss is custom types. But that falls into
> the category of features to be added when Vim9 script is frozen,
> I guess. Other than that, I am really enjoying Vim9 script!

Defining types is planned to be added later.  It can build on top of
what we have without changing it.  I expect it to be quite a bit of work
to get right, which is why I want to do it later.  Otherwise Vim9 will
never be launched.

-- 
hundred-and-one symptoms of being an internet addict:
198. You read all the quotes at Netaholics Anonymous and keep thinking
 "What's wrong with that?"

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220103110432.57AF81C0CF0%40moolenaar.net.


Patch 8.2.3989

2022-01-03 Fir de Conversatie Bram Moolenaar


Patch 8.2.3989
Problem:Some insert completion code is not tested.
Solution:   Add a few tests.  Refactor thesaurus completion. (Yegappan
Lakshmanan, closes #9460)
Files:  src/insexpand.c, src/testdir/test_edit.vim,
src/testdir/test_ins_complete.vim


*** ../vim-8.2.3988/src/insexpand.c 2022-01-01 15:58:19.114486366 +
--- src/insexpand.c 2022-01-03 11:02:39.358931895 +
***
*** 1017,1022 
--- 1017,1026 
  return dict;
  }
  
+ /*
+  * Trigger the CompleteChanged autocmd event. Invoked each time the Insert 
mode
+  * completion menu is changed.
+  */
  static void
  trigger_complete_changed_event(int cur)
  {
***
*** 1219,1226 
  #define DICT_EXACT(2) // "dict" is the exact name of a file
  
  /*
!  * Add any identifiers that match the given pattern in the list of dictionary
!  * files "dict_start" to the list of completions.
   */
  static void
  ins_compl_dictionaries(
--- 1223,1230 
  #define DICT_EXACT(2) // "dict" is the exact name of a file
  
  /*
!  * Add any identifiers that match the given pattern "pat" in the list of
!  * dictionary files "dict_start" to the list of completions.
   */
  static void
  ins_compl_dictionaries(
***
*** 1346,1351 
--- 1350,1415 
  vim_free(buf);
  }
  
+ /*
+  * Add all the words in the line "*buf_arg" from the thesaurus file "fname"
+  * skipping the word at 'skip_word'.  Returns OK on success.
+  */
+ static int
+ thesarurs_add_words_in_line(
+   char_u  *fname,
+   char_u  **buf_arg,
+   int dir,
+   char_u  *skip_word)
+ {
+ int   status = OK;
+ char_u*ptr;
+ char_u*wstart;
+ 
+ // Add the other matches on the line
+ ptr = *buf_arg;
+ while (!got_int)
+ {
+   // Find start of the next word.  Skip white
+   // space and punctuation.
+   ptr = find_word_start(ptr);
+   if (*ptr == NUL || *ptr == NL)
+   break;
+   wstart = ptr;
+ 
+   // Find end of the word.
+   if (has_mbyte)
+   // Japanese words may have characters in
+   // different classes, only separate words
+   // with single-byte non-word characters.
+   while (*ptr != NUL)
+   {
+   int l = (*mb_ptr2len)(ptr);
+ 
+   if (l < 2 && !vim_iswordc(*ptr))
+   break;
+   ptr += l;
+   }
+   else
+   ptr = find_word_end(ptr);
+ 
+   // Add the word. Skip the regexp match.
+   if (wstart != skip_word)
+   {
+   status = ins_compl_add_infercase(wstart, (int)(ptr - wstart), p_ic,
+   fname, dir, FALSE);
+   if (status == FAIL)
+   break;
+   }
+ }
+ 
+ *buf_arg = ptr;
+ return status;
+ }
+ 
+ /*
+  * Process "count" dictionary/thesaurus "files" and add the text matching
+  * "regmatch".
+  */
  static void
  ins_compl_files(
  int   count,
***
*** 1392,1432 
p_ic, files[i], *dir, FALSE);
if (thesaurus)
{
!   char_u *wstart;
! 
!   // Add the other matches on the line
ptr = buf;
!   while (!got_int)
!   {
!   // Find start of the next word.  Skip white
!   // space and punctuation.
!   ptr = find_word_start(ptr);
!   if (*ptr == NUL || *ptr == NL)
!   break;
!   wstart = ptr;
! 
!   // Find end of the word.
!   if (has_mbyte)
!   // Japanese words may have characters in
!   // different classes, only separate words
!   // with single-byte non-word characters.
!   while (*ptr != NUL)
!   {
!   int l = (*mb_ptr2len)(ptr);
! 
!   if (l < 2 && !vim_iswordc(*ptr))
!   break;
!   ptr += l;
!   }
!   else
!   ptr = find_word_end(ptr);
! 
!   // Add the word. Skip the regexp match.
!   if (wstart != regmatch->startp[0])
!   add_r = ins_compl_add_infercase(wstart,
!   (int)(ptr - wstart),
!   p_ic, files[i], *dir, FALSE);
!   }
}
if (add_r == OK)
// if dir was BACKWARD then honor it just once
--- 1456,1465 
p_ic, files[i], *dir, FALSE);
if (thesaurus)
{
!   // Fo