mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
Vendored
+7
-7
@@ -83,7 +83,7 @@ export def FTbas()
|
||||
setf freebasic
|
||||
elseif match(lines, qb64_preproc) > -1
|
||||
setf qb64
|
||||
elseif match(lines, s:ft_visual_basic_content) > -1
|
||||
elseif match(lines, ft_visual_basic_content) > -1
|
||||
setf vb
|
||||
else
|
||||
setf basic
|
||||
@@ -241,7 +241,7 @@ export def FTfrm()
|
||||
|
||||
var lines = getline(1, min([line("$"), 5]))
|
||||
|
||||
if match(lines, s:ft_visual_basic_content) > -1
|
||||
if match(lines, ft_visual_basic_content) > -1
|
||||
setf vb
|
||||
else
|
||||
setf form
|
||||
@@ -434,7 +434,7 @@ export def FTinc()
|
||||
setf php
|
||||
# Pascal supports // comments but they're vary rarely used for file
|
||||
# headers so assume POV-Ray
|
||||
elseif lines =~ '^\s*\%({\|(\*\)' || lines =~? s:ft_pascal_keywords
|
||||
elseif lines =~ '^\s*\%({\|(\*\)' || lines =~? ft_pascal_keywords
|
||||
setf pascal
|
||||
else
|
||||
FTasmsyntax()
|
||||
@@ -496,7 +496,7 @@ export def FTprogress_pascal()
|
||||
var lnum = 1
|
||||
while lnum <= 10 && lnum < line('$')
|
||||
var line = getline(lnum)
|
||||
if line =~ s:ft_pascal_comments || line =~? s:ft_pascal_keywords
|
||||
if line =~ ft_pascal_comments || line =~? ft_pascal_keywords
|
||||
setf pascal
|
||||
return
|
||||
elseif line !~ '^\s*$' || line =~ '^/\*'
|
||||
@@ -514,7 +514,7 @@ export def FTpp()
|
||||
exe "setf " .. g:filetype_pp
|
||||
else
|
||||
var line = getline(nextnonblank(1))
|
||||
if line =~ s:ft_pascal_comments || line =~? s:ft_pascal_keywords
|
||||
if line =~ ft_pascal_comments || line =~? ft_pascal_keywords
|
||||
setf pascal
|
||||
else
|
||||
setf puppet
|
||||
@@ -685,8 +685,8 @@ export def FTRules()
|
||||
endtry
|
||||
var dir = expand('<amatch>:p:h')
|
||||
for line in config_lines
|
||||
if line =~ s:ft_rules_udev_rules_pattern
|
||||
var udev_rules = substitute(line, s:ft_rules_udev_rules_pattern, '\1', "")
|
||||
if line =~ ft_rules_udev_rules_pattern
|
||||
var udev_rules = substitute(line, ft_rules_udev_rules_pattern, '\1', "")
|
||||
if dir == udev_rules
|
||||
setf udevrules
|
||||
endif
|
||||
|
||||
+12
-11
@@ -539,8 +539,8 @@ sin({expr}) Float sine of {expr}
|
||||
sinh({expr}) Float hyperbolic sine of {expr}
|
||||
slice({expr}, {start} [, {end}]) String, List or Blob
|
||||
slice of a String, List or Blob
|
||||
sort({list} [, {func} [, {dict}]])
|
||||
List sort {list}, using {func} to compare
|
||||
sort({list} [, {how} [, {dict}]])
|
||||
List sort {list}, compare with {how}
|
||||
sound_clear() none stop playing all sounds
|
||||
sound_playevent({name} [, {callback}])
|
||||
Number play an event sound
|
||||
@@ -8033,21 +8033,22 @@ slice({expr}, {start} [, {end}]) *slice()*
|
||||
GetList()->slice(offset)
|
||||
|
||||
|
||||
sort({list} [, {func} [, {dict}]]) *sort()* *E702*
|
||||
sort({list} [, {how} [, {dict}]]) *sort()* *E702*
|
||||
Sort the items in {list} in-place. Returns {list}.
|
||||
|
||||
If you want a list to remain unmodified make a copy first: >
|
||||
:let sortedlist = sort(copy(mylist))
|
||||
|
||||
< When {func} is omitted, is empty or zero, then sort() uses the
|
||||
< When {how} is omitted or is an string, then sort() uses the
|
||||
string representation of each item to sort on. Numbers sort
|
||||
after Strings, |Lists| after Numbers. For sorting text in the
|
||||
current buffer use |:sort|.
|
||||
|
||||
When {func} is given and it is '1' or 'i' then case is
|
||||
ignored.
|
||||
When {how} is given and it is 'i' then case is ignored.
|
||||
In legacy script, for backwards compatibility, the value one
|
||||
can be used to ignore case. Zero means to not ignore case.
|
||||
|
||||
When {func} is given and it is 'l' then the current collation
|
||||
When {how} is given and it is 'l' then the current collation
|
||||
locale is used for ordering. Implementation details: strcoll()
|
||||
is used to compare strings. See |:language| check or set the
|
||||
collation locale. |v:collate| can also be used to check the
|
||||
@@ -8064,19 +8065,19 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702*
|
||||
< ['n', 'o', 'O', 'p', 'z', 'ö'] ~
|
||||
This does not work properly on Mac.
|
||||
|
||||
When {func} is given and it is 'n' then all items will be
|
||||
When {how} is given and it is 'n' then all items will be
|
||||
sorted numerical (Implementation detail: this uses the
|
||||
strtod() function to parse numbers, Strings, Lists, Dicts and
|
||||
Funcrefs will be considered as being 0).
|
||||
|
||||
When {func} is given and it is 'N' then all items will be
|
||||
When {how} is given and it is 'N' then all items will be
|
||||
sorted numerical. This is like 'n' but a string containing
|
||||
digits will be used as the number they represent.
|
||||
|
||||
When {func} is given and it is 'f' then all items will be
|
||||
When {how} is given and it is 'f' then all items will be
|
||||
sorted numerical. All values must be a Number or a Float.
|
||||
|
||||
When {func} is a |Funcref| or a function name, this function
|
||||
When {how} is a |Funcref| or a function name, this function
|
||||
is called to compare items. The function is invoked with two
|
||||
items as argument and must return zero if they are equal, 1 or
|
||||
bigger if the first one sorts after the second one, -1 or
|
||||
|
||||
@@ -411,6 +411,7 @@ T *+mouse* Mouse handling |mouse-using|
|
||||
N *+mouseshape* |'mouseshape'|
|
||||
B *+mouse_dec* Unix only: Dec terminal mouse handling |dec-mouse|
|
||||
N *+mouse_gpm* Unix only: Linux console mouse handling |gpm-mouse|
|
||||
m *+mouse_gpm/dyn* Same as |+mouse_gpm| with optional library dependency |/dyn|
|
||||
N *+mouse_jsbterm* JSB mouse handling |jsbterm-mouse|
|
||||
B *+mouse_netterm* Unix only: netterm mouse handling |netterm-mouse|
|
||||
N *+mouse_pterm* QNX only: pterm mouse handling |qnx-terminal|
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2022 Feb 18
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2022 Feb 22
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -245,9 +245,11 @@ that the name interferes with builtin functions.
|
||||
*vim9-s-namespace*
|
||||
The use of the "s:" prefix is not supported at the Vim9 script level. All
|
||||
functions and variables without a prefix are script-local.
|
||||
In :def functions the use of "s:" is optional. This is because in legacy
|
||||
script the "s:" might be needed. Disallowing the use of "s:" only in a :def
|
||||
function in Vim9 script would be a bit confusing.
|
||||
|
||||
In :def functions the use of "s:" depends on the script: Script-local
|
||||
variables and functions in a legacy script do use "s:", while in a Vim9 script
|
||||
they do not use "s:". This matches what you see in the rest of the file.
|
||||
|
||||
In legacy functions the use of "s:" for script items is required, as before.
|
||||
|
||||
In all cases the function must be defined before used. That is when it is
|
||||
@@ -1467,7 +1469,7 @@ strings: >
|
||||
# typename(mylist) == "list<string>", no error
|
||||
|
||||
There is a subtle difference between using a list constant directly and
|
||||
through a variable declaraiton. Because of type inference, when using a list
|
||||
through a variable declaration. Because of type inference, when using a list
|
||||
constant to initialize a variable, this also sets the declared type: >
|
||||
var mylist = [1, 2, 3]
|
||||
# typename(mylist) == "list<number>"
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
" You can also use this as a start for your own set of menus.
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2022 Feb 04
|
||||
" Last Change: 2022 Feb 23
|
||||
|
||||
" Note that ":an" (short for ":anoremenu") is often used to make a menu work
|
||||
" in all modes and avoid side effects from mappings defined by the user.
|
||||
@@ -443,7 +443,7 @@ def s:SetupColorSchemes()
|
||||
n += globpath(&packpath, "pack/*/opt/*/colors/*.vim", 1, 1)
|
||||
|
||||
# Ignore case for VMS and windows, sort on name
|
||||
var names = sort(map(n, 'substitute(v:val, "\\c.*[/\\\\:\\]]\\([^/\\\\:]*\\)\\.vim", "\\1", "")'), 1)
|
||||
var names = sort(map(n, 'substitute(v:val, "\\c.*[/\\\\:\\]]\\([^/\\\\:]*\\)\\.vim", "\\1", "")'), 'i')
|
||||
|
||||
# define all the submenu entries
|
||||
var idx = 100
|
||||
|
||||
@@ -526,6 +526,8 @@ CClink = $(CC)
|
||||
# though you have gpm libraries and includes.
|
||||
# For Debian/Ubuntu gpm support requires the libgpm-dev package.
|
||||
#CONF_OPT_GPM = --disable-gpm
|
||||
# Use this to enable dynamic loading of the GPM library.
|
||||
#CONF_OPT_GPM = --enable-gpm=dynamic
|
||||
|
||||
# sysmouse - For mouse support on FreeBSD and DragonFly console via sysmouse
|
||||
# Uncomment this when you do not want do include sysmouse support, even
|
||||
|
||||
@@ -507,3 +507,6 @@
|
||||
|
||||
/* Define if _SC_SIGSTKSZ is available via sysconf() */
|
||||
#undef HAVE_SYSCONF_SIGSTKSZ
|
||||
|
||||
/* Define if you want to load libgpm dynamically */
|
||||
#undef DYNAMIC_GPM
|
||||
|
||||
+10
-6
@@ -4294,13 +4294,13 @@ if test "x$GTK_CFLAGS" != "x"; then
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(--disable-gpm argument)
|
||||
AC_MSG_CHECKING(--enable-gpm argument)
|
||||
AC_ARG_ENABLE(gpm,
|
||||
[ --disable-gpm Don't use gpm (Linux mouse daemon).], ,
|
||||
[ --enable-gpm=OPTS Use gpm (Linux mouse daemon). default=yes OPTS=yes/no/dynamic], ,
|
||||
[enable_gpm="yes"])
|
||||
|
||||
if test "$enable_gpm" = "yes"; then
|
||||
AC_MSG_RESULT(no)
|
||||
if test "$enable_gpm" = "yes" -o "$enable_gpm" = "dynamic"; then
|
||||
AC_MSG_RESULT($enable_gpm)
|
||||
dnl Checking if gpm support can be compiled
|
||||
AC_CACHE_CHECK([for gpm], vi_cv_have_gpm,
|
||||
[olibs="$LIBS" ; LIBS="-lgpm"]
|
||||
@@ -4315,11 +4315,15 @@ if test "$enable_gpm" = "yes"; then
|
||||
[LIBS="$olibs"]
|
||||
)
|
||||
if test $vi_cv_have_gpm = yes; then
|
||||
LIBS="$LIBS -lgpm"
|
||||
if test "$enable_gpm" = "yes"; then
|
||||
LIBS="$LIBS -lgpm"
|
||||
else
|
||||
AC_DEFINE(DYNAMIC_GPM)
|
||||
fi
|
||||
AC_DEFINE(HAVE_GPM)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(--disable-sysmouse argument)
|
||||
|
||||
+2
-1
@@ -3015,7 +3015,8 @@ EXTERN char e_variable_arguments_type_must_be_list_str[]
|
||||
INIT(= N_("E1180: Variable arguments type must be a list: %s"));
|
||||
EXTERN char e_cannot_use_underscore_here[]
|
||||
INIT(= N_("E1181: Cannot use an underscore here"));
|
||||
// E1182 unused
|
||||
EXTERN char e_cannot_define_dict_func_in_vim9_script_str[]
|
||||
INIT(= N_("E1182: Cannot define a dict function in Vim9 script: %s"));
|
||||
EXTERN char e_cannot_use_range_with_assignment_operator_str[]
|
||||
INIT(= N_("E1183: Cannot use a range with an assignment operator: %s"));
|
||||
#endif
|
||||
|
||||
+116
-77
@@ -485,6 +485,82 @@ arg_list_or_dict_or_blob_or_string(type_T *type, type_T *decl_type UNUSED, argco
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check second argument of map() or filter().
|
||||
*/
|
||||
static int
|
||||
check_map_filter_arg2(type_T *type, argcontext_T *context, int is_map)
|
||||
{
|
||||
type_T *expected_member = NULL;
|
||||
type_T *(args[2]);
|
||||
type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, args};
|
||||
|
||||
if (context->arg_types[0].type_curr->tt_type == VAR_LIST
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_DICT)
|
||||
{
|
||||
// Use the declared type if possible, so that an error is given if
|
||||
// a declared list changes type, but not if a constant list changes
|
||||
// type.
|
||||
if (context->arg_types[0].type_decl->tt_type == VAR_LIST
|
||||
|| context->arg_types[0].type_decl->tt_type == VAR_DICT)
|
||||
expected_member = context->arg_types[0].type_decl->tt_member;
|
||||
else
|
||||
expected_member = context->arg_types[0].type_curr->tt_member;
|
||||
}
|
||||
else if (context->arg_types[0].type_curr->tt_type == VAR_STRING)
|
||||
expected_member = &t_string;
|
||||
else if (context->arg_types[0].type_curr->tt_type == VAR_BLOB)
|
||||
expected_member = &t_number;
|
||||
|
||||
args[0] = NULL;
|
||||
args[1] = &t_unknown;
|
||||
if (type->tt_argcount != -1)
|
||||
{
|
||||
if (!(type->tt_argcount == 2 || (type->tt_argcount == 1
|
||||
&& (type->tt_flags & TTFLAG_VARARGS))))
|
||||
{
|
||||
emsg(_(e_invalid_number_of_arguments));
|
||||
return FAIL;
|
||||
}
|
||||
if (type->tt_flags & TTFLAG_VARARGS)
|
||||
// check the argument types at runtime
|
||||
t_func_exp.tt_argcount = -1;
|
||||
else
|
||||
{
|
||||
if (context->arg_types[0].type_curr->tt_type == VAR_STRING
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_BLOB
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_LIST)
|
||||
args[0] = &t_number;
|
||||
else if (context->arg_types[0].type_decl->tt_type == VAR_DICT)
|
||||
args[0] = &t_string;
|
||||
if (args[0] != NULL)
|
||||
args[1] = expected_member;
|
||||
}
|
||||
}
|
||||
|
||||
if ((type->tt_member != &t_any && type->tt_member != &t_unknown)
|
||||
|| args[0] != NULL)
|
||||
{
|
||||
where_T where = WHERE_INIT;
|
||||
|
||||
if (is_map)
|
||||
t_func_exp.tt_member = expected_member == NULL
|
||||
|| type->tt_member == &t_any
|
||||
|| type->tt_member == &t_unknown
|
||||
? &t_any : expected_member;
|
||||
else
|
||||
t_func_exp.tt_member = &t_bool;
|
||||
if (args[0] == NULL)
|
||||
args[0] = &t_unknown;
|
||||
if (type->tt_argcount == -1)
|
||||
t_func_exp.tt_argcount = -1;
|
||||
|
||||
where.wt_index = 2;
|
||||
return check_type(&t_func_exp, type, TRUE, where);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check second argument of filter(): func must return a bool.
|
||||
*/
|
||||
@@ -498,22 +574,9 @@ arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
|
||||
return OK;
|
||||
|
||||
if (type->tt_type == VAR_FUNC)
|
||||
{
|
||||
if (!(type->tt_member->tt_type == VAR_BOOL
|
||||
|| type->tt_member->tt_type == VAR_NUMBER
|
||||
|| type->tt_member->tt_type == VAR_UNKNOWN
|
||||
|| type->tt_member->tt_type == VAR_ANY))
|
||||
{
|
||||
arg_type_mismatch(&t_func_bool, type, context->arg_idx + 1);
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
semsg(_(e_string_or_function_required_for_argument_nr), 2);
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
return check_map_filter_arg2(type, context, FALSE);
|
||||
semsg(_(e_string_or_function_required_for_argument_nr), 2);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -521,6 +584,24 @@ arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
|
||||
*/
|
||||
static int
|
||||
arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
|
||||
{
|
||||
if (type->tt_type == VAR_STRING
|
||||
|| type->tt_type == VAR_PARTIAL
|
||||
|| type == &t_unknown
|
||||
|| type == &t_any)
|
||||
return OK;
|
||||
|
||||
if (type->tt_type == VAR_FUNC)
|
||||
return check_map_filter_arg2(type, context, TRUE);
|
||||
semsg(_(e_string_or_function_required_for_argument_nr), 2);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check second argument of sort() and uniq(), the "how" argument.
|
||||
*/
|
||||
static int
|
||||
arg_sort_how(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
|
||||
{
|
||||
if (type->tt_type == VAR_STRING
|
||||
|| type->tt_type == VAR_PARTIAL
|
||||
@@ -530,75 +611,29 @@ arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
|
||||
|
||||
if (type->tt_type == VAR_FUNC)
|
||||
{
|
||||
type_T *expected_ret = NULL;
|
||||
type_T *(args[2]);
|
||||
type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, args};
|
||||
|
||||
if (context->arg_types[0].type_curr->tt_type == VAR_LIST
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_DICT)
|
||||
{
|
||||
// Use the declared type if possible, so that an error is given if
|
||||
// a declared list changes type, but not if a constant list changes
|
||||
// type.
|
||||
if (context->arg_types[0].type_decl->tt_type == VAR_LIST
|
||||
|| context->arg_types[0].type_decl->tt_type == VAR_DICT)
|
||||
expected_ret = context->arg_types[0].type_decl->tt_member;
|
||||
else
|
||||
expected_ret = context->arg_types[0].type_curr->tt_member;
|
||||
}
|
||||
else if (context->arg_types[0].type_curr->tt_type == VAR_STRING)
|
||||
expected_ret = &t_string;
|
||||
else if (context->arg_types[0].type_curr->tt_type == VAR_BLOB)
|
||||
expected_ret = &t_number;
|
||||
|
||||
args[0] = NULL;
|
||||
args[1] = &t_unknown;
|
||||
if (type->tt_argcount != -1)
|
||||
{
|
||||
if (!(type->tt_argcount == 2 || (type->tt_argcount == 1
|
||||
&& (type->tt_flags & TTFLAG_VARARGS))))
|
||||
{
|
||||
emsg(_(e_invalid_number_of_arguments));
|
||||
return FAIL;
|
||||
}
|
||||
if (type->tt_flags & TTFLAG_VARARGS)
|
||||
// check the argument types at runtime
|
||||
t_func_exp.tt_argcount = -1;
|
||||
else
|
||||
{
|
||||
if (context->arg_types[0].type_curr->tt_type == VAR_STRING
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_BLOB
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_LIST)
|
||||
args[0] = &t_number;
|
||||
else if (context->arg_types[0].type_decl->tt_type == VAR_DICT)
|
||||
args[0] = &t_string;
|
||||
if (args[0] != NULL)
|
||||
args[1] = expected_ret;
|
||||
}
|
||||
}
|
||||
type_T t_func_exp = {VAR_FUNC, 2, 0, 0, &t_number, args};
|
||||
|
||||
if (context->arg_types[0].type_curr->tt_type == VAR_LIST)
|
||||
args[0] = context->arg_types[0].type_curr->tt_member;
|
||||
else
|
||||
args[0] = &t_unknown;
|
||||
if ((type->tt_member != &t_any && type->tt_member != &t_unknown)
|
||||
|| args[0] != NULL)
|
||||
|| args[0] != &t_unknown)
|
||||
{
|
||||
where_T where = WHERE_INIT;
|
||||
|
||||
t_func_exp.tt_member = expected_ret == NULL
|
||||
|| type->tt_member == &t_any
|
||||
|| type->tt_member == &t_unknown
|
||||
? &t_any : expected_ret;
|
||||
if (args[0] == NULL)
|
||||
args[0] = &t_unknown;
|
||||
|
||||
args[1] = args[0];
|
||||
if (type->tt_argcount == -1)
|
||||
t_func_exp.tt_argcount = -1;
|
||||
where.wt_index = 2;
|
||||
return check_type(&t_func_exp, type, TRUE, where);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
semsg(_(e_string_or_function_required_for_argument_nr), 2);
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
semsg(_(e_string_or_function_required_for_argument_nr), 2);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1012,7 +1047,7 @@ static argcheck_T arg23_settagstack[] = {arg_number, arg_dict_any, arg_string};
|
||||
static argcheck_T arg02_sign_getplaced[] = {arg_buffer, arg_dict_any};
|
||||
static argcheck_T arg45_sign_place[] = {arg_number, arg_string, arg_string, arg_buffer, arg_dict_any};
|
||||
static argcheck_T arg23_slice[] = {arg_slice1, arg_number, arg_number};
|
||||
static argcheck_T arg13_sortuniq[] = {arg_list_any, NULL, arg_dict_any};
|
||||
static argcheck_T arg13_sortuniq[] = {arg_list_any, arg_sort_how, arg_dict_any};
|
||||
static argcheck_T arg24_strpart[] = {arg_string, arg_number, arg_number, arg_bool};
|
||||
static argcheck_T arg12_system[] = {arg_string, arg_str_or_nr_or_list};
|
||||
static argcheck_T arg23_win_execute[] = {arg_number, arg_string_or_list_string, arg_string};
|
||||
@@ -5769,7 +5804,7 @@ f_has(typval_T *argvars, typval_T *rettv)
|
||||
#endif
|
||||
},
|
||||
{"mouse_gpm",
|
||||
#if (defined(UNIX) || defined(VMS)) && defined(FEAT_MOUSE_GPM)
|
||||
#if (defined(UNIX) || defined(VMS)) && defined(FEAT_MOUSE_GPM) && !defined(DYNAMIC_GPM)
|
||||
1
|
||||
#else
|
||||
0
|
||||
@@ -6395,6 +6430,10 @@ f_has(typval_T *argvars, typval_T *rettv)
|
||||
#if defined(FEAT_TERMINAL) && defined(MSWIN)
|
||||
else if (STRICMP(name, "terminal") == 0)
|
||||
n = terminal_enabled();
|
||||
#endif
|
||||
#ifdef DYNAMIC_GPM
|
||||
else if (STRICMP(name, "mouse_gpm") == 0)
|
||||
n = gpm_available();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -964,6 +964,12 @@
|
||||
*/
|
||||
#if defined(FEAT_NORMAL) && defined(HAVE_GPM)
|
||||
# define FEAT_MOUSE_GPM
|
||||
/*
|
||||
* +mouse_gpm/dyn Load libgpm dynamically.
|
||||
*/
|
||||
# ifndef DYNAMIC_GPM
|
||||
// # define DYNAMIC_GPM
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_NORMAL) && defined(HAVE_SYSMOUSE)
|
||||
|
||||
+2
-1
@@ -2198,7 +2198,8 @@ do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
|
||||
if (in_vim9script()
|
||||
&& (check_for_list_arg(argvars, 0) == FAIL
|
||||
|| (argvars[1].v_type != VAR_UNKNOWN
|
||||
&& check_for_opt_dict_arg(argvars, 2) == FAIL)))
|
||||
&& (check_for_string_or_func_arg(argvars, 1) == FAIL
|
||||
|| check_for_opt_dict_arg(argvars, 2) == FAIL))))
|
||||
return;
|
||||
|
||||
if (argvars[0].v_type != VAR_LIST)
|
||||
|
||||
+2
-1
@@ -318,6 +318,7 @@ enc_alias_table[] =
|
||||
{
|
||||
{"ansi", IDX_LATIN_1},
|
||||
{"iso-8859-1", IDX_LATIN_1},
|
||||
{"iso-8859", IDX_LATIN_1},
|
||||
{"latin2", IDX_ISO_2},
|
||||
{"latin3", IDX_ISO_3},
|
||||
{"latin4", IDX_ISO_4},
|
||||
@@ -4523,7 +4524,7 @@ enc_canonize(char_u *enc)
|
||||
}
|
||||
|
||||
// "iso-8859n" -> "iso-8859-n"
|
||||
if (STRNCMP(p, "iso-8859", 8) == 0 && p[8] != '-')
|
||||
if (STRNCMP(p, "iso-8859", 8) == 0 && isdigit(p[8]))
|
||||
{
|
||||
STRMOVE(p + 9, p + 8);
|
||||
p[8] = '-';
|
||||
|
||||
@@ -4587,6 +4587,14 @@ get_encoding_default(void)
|
||||
return (char_u *)NULL;
|
||||
}
|
||||
|
||||
int
|
||||
is_option_allocated(char *name)
|
||||
{
|
||||
int idx = findoption((char_u *)name);
|
||||
|
||||
return idx >= 0 && (options[idx].flags & P_ALLOCED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
|
||||
* When "has_lt" is true there is a '<' before "*arg_arg".
|
||||
|
||||
+67
-1
@@ -55,7 +55,25 @@ static int selinux_enabled = -1;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_MOUSE_GPM
|
||||
|
||||
# include <gpm.h>
|
||||
|
||||
# ifdef DYNAMIC_GPM
|
||||
# define Gpm_Open (*dll_Gpm_Open)
|
||||
# define Gpm_Close (*dll_Gpm_Close)
|
||||
# define Gpm_GetEvent (*dll_Gpm_GetEvent)
|
||||
# define gpm_flag (dll_gpm_flag != NULL ? *dll_gpm_flag : 0)
|
||||
# define gpm_fd (dll_gpm_fd != NULL ? *dll_gpm_fd : -1)
|
||||
|
||||
static int (*dll_Gpm_Open) (Gpm_Connect *, int);
|
||||
static int (*dll_Gpm_Close) (void);
|
||||
static int (*dll_Gpm_GetEvent) (Gpm_Event *);
|
||||
static int *dll_gpm_flag;
|
||||
static int *dll_gpm_fd;
|
||||
|
||||
static void *libgpm_hinst;
|
||||
# endif
|
||||
|
||||
// <linux/keyboard.h> contains defines conflicting with "keymap.h",
|
||||
// I just copied relevant defines here. A cleaner solution would be to put gpm
|
||||
// code into separate file and include there linux/keyboard.h
|
||||
@@ -6468,7 +6486,7 @@ select_eintr:
|
||||
}
|
||||
# endif
|
||||
# ifdef FEAT_MOUSE_GPM
|
||||
if (ret > 0 && gpm_flag && check_for_gpm != NULL && gpm_fd >= 0)
|
||||
if (ret > 0 && check_for_gpm != NULL && gpm_flag && gpm_fd >= 0)
|
||||
{
|
||||
if (FD_ISSET(gpm_fd, &efds))
|
||||
gpm_close();
|
||||
@@ -7194,6 +7212,49 @@ mch_rename(const char *src, const char *dest)
|
||||
#endif // !HAVE_RENAME
|
||||
|
||||
#if defined(FEAT_MOUSE_GPM) || defined(PROTO)
|
||||
# if defined(DYNAMIC_GPM) || defined(PROTO)
|
||||
/*
|
||||
* Initialize Gpm's symbols for dynamic linking.
|
||||
* Must be called only if libgpm_hinst is NULL.
|
||||
*/
|
||||
static int
|
||||
load_libgpm(void)
|
||||
{
|
||||
libgpm_hinst = dlopen("libgpm.so", RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
if (libgpm_hinst == NULL)
|
||||
{
|
||||
if (p_verbose > 0)
|
||||
smsg_attr(HL_ATTR(HLF_W),
|
||||
_("Could not load gpm library: %s"), dlerror());
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (
|
||||
(dll_Gpm_Open = dlsym(libgpm_hinst, "Gpm_Open")) == NULL
|
||||
|| (dll_Gpm_Close = dlsym(libgpm_hinst, "Gpm_Close")) == NULL
|
||||
|| (dll_Gpm_GetEvent = dlsym(libgpm_hinst, "Gpm_GetEvent")) == NULL
|
||||
|| (dll_gpm_flag = dlsym(libgpm_hinst, "gpm_flag")) == NULL
|
||||
|| (dll_gpm_fd = dlsym(libgpm_hinst, "gpm_fd")) == NULL
|
||||
)
|
||||
{
|
||||
semsg(_(e_could_not_load_library_str_str), "gpm", dlerror());
|
||||
dlclose(libgpm_hinst);
|
||||
libgpm_hinst = NULL;
|
||||
dll_gpm_flag = NULL;
|
||||
dll_gpm_fd = NULL;
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
gpm_available(void)
|
||||
{
|
||||
return libgpm_hinst != NULL || load_libgpm() == OK;
|
||||
}
|
||||
# endif // DYNAMIC_GPM
|
||||
|
||||
/*
|
||||
* Initializes connection with gpm (if it isn't already opened)
|
||||
* Return 1 if succeeded (or connection already opened), 0 if failed
|
||||
@@ -7203,6 +7264,11 @@ gpm_open(void)
|
||||
{
|
||||
static Gpm_Connect gpm_connect; // Must it be kept till closing ?
|
||||
|
||||
#ifdef DYNAMIC_GPM
|
||||
if (!gpm_available())
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (!gpm_flag)
|
||||
{
|
||||
gpm_connect.eventMask = (GPM_UP | GPM_DRAG | GPM_DOWN);
|
||||
|
||||
@@ -41,6 +41,7 @@ char *set_option_value(char_u *name, long number, char_u *string, int opt_flags)
|
||||
char_u *get_term_code(char_u *tname);
|
||||
char_u *get_highlight_default(void);
|
||||
char_u *get_encoding_default(void);
|
||||
int is_option_allocated(char *name);
|
||||
int makeset(FILE *fd, int opt_flags, int local_only);
|
||||
int makefoldset(FILE *fd);
|
||||
void clear_termoptions(void);
|
||||
|
||||
@@ -85,4 +85,5 @@ void clip_xterm_set_selection(Clipboard_T *cbd);
|
||||
int xsmp_handle_requests(void);
|
||||
void xsmp_init(void);
|
||||
void xsmp_close(void);
|
||||
int gpm_available(void);
|
||||
/* vim: set ft=c : */
|
||||
|
||||
+4
-1
@@ -8235,6 +8235,7 @@ ex_helpgrep(exarg_T *eap)
|
||||
{
|
||||
regmatch_T regmatch;
|
||||
char_u *save_cpo;
|
||||
int save_cpo_allocated;
|
||||
qf_info_T *qi = &ql_info;
|
||||
int new_qi = FALSE;
|
||||
char_u *au_name = NULL;
|
||||
@@ -8265,6 +8266,7 @@ ex_helpgrep(exarg_T *eap)
|
||||
|
||||
// Make 'cpoptions' empty, the 'l' flag should not be used here.
|
||||
save_cpo = p_cpo;
|
||||
save_cpo_allocated = is_option_allocated("cpo");
|
||||
p_cpo = empty_option;
|
||||
|
||||
incr_quickfix_busy();
|
||||
@@ -8302,7 +8304,8 @@ ex_helpgrep(exarg_T *eap)
|
||||
// changed and restored, need to restore in the complicated way.
|
||||
if (*p_cpo == NUL)
|
||||
set_option_value((char_u *)"cpo", 0L, save_cpo, 0);
|
||||
free_string_option(save_cpo);
|
||||
if (save_cpo_allocated)
|
||||
free_string_option(save_cpo);
|
||||
}
|
||||
|
||||
if (updated)
|
||||
|
||||
@@ -4615,6 +4615,11 @@ regmatch(
|
||||
if (rex.input == rex.line)
|
||||
{
|
||||
// backup to last char of previous line
|
||||
if (rex.lnum == 0)
|
||||
{
|
||||
status = RA_NOMATCH;
|
||||
break;
|
||||
}
|
||||
--rex.lnum;
|
||||
rex.line = reg_getline(rex.lnum);
|
||||
// Just in case regrepeat() didn't count
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
" Tests for exiting Vim.
|
||||
|
||||
source shared.vim
|
||||
source check.vim
|
||||
|
||||
func Test_exiting()
|
||||
let after =<< trim [CODE]
|
||||
@@ -109,4 +110,21 @@ func Test_exit_code()
|
||||
call delete('Xtestout')
|
||||
endfunc
|
||||
|
||||
func Test_exit_error_reading_input()
|
||||
CheckNotGui
|
||||
CheckNotMSWindows
|
||||
" The early exit causes memory not to be freed somehow
|
||||
CheckNotAsan
|
||||
|
||||
call writefile([":au VimLeave * call writefile(['l = ' .. v:exiting], 'Xtestout')", ":tabnew", "q:"], 'Xscript', 'b')
|
||||
|
||||
if RunVim([], [], '<Xscript')
|
||||
call assert_equal(1, v:shell_error)
|
||||
call assert_equal(['l = 1'], readfile('Xtestout'))
|
||||
endif
|
||||
call delete('Xscript')
|
||||
call delete('Xtestout')
|
||||
endfun
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -949,7 +949,7 @@ func Test_reverse_sort_uniq()
|
||||
call assert_equal([-1, 'one', 'two', 'three', 'four', 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255], sort(copy(l), 'n'))
|
||||
|
||||
LET l = [7, 9, 18, 12, 22, 10.0e-16, -1, 0xff, 0, -0, 0.22, 'bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', {}, []]
|
||||
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1))
|
||||
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i'))
|
||||
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i'))
|
||||
call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l)))
|
||||
endif
|
||||
@@ -961,6 +961,16 @@ func Test_reverse_sort_uniq()
|
||||
call assert_fails("call sort([1, 2], function('min'), 1)", "E715:")
|
||||
call assert_fails("call sort([1, 2], function('invalid_func'))", "E700:")
|
||||
call assert_fails("call sort([1, 2], function('min'))", "E118:")
|
||||
|
||||
let lines =<< trim END
|
||||
call sort(['a', 'b'], 0)
|
||||
END
|
||||
call v9.CheckDefAndScriptFailure(lines, 'E1256: String or function required for argument 2')
|
||||
|
||||
let lines =<< trim END
|
||||
call sort(['a', 'b'], 1)
|
||||
END
|
||||
call v9.CheckDefAndScriptFailure(lines, 'E1256: String or function required for argument 2')
|
||||
endfunc
|
||||
|
||||
" reduce a list, blob or string
|
||||
|
||||
@@ -445,6 +445,31 @@ func Test_set_errors()
|
||||
call assert_fails('set t_#-&', 'E522:')
|
||||
endfunc
|
||||
|
||||
func Test_set_encoding()
|
||||
let save_encoding = &encoding
|
||||
|
||||
set enc=iso8859-1
|
||||
call assert_equal('latin1', &enc)
|
||||
set enc=iso8859_1
|
||||
call assert_equal('latin1', &enc)
|
||||
set enc=iso-8859-1
|
||||
call assert_equal('latin1', &enc)
|
||||
set enc=iso_8859_1
|
||||
call assert_equal('latin1', &enc)
|
||||
set enc=iso88591
|
||||
call assert_equal('latin1', &enc)
|
||||
set enc=iso8859
|
||||
call assert_equal('latin1', &enc)
|
||||
set enc=iso-8859
|
||||
call assert_equal('latin1', &enc)
|
||||
set enc=iso_8859
|
||||
call assert_equal('latin1', &enc)
|
||||
call assert_fails('set enc=iso8858', 'E474:')
|
||||
call assert_equal('latin1', &enc)
|
||||
|
||||
let &encoding = save_encoding
|
||||
endfunc
|
||||
|
||||
func CheckWasSet(name)
|
||||
let verb_cm = execute('verbose set ' .. a:name .. '?')
|
||||
call assert_match('Last set from.*test_options.vim', verb_cm)
|
||||
|
||||
@@ -745,6 +745,33 @@ def Test_helpgrep_vim9_restore_cpo()
|
||||
helpclose
|
||||
enddef
|
||||
|
||||
func Test_helpgrep_restore_cpo_aucmd()
|
||||
let save_cpo = &cpo
|
||||
augroup QF_Test
|
||||
au!
|
||||
autocmd BufNew * set cpo=acd
|
||||
augroup END
|
||||
|
||||
helpgrep quickfix
|
||||
call assert_equal('acd', &cpo)
|
||||
%bw!
|
||||
|
||||
set cpo&vim
|
||||
augroup QF_Test
|
||||
au!
|
||||
autocmd BufReadPost * set cpo=
|
||||
augroup END
|
||||
|
||||
helpgrep buffer
|
||||
call assert_equal('', &cpo)
|
||||
|
||||
augroup QF_Test
|
||||
au!
|
||||
augroup END
|
||||
%bw!
|
||||
let &cpo = save_cpo
|
||||
endfunc
|
||||
|
||||
def Test_vim9_cexpr()
|
||||
var text = 'somefile:95:error'
|
||||
cexpr text
|
||||
|
||||
@@ -508,7 +508,6 @@ endfunc
|
||||
" Check that [[:upper:]] matches for automatic engine
|
||||
func Test_match_char_class_upper()
|
||||
new
|
||||
let _engine=®expengine
|
||||
|
||||
" Test 1: [[:upper:]]\{2,\}
|
||||
set regexpengine=0
|
||||
@@ -549,7 +548,7 @@ func Test_match_char_class_upper()
|
||||
call assert_equal(4, searchcount().total, 'TEST 3 lower')
|
||||
|
||||
" clean up
|
||||
let ®expengine=_engine
|
||||
set regexpengine=0
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
@@ -561,4 +560,13 @@ func Test_match_invalid_byte()
|
||||
call delete('Xinvalid')
|
||||
endfunc
|
||||
|
||||
func Test_match_too_complicated()
|
||||
set regexpengine=1
|
||||
exe "noswapfile vsplit \xeb\xdb\x99"
|
||||
silent! buf \&\zs*\zs*0
|
||||
bwipe!
|
||||
set regexpengine=0
|
||||
endfunc
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -715,7 +715,8 @@ endfunction
|
||||
func Test_terminal_noblock()
|
||||
let g:test_is_flaky = 1
|
||||
let buf = term_start(&shell)
|
||||
let wait_time = 5000
|
||||
" Starting a terminal can be slow, esp. on busy CI machines.
|
||||
let wait_time = 7500
|
||||
let letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
if has('bsd') || has('mac') || has('sun')
|
||||
" The shell or something else has a problem dealing with more than 1000
|
||||
|
||||
@@ -445,12 +445,13 @@ endfunc
|
||||
func Test_vartabstop_latin1()
|
||||
let save_encoding = &encoding
|
||||
new
|
||||
set encoding=iso8859
|
||||
silent norm :se
|
||||
set encoding=iso8859-1
|
||||
set compatible linebreak list revins smarttab
|
||||
set vartabstop=400
|
||||
norm i00
|
||||
exe "norm i00\t\<C-D>"
|
||||
bwipe!
|
||||
let &encoding = save_encoding
|
||||
set nocompatible linebreak& list& revins& smarttab& vartabstop&
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ def Test_assignment()
|
||||
enddef
|
||||
defcompile
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1089:')
|
||||
v9.CheckScriptFailure(lines, 'E1268:')
|
||||
|
||||
g:inc_counter += 1
|
||||
assert_equal(2, g:inc_counter)
|
||||
@@ -2460,6 +2460,49 @@ def Run_Test_declare_command_line()
|
||||
g:StopVimInTerminal(buf)
|
||||
enddef
|
||||
|
||||
def Test_using_s_var_in_function()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
var scriptlevel = 123
|
||||
def SomeFunc()
|
||||
echo s:scriptlevel
|
||||
enddef
|
||||
SomeFunc()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1268:')
|
||||
|
||||
# OK in legacy script
|
||||
lines =<< trim END
|
||||
let s:scriptlevel = 123
|
||||
def s:SomeFunc()
|
||||
echo s:scriptlevel
|
||||
enddef
|
||||
call s:SomeFunc()
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var scriptlevel = 123
|
||||
def SomeFunc()
|
||||
s:scriptlevel = 456
|
||||
enddef
|
||||
SomeFunc()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1268:')
|
||||
|
||||
# OK in legacy script
|
||||
lines =<< trim END
|
||||
let s:scriptlevel = 123
|
||||
def s:SomeFunc()
|
||||
s:scriptlevel = 456
|
||||
enddef
|
||||
call s:SomeFunc()
|
||||
call assert_equal(456, s:scriptlevel)
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
|
||||
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
||||
@@ -427,6 +427,21 @@ def Test_call_call()
|
||||
call('reverse', [l])
|
||||
l->assert_equal([1, 2, 3])
|
||||
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def Outer()
|
||||
def g:Inner()
|
||||
g:done = 'Inner'
|
||||
enddef
|
||||
call(g:Inner, [])
|
||||
enddef
|
||||
Outer()
|
||||
assert_equal('Inner', g:done)
|
||||
unlet g:done
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
delfunc g:Inner
|
||||
|
||||
v9.CheckDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1')
|
||||
v9.CheckDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1')
|
||||
v9.CheckDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
|
||||
@@ -1315,17 +1330,6 @@ def Wrong_dict_key_type(items: list<number>): list<number>
|
||||
enddef
|
||||
|
||||
def Test_filter()
|
||||
v9.CheckDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got float', 'E1251: List, Dictionary, Blob or String required for argument 1'])
|
||||
v9.CheckDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String'])
|
||||
|
||||
var lines =<< trim END
|
||||
def F(i: number, v: any): string
|
||||
return 'bad'
|
||||
enddef
|
||||
echo filter([1, 2, 3], F)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(...): bool', 'E1135: Using a String as a Bool:'])
|
||||
|
||||
assert_equal([], filter([1, 2, 3], '0'))
|
||||
assert_equal([1, 2, 3], filter([1, 2, 3], '1'))
|
||||
assert_equal({b: 20}, filter({a: 10, b: 20}, 'v:val == 20'))
|
||||
@@ -1335,6 +1339,72 @@ def Test_filter()
|
||||
return range(3)->filter(Odd)
|
||||
enddef
|
||||
assert_equal([1], GetFiltered())
|
||||
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def Func(): list<string>
|
||||
var MatchWord: func: bool = (_, v) => true
|
||||
var l = ['xxx']
|
||||
return l->filter(MatchWord)
|
||||
enddef
|
||||
assert_equal(['xxx'], Func())
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
v9.CheckDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got float', 'E1251: List, Dictionary, Blob or String required for argument 1'])
|
||||
v9.CheckDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String'])
|
||||
|
||||
lines =<< trim END
|
||||
def F(i: number, v: any): string
|
||||
return 'bad'
|
||||
enddef
|
||||
echo filter([1, 2, 3], F)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?any): bool but got func(number, any): string', 'E1135: Using a String as a Bool:'])
|
||||
|
||||
# check first function argument type
|
||||
lines =<< trim END
|
||||
var l = [1, 2, 3]
|
||||
filter(l, (i: string, v: number) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
|
||||
lines =<< trim END
|
||||
var d = {a: 1}
|
||||
filter(d, (i: number, v: number) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(number, number): bool', 'E1013: Argument 1: type mismatch, expected number but got string'])
|
||||
lines =<< trim END
|
||||
var b = 0z1122
|
||||
filter(b, (i: string, v: number) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(string, number): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
|
||||
lines =<< trim END
|
||||
var s = 'text'
|
||||
filter(s, (i: string, v: string) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(string, string): bool', 'E1013: Argument 1: type mismatch, expected string but got number'])
|
||||
|
||||
# check second function argument type
|
||||
lines =<< trim END
|
||||
var l = [1, 2, 3]
|
||||
filter(l, (i: number, v: string) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
|
||||
lines =<< trim END
|
||||
var d = {a: 1}
|
||||
filter(d, (i: string, v: string) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?number): bool but got func(string, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
|
||||
lines =<< trim END
|
||||
var b = 0z1122
|
||||
filter(b, (i: number, v: string) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): bool but got func(number, string): bool', 'E1013: Argument 2: type mismatch, expected string but got number'])
|
||||
lines =<< trim END
|
||||
var s = 'text'
|
||||
filter(s, (i: number, v: number) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?string): bool but got func(number, number): bool', 'E1013: Argument 2: type mismatch, expected number but got string'])
|
||||
enddef
|
||||
|
||||
def Test_filter_wrong_dict_key_type()
|
||||
@@ -3737,19 +3807,52 @@ def Test_sort_argument()
|
||||
assert_equal([1, 2, 3, 4, 5, 6, 7, 8], l)
|
||||
END
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
v9.CheckDefAndScriptFailure(['sort("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
|
||||
v9.CheckDefAndScriptFailure(['sort([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
|
||||
|
||||
lines =<< trim END
|
||||
sort([1, 2, 3], (a: any, b: any) => 1)
|
||||
END
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
def SortedList(): list<number>
|
||||
var Lambda: func: number = (a, b): number => a - b
|
||||
var l = [3, 2, 1]
|
||||
return l->sort(Lambda)
|
||||
enddef
|
||||
SortedList()->assert_equal([1, 2, 3])
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_sort_compare_func_fails()
|
||||
v9.CheckDefAndScriptFailure(['sort("a")'], ['E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1'])
|
||||
v9.CheckDefAndScriptFailure(['sort([1], "", [1])'], ['E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3'])
|
||||
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
echo ['a', 'b', 'c']->sort((a: number, b: number) => 0)
|
||||
END
|
||||
writefile(lines, 'Xbadsort')
|
||||
assert_fails('source Xbadsort', ['E1013:', 'E702:'])
|
||||
|
||||
delete('Xbadsort')
|
||||
|
||||
lines =<< trim END
|
||||
var l = [1, 2, 3]
|
||||
sort(l, (a: string, b: number) => 1)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(string, number): number', 'E1013: Argument 1: type mismatch, expected string but got number'])
|
||||
|
||||
lines =<< trim END
|
||||
var l = ['a', 'b', 'c']
|
||||
sort(l, (a: string, b: number) => 1)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?string, ?string): number but got func(string, number): number', 'E1013: Argument 2: type mismatch, expected number but got string'])
|
||||
|
||||
lines =<< trim END
|
||||
sort([1, 2, 3], (a: number, b: number) => true)
|
||||
END
|
||||
v9.CheckDefAndScriptFailure(lines, ['E1013: Argument 2: type mismatch, expected func(?number, ?number): number but got func(number, number): bool', 'E1138: Using a Bool as a Number'])
|
||||
enddef
|
||||
|
||||
def Test_spellbadword()
|
||||
|
||||
@@ -106,6 +106,63 @@ def Test_wrong_function_name()
|
||||
enddef
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1267:')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var Object = {}
|
||||
function Object.Method()
|
||||
endfunction
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1182:')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var Object = {}
|
||||
def Object.Method()
|
||||
enddef
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1182:')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
g:Object = {}
|
||||
function g:Object.Method()
|
||||
endfunction
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1182:')
|
||||
|
||||
lines =<< trim END
|
||||
let s:Object = {}
|
||||
def Define()
|
||||
function s:Object.Method()
|
||||
endfunction
|
||||
enddef
|
||||
defcompile
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1182:')
|
||||
delfunc g:Define
|
||||
|
||||
lines =<< trim END
|
||||
let s:Object = {}
|
||||
def Define()
|
||||
def Object.Method()
|
||||
enddef
|
||||
enddef
|
||||
defcompile
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1182:')
|
||||
delfunc g:Define
|
||||
|
||||
lines =<< trim END
|
||||
let g:Object = {}
|
||||
def Define()
|
||||
function g:Object.Method()
|
||||
endfunction
|
||||
enddef
|
||||
defcompile
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1182:')
|
||||
delfunc g:Define
|
||||
enddef
|
||||
|
||||
def Test_autoload_name_mismatch()
|
||||
|
||||
+14
-3
@@ -4268,10 +4268,21 @@ define_function(exarg_T *eap, char_u *name_arg, garray_T *lines_to_free)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vim9script && p[0] == 's' && p[1] == ':')
|
||||
if (vim9script)
|
||||
{
|
||||
semsg(_(e_cannot_use_s_colon_in_vim9_script_str), p);
|
||||
return NULL;
|
||||
if (p[0] == 's' && p[1] == ':')
|
||||
{
|
||||
semsg(_(e_cannot_use_s_colon_in_vim9_script_str), p);
|
||||
return NULL;
|
||||
}
|
||||
p = to_name_end(p, TRUE);
|
||||
if (*skipwhite(p) == '.' && vim_strchr(p, '(') != NULL)
|
||||
{
|
||||
semsg(_(e_cannot_define_dict_func_in_vim9_script_str),
|
||||
eap->arg);
|
||||
return NULL;
|
||||
}
|
||||
p = eap->arg;
|
||||
}
|
||||
|
||||
name = save_function_name(&p, &is_global, eap->skip,
|
||||
|
||||
@@ -380,7 +380,11 @@ static char *(features[]) =
|
||||
"-mouse_dec",
|
||||
# endif
|
||||
# ifdef FEAT_MOUSE_GPM
|
||||
# ifdef DYNAMIC_GPM
|
||||
"+mouse_gpm/dyn",
|
||||
# else
|
||||
"+mouse_gpm",
|
||||
# endif
|
||||
# else
|
||||
"-mouse_gpm",
|
||||
# endif
|
||||
@@ -765,6 +769,54 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
4460,
|
||||
/**/
|
||||
4459,
|
||||
/**/
|
||||
4458,
|
||||
/**/
|
||||
4457,
|
||||
/**/
|
||||
4456,
|
||||
/**/
|
||||
4455,
|
||||
/**/
|
||||
4454,
|
||||
/**/
|
||||
4453,
|
||||
/**/
|
||||
4452,
|
||||
/**/
|
||||
4451,
|
||||
/**/
|
||||
4450,
|
||||
/**/
|
||||
4449,
|
||||
/**/
|
||||
4448,
|
||||
/**/
|
||||
4447,
|
||||
/**/
|
||||
4446,
|
||||
/**/
|
||||
4445,
|
||||
/**/
|
||||
4444,
|
||||
/**/
|
||||
4443,
|
||||
/**/
|
||||
4442,
|
||||
/**/
|
||||
4441,
|
||||
/**/
|
||||
4440,
|
||||
/**/
|
||||
4439,
|
||||
/**/
|
||||
4438,
|
||||
/**/
|
||||
4437,
|
||||
/**/
|
||||
4436,
|
||||
/**/
|
||||
|
||||
+11
-1
@@ -831,7 +831,11 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
|
||||
{
|
||||
if (!ends_excmd2(name_start, name_end))
|
||||
{
|
||||
semsg(_(e_invalid_command_str), eap->cmd);
|
||||
if (*skipwhite(name_end) == '.')
|
||||
semsg(_(e_cannot_define_dict_func_in_vim9_script_str),
|
||||
eap->cmd);
|
||||
else
|
||||
semsg(_(e_invalid_command_str), eap->cmd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1331,6 +1335,12 @@ compile_lhs(
|
||||
char_u *rawname = lhs->lhs_name
|
||||
+ (lhs->lhs_name[1] == ':' ? 2 : 0);
|
||||
|
||||
if (script_namespace && current_script_is_vim9())
|
||||
{
|
||||
semsg(_(e_cannot_use_s_colon_in_vim9_script_str),
|
||||
var_start);
|
||||
return FAIL;
|
||||
}
|
||||
if (is_decl)
|
||||
{
|
||||
if (script_namespace)
|
||||
|
||||
+22
-5
@@ -2333,16 +2333,33 @@ load_namespace_var(ectx_T *ectx, isntype_T isn_type, isn_T *iptr)
|
||||
|
||||
if (di == NULL)
|
||||
{
|
||||
if (isn_type == ISN_LOADG)
|
||||
{
|
||||
ufunc_T *ufunc = find_func(iptr->isn_arg.string, TRUE);
|
||||
|
||||
// g:Something could be a function
|
||||
if (ufunc != NULL)
|
||||
{
|
||||
typval_T *tv = STACK_TV_BOT(0);
|
||||
|
||||
++ectx->ec_stack.ga_len;
|
||||
tv->v_type = VAR_FUNC;
|
||||
tv->vval.v_string = alloc(STRLEN(iptr->isn_arg.string) + 3);
|
||||
if (tv->vval.v_string == NULL)
|
||||
return FAIL;
|
||||
STRCPY(tv->vval.v_string, "g:");
|
||||
STRCPY(tv->vval.v_string + 2, iptr->isn_arg.string);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
SOURCING_LNUM = iptr->isn_lnum;
|
||||
if (vim_strchr(iptr->isn_arg.string,
|
||||
AUTOLOAD_CHAR) != NULL)
|
||||
if (vim_strchr(iptr->isn_arg.string, AUTOLOAD_CHAR) != NULL)
|
||||
// no check if the item exists in the script but
|
||||
// isn't exported, it is too complicated
|
||||
semsg(_(e_item_not_found_in_script_str),
|
||||
iptr->isn_arg.string);
|
||||
semsg(_(e_item_not_found_in_script_str), iptr->isn_arg.string);
|
||||
else
|
||||
semsg(_(e_undefined_variable_char_str),
|
||||
namespace, iptr->isn_arg.string);
|
||||
namespace, iptr->isn_arg.string);
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
|
||||
+9
-2
@@ -422,8 +422,15 @@ compile_load(
|
||||
{
|
||||
case 'v': res = generate_LOADV(cctx, name, error);
|
||||
break;
|
||||
case 's': if (is_expr && ASCII_ISUPPER(*name)
|
||||
&& find_func(name, FALSE) != NULL)
|
||||
case 's': if (current_script_is_vim9())
|
||||
{
|
||||
semsg(_(e_cannot_use_s_colon_in_vim9_script_str),
|
||||
*arg);
|
||||
vim_free(name);
|
||||
return FAIL;
|
||||
}
|
||||
if (is_expr && ASCII_ISUPPER(*name)
|
||||
&& find_func(name, FALSE) != NULL)
|
||||
res = generate_funcref(cctx, name, FALSE);
|
||||
else
|
||||
res = compile_load_scriptvar(cctx, name,
|
||||
|
||||
@@ -2861,6 +2861,10 @@ win_free_all(void)
|
||||
{
|
||||
int dummy;
|
||||
|
||||
#ifdef FEAT_CMDWIN
|
||||
// avoid an error for switching tabpage with the cmdline window open
|
||||
cmdwin_type = 0;
|
||||
#endif
|
||||
while (first_tabpage->tp_next != NULL)
|
||||
tabpage_close(TRUE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user