Compare commits

...

10 Commits

Author SHA1 Message Date
Bram Moolenaar
3445320839 patch 8.2.2435: setline() gives an error for some types
Problem:    setline() gives an error for some types.
Solution:   Allow any type, convert each item to a string.
2021-01-31 13:08:38 +01:00
Bram Moolenaar
f2b26bcf8f patch 8.2.2434: Vim9: no error when compiling str2nr() with a number
Problem:    Vim9: no error when compiling str2nr() with a number.
Solution:   Add argument type checks. (closes #7759)
2021-01-30 23:05:11 +01:00
Bram Moolenaar
b63f3ca66d patch 8.2.2433: opening cmdline window gives error in BufLeave autocommand
Problem:    Opening cmdline window gives error in BufLeave autocommand.
Solution:   Reset cmdwin_type when triggering the autocommand.
2021-01-30 21:40:03 +01:00
Bram Moolenaar
76ab5446d5 patch 8.2.2432: libvterm tests are executed even when libtool doesn't work
Problem:    Libvterm tests are executed even when libtool doesn't work.
Solution:   Only run libvterm tests if /usr/bin/gcc exists.
2021-01-30 20:35:28 +01:00
Bram Moolenaar
ebd211c8a3 patch 8.2.2431: warning for -fno-strength-reduce with Clang 11
Problem:    Warning for -fno-strength-reduce with Clang 11.
Solution:   Adjust check for clang version number.
2021-01-30 19:33:36 +01:00
Bram Moolenaar
f8c6a17180 patch 8.2.2430: :vimgrep expands wildcards twice
Problem:    :vimgrep expands wildcards twice.
Solution:   Do not expand wildcards a second time.
2021-01-30 18:09:06 +01:00
Bram Moolenaar
59ff64079b patch 8.2.2429: :goto does not work correctly with text properties
Problem:    :goto does not work correctly with text properties. (Sam McCall)
Solution:   Add a test. (Andrew Radev)  Also use the text property size when
            computing the remaining offset. (closes #5930)
2021-01-30 17:16:28 +01:00
Bram Moolenaar
92e5df8047 patch 8.2.2428: FocusGained does not work when 'ttymouse' is empty
Problem:    FocusGained does not work when 'ttymouse' is empty.
Solution:   Don't use the short mouse code if there is a longer matching code.
            (closes #7755)  Add a test.
2021-01-30 15:39:47 +01:00
Bram Moolenaar
3eb6bd9c2b patch 8.2.2427: can still switch windows for 'completefunc'
Problem:    Can still switch windows for 'completefunc'.
Solution:   Also disallow switching windows for other completions.
2021-01-29 21:47:24 +01:00
Bram Moolenaar
28976e2acc patch 8.2.2426: allowing 'completefunc' to switch windows causes trouble
Problem:    Allowing 'completefunc' to switch windows causes trouble.
Solution:   use "textwinlock" instead of "textlock".
2021-01-29 21:07:07 +01:00
25 changed files with 318 additions and 90 deletions

View File

@@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.2. Last change: 2021 Jan 22
*eval.txt* For Vim version 8.2. Last change: 2021 Jan 31
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -293,13 +293,13 @@ is not available it returns zero or the default value you specify: >
List concatenation ~
*list-concatenation*
Two lists can be concatenated with the "+" operator: >
:let longlist = mylist + [5, 6]
:let mylist += [7, 8]
To prepend or append an item turn the item into a list by putting [] around
it. To change a list in-place see |list-modification| below.
To prepend or append an item, turn the item into a list by putting [] around
it. To change a list in-place, refer to |list-modification| below.
Sublist ~
@@ -3133,6 +3133,7 @@ append({lnum}, {text}) *append()*
text line below line {lnum} in the current buffer.
Otherwise append {text} as one text line below line {lnum} in
the current buffer.
Any type of item is accepted and converted to a String.
{lnum} can be zero to insert a line before the first one.
Returns 1 for failure ({lnum} out of range or out of memory),
0 for success. Example: >
@@ -9409,6 +9410,8 @@ setline({lnum}, {text}) *setline()*
{lnum} is used like with |getline()|.
When {lnum} is just below the last line the {text} will be
added below the last line.
{text} can be any type or a List of any type, each item is
converted to a String.
If this succeeds, FALSE is returned. If this fails (most likely
because {lnum} is invalid) TRUE is returned.

View File

@@ -2294,9 +2294,12 @@ run_message_test: $(MESSAGE_TEST_TARGET)
# Run the libvterm tests.
# This works only on GNU make, not on BSD make.
# Libtool requires "gcc".
test_libvterm:
@if $(MAKE) --version 2>/dev/null | grep -qs "GNU Make"; then \
cd libvterm; $(MAKE) -f Makefile test CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"; \
if test -x "/usr/bin/gcc"; then \
cd libvterm; $(MAKE) -f Makefile test CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"; \
fi \
fi
# Run individual OLD style test.

View File

@@ -315,10 +315,10 @@ get_arglist_exp(
return FAIL;
if (wig == TRUE)
i = expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
fcountp, fnamesp, EW_FILE|EW_NOTFOUND|EW_NOTWILD);
else
i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
fcountp, fnamesp, EW_FILE|EW_NOTFOUND|EW_NOTWILD);
ga_clear(&ga);
return i;

4
src/auto/configure vendored
View File

@@ -4510,9 +4510,9 @@ if test x"$CLANG_VERSION_STRING" != x"" ; then
CLANG_VERSION=`expr $CLANG_MAJOR '*' 1000000 '+' $CLANG_MINOR '*' 1000 '+' $CLANG_REVISION`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CLANG_VERSION" >&5
$as_echo "$CLANG_VERSION" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if clang supports -fno-strength-reduce" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if clang supports -fno-strength-reduce" >&5
$as_echo_n "checking if clang supports -fno-strength-reduce... " >&6; }
if test "$CLANG_VERSION" -ge 500002075 ; then
if test "$CLANG_MAJOR" -ge 10 -o "$CLANG_VERSION" -ge 500002075 ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
CFLAGS=`echo "$CFLAGS" | sed -e 's/-fno-strength-reduce/ /'`

View File

@@ -127,8 +127,9 @@ if test x"$CLANG_VERSION_STRING" != x"" ; then
dnl change the constant 500002075 below appropriately. To get the
dnl integer corresponding to a version number, refer to the
dnl definition of CLANG_VERSION above.
dnl Clang 11 reports "11", assume Clang 10 and later work like this.
AC_MSG_CHECKING(if clang supports -fno-strength-reduce)
if test "$CLANG_VERSION" -ge 500002075 ; then
if test "$CLANG_MAJOR" -ge 10 -o "$CLANG_VERSION" -ge 500002075 ; then
AC_MSG_RESULT(no)
CFLAGS=`echo "$CFLAGS" | sed -e 's/-fno-strength-reduce/ /'`
else

View File

@@ -940,9 +940,9 @@ debuggy_find(
{
if (bp->dbg_val == NULL)
{
debug_oldval = typval_tostring(NULL);
debug_oldval = typval_tostring(NULL, TRUE);
bp->dbg_val = tv;
debug_newval = typval_tostring(bp->dbg_val);
debug_newval = typval_tostring(bp->dbg_val, TRUE);
line = TRUE;
}
else
@@ -953,11 +953,11 @@ debuggy_find(
typval_T *v;
line = TRUE;
debug_oldval = typval_tostring(bp->dbg_val);
debug_oldval = typval_tostring(bp->dbg_val, TRUE);
// Need to evaluate again, typval_compare() overwrites
// "tv".
v = eval_expr(bp->dbg_name, NULL);
debug_newval = typval_tostring(v);
debug_newval = typval_tostring(v, TRUE);
free_tv(bp->dbg_val);
bp->dbg_val = v;
}
@@ -966,8 +966,8 @@ debuggy_find(
}
else if (bp->dbg_val != NULL)
{
debug_oldval = typval_tostring(bp->dbg_val);
debug_newval = typval_tostring(NULL);
debug_oldval = typval_tostring(bp->dbg_val, TRUE);
debug_newval = typval_tostring(NULL, TRUE);
free_tv(bp->dbg_val);
bp->dbg_val = NULL;
line = TRUE;

View File

@@ -128,7 +128,8 @@ find_win_for_curbuf(void)
}
/*
* Set line or list of lines in buffer "buf".
* Set line or list of lines in buffer "buf" to "lines".
* Any type is allowed and converted to a string.
*/
static void
set_buffer_lines(
@@ -187,7 +188,7 @@ set_buffer_lines(
li = l->lv_first;
}
else
line = tv_get_string_chk(lines);
line = typval_tostring(lines, FALSE);
// default result is zero == OK
for (;;)
@@ -197,7 +198,8 @@ set_buffer_lines(
// list argument, get next string
if (li == NULL)
break;
line = tv_get_string_chk(&li->li_tv);
vim_free(line);
line = typval_tostring(&li->li_tv, FALSE);
li = li->li_next;
}
@@ -238,6 +240,7 @@ set_buffer_lines(
break;
++lnum;
}
vim_free(line);
if (added > 0)
{

View File

@@ -330,6 +330,18 @@ arg_string(type_T *type, argcontext_T *context)
return check_arg_type(&t_string, type, context);
}
/*
* Check "type" is a bool or number 0 or 1.
*/
static int
arg_bool(type_T *type, argcontext_T *context)
{
if (type->tt_type == VAR_ANY
|| type->tt_type == VAR_NUMBER || type->tt_type == VAR_BOOL)
return OK;
return check_arg_type(&t_bool, type, context);
}
/*
* Check "type" is a list or a blob.
*/
@@ -423,6 +435,7 @@ arg_extend3(type_T *type, argcontext_T *context)
/*
* Lists of functions that check the argument types of a builtin function.
*/
argcheck_T arg3_string_nr_bool[] = {arg_string, arg_number, arg_bool};
argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev};
argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3};
@@ -1552,7 +1565,7 @@ static funcentry_T global_functions[] =
ret_float, FLOAT_FUNC(f_str2float)},
{"str2list", 1, 2, FEARG_1, NULL,
ret_list_number, f_str2list},
{"str2nr", 1, 3, FEARG_1, NULL,
{"str2nr", 1, 3, FEARG_1, arg3_string_nr_bool,
ret_number, f_str2nr},
{"strcharpart", 2, 3, FEARG_1, NULL,
ret_string, f_strcharpart},
@@ -9076,7 +9089,7 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
what |= STR2NR_QUOTE;
}
p = skipwhite(tv_get_string(&argvars[0]));
p = skipwhite(tv_get_string_strict(&argvars[0]));
isneg = (*p == '-');
if (*p == '+' || *p == '-')
p = skipwhite(p + 1);

View File

@@ -2710,6 +2710,12 @@ do_ecmd(
*/
if (buf != curbuf)
{
#ifdef FEAT_CMDWIN
int save_cmdwin_type = cmdwin_type;
// BufLeave applies to the old buffer.
cmdwin_type = 0;
#endif
/*
* Be careful: The autocommands may delete any buffer and change
* the current buffer.
@@ -2724,6 +2730,9 @@ do_ecmd(
new_name = vim_strsave(buf->b_fname);
set_bufref(&au_new_curbuf, buf);
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
#ifdef FEAT_CMDWIN
cmdwin_type = save_cmdwin_type;
#endif
if (!bufref_valid(&au_new_curbuf))
{
// new buffer has been deleted

View File

@@ -121,7 +121,6 @@ struct compl_S
static char e_hitend[] = N_("Hit end of paragraph");
# ifdef FEAT_COMPL_FUNC
static char e_complwin[] = N_("E839: Completion function changed window");
static char e_compldel[] = N_("E840: Completion function deleted text");
# endif
@@ -2199,8 +2198,6 @@ expand_by_function(
typval_T args[3];
char_u *funcname;
pos_T pos;
win_T *curwin_save;
buf_T *curbuf_save;
typval_T rettv;
int save_State = State;
@@ -2216,11 +2213,10 @@ expand_by_function(
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
// Lock the text to avoid weird things from happening. Do allow switching
// to another window temporarily.
++textlock;
// Lock the text to avoid weird things from happening. Also disallow
// switching to another window, it should not be needed and may end up in
// Insert mode in another buffer.
++textwinlock;
// Call a function, which returns a list or dict.
if (call_vim_function(funcname, 2, args, &rettv) == OK)
@@ -2243,13 +2239,8 @@ expand_by_function(
break;
}
}
--textlock;
--textwinlock;
if (curwin_save != curwin || curbuf_save != curbuf)
{
emsg(_(e_complwin));
goto theend;
}
curwin->w_cursor = pos; // restore the cursor position
validate_cursor();
if (!EQUAL_POS(curwin->w_cursor, pos))
@@ -3226,7 +3217,7 @@ ins_compl_next(
return -1;
if (compl_leader != NULL
&& (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0)
&& (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0)
{
// Set "compl_shown_match" to the actually shown match, it may differ
// when "compl_leader" is used to omit some of the matches.
@@ -3842,8 +3833,6 @@ ins_complete(int c, int enable_pum)
int col;
char_u *funcname;
pos_T pos;
win_T *curwin_save;
buf_T *curbuf_save;
int save_State = State;
// Call 'completefunc' or 'omnifunc' and get pattern length as a
@@ -3865,16 +3854,11 @@ ins_complete(int c, int enable_pum)
args[1].vval.v_string = (char_u *)"";
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
++textwinlock;
col = call_func_retnr(funcname, 2, args);
--textwinlock;
State = save_State;
if (curwin_save != curwin || curbuf_save != curbuf)
{
emsg(_(e_complwin));
return FAIL;
}
curwin->w_cursor = pos; // restore the cursor position
validate_cursor();
if (!EQUAL_POS(curwin->w_cursor, pos))

View File

@@ -5701,6 +5701,10 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset))
{
#ifdef FEAT_PROP_POPUP
size_t textprop_total = 0;
#endif
if (curline > buf->b_ml.ml_line_count
|| (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
return -1;
@@ -5722,18 +5726,16 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
}
else
{
#ifdef FEAT_PROP_POPUP
size_t textprop_total = 0;
size_t textprop_size = 0;
char_u *l1, *l2;
#endif
extra = 0;
for (;;)
{
#ifdef FEAT_PROP_POPUP
size_t textprop_size = 0;
if (buf->b_has_textprop)
{
char_u *l1, *l2;
// compensate for the extra bytes taken by textprops
l1 = (char_u *)dp + ((dp->db_index[idx]) & DB_INDEX_MASK);
l2 = (char_u *)dp + (idx == 0 ? dp->db_txt_end
@@ -5763,7 +5765,7 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
}
}
#ifdef FEAT_PROP_POPUP
if (buf->b_has_textprop)
if (buf->b_has_textprop && lnum != 0)
{
int i;
@@ -5771,12 +5773,18 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
// lengths.
len = 0;
for (i = start_idx; i <= idx; ++i)
len += (int)STRLEN((char_u *)dp
+ ((dp->db_index[i]) & DB_INDEX_MASK)) + 1;
{
char_u *p = (char_u *)dp + ((dp->db_index[i]) & DB_INDEX_MASK);
len += (int)STRLEN(p) + 1;
}
}
else
#endif
len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK)
#ifdef FEAT_PROP_POPUP
- (long)textprop_total
#endif
;
size += len;
if (offset != 0 && size >= offset)
{
@@ -5786,7 +5794,11 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
*offp = offset - size + len;
else
*offp = offset - size + len
- (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
- (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK))
#ifdef FEAT_PROP_POPUP
+ (long)textprop_total
#endif
;
curline += idx - start_idx + extra;
if (curline > buf->b_ml.ml_line_count)
return -1; // exactly one byte beyond the end

View File

@@ -12,14 +12,16 @@ float_T tv_get_float(typval_T *varp);
int check_for_string(typval_T *tv);
int check_for_nonempty_string(typval_T *tv);
char_u *tv_get_string(typval_T *varp);
char_u *tv_get_string_strict(typval_T *varp);
char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
char_u *tv_get_string_chk(typval_T *varp);
char_u *tv_get_string_buf_chk(typval_T *varp, char_u *buf);
char_u *tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict);
char_u *tv_stringify(typval_T *varp, char_u *buf);
int tv_check_lock(typval_T *tv, char_u *name, int use_gettext);
void copy_tv(typval_T *from, typval_T *to);
int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, int ic);
char_u *typval_tostring(typval_T *arg);
char_u *typval_tostring(typval_T *arg, int quotes);
int tv_islocked(typval_T *tv);
int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
int eval_option(char_u **arg, typval_T *rettv, int evaluate);

View File

@@ -6053,7 +6053,7 @@ vgr_process_args(
return FAIL;
}
// parse the list of arguments
// Parse the list of arguments, wildcards have already been expanded.
if (get_arglist_exp(p, &args->fcount, &args->fnames, TRUE) == FAIL)
return FAIL;
if (args->fcount == 0)

View File

@@ -5339,6 +5339,8 @@ check_termcode(
else
#endif // FEAT_GUI
{
int mouse_index_found = -1;
for (idx = 0; idx < tc_len; ++idx)
{
/*
@@ -5376,9 +5378,24 @@ check_termcode(
}
}
key_name[0] = termcodes[idx].name[0];
key_name[1] = termcodes[idx].name[1];
break;
// The mouse termcode "ESC [" is also the prefix of
// "ESC [ I" (focus gained). Only use it when there is
// no other match. Do use it when a digit is following to
// avoid waiting for more bytes.
if (slen == 2 && len > 2
&& termcodes[idx].code[0] == ESC
&& termcodes[idx].code[1] == '['
&& !isdigit(tp[2]))
{
if (mouse_index_found < 0)
mouse_index_found = idx;
}
else
{
key_name[0] = termcodes[idx].name[0];
key_name[1] = termcodes[idx].name[1];
break;
}
}
/*
@@ -5389,7 +5406,7 @@ check_termcode(
* When there is a modifier the * matches a number.
* When there is no modifier the ;* or * is omitted.
*/
if (termcodes[idx].modlen > 0)
if (termcodes[idx].modlen > 0 && mouse_index_found < 0)
{
int at_code;
@@ -5442,6 +5459,11 @@ check_termcode(
}
}
}
if (idx == tc_len && mouse_index_found >= 0)
{
key_name[0] = termcodes[mouse_index_found].name[0];
key_name[1] = termcodes[mouse_index_found].name[1];
}
}
#ifdef FEAT_TERMRESPONSE

View File

@@ -5,6 +5,7 @@ source screendump.vim
source check.vim
func Test_setbufline_getbufline()
" similar to Test_set_get_bufline()
new
let b = bufnr('%')
hide
@@ -38,6 +39,12 @@ func Test_setbufline_getbufline()
call assert_equal(['e'], getbufline(b, 5))
call assert_equal([], getbufline(b, 6))
call assert_equal([], getbufline(b, 2, 1))
call setbufline(b, 2, [function('eval'), #{key: 123}, test_null_job()])
call assert_equal(["function('eval')",
\ "{'key': 123}",
\ "no process"],
\ getbufline(b, 2, 4))
exe "bwipe! " . b
endfunc

View File

@@ -1237,6 +1237,7 @@ func Test_cmdwin_autocmd()
augroup CmdWin
au!
autocmd BufLeave * if &buftype == '' | update | endif
autocmd CmdwinEnter * startinsert
augroup END

View File

@@ -548,7 +548,7 @@ func Test_completefunc_error()
endfunc
set completefunc=CompleteFunc
call setline(1, ['', 'abcd', ''])
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E840:')
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
" delete text when called for the second time
func CompleteFunc2(findstart, base)
@@ -562,31 +562,24 @@ func Test_completefunc_error()
call setline(1, ['', 'abcd', ''])
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
set completefunc&
delfunc CompleteFunc
delfunc CompleteFunc2
close!
endfunc
func Test_completefunc_error_not_asan()
" The following test causes an ASAN failure.
CheckNotAsan
" Jump to a different window from the complete function
func! CompleteFunc(findstart, base)
func CompleteFunc3(findstart, base)
if a:findstart == 1
return col('.') - 1
endif
wincmd p
return ['a', 'b']
endfunc
set completefunc=CompleteFunc
set completefunc=CompleteFunc3
new
call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E839:')
call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E565:')
close!
set completefunc&
delfunc CompleteFunc
delfunc CompleteFunc2
delfunc CompleteFunc3
close!
endfunc
" Test for returning non-string values from 'completefunc'

View File

@@ -342,7 +342,7 @@ func Test_completefunc_opens_new_window_one()
setlocal completefunc=DummyCompleteOne
call setline(1, 'one')
/^one
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E578:')
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
call assert_equal(winid, win_getid())
call assert_equal('onedef', getline(1))
q!
@@ -367,11 +367,9 @@ func Test_completefunc_opens_new_window_two()
setlocal completefunc=DummyCompleteTwo
call setline(1, 'two')
/^two
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:')
call assert_notequal(winid, win_getid())
q!
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
call assert_equal(winid, win_getid())
call assert_equal('two', getline(1))
call assert_equal('twodef', getline(1))
q!
endfunc
@@ -642,8 +640,8 @@ func Test_complete_func_mess()
set completefunc=MessComplete
new
call setline(1, 'Ju')
call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx')
call assert_equal('Oct/Oct', getline(1))
call assert_fails('call feedkeys("A\<c-x>\<c-u>/\<esc>", "tx")', 'E578:')
call assert_equal('Jan/', getline(1))
bwipe!
set completefunc=
endfunc

View File

@@ -2865,6 +2865,13 @@ func Test_vimgrep()
call XvimgrepTests('l')
endfunc
func Test_vimgrep_wildcards_expanded_once()
new X[id-01] file.txt
call setline(1, 'some text to search for')
vimgrep text %
bwipe!
endfunc
" Test for incsearch highlighting of the :vimgrep pattern
" This test used to cause "E315: ml_get: invalid lnum" errors.
func Test_vimgrep_incsearch()

View File

@@ -1868,6 +1868,34 @@ func Test_xx07_xterm_response()
call test_override('term_props', 0)
endfunc
func Test_focus_events()
let save_term = &term
let save_ttymouse = &ttymouse
set term=xterm ttymouse=xterm2
au FocusGained * let g:focus_gained += 1
au FocusLost * let g:focus_lost += 1
let g:focus_gained = 0
let g:focus_lost = 0
call feedkeys("\<Esc>[O", "Lx!")
call assert_equal(1, g:focus_lost)
call feedkeys("\<Esc>[I", "Lx!")
call assert_equal(1, g:focus_gained)
" still works when 'ttymouse' is empty
set ttymouse=
call feedkeys("\<Esc>[O", "Lx!")
call assert_equal(2, g:focus_lost)
call feedkeys("\<Esc>[I", "Lx!")
call assert_equal(2, g:focus_gained)
au! FocusGained
au! FocusLost
let &term = save_term
let &ttymouse = save_ttymouse
endfunc
func Test_get_termcode()
try
let k1 = &t_k1
@@ -2261,7 +2289,7 @@ func Test_cmdline_literal()
endfunc
" Test for translation of special key codes (<xF1>, <xF2>, etc.)
func Test_Keycode_Tranlsation()
func Test_Keycode_Translation()
let keycodes = [
\ ["<xUp>", "<Up>"],
\ ["<xDown>", "<Down>"],

View File

@@ -771,6 +771,36 @@ func Test_prop_byte2line()
call prop_type_delete('prop')
endfunc
func Test_prop_goto_byte()
new
call setline(1, '')
call setline(2, 'two three')
call setline(3, '')
call setline(4, 'four five')
call prop_type_add('testprop', {'highlight': 'Directory'})
call search('^two')
call prop_add(line('.'), col('.'), {
\ 'length': len('two'),
\ 'type': 'testprop'
\ })
call search('two \zsthree')
let expected_pos = line2byte(line('.')) + col('.') - 1
exe expected_pos .. 'goto'
let actual_pos = line2byte(line('.')) + col('.') - 1
eval actual_pos->assert_equal(expected_pos)
call search('four \zsfive')
let expected_pos = line2byte(line('.')) + col('.') - 1
exe expected_pos .. 'goto'
let actual_pos = line2byte(line('.')) + col('.') - 1
eval actual_pos->assert_equal(expected_pos)
call prop_type_delete('testprop')
bwipe!
endfunc
func Test_prop_undo()
new
call prop_type_add('comment', {'highlight': 'Directory'})

View File

@@ -767,6 +767,54 @@ def Test_searchcount()
bwipe!
enddef
def Test_set_get_bufline()
# similar to Test_setbufline_getbufline()
var lines =<< trim END
new
var b = bufnr('%')
hide
assert_equal(0, setbufline(b, 1, ['foo', 'bar']))
assert_equal(['foo'], getbufline(b, 1))
assert_equal(['bar'], getbufline(b, '$'))
assert_equal(['foo', 'bar'], getbufline(b, 1, 2))
exe "bd!" b
assert_equal([], getbufline(b, 1, 2))
split Xtest
setline(1, ['a', 'b', 'c'])
b = bufnr('%')
wincmd w
assert_equal(1, setbufline(b, 5, 'x'))
assert_equal(1, setbufline(b, 5, ['x']))
assert_equal(1, setbufline(b, 5, []))
assert_equal(1, setbufline(b, 5, test_null_list()))
assert_equal(1, 'x'->setbufline(bufnr('$') + 1, 1))
assert_equal(1, ['x']->setbufline(bufnr('$') + 1, 1))
assert_equal(1, []->setbufline(bufnr('$') + 1, 1))
assert_equal(1, test_null_list()->setbufline(bufnr('$') + 1, 1))
assert_equal(['a', 'b', 'c'], getbufline(b, 1, '$'))
assert_equal(0, setbufline(b, 4, ['d', 'e']))
assert_equal(['c'], b->getbufline(3))
assert_equal(['d'], getbufline(b, 4))
assert_equal(['e'], getbufline(b, 5))
assert_equal([], getbufline(b, 6))
assert_equal([], getbufline(b, 2, 1))
setbufline(b, 2, [function('eval'), {key: 123}, test_null_job()])
assert_equal(["function('eval')",
"{'key': 123}",
"no process"],
getbufline(b, 2, 4))
exe 'bwipe! ' .. b
END
CheckDefAndScriptSuccess(lines)
enddef
def Test_searchdecl()
searchdecl('blah', true, true)->assert_equal(1)
enddef
@@ -867,6 +915,13 @@ enddef
def Test_str2nr()
str2nr("1'000'000", 10, true)->assert_equal(1000000)
CheckDefFailure(['echo str2nr(123)'], 'E1013:')
CheckScriptFailure(['vim9script', 'echo str2nr(123)'], 'E1024:')
CheckDefFailure(['echo str2nr("123", "x")'], 'E1013:')
CheckScriptFailure(['vim9script', 'echo str2nr("123", "x")'], 'E1030:')
CheckDefFailure(['echo str2nr("123", 10, "x")'], 'E1013:')
CheckScriptFailure(['vim9script', 'echo str2nr("123", 10, "x")'], 'E1135:')
enddef
def Test_strchars()

View File

@@ -388,6 +388,19 @@ tv_get_string(typval_T *varp)
return tv_get_string_buf(varp, mybuf);
}
/*
* Like tv_get_string() but don't allow number to string conversion for Vim9.
*/
char_u *
tv_get_string_strict(typval_T *varp)
{
static char_u mybuf[NUMBUFLEN];
char_u *res = tv_get_string_buf_chk_strict(
varp, mybuf, in_vim9script());
return res != NULL ? res : (char_u *)"";
}
char_u *
tv_get_string_buf(typval_T *varp, char_u *buf)
{
@@ -409,10 +422,21 @@ tv_get_string_chk(typval_T *varp)
char_u *
tv_get_string_buf_chk(typval_T *varp, char_u *buf)
{
return tv_get_string_buf_chk_strict(varp, buf, FALSE);
}
char_u *
tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
{
switch (varp->v_type)
{
case VAR_NUMBER:
if (strict)
{
emsg(_(e_using_number_as_string));
break;
}
vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
(varnumber_T)varp->vval.v_number);
return buf;
@@ -903,8 +927,13 @@ typval_compare(
return OK;
}
/*
* Convert any type to a string, never give an error.
* When "quotes" is TRUE add quotes to a string.
* Returns an allocated string.
*/
char_u *
typval_tostring(typval_T *arg)
typval_tostring(typval_T *arg, int quotes)
{
char_u *tofree;
char_u numbuf[NUMBUFLEN];
@@ -912,10 +941,18 @@ typval_tostring(typval_T *arg)
if (arg == NULL)
return vim_strsave((char_u *)"(does not exist)");
ret = tv2string(arg, &tofree, numbuf, 0);
// Make a copy if we have a value but it's not in allocated memory.
if (ret != NULL && tofree == NULL)
ret = vim_strsave(ret);
if (!quotes && arg->v_type == VAR_STRING)
{
ret = vim_strsave(arg->vval.v_string == NULL ? (char_u *)""
: arg->vval.v_string);
}
else
{
ret = tv2string(arg, &tofree, numbuf, 0);
// Make a copy if we have a value but it's not in allocated memory.
if (ret != NULL && tofree == NULL)
ret = vim_strsave(ret);
}
return ret;
}

View File

@@ -750,6 +750,26 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2435,
/**/
2434,
/**/
2433,
/**/
2432,
/**/
2431,
/**/
2430,
/**/
2429,
/**/
2428,
/**/
2427,
/**/
2426,
/**/
2425,
/**/

View File

@@ -879,7 +879,7 @@ do_2string(typval_T *tv, int is_2string_any)
return FAIL;
}
}
str = typval_tostring(tv);
str = typval_tostring(tv, TRUE);
clear_tv(tv);
tv->v_type = VAR_STRING;
tv->vval.v_string = str;