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:
@@ -3256,6 +3256,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
|
||||
messages |:messages| suboptions
|
||||
option options
|
||||
packadd optional package |pack-add| names
|
||||
scriptnames sourced script names |:scriptnames|
|
||||
shellcmd Shell command
|
||||
sign |:sign| suboptions
|
||||
syntax syntax file names |'syntax'|
|
||||
@@ -3273,6 +3274,13 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
|
||||
is applied to filter the results. Otherwise all the matches
|
||||
are returned. The 'wildignorecase' option always applies.
|
||||
|
||||
If the 'wildoptions' option contains 'fuzzy', then fuzzy
|
||||
matching is used to get the completion matches. Otherwise
|
||||
regular expression matching is used. Thus this function
|
||||
follows the user preference, what happens on the command line.
|
||||
If you do not want this you can make 'wildoptions' empty
|
||||
before calling getcompletion() and restore it afterwards.
|
||||
|
||||
If {type} is "cmdline", then the |cmdline-completion| result is
|
||||
returned. For example, to complete the possible values after
|
||||
a ":call" command: >
|
||||
|
||||
+33
-8
@@ -198,10 +198,35 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
|
||||
start with a ":".
|
||||
Triggers the |SourcePre| autocommand.
|
||||
|
||||
:[range]so[urce] Read Ex commands from the [range] of lines in the
|
||||
current buffer. When sourcing commands from the
|
||||
current buffer, the same script-ID |<SID>| is used
|
||||
even if the buffer is sourced multiple times.
|
||||
:[range]so[urce] [++clear]
|
||||
Read Ex commands from the [range] of lines in the
|
||||
current buffer.
|
||||
|
||||
When sourcing commands from the current buffer, the
|
||||
same script-ID |<SID>| is used even if the buffer is
|
||||
sourced multiple times. If a buffer is sourced more
|
||||
than once, then the functions in the buffer are
|
||||
defined again.
|
||||
|
||||
To source a range of lines that doesn't start with the
|
||||
|:vim9script| command in Vim9 script context, the
|
||||
|:vim9cmd| modifier can be used.
|
||||
|
||||
When a range of lines in a buffer is sourced in the
|
||||
Vim9 script context, the previously defined
|
||||
script-local variables and functions are not cleared.
|
||||
This works like the range started with the
|
||||
":vim9script noclear" command. The "++clear" argument
|
||||
can be used to clear the script-local variables and
|
||||
functions before sourcing the script. This works like
|
||||
the range started with the |:vimscript| command
|
||||
without the "noclear" argument. See |vim9-reload| for
|
||||
more information.
|
||||
Examples: >
|
||||
|
||||
:4,5source
|
||||
:vim9cmd :'<,'>source
|
||||
:10,18source ++clear
|
||||
|
||||
*:source!*
|
||||
:so[urce]! {file} Read Vim commands from {file}. These are commands
|
||||
@@ -425,10 +450,10 @@ An alternative is to put the commands in a file, and execute them with the
|
||||
':source!' command. Useful for long command sequences. Can be combined with
|
||||
the ':map' command to put complicated commands under a function key.
|
||||
|
||||
The ':source' command reads Ex commands from a file line by line. You will
|
||||
have to type any needed keyboard input. The ':source!' command reads from a
|
||||
script file character by character, interpreting each character as if you
|
||||
typed it.
|
||||
The ':source' command reads Ex commands from a file or a buffer line by line.
|
||||
You will have to type any needed keyboard input. The ':source!' command reads
|
||||
from a script file character by character, interpreting each character as if
|
||||
you typed it.
|
||||
|
||||
Example: When you give the ":!ls" command you get the |hit-enter| prompt. If
|
||||
you ':source' a file with the line "!ls" in it, you will have to type the
|
||||
|
||||
+14
-10
@@ -5340,17 +5340,21 @@ ex_buffer_all(exarg_T *eap)
|
||||
{
|
||||
wpnext = wp->w_next;
|
||||
if ((wp->w_buffer->b_nwindows > 1
|
||||
|| ((cmdmod.cmod_split & WSP_VERT)
|
||||
? wp->w_height + wp->w_status_height < Rows - p_ch
|
||||
- tabline_height()
|
||||
: wp->w_width != Columns)
|
||||
|| (had_tab > 0 && wp != firstwin)) && !ONE_WINDOW
|
||||
&& !(wp->w_closing || wp->w_buffer->b_locked > 0))
|
||||
|| ((cmdmod.cmod_split & WSP_VERT)
|
||||
? wp->w_height + wp->w_status_height < Rows - p_ch
|
||||
- tabline_height()
|
||||
: wp->w_width != Columns)
|
||||
|| (had_tab > 0 && wp != firstwin))
|
||||
&& !ONE_WINDOW
|
||||
&& !(wp->w_closing || wp->w_buffer->b_locked > 0)
|
||||
&& !win_unlisted(wp))
|
||||
{
|
||||
win_close(wp, FALSE);
|
||||
wpnext = firstwin; // just in case an autocommand does
|
||||
// something strange with windows
|
||||
tpnext = first_tabpage; // start all over...
|
||||
if (win_close(wp, FALSE) == FAIL)
|
||||
break;
|
||||
// Just in case an autocommand does something strange with
|
||||
// windows: start all over...
|
||||
wpnext = firstwin;
|
||||
tpnext = first_tabpage;
|
||||
open_wins = 0;
|
||||
}
|
||||
else
|
||||
|
||||
+3
-3
@@ -422,7 +422,7 @@ cmdsrv_main(
|
||||
* For --remote-wait: Wait until the server did edit each
|
||||
* file. Also detect that the server no longer runs.
|
||||
*/
|
||||
if (ret >= 0 && argtype == ARGTYPE_EDIT_WAIT)
|
||||
if (argtype == ARGTYPE_EDIT_WAIT)
|
||||
{
|
||||
int numFiles = *argc - i - 1;
|
||||
int j;
|
||||
@@ -801,6 +801,7 @@ f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
if (in_vim9script()
|
||||
&& (check_for_string_arg(argvars, 0) == FAIL
|
||||
|| check_for_string_arg(argvars, 1) == FAIL
|
||||
@@ -809,7 +810,6 @@ f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
&& check_for_opt_number_arg(argvars, 3) == FAIL)))
|
||||
return;
|
||||
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
remote_common(argvars, rettv, TRUE);
|
||||
#endif
|
||||
}
|
||||
@@ -956,13 +956,13 @@ f_remote_send(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
if (in_vim9script()
|
||||
&& (check_for_string_arg(argvars, 0) == FAIL
|
||||
|| check_for_string_arg(argvars, 1) == FAIL
|
||||
|| check_for_opt_string_arg(argvars, 2) == FAIL))
|
||||
return;
|
||||
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
remote_common(argvars, rettv, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
+64
-16
@@ -1709,6 +1709,24 @@ set_context_in_breakadd_cmd(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char_u *
|
||||
set_context_in_scriptnames_cmd(expand_T *xp, char_u *arg)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
xp->xp_pattern = NULL;
|
||||
|
||||
p = skipwhite(arg);
|
||||
if (VIM_ISDIGIT(*p))
|
||||
return NULL;
|
||||
|
||||
xp->xp_context = EXPAND_SCRIPTNAMES;
|
||||
xp->xp_pattern = p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2081,6 +2099,9 @@ set_context_by_cmdname(
|
||||
case CMD_profdel:
|
||||
case CMD_breakdel:
|
||||
return set_context_in_breakadd_cmd(xp, arg, cmdidx);
|
||||
|
||||
case CMD_scriptnames:
|
||||
return set_context_in_scriptnames_cmd(xp, arg);
|
||||
#endif
|
||||
|
||||
default:
|
||||
@@ -2504,6 +2525,23 @@ get_breakadd_arg(expand_T *xp UNUSED, int idx)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the possible arguments for the
|
||||
* ":scriptnames" command.
|
||||
*/
|
||||
static char_u *
|
||||
get_scriptnames_arg(expand_T *xp UNUSED, int idx)
|
||||
{
|
||||
scriptitem_T *si;
|
||||
|
||||
if (!SCRIPT_ID_VALID(idx + 1))
|
||||
return NULL;
|
||||
|
||||
si = SCRIPT_ITEM(idx + 1);
|
||||
home_replace(NULL, si->sn_name, NameBuff, MAXPATHL, TRUE);
|
||||
return NameBuff;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2593,6 +2631,7 @@ ExpandOther(
|
||||
{EXPAND_ARGLIST, get_arglist_name, TRUE, FALSE},
|
||||
#ifdef FEAT_EVAL
|
||||
{EXPAND_BREAKPOINT, get_breakadd_arg, TRUE, TRUE},
|
||||
{EXPAND_SCRIPTNAMES, get_scriptnames_arg, TRUE, FALSE},
|
||||
#endif
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
{EXPAND_MACACTION, get_macaction_name, FALSE, FALSE},
|
||||
@@ -2803,6 +2842,8 @@ ExpandGeneric(
|
||||
int score = 0;
|
||||
int fuzzy;
|
||||
int match;
|
||||
int sort_matches = FALSE;
|
||||
int funcsort = FALSE;
|
||||
|
||||
fuzzy = cmdline_fuzzy_complete(pat);
|
||||
*matches = NULL;
|
||||
@@ -2890,14 +2931,25 @@ ExpandGeneric(
|
||||
if (ga.ga_len == 0)
|
||||
return OK;
|
||||
|
||||
// Sort the results. Keep menu's in the specified order.
|
||||
// sort the matches when using regular expression matching and sorting
|
||||
// applies to the completion context. Menus and scriptnames should be kept
|
||||
// in the specified order.
|
||||
if (!fuzzy && xp->xp_context != EXPAND_MENUNAMES
|
||||
&& xp->xp_context != EXPAND_MENUS)
|
||||
&& xp->xp_context != EXPAND_MENUS
|
||||
&& xp->xp_context != EXPAND_SCRIPTNAMES)
|
||||
sort_matches = TRUE;
|
||||
|
||||
// <SNR> functions should be sorted to the end.
|
||||
if (xp->xp_context == EXPAND_EXPRESSION
|
||||
|| xp->xp_context == EXPAND_FUNCTIONS
|
||||
|| xp->xp_context == EXPAND_USER_FUNC
|
||||
|| xp->xp_context == EXPAND_DISASSEMBLE)
|
||||
funcsort = TRUE;
|
||||
|
||||
// Sort the matches.
|
||||
if (sort_matches)
|
||||
{
|
||||
if (xp->xp_context == EXPAND_EXPRESSION
|
||||
|| xp->xp_context == EXPAND_FUNCTIONS
|
||||
|| xp->xp_context == EXPAND_USER_FUNC
|
||||
|| xp->xp_context == EXPAND_DISASSEMBLE)
|
||||
if (funcsort)
|
||||
// <SNR> functions should be sorted to the end.
|
||||
qsort((void *)ga.ga_data, (size_t)ga.ga_len, sizeof(char_u *),
|
||||
sort_func_compare);
|
||||
@@ -2912,15 +2964,6 @@ ExpandGeneric(
|
||||
}
|
||||
else
|
||||
{
|
||||
int funcsort = FALSE;
|
||||
|
||||
if (xp->xp_context == EXPAND_EXPRESSION
|
||||
|| xp->xp_context == EXPAND_FUNCTIONS
|
||||
|| xp->xp_context == EXPAND_USER_FUNC
|
||||
|| xp->xp_context == EXPAND_DISASSEMBLE)
|
||||
// <SNR> functions should be sorted to the end.
|
||||
funcsort = TRUE;
|
||||
|
||||
if (fuzzymatches_to_strmatches(ga.ga_data, matches, ga.ga_len,
|
||||
funcsort) == FAIL)
|
||||
return FAIL;
|
||||
@@ -3719,7 +3762,12 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
|
||||
# endif
|
||||
}
|
||||
|
||||
pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
|
||||
if (cmdline_fuzzy_completion_supported(&xpc))
|
||||
// when fuzzy matching, don't modify the search string
|
||||
pat = vim_strsave(xpc.xp_pattern);
|
||||
else
|
||||
pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
|
||||
|
||||
if ((rettv_list_alloc(rettv) != FAIL) && (pat != NULL))
|
||||
{
|
||||
int i;
|
||||
|
||||
+2
-8
@@ -945,8 +945,7 @@ win_line(
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
|
||||
{
|
||||
// Do not show the cursor line in the text when Visual mode is active,
|
||||
// because it's not clear what is selected then. Do update
|
||||
// w_last_cursorline.
|
||||
// because it's not clear what is selected then.
|
||||
if (!(wp == curwin && VIsual_active)
|
||||
&& wp->w_p_culopt_flags != CULOPT_NBR)
|
||||
{
|
||||
@@ -971,18 +970,14 @@ win_line(
|
||||
else
|
||||
# endif
|
||||
line_attr = cul_attr;
|
||||
wp->w_last_cursorline = wp->w_cursor.lnum;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_attr_save = line_attr;
|
||||
wp->w_last_cursorline = 0;
|
||||
margin_columns_win(wp, &left_curline_col, &right_curline_col);
|
||||
}
|
||||
area_highlighting = TRUE;
|
||||
}
|
||||
else
|
||||
wp->w_last_cursorline = wp->w_cursor.lnum;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1226,8 +1221,7 @@ win_line(
|
||||
{
|
||||
draw_state = WL_BRI;
|
||||
// if need_showbreak is set, breakindent also applies
|
||||
if (wp->w_p_bri && n_extra == 0
|
||||
&& (row != startrow || need_showbreak)
|
||||
if (wp->w_p_bri && (row != startrow || need_showbreak)
|
||||
# ifdef FEAT_DIFF
|
||||
&& filler_lines == 0
|
||||
# endif
|
||||
|
||||
+10
-8
@@ -1468,9 +1468,6 @@ win_update(win_T *wp)
|
||||
# define DID_FOLD 3 // updated a folded line
|
||||
int did_update = DID_NONE;
|
||||
linenr_T syntax_last_parsed = 0; // last parsed text line
|
||||
// remember the current w_last_cursorline, it changes when drawing the new
|
||||
// cursor line
|
||||
linenr_T last_cursorline = wp->w_last_cursorline;
|
||||
#endif
|
||||
linenr_T mod_top = 0;
|
||||
linenr_T mod_bot = 0;
|
||||
@@ -1950,9 +1947,8 @@ win_update(win_T *wp)
|
||||
|
||||
if (VIsual_active)
|
||||
{
|
||||
if (VIsual_active
|
||||
&& (VIsual_mode != wp->w_old_visual_mode
|
||||
|| type == INVERTED_ALL))
|
||||
if (VIsual_mode != wp->w_old_visual_mode
|
||||
|| type == INVERTED_ALL)
|
||||
{
|
||||
// If the type of Visual selection changed, redraw the whole
|
||||
// selection. Also when the ownership of the X selection is
|
||||
@@ -2246,8 +2242,8 @@ win_update(win_T *wp)
|
||||
#endif
|
||||
))))
|
||||
#ifdef FEAT_SYN_HL
|
||||
|| (wp->w_p_cul && (lnum == wp->w_cursor.lnum
|
||||
|| lnum == last_cursorline))
|
||||
|| (wp->w_p_cul && lnum == wp->w_cursor.lnum)
|
||||
|| lnum == wp->w_last_cursorline
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -2552,6 +2548,12 @@ win_update(win_T *wp)
|
||||
|
||||
// End of loop over all window lines.
|
||||
|
||||
#ifdef FEAT_SYN_HL
|
||||
// Now that the window has been redrawn with the old and new cursor line,
|
||||
// update w_last_cursorline.
|
||||
wp->w_last_cursorline = wp->w_p_cul ? wp->w_cursor.lnum : 0;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_VTP
|
||||
// Rewrite the character at the end of the screen line.
|
||||
// See the version that was fixed.
|
||||
|
||||
+1
-1
@@ -2720,7 +2720,7 @@ EXTERN char e_cannot_use_scriptversion_after_vim9script[]
|
||||
INIT(= N_("E1040: Cannot use :scriptversion after :vim9script"));
|
||||
#ifdef FEAT_EVAL
|
||||
EXTERN char e_redefining_script_item_str[]
|
||||
INIT(= N_("E1041: Redefining script item %s"));
|
||||
INIT(= N_("E1041: Redefining script item: \"%s\""));
|
||||
EXTERN char e_export_can_only_be_used_in_vim9script[]
|
||||
INIT(= N_("E1042: Export can only be used in vim9script"));
|
||||
EXTERN char e_invalid_command_after_export[]
|
||||
|
||||
+1
-2
@@ -2411,8 +2411,7 @@ getfile(
|
||||
if (curbufIsChanged())
|
||||
#endif
|
||||
{
|
||||
if (other)
|
||||
--no_wait_return;
|
||||
--no_wait_return;
|
||||
no_write_message();
|
||||
retval = GETFILE_NOT_WRITTEN; // file has been changed
|
||||
goto theend;
|
||||
|
||||
+1
-1
@@ -1362,7 +1362,7 @@ EXCMD(CMD_sbrewind, "sbrewind", ex_brewind,
|
||||
EX_CMDARG|EX_TRLBAR,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_scriptnames, "scriptnames", ex_scriptnames,
|
||||
EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
EX_BANG|EX_FILES|EX_RANGE|EX_COUNT|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_OTHER),
|
||||
EXCMD(CMD_scriptencoding, "scriptencoding", ex_scriptencoding,
|
||||
EX_WORD1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
|
||||
+50
-31
@@ -2281,7 +2281,7 @@ do_one_cmd(
|
||||
*/
|
||||
if ((ea.argt & EX_TRLBAR) && !ea.usefilter)
|
||||
{
|
||||
separate_nextcmd(&ea);
|
||||
separate_nextcmd(&ea, FALSE);
|
||||
}
|
||||
else if (ea.cmdidx == CMD_bang
|
||||
|| ea.cmdidx == CMD_terminal
|
||||
@@ -2578,7 +2578,7 @@ do_one_cmd(
|
||||
#ifdef FEAT_EVAL
|
||||
// Set flag that any command was executed, used by ex_vim9script().
|
||||
// Not if this was a command that wasn't executed or :endif.
|
||||
if (getline_equal(ea.getline, ea.cookie, getsourceline)
|
||||
if (sourcing_a_script(&ea)
|
||||
&& current_sctx.sc_sid > 0
|
||||
&& ea.cmdidx != CMD_endif
|
||||
&& (cstack->cs_idx < 0
|
||||
@@ -3426,6 +3426,38 @@ skip_option_env_lead(char_u *start)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return TRUE and set "*idx" if "p" points to a one letter command.
|
||||
* If not in Vim9 script:
|
||||
* - The 'k' command can directly be followed by any character.
|
||||
* - The 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
|
||||
* but :sre[wind] is another command, as are :scr[iptnames],
|
||||
* :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
|
||||
*/
|
||||
static int
|
||||
one_letter_cmd(char_u *p, cmdidx_T *idx)
|
||||
{
|
||||
if (in_vim9script())
|
||||
return FALSE;
|
||||
if (*p == 'k')
|
||||
{
|
||||
*idx = CMD_k;
|
||||
return TRUE;
|
||||
}
|
||||
if (p[0] == 's'
|
||||
&& ((p[1] == 'c' && (p[2] == NUL || (p[2] != 's' && p[2] != 'r'
|
||||
&& (p[3] == NUL || (p[3] != 'i' && p[4] != 'p')))))
|
||||
|| p[1] == 'g'
|
||||
|| (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
|
||||
|| p[1] == 'I'
|
||||
|| (p[1] == 'r' && p[2] != 'e')))
|
||||
{
|
||||
*idx = CMD_substitute;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an Ex command by its name, either built-in or user.
|
||||
* Start of the name can be found at eap->cmd.
|
||||
@@ -3660,30 +3692,10 @@ find_ex_command(
|
||||
|
||||
/*
|
||||
* Isolate the command and search for it in the command table.
|
||||
* Exceptions:
|
||||
* - The 'k' command can directly be followed by any character.
|
||||
* But it is not used in Vim9 script.
|
||||
* - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
|
||||
* but :sre[wind] is another command, as are :scr[iptnames],
|
||||
* :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
|
||||
* - the "d" command can directly be followed by 'l' or 'p' flag.
|
||||
*/
|
||||
p = eap->cmd;
|
||||
if (!vim9 && *p == 'k')
|
||||
if (one_letter_cmd(p, &eap->cmdidx))
|
||||
{
|
||||
eap->cmdidx = CMD_k;
|
||||
++p;
|
||||
}
|
||||
else if (!vim9
|
||||
&& p[0] == 's'
|
||||
&& ((p[1] == 'c' && (p[2] == NUL || (p[2] != 's' && p[2] != 'r'
|
||||
&& (p[3] == NUL || (p[3] != 'i' && p[4] != 'p')))))
|
||||
|| p[1] == 'g'
|
||||
|| (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
|
||||
|| p[1] == 'I'
|
||||
|| (p[1] == 'r' && p[2] != 'e')))
|
||||
{
|
||||
eap->cmdidx = CMD_substitute;
|
||||
++p;
|
||||
}
|
||||
else
|
||||
@@ -3708,6 +3720,8 @@ find_ex_command(
|
||||
if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#}", *p) != NULL)
|
||||
++p;
|
||||
len = (int)(p - eap->cmd);
|
||||
// The "d" command can directly be followed by 'l' or 'p' flag, when
|
||||
// not in Vim9 script.
|
||||
if (!vim9 && *eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
|
||||
{
|
||||
// Check for ":dl", ":dell", etc. to ":deletel": that's
|
||||
@@ -3961,10 +3975,11 @@ excmd_get_cmdidx(char_u *cmd, int len)
|
||||
{
|
||||
cmdidx_T idx;
|
||||
|
||||
for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE;
|
||||
idx = (cmdidx_T)((int)idx + 1))
|
||||
if (STRNCMP(cmdnames[(int)idx].cmd_name, cmd, (size_t)len) == 0)
|
||||
break;
|
||||
if (!one_letter_cmd(cmd, &idx))
|
||||
for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE;
|
||||
idx = (cmdidx_T)((int)idx + 1))
|
||||
if (STRNCMP(cmdnames[(int)idx].cmd_name, cmd, (size_t)len) == 0)
|
||||
break;
|
||||
|
||||
return idx;
|
||||
}
|
||||
@@ -5087,9 +5102,10 @@ repl_cmdline(
|
||||
|
||||
/*
|
||||
* Check for '|' to separate commands and '"' to start comments.
|
||||
* If "keep_backslash" is TRUE do not remove any backslash.
|
||||
*/
|
||||
void
|
||||
separate_nextcmd(exarg_T *eap)
|
||||
separate_nextcmd(exarg_T *eap, int keep_backslash)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
@@ -5103,7 +5119,7 @@ separate_nextcmd(exarg_T *eap)
|
||||
{
|
||||
if (*p == Ctrl_V)
|
||||
{
|
||||
if (eap->argt & (EX_CTRLV | EX_XFILE))
|
||||
if ((eap->argt & (EX_CTRLV | EX_XFILE)) || keep_backslash)
|
||||
++p; // skip CTRL-V and next char
|
||||
else
|
||||
// remove CTRL-V and skip next char
|
||||
@@ -5150,8 +5166,11 @@ separate_nextcmd(exarg_T *eap)
|
||||
if ((vim_strchr(p_cpo, CPO_BAR) == NULL
|
||||
|| !(eap->argt & EX_CTRLV)) && *(p - 1) == '\\')
|
||||
{
|
||||
STRMOVE(p - 1, p); // remove the '\'
|
||||
--p;
|
||||
if (!keep_backslash)
|
||||
{
|
||||
STRMOVE(p - 1, p); // remove the '\'
|
||||
--p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -4974,7 +4974,7 @@ readdir_core(
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ignore && checkitem != NULL)
|
||||
if (checkitem != NULL)
|
||||
{
|
||||
int r = checkitem(context, item);
|
||||
|
||||
|
||||
@@ -736,6 +736,9 @@ EXTERN win_T *popup_dragwin INIT(= NULL); // popup window being dragged
|
||||
// Set to TRUE if there is any visible popup window.
|
||||
EXTERN int popup_visible INIT(= FALSE);
|
||||
|
||||
// Set to TRUE if a visible popup window may use a MOUSE_MOVE event
|
||||
EXTERN int popup_uses_mouse_move INIT(= FALSE);
|
||||
|
||||
EXTERN int text_prop_frozen INIT(= 0);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5008,7 +5008,7 @@ gui_mouse_moved(int x, int y)
|
||||
gui_mouse_focus(x, y);
|
||||
|
||||
#ifdef FEAT_PROP_POPUP
|
||||
if (popup_visible)
|
||||
if (popup_uses_mouse_move)
|
||||
// Generate a mouse-moved event, so that the popup can perhaps be
|
||||
// closed, just like in the terminal.
|
||||
gui_send_mouse_event(MOUSE_MOVE, x, y, FALSE, 0);
|
||||
|
||||
+6
-6
@@ -142,12 +142,12 @@ tabline_button_cb(
|
||||
XtPointer client_data UNUSED,
|
||||
XtPointer call_data UNUSED)
|
||||
{
|
||||
int cmd, tab_idx;
|
||||
XtPointer cmd, tab_idx;
|
||||
|
||||
XtVaGetValues(w, XmNuserData, &cmd, NULL);
|
||||
XtVaGetValues(tabLine_menu, XmNuserData, &tab_idx, NULL);
|
||||
|
||||
send_tabline_menu_event(tab_idx, cmd);
|
||||
send_tabline_menu_event((int)(long)tab_idx, (int)(long)cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -254,7 +254,7 @@ tabline_menu_cb(
|
||||
XtVaGetValues(tab_w, XmNpageNumber, &tab_idx, NULL);
|
||||
}
|
||||
|
||||
XtVaSetValues(tabLine_menu, XmNuserData, tab_idx, NULL);
|
||||
XtVaSetValues(tabLine_menu, XmNuserData, (XtPointer)(long)tab_idx, NULL);
|
||||
XtVaGetValues(tabLine_menu, XmNchildren, &children, XmNnumChildren,
|
||||
&numChildren, NULL);
|
||||
XtManageChildren(children, numChildren);
|
||||
@@ -517,7 +517,7 @@ gui_x11_create_widgets(void)
|
||||
|
||||
// Add the buttons to the tabline popup menu
|
||||
n = 0;
|
||||
XtSetArg(args[n], XmNuserData, TABLINE_MENU_CLOSE); n++;
|
||||
XtSetArg(args[n], XmNuserData, (XtPointer)TABLINE_MENU_CLOSE); n++;
|
||||
xms = XmStringCreate((char *)"Close tab", STRING_TAG);
|
||||
XtSetArg(args[n], XmNlabelString, xms); n++;
|
||||
button = XmCreatePushButton(tabLine_menu, "Close", args, n);
|
||||
@@ -526,7 +526,7 @@ gui_x11_create_widgets(void)
|
||||
XmStringFree(xms);
|
||||
|
||||
n = 0;
|
||||
XtSetArg(args[n], XmNuserData, TABLINE_MENU_NEW); n++;
|
||||
XtSetArg(args[n], XmNuserData, (XtPointer)TABLINE_MENU_NEW); n++;
|
||||
xms = XmStringCreate((char *)"New Tab", STRING_TAG);
|
||||
XtSetArg(args[n], XmNlabelString, xms); n++;
|
||||
button = XmCreatePushButton(tabLine_menu, "New Tab", args, n);
|
||||
@@ -535,7 +535,7 @@ gui_x11_create_widgets(void)
|
||||
XmStringFree(xms);
|
||||
|
||||
n = 0;
|
||||
XtSetArg(args[n], XmNuserData, TABLINE_MENU_OPEN); n++;
|
||||
XtSetArg(args[n], XmNuserData, (XtPointer)TABLINE_MENU_OPEN); n++;
|
||||
xms = XmStringCreate((char *)"Open tab...", STRING_TAG);
|
||||
XtSetArg(args[n], XmNlabelString, xms); n++;
|
||||
button = XmCreatePushButton(tabLine_menu, "Open tab...", args, n);
|
||||
|
||||
+1
-1
@@ -2261,7 +2261,7 @@ swapfile_info(char_u *fname)
|
||||
* Return TRUE if the swap file looks OK and there are no changes, thus it can
|
||||
* be safely deleted.
|
||||
*/
|
||||
static time_t
|
||||
static int
|
||||
swapfile_unchanged(char_u *fname)
|
||||
{
|
||||
stat_T st;
|
||||
|
||||
+1
-1
@@ -1808,7 +1808,7 @@ str2special(
|
||||
int len = (*mb_ptr2len)(str);
|
||||
|
||||
// For multi-byte characters check for an illegal byte.
|
||||
if (has_mbyte && MB_BYTE2LEN(*str) > len)
|
||||
if (MB_BYTE2LEN(*str) > len)
|
||||
{
|
||||
transchar_nonprint(curbuf, buf, c);
|
||||
*sp = str + 1;
|
||||
|
||||
+1
-1
@@ -596,7 +596,7 @@ check_cursor_col_win(win_T *win)
|
||||
// Make sure that coladd is not more than the char width.
|
||||
// Not for the last character, coladd is then used when the cursor
|
||||
// is actually after the last character.
|
||||
if (win->w_cursor.col + 1 < len && win->w_cursor.coladd > 0)
|
||||
if (win->w_cursor.col + 1 < len)
|
||||
{
|
||||
int cs, ce;
|
||||
|
||||
|
||||
+2
-26
@@ -115,14 +115,6 @@ comp_botline(win_T *wp)
|
||||
set_empty_rows(wp, done);
|
||||
}
|
||||
|
||||
#ifdef FEAT_SYN_HL
|
||||
void
|
||||
reset_cursorline(void)
|
||||
{
|
||||
curwin->w_last_cursorline = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is
|
||||
* set.
|
||||
@@ -138,24 +130,8 @@ redraw_for_cursorline(win_T *wp)
|
||||
&& (wp->w_valid & VALID_CROW) == 0
|
||||
&& !pum_visible())
|
||||
{
|
||||
if (wp->w_p_rnu)
|
||||
// win_line() will redraw the number column only.
|
||||
redraw_win_later(wp, VALID);
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (wp->w_p_cul)
|
||||
{
|
||||
if (wp->w_redr_type <= VALID && wp->w_last_cursorline != 0)
|
||||
{
|
||||
// "w_last_cursorline" may be outdated, worst case we redraw
|
||||
// too much. This is optimized for moving the cursor around in
|
||||
// the current window.
|
||||
redrawWinline(wp, wp->w_last_cursorline);
|
||||
redrawWinline(wp, wp->w_cursor.lnum);
|
||||
}
|
||||
else
|
||||
redraw_win_later(wp, SOME_VALID);
|
||||
}
|
||||
#endif
|
||||
// win_line() will redraw the number column and cursorline only.
|
||||
redraw_win_later(wp, VALID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1310,7 +1310,7 @@ op_tilde(oparg_T *oap)
|
||||
changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
|
||||
0L);
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
if (netbeans_active() && did_change)
|
||||
if (netbeans_active())
|
||||
{
|
||||
char_u *ptr;
|
||||
int count;
|
||||
|
||||
@@ -2804,11 +2804,6 @@ set_bool_option(
|
||||
p_lrm = !p_lnr;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_SYN_HL
|
||||
else if ((int *)varp == &curwin->w_p_cul && !value && old_value)
|
||||
reset_cursorline();
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_PERSISTENT_UNDO
|
||||
// 'undofile'
|
||||
else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf)
|
||||
|
||||
+26
-1
@@ -150,6 +150,29 @@ set_mousemoved_values(win_T *wp)
|
||||
wp->w_popup_mouse_maxcol = mouse_col;
|
||||
}
|
||||
|
||||
static void
|
||||
update_popup_uses_mouse_move(void)
|
||||
{
|
||||
popup_uses_mouse_move = FALSE;
|
||||
if (popup_visible)
|
||||
{
|
||||
win_T *wp;
|
||||
|
||||
FOR_ALL_POPUPWINS(wp)
|
||||
if (wp->w_popup_mouse_row != 0)
|
||||
{
|
||||
popup_uses_mouse_move = TRUE;
|
||||
return;
|
||||
}
|
||||
FOR_ALL_POPUPWINS_IN_TAB(curtab, wp)
|
||||
if (wp->w_popup_mouse_row != 0)
|
||||
{
|
||||
popup_uses_mouse_move = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used when popup options contain "moved" with "word" or "WORD".
|
||||
*/
|
||||
@@ -3586,7 +3609,7 @@ popup_need_position_adjust(win_T *wp)
|
||||
/*
|
||||
* Update "popup_mask" if needed.
|
||||
* Also recomputes the popup size and positions.
|
||||
* Also updates "popup_visible".
|
||||
* Also updates "popup_visible" and "popup_uses_mouse_move".
|
||||
* Also marks window lines for redrawing.
|
||||
*/
|
||||
void
|
||||
@@ -3755,6 +3778,8 @@ may_update_popup_mask(int type)
|
||||
|
||||
vim_free(plines_cache);
|
||||
}
|
||||
|
||||
update_popup_uses_mouse_move();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,7 +26,7 @@ long excmd_get_argt(cmdidx_T idx);
|
||||
char_u *skip_range(char_u *cmd_start, int skip_star, int *ctx);
|
||||
void ex_ni(exarg_T *eap);
|
||||
int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp);
|
||||
void separate_nextcmd(exarg_T *eap);
|
||||
void separate_nextcmd(exarg_T *eap, int keep_backslash);
|
||||
char_u *skip_cmd_arg(char_u *p, int rembs);
|
||||
int get_bad_opt(char_u *p, exarg_T *eap);
|
||||
int ends_excmd(int c);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* move.c */
|
||||
void reset_cursorline(void);
|
||||
void redraw_for_cursorline(win_T *wp);
|
||||
void update_topline_redraw(void);
|
||||
void update_topline(void);
|
||||
|
||||
@@ -32,6 +32,7 @@ void free_scriptnames(void);
|
||||
void free_autoload_scriptnames(void);
|
||||
linenr_T get_sourced_lnum(char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
|
||||
char_u *getsourceline(int c, void *cookie, int indent, getline_opt_T options);
|
||||
int sourcing_a_script(exarg_T *eap);
|
||||
void ex_scriptencoding(exarg_T *eap);
|
||||
void ex_scriptversion(exarg_T *eap);
|
||||
void ex_finish(exarg_T *eap);
|
||||
@@ -42,5 +43,4 @@ char_u *get_autoload_prefix(scriptitem_T *si);
|
||||
char_u *may_prefix_autoload(char_u *name);
|
||||
char_u *autoload_name(char_u *name);
|
||||
int script_autoload(char_u *name, int reload);
|
||||
int sourcing_a_script(exarg_T *eap);
|
||||
/* vim: set ft=c : */
|
||||
|
||||
@@ -38,7 +38,7 @@ int generate_OLDSCRIPT(cctx_T *cctx, isntype_T isn_type, char_u *name, int sid,
|
||||
int generate_VIM9SCRIPT(cctx_T *cctx, isntype_T isn_type, int sid, int idx, type_T *type);
|
||||
int generate_NEWLIST(cctx_T *cctx, int count);
|
||||
int generate_NEWDICT(cctx_T *cctx, int count);
|
||||
int generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc);
|
||||
int generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc, isn_T **isnp);
|
||||
int generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name);
|
||||
int generate_DEF(cctx_T *cctx, char_u *name, size_t len);
|
||||
int generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
int in_vim9script(void);
|
||||
int in_old_script(int max_version);
|
||||
int current_script_is_vim9(void);
|
||||
void clear_vim9_scriptlocal_vars(int sid);
|
||||
void ex_vim9script(exarg_T *eap);
|
||||
int not_in_vim9(exarg_T *eap);
|
||||
int vim9_bad_comment(char_u *p);
|
||||
|
||||
@@ -46,6 +46,7 @@ win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, int left, long count);
|
||||
void win_enter(win_T *wp, int undo_sync);
|
||||
win_T *buf_jump_open_win(buf_T *buf);
|
||||
win_T *buf_jump_open_tab(buf_T *buf);
|
||||
int win_unlisted(win_T *wp);
|
||||
void win_free_popup(win_T *win);
|
||||
void win_remove(win_T *wp, tabpage_T *tp);
|
||||
int win_alloc_lines(win_T *wp);
|
||||
|
||||
+180
-296
@@ -23,6 +23,8 @@ static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
|
||||
static int last_current_SID_seq = 0;
|
||||
#endif
|
||||
|
||||
static int do_source_ext(char_u *fname, int check_other, int is_vimrc, int *ret_sid, exarg_T *eap, int clearvars);
|
||||
|
||||
/*
|
||||
* Initialize the execution stack.
|
||||
*/
|
||||
@@ -1079,254 +1081,23 @@ ExpandPackAddDir(
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cookie used to source Ex commands from a buffer.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
garray_T lines_to_source;
|
||||
int lnum;
|
||||
linenr_T sourcing_lnum;
|
||||
} bufline_cookie_T;
|
||||
|
||||
/*
|
||||
* Concatenate a Vim script line if it starts with a line continuation into a
|
||||
* growarray (excluding the continuation chars and leading whitespace).
|
||||
* Growsize of the growarray may be changed to speed up concatenations!
|
||||
*
|
||||
* Returns TRUE if this line did begin with a continuation (the next line
|
||||
* should also be considered, if it exists); FALSE otherwise.
|
||||
*/
|
||||
static int
|
||||
concat_continued_line(
|
||||
garray_T *ga,
|
||||
int init_growsize,
|
||||
char_u *nextline,
|
||||
int options)
|
||||
{
|
||||
int comment_char = in_vim9script() ? '#' : '"';
|
||||
char_u *p = skipwhite(nextline);
|
||||
int contline;
|
||||
int do_vim9_all = in_vim9script()
|
||||
&& options == GETLINE_CONCAT_ALL;
|
||||
int do_bar_cont = do_vim9_all
|
||||
|| options == GETLINE_CONCAT_CONTBAR;
|
||||
|
||||
if (*p == NUL)
|
||||
return FALSE;
|
||||
|
||||
// Concatenate the next line when it starts with a backslash.
|
||||
/* Also check for a comment in between continuation lines: "\ */
|
||||
// Also check for a Vim9 comment, empty line, line starting with '|',
|
||||
// but not "||".
|
||||
if ((p[0] == comment_char && p[1] == '\\' && p[2] == ' ')
|
||||
|| (do_vim9_all && (*p == NUL
|
||||
|| vim9_comment_start(p))))
|
||||
return TRUE;
|
||||
|
||||
contline = (*p == '\\' || (do_bar_cont && p[0] == '|' && p[1] != '|'));
|
||||
if (!contline)
|
||||
return FALSE;
|
||||
|
||||
// Adjust the growsize to the current length to speed up concatenating many
|
||||
// lines.
|
||||
if (ga->ga_len > init_growsize)
|
||||
ga->ga_growsize = ga->ga_len > 8000 ? 8000 : ga->ga_len;
|
||||
if (*p == '\\')
|
||||
ga_concat(ga, (char_u *)p + 1);
|
||||
else if (*p == '|')
|
||||
{
|
||||
ga_concat(ga, (char_u *)" ");
|
||||
ga_concat(ga, p);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get one full line from a sourced string (in-memory, no file).
|
||||
* Called by do_cmdline() when it's called from source_using_linegetter().
|
||||
*
|
||||
* Returns a pointer to allocated line, or NULL for end-of-file.
|
||||
*/
|
||||
static char_u *
|
||||
source_getbufline(
|
||||
int c UNUSED,
|
||||
void *cookie,
|
||||
int indent UNUSED,
|
||||
getline_opt_T opts)
|
||||
{
|
||||
bufline_cookie_T *p = cookie;
|
||||
char_u *line;
|
||||
garray_T ga;
|
||||
|
||||
SOURCING_LNUM = p->sourcing_lnum + 1;
|
||||
|
||||
if (p->lnum >= p->lines_to_source.ga_len)
|
||||
return NULL;
|
||||
line = ((char_u **)p->lines_to_source.ga_data)[p->lnum];
|
||||
|
||||
ga_init2(&ga, sizeof(char_u), 400);
|
||||
ga_concat(&ga, (char_u *)line);
|
||||
p->lnum++;
|
||||
|
||||
if ((opts != GETLINE_NONE) && vim_strchr(p_cpo, CPO_CONCAT) == NULL)
|
||||
{
|
||||
while (p->lnum < p->lines_to_source.ga_len)
|
||||
{
|
||||
line = ((char_u **)p->lines_to_source.ga_data)[p->lnum];
|
||||
if (!concat_continued_line(&ga, 400, line, opts))
|
||||
break;
|
||||
p->sourcing_lnum++;
|
||||
p->lnum++;
|
||||
}
|
||||
}
|
||||
ga_append(&ga, NUL);
|
||||
p->sourcing_lnum++;
|
||||
|
||||
return ga.ga_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Source Ex commands from the lines in 'cookie'.
|
||||
*/
|
||||
static int
|
||||
do_sourcebuffer(
|
||||
void *cookie,
|
||||
char_u *scriptname)
|
||||
{
|
||||
char_u *save_sourcing_name = SOURCING_NAME;
|
||||
linenr_T save_sourcing_lnum = SOURCING_LNUM;
|
||||
char_u sourcing_name_buf[256];
|
||||
sctx_T save_current_sctx;
|
||||
#ifdef FEAT_EVAL
|
||||
int sid;
|
||||
funccal_entry_T funccalp_entry;
|
||||
int save_estack_compiling = estack_compiling;
|
||||
scriptitem_T *si = NULL;
|
||||
#endif
|
||||
int save_sticky_cmdmod_flags = sticky_cmdmod_flags;
|
||||
int retval = FAIL;
|
||||
ESTACK_CHECK_DECLARATION
|
||||
|
||||
if (save_sourcing_name == NULL)
|
||||
SOURCING_NAME = (char_u *)scriptname;
|
||||
else
|
||||
{
|
||||
vim_snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf),
|
||||
"%s called at %s:%ld", scriptname, save_sourcing_name,
|
||||
save_sourcing_lnum);
|
||||
SOURCING_NAME = sourcing_name_buf;
|
||||
}
|
||||
SOURCING_LNUM = 0;
|
||||
|
||||
// Keep the sourcing name/lnum, for recursive calls.
|
||||
estack_push(ETYPE_SCRIPT, scriptname, 0);
|
||||
ESTACK_CHECK_SETUP
|
||||
|
||||
// "legacy" does not apply to commands in the script
|
||||
sticky_cmdmod_flags = 0;
|
||||
|
||||
save_current_sctx = current_sctx;
|
||||
current_sctx.sc_version = 1; // default script version
|
||||
#ifdef FEAT_EVAL
|
||||
estack_compiling = FALSE;
|
||||
// Always use a new sequence number.
|
||||
current_sctx.sc_seq = ++last_current_SID_seq;
|
||||
current_sctx.sc_lnum = save_sourcing_lnum;
|
||||
save_funccal(&funccalp_entry);
|
||||
|
||||
sid = find_script_by_name(scriptname);
|
||||
if (sid < 0)
|
||||
{
|
||||
int error = OK;
|
||||
|
||||
// First time sourcing this buffer, create a new script item.
|
||||
|
||||
sid = get_new_scriptitem(&error);
|
||||
if (error == FAIL)
|
||||
goto theend;
|
||||
current_sctx.sc_sid = sid;
|
||||
si = SCRIPT_ITEM(current_sctx.sc_sid);
|
||||
si->sn_name = vim_strsave(scriptname);
|
||||
si->sn_state = SN_STATE_NEW;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the buffer was sourced previously, reuse the script ID.
|
||||
current_sctx.sc_sid = sid;
|
||||
si = SCRIPT_ITEM(current_sctx.sc_sid);
|
||||
si->sn_state = SN_STATE_RELOAD;
|
||||
}
|
||||
#endif
|
||||
|
||||
retval = do_cmdline(NULL, source_getbufline, cookie,
|
||||
DOCMD_VERBOSE | DOCMD_NOWAIT | DOCMD_REPEAT);
|
||||
|
||||
if (got_int)
|
||||
emsg(_(e_interrupted));
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
theend:
|
||||
#endif
|
||||
ESTACK_CHECK_NOW
|
||||
estack_pop();
|
||||
current_sctx = save_current_sctx;
|
||||
SOURCING_LNUM = save_sourcing_lnum;
|
||||
SOURCING_NAME = save_sourcing_name;
|
||||
sticky_cmdmod_flags = save_sticky_cmdmod_flags;
|
||||
#ifdef FEAT_EVAL
|
||||
restore_funccal();
|
||||
estack_compiling = save_estack_compiling;
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* :source Ex commands from the current buffer
|
||||
*/
|
||||
static void
|
||||
cmd_source_buffer(exarg_T *eap)
|
||||
{
|
||||
char_u *line = NULL;
|
||||
linenr_T curr_lnum;
|
||||
bufline_cookie_T cp;
|
||||
char_u sname[32];
|
||||
|
||||
if (curbuf == NULL)
|
||||
return;
|
||||
|
||||
// Use ":source buffer=<num>" as the script name
|
||||
vim_snprintf((char *)sname, sizeof(sname), ":source buffer=%d",
|
||||
curbuf->b_fnum);
|
||||
|
||||
ga_init2(&cp.lines_to_source, sizeof(char_u *), 100);
|
||||
|
||||
// Copy the lines from the buffer into a grow array
|
||||
for (curr_lnum = eap->line1; curr_lnum <= eap->line2; curr_lnum++)
|
||||
{
|
||||
line = vim_strsave(ml_get(curr_lnum));
|
||||
if (line == NULL)
|
||||
goto errret;
|
||||
if (ga_add_string(&cp.lines_to_source, line) == FAIL)
|
||||
goto errret;
|
||||
line = NULL;
|
||||
}
|
||||
cp.sourcing_lnum = 0;
|
||||
cp.lnum = 0;
|
||||
|
||||
// Execute the Ex commands
|
||||
do_sourcebuffer((void *)&cp, (char_u *)sname);
|
||||
|
||||
errret:
|
||||
vim_free(line);
|
||||
ga_clear_strings(&cp.lines_to_source);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_source(char_u *fname, exarg_T *eap)
|
||||
{
|
||||
int clearvars = FALSE;
|
||||
|
||||
if (*fname != NUL && STRNCMP(fname, "++clear", 7) == 0)
|
||||
{
|
||||
// ++clear argument is supplied
|
||||
clearvars = TRUE;
|
||||
fname = fname + 7;
|
||||
if (*fname != NUL)
|
||||
{
|
||||
semsg(_(e_invalid_argument_str), eap->arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (*fname != NUL && eap != NULL && eap->addr_count > 0)
|
||||
{
|
||||
// if a filename is specified to :source, then a range is not allowed
|
||||
@@ -1341,7 +1112,7 @@ cmd_source(char_u *fname, exarg_T *eap)
|
||||
emsg(_(e_argument_required));
|
||||
else
|
||||
// source ex commands from the current buffer
|
||||
cmd_source_buffer(eap);
|
||||
do_source_ext(NULL, FALSE, FALSE, NULL, eap, clearvars);
|
||||
}
|
||||
else if (eap != NULL && eap->forceit)
|
||||
// ":source!": read Normal mode commands
|
||||
@@ -1480,21 +1251,78 @@ fopen_noinh_readbin(char *filename)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* do_source: Read the file "fname" and execute its lines as EX commands.
|
||||
* Initialization for sourcing lines from the current buffer. Reads all the
|
||||
* lines from the buffer and stores it in the cookie grow array.
|
||||
* Returns a pointer to the name ":source buffer=<n>" on success and NULL on
|
||||
* failure.
|
||||
*/
|
||||
static char_u *
|
||||
do_source_buffer_init(source_cookie_T *sp, exarg_T *eap)
|
||||
{
|
||||
linenr_T curr_lnum;
|
||||
char_u *line = NULL;
|
||||
char_u *fname;
|
||||
|
||||
CLEAR_FIELD(*sp);
|
||||
|
||||
if (curbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
// Use ":source buffer=<num>" as the script name
|
||||
vim_snprintf((char *)IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum);
|
||||
fname = vim_strsave(IObuff);
|
||||
if (fname == NULL)
|
||||
return NULL;
|
||||
|
||||
ga_init2(&sp->buflines, sizeof(char_u *), 100);
|
||||
|
||||
// Copy the lines from the buffer into a grow array
|
||||
for (curr_lnum = eap->line1; curr_lnum <= eap->line2; curr_lnum++)
|
||||
{
|
||||
line = vim_strsave(ml_get(curr_lnum));
|
||||
if (line == NULL)
|
||||
goto errret;
|
||||
if (ga_add_string(&sp->buflines, line) == FAIL)
|
||||
goto errret;
|
||||
line = NULL;
|
||||
}
|
||||
sp->buf_lnum = 0;
|
||||
sp->source_from_buf = TRUE;
|
||||
|
||||
return fname;
|
||||
|
||||
errret:
|
||||
vim_free(fname);
|
||||
vim_free(line);
|
||||
ga_clear_strings(&sp->buflines);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the file "fname" and execute its lines as EX commands.
|
||||
* When "ret_sid" is not NULL and we loaded the script before, don't load it
|
||||
* again.
|
||||
*
|
||||
* The 'eap' argument is used when sourcing lines from a buffer instead of a
|
||||
* file.
|
||||
*
|
||||
* If 'clearvars' is TRUE, then for scripts which are loaded more than
|
||||
* once, clear all the functions and variables previously defined in that
|
||||
* script.
|
||||
*
|
||||
* This function may be called recursively!
|
||||
*
|
||||
* Return FAIL if file could not be opened, OK otherwise.
|
||||
* If a scriptitem_T was found or created "*ret_sid" is set to the SID.
|
||||
*/
|
||||
int
|
||||
do_source(
|
||||
static int
|
||||
do_source_ext(
|
||||
char_u *fname,
|
||||
int check_other, // check for .vimrc and _vimrc
|
||||
int is_vimrc, // DOSO_ value
|
||||
int *ret_sid UNUSED)
|
||||
int *ret_sid UNUSED,
|
||||
exarg_T *eap,
|
||||
int clearvars UNUSED)
|
||||
{
|
||||
source_cookie_T cookie;
|
||||
char_u *p;
|
||||
@@ -1520,17 +1348,28 @@ do_source(
|
||||
int trigger_source_post = FALSE;
|
||||
ESTACK_CHECK_DECLARATION
|
||||
|
||||
p = expand_env_save(fname);
|
||||
if (p == NULL)
|
||||
return retval;
|
||||
fname_exp = fix_fname(p);
|
||||
vim_free(p);
|
||||
if (fname_exp == NULL)
|
||||
return retval;
|
||||
if (mch_isdir(fname_exp))
|
||||
CLEAR_FIELD(cookie);
|
||||
if (fname == NULL)
|
||||
{
|
||||
smsg(_("Cannot source a directory: \"%s\""), fname);
|
||||
goto theend;
|
||||
// sourcing lines from a buffer
|
||||
fname_exp = do_source_buffer_init(&cookie, eap);
|
||||
if (fname_exp == NULL)
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = expand_env_save(fname);
|
||||
if (p == NULL)
|
||||
return retval;
|
||||
fname_exp = fix_fname(p);
|
||||
vim_free(p);
|
||||
if (fname_exp == NULL)
|
||||
return retval;
|
||||
if (mch_isdir(fname_exp))
|
||||
{
|
||||
smsg(_("Cannot source a directory: \"%s\""), fname);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_EVAL
|
||||
estack_compiling = FALSE;
|
||||
@@ -1567,11 +1406,14 @@ do_source(
|
||||
// Apply SourcePre autocommands, they may get the file.
|
||||
apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
|
||||
|
||||
if (!cookie.source_from_buf)
|
||||
{
|
||||
#ifdef USE_FOPEN_NOINH
|
||||
cookie.fp = fopen_noinh_readbin((char *)fname_exp);
|
||||
cookie.fp = fopen_noinh_readbin((char *)fname_exp);
|
||||
#else
|
||||
cookie.fp = mch_fopen((char *)fname_exp, READBIN);
|
||||
cookie.fp = mch_fopen((char *)fname_exp, READBIN);
|
||||
#endif
|
||||
}
|
||||
if (cookie.fp == NULL && check_other)
|
||||
{
|
||||
// Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
|
||||
@@ -1594,7 +1436,7 @@ do_source(
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie.fp == NULL)
|
||||
if (cookie.fp == NULL && !cookie.source_from_buf)
|
||||
{
|
||||
if (p_verbose > 0)
|
||||
{
|
||||
@@ -1632,12 +1474,14 @@ do_source(
|
||||
cookie.fileformat = EOL_DOS;
|
||||
else
|
||||
cookie.fileformat = EOL_UNKNOWN;
|
||||
cookie.error = FALSE;
|
||||
#endif
|
||||
|
||||
cookie.nextline = NULL;
|
||||
cookie.sourcing_lnum = 0;
|
||||
cookie.finished = FALSE;
|
||||
if (fname == NULL)
|
||||
// When sourcing a range of lines from a buffer, use the buffer line
|
||||
// number.
|
||||
cookie.sourcing_lnum = eap->line1 - 1;
|
||||
else
|
||||
cookie.sourcing_lnum = 0;
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
// Check if this script has a breakpoint.
|
||||
@@ -1661,7 +1505,12 @@ do_source(
|
||||
sticky_cmdmod_flags = 0;
|
||||
|
||||
save_current_sctx = current_sctx;
|
||||
current_sctx.sc_version = 1; // default script version
|
||||
if (cmdmod.cmod_flags & CMOD_VIM9CMD)
|
||||
// When the ":vim9cmd" command modifier is used, source the script as a
|
||||
// Vim9 script.
|
||||
current_sctx.sc_version = SCRIPT_VERSION_VIM9;
|
||||
else
|
||||
current_sctx.sc_version = 1; // default script version
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
# ifdef FEAT_PROFILE
|
||||
@@ -1697,20 +1546,25 @@ do_source(
|
||||
{
|
||||
si->sn_state = SN_STATE_RELOAD;
|
||||
|
||||
// Script-local variables remain but "const" can be set again.
|
||||
// In Vim9 script variables will be cleared when "vim9script" is
|
||||
// encountered without the "noclear" argument.
|
||||
ht = &SCRIPT_VARS(sid);
|
||||
todo = (int)ht->ht_used;
|
||||
for (hi = ht->ht_array; todo > 0; ++hi)
|
||||
if (!HASHITEM_EMPTY(hi))
|
||||
{
|
||||
--todo;
|
||||
di = HI2DI(hi);
|
||||
di->di_flags |= DI_FLAGS_RELOAD;
|
||||
}
|
||||
// imports can be redefined once
|
||||
mark_imports_for_reload(sid);
|
||||
if (!clearvars)
|
||||
{
|
||||
// Script-local variables remain but "const" can be set again.
|
||||
// In Vim9 script variables will be cleared when "vim9script"
|
||||
// is encountered without the "noclear" argument.
|
||||
ht = &SCRIPT_VARS(sid);
|
||||
todo = (int)ht->ht_used;
|
||||
for (hi = ht->ht_array; todo > 0; ++hi)
|
||||
if (!HASHITEM_EMPTY(hi))
|
||||
{
|
||||
--todo;
|
||||
di = HI2DI(hi);
|
||||
di->di_flags |= DI_FLAGS_RELOAD;
|
||||
}
|
||||
// imports can be redefined once
|
||||
mark_imports_for_reload(sid);
|
||||
}
|
||||
else
|
||||
clear_vim9_scriptlocal_vars(sid);
|
||||
|
||||
// reset version, "vim9script" may have been added or removed.
|
||||
si->sn_version = 1;
|
||||
@@ -1874,7 +1728,10 @@ almosttheend:
|
||||
#endif
|
||||
current_sctx = save_current_sctx;
|
||||
|
||||
fclose(cookie.fp);
|
||||
if (cookie.fp != NULL)
|
||||
fclose(cookie.fp);
|
||||
if (cookie.source_from_buf)
|
||||
ga_clear_strings(&cookie.buflines);
|
||||
vim_free(cookie.nextline);
|
||||
vim_free(firstline);
|
||||
convert_setup(&cookie.conv, NULL, NULL);
|
||||
@@ -1891,6 +1748,17 @@ theend:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
do_source(
|
||||
char_u *fname,
|
||||
int check_other, // check for .vimrc and _vimrc
|
||||
int is_vimrc, // DOSO_ value
|
||||
int *ret_sid UNUSED)
|
||||
{
|
||||
return do_source_ext(fname, check_other, is_vimrc, ret_sid, NULL, FALSE);
|
||||
}
|
||||
|
||||
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
|
||||
/*
|
||||
@@ -1901,14 +1769,20 @@ ex_scriptnames(exarg_T *eap)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (eap->addr_count > 0)
|
||||
if (eap->addr_count > 0 || *eap->arg != NUL)
|
||||
{
|
||||
// :script {scriptId}: edit the script
|
||||
if (!SCRIPT_ID_VALID(eap->line2))
|
||||
if (eap->addr_count > 0 && !SCRIPT_ID_VALID(eap->line2))
|
||||
emsg(_(e_invalid_argument));
|
||||
else
|
||||
{
|
||||
eap->arg = SCRIPT_ITEM(eap->line2)->sn_name;
|
||||
if (eap->addr_count > 0)
|
||||
eap->arg = SCRIPT_ITEM(eap->line2)->sn_name;
|
||||
else
|
||||
{
|
||||
expand_env(eap->arg, NameBuff, MAXPATHL);
|
||||
eap->arg = NameBuff;
|
||||
}
|
||||
do_exedit(eap, NULL);
|
||||
}
|
||||
return;
|
||||
@@ -2038,11 +1912,21 @@ get_one_sourceline(source_cookie_T *sp)
|
||||
// make room to read at least 120 (more) characters
|
||||
if (ga_grow(&ga, 120) == FAIL)
|
||||
break;
|
||||
buf = (char_u *)ga.ga_data;
|
||||
|
||||
if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
|
||||
sp->fp) == NULL)
|
||||
break;
|
||||
if (sp->source_from_buf)
|
||||
{
|
||||
if (sp->buf_lnum >= sp->buflines.ga_len)
|
||||
break; // all the lines are processed
|
||||
ga_concat(&ga, ((char_u **)sp->buflines.ga_data)[sp->buf_lnum]);
|
||||
sp->buf_lnum++;
|
||||
buf = (char_u *)ga.ga_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = (char_u *)ga.ga_data;
|
||||
if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
|
||||
sp->fp) == NULL)
|
||||
break;
|
||||
}
|
||||
len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
|
||||
#ifdef USE_CRNL
|
||||
// Ignore a trailing CTRL-Z, when in Dos mode. Only recognize the
|
||||
@@ -2145,7 +2029,7 @@ getsourceline(
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
// If breakpoints have been added/deleted need to check for it.
|
||||
if (sp->dbg_tick < debug_tick)
|
||||
if ((sp->dbg_tick < debug_tick) && !sp->source_from_buf)
|
||||
{
|
||||
sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, SOURCING_LNUM);
|
||||
sp->dbg_tick = debug_tick;
|
||||
@@ -2161,7 +2045,7 @@ getsourceline(
|
||||
|
||||
// Get current line. If there is a read-ahead line, use it, otherwise get
|
||||
// one now. "fp" is NULL if actually using a string.
|
||||
if (sp->finished || sp->fp == NULL)
|
||||
if (sp->finished || (!sp->source_from_buf && sp->fp == NULL))
|
||||
line = NULL;
|
||||
else if (sp->nextline == NULL)
|
||||
line = get_one_sourceline(sp);
|
||||
@@ -2265,7 +2149,8 @@ getsourceline(
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
// Did we encounter a breakpoint?
|
||||
if (sp->breakpoint != 0 && sp->breakpoint <= SOURCING_LNUM)
|
||||
if (!sp->source_from_buf && sp->breakpoint != 0
|
||||
&& sp->breakpoint <= SOURCING_LNUM)
|
||||
{
|
||||
dbg_breakpoint(sp->fname, SOURCING_LNUM);
|
||||
// Find next breakpoint.
|
||||
@@ -2284,8 +2169,7 @@ getsourceline(
|
||||
int
|
||||
sourcing_a_script(exarg_T *eap)
|
||||
{
|
||||
return (getline_equal(eap->getline, eap->cookie, getsourceline)
|
||||
|| getline_equal(eap->getline, eap->cookie, source_getbufline));
|
||||
return (getline_equal(eap->getline, eap->cookie, getsourceline));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -847,7 +847,7 @@ sign_mark_adjust(
|
||||
if (sign->se_lnum < line1)
|
||||
continue;
|
||||
new_lnum = sign->se_lnum;
|
||||
if (sign->se_lnum >= line1 && sign->se_lnum <= line2)
|
||||
if (sign->se_lnum <= line2)
|
||||
{
|
||||
if (amount != MAXLNUM)
|
||||
new_lnum += amount;
|
||||
|
||||
+3
-4
@@ -1371,11 +1371,10 @@ spell_move_to(
|
||||
// the cursor.
|
||||
if (dir == BACKWARD
|
||||
|| lnum != wp->w_cursor.lnum
|
||||
|| (lnum == wp->w_cursor.lnum
|
||||
&& (wrapped
|
||||
|| (colnr_T)(curline ? p - buf + len
|
||||
|| (wrapped
|
||||
|| (colnr_T)(curline ? p - buf + len
|
||||
: p - buf)
|
||||
> wp->w_cursor.col)))
|
||||
> wp->w_cursor.col))
|
||||
{
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (has_syntax)
|
||||
|
||||
@@ -4445,6 +4445,9 @@ typedef struct {
|
||||
char_u *nextline; // if not NULL: line that was read ahead
|
||||
linenr_T sourcing_lnum; // line number of the source file
|
||||
int finished; // ":finish" used
|
||||
int source_from_buf;// TRUE if sourcing from current buffer
|
||||
int buf_lnum; // line number in the current buffer
|
||||
garray_T buflines; // lines in the current buffer
|
||||
#ifdef USE_CRNL
|
||||
int fileformat; // EOL_UNKNOWN, EOL_UNIX or EOL_DOS
|
||||
int error; // TRUE if LF found after CR-LF
|
||||
|
||||
+1
-1
@@ -4764,7 +4764,7 @@ syn_cmd_include(exarg_T *eap, int syncing UNUSED)
|
||||
* filename to include.
|
||||
*/
|
||||
eap->argt |= (EX_XFILE | EX_NOSPC);
|
||||
separate_nextcmd(eap);
|
||||
separate_nextcmd(eap, FALSE);
|
||||
if (*eap->arg == '<' || *eap->arg == '$' || mch_isFullName(eap->arg))
|
||||
{
|
||||
// For an absolute path, "$VIM/..." or "<sfile>.." we ":source" the
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
source shared.vim
|
||||
source check.vim
|
||||
source term_util.vim
|
||||
import './vim9.vim' as v9
|
||||
|
||||
func s:cleanup_buffers() abort
|
||||
for bnr in range(1, bufnr('$'))
|
||||
@@ -2975,4 +2976,18 @@ func Test_Changed_ChangedI()
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
func Test_closing_autocmd_window()
|
||||
let lines =<< trim END
|
||||
edit Xa.txt
|
||||
tabnew Xb.txt
|
||||
autocmd BufEnter Xa.txt unhide 1
|
||||
doautoall BufEnter
|
||||
END
|
||||
call v9.CheckScriptFailure(lines, 'E814:')
|
||||
au! BufEnter
|
||||
only!
|
||||
bwipe Xa.txt
|
||||
bwipe Xb.txt
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -731,7 +731,7 @@ func Test_breakindent20_list()
|
||||
\ "shall make no law ",
|
||||
\ ]
|
||||
call s:compare_lines(expect, lines)
|
||||
" set mininum indent
|
||||
" set minimum indent
|
||||
setl briopt=min:5
|
||||
redraw!
|
||||
let lines = s:screen_lines2(1, 6, 20)
|
||||
|
||||
@@ -552,6 +552,22 @@ func Test_getcompletion()
|
||||
call assert_fails('call getcompletion("abc", [])', 'E475:')
|
||||
endfunc
|
||||
|
||||
" Test for getcompletion() with "fuzzy" in 'wildoptions'
|
||||
func Test_getcompletion_wildoptions()
|
||||
let save_wildoptions = &wildoptions
|
||||
set wildoptions&
|
||||
let l = getcompletion('space', 'option')
|
||||
call assert_equal([], l)
|
||||
let l = getcompletion('ier', 'command')
|
||||
call assert_equal([], l)
|
||||
set wildoptions=fuzzy
|
||||
let l = getcompletion('space', 'option')
|
||||
call assert_true(index(l, 'backspace') >= 0)
|
||||
let l = getcompletion('ier', 'command')
|
||||
call assert_true(index(l, 'compiler') >= 0)
|
||||
let &wildoptions = save_wildoptions
|
||||
endfunc
|
||||
|
||||
func Test_complete_autoload_error()
|
||||
let save_rtp = &rtp
|
||||
let lines =<< trim END
|
||||
@@ -3241,4 +3257,31 @@ func Test_cmdline_complete_breakdel()
|
||||
call assert_equal("\"breakdel here ", @:)
|
||||
endfunc
|
||||
|
||||
" Test for :scriptnames argument completion
|
||||
func Test_cmdline_complete_scriptnames()
|
||||
set wildmenu
|
||||
call writefile(['let a = 1'], 'Xa1b2c3.vim')
|
||||
source Xa1b2c3.vim
|
||||
call feedkeys(":script \<Tab>\<Left>\<Left>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_match("\"script .*Xa1b2c3.vim$", @:)
|
||||
call feedkeys(":script \<Tab>\<Left>\<Left>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_match("\"script .*Xa1b2c3.vim$", @:)
|
||||
call feedkeys(":script b2c3\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_equal("\"script b2c3", @:)
|
||||
call feedkeys(":script 2\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_match("\"script 2\<Tab>$", @:)
|
||||
call feedkeys(":script \<Tab>\<Left>\<Left> \<Tab>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_match("\"script .*Xa1b2c3.vim $", @:)
|
||||
call feedkeys(":script \<Tab>\<Left>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_equal("\"script ", @:)
|
||||
call assert_match('Xa1b2c3.vim$', getcompletion('.*Xa1b2.*', 'scriptnames')[0])
|
||||
call assert_equal([], getcompletion('Xa1b2', 'scriptnames'))
|
||||
new
|
||||
call feedkeys(":script \<Tab>\<Left>\<Left>\<CR>", 'tx')
|
||||
call assert_equal('Xa1b2c3.vim', fnamemodify(@%, ':t'))
|
||||
bw!
|
||||
call delete('Xa1b2c3.vim')
|
||||
set wildmenu&
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -172,7 +172,7 @@ func Test_uncrypt_xchacha20_2()
|
||||
call assert_equal(range(1, 4000)->map( {_, v -> string(v)}), getline(1,'$'))
|
||||
set key=
|
||||
w! ++ff=unix
|
||||
" enryption removed (on MS-Windows the .* matches [unix])
|
||||
" encryption removed (on MS-Windows the .* matches [unix])
|
||||
call assert_match('"Xcrypt_sodium.txt".*4000L, 18893B written', execute(':message'))
|
||||
bw!
|
||||
call delete('Xcrypt_sodium.txt')
|
||||
|
||||
@@ -162,7 +162,7 @@ func Test_cursorline_screenline()
|
||||
call term_sendkeys(buf, "gj")
|
||||
call VerifyScreenDump(buf, 'Test_'. filename. '_12', {})
|
||||
if exists("+foldcolumn") && exists("+signcolumn") && exists("+breakindent")
|
||||
" test with set foldcolumn signcoloumn and breakindent
|
||||
" test with set foldcolumn signcolumn and breakindent
|
||||
call term_sendkeys(buf, "gg0")
|
||||
call term_sendkeys(buf, ":set breakindent foldcolumn=2 signcolumn=yes\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_'. filename. '_13', {})
|
||||
|
||||
@@ -51,7 +51,7 @@ func Test_digraphs()
|
||||
call Put_Dig("'e")
|
||||
call Put_Dig("b'") " not defined
|
||||
call assert_equal(["á", "é", "'"], getline(line('.')-2,line('.')))
|
||||
" Cicumflex
|
||||
" Circumflex
|
||||
call Put_Dig("a>")
|
||||
call Put_Dig(">e")
|
||||
call Put_Dig("b>") " not defined
|
||||
|
||||
@@ -274,7 +274,7 @@ func Test_set_balloonexpr()
|
||||
" Multiline balloon using NL
|
||||
new
|
||||
func MyBalloonFuncForMultilineUsingNL()
|
||||
return "Multiline\nSuppported\nBalloon\nusing NL"
|
||||
return "Multiline\nSupported\nBalloon\nusing NL"
|
||||
endfunc
|
||||
setl balloonexpr=MyBalloonFuncForMultilineUsingNL()
|
||||
setl ballooneval
|
||||
@@ -289,7 +289,7 @@ func Test_set_balloonexpr()
|
||||
" Multiline balloon using List
|
||||
new
|
||||
func MyBalloonFuncForMultilineUsingList()
|
||||
return [ 'Multiline', 'Suppported', 'Balloon', 'using List' ]
|
||||
return [ 'Multiline', 'Supported', 'Balloon', 'using List' ]
|
||||
endfunc
|
||||
setl balloonexpr=MyBalloonFuncForMultilineUsingList()
|
||||
setl ballooneval
|
||||
@@ -1458,25 +1458,25 @@ func Test_gui_findrepl()
|
||||
call test_gui_event('findrepl', args)
|
||||
call assert_equal(['ONE TWO ONE', 'Twoo ONE TWO ONEo'], getline(1, '$'))
|
||||
|
||||
" Find next occurance of a string (in a find dialog)
|
||||
" Find next occurrence of a string (in a find dialog)
|
||||
call cursor(1, 11)
|
||||
let args = #{find_text: 'TWO', repl_text: '', flags: 0x11, forward: 1}
|
||||
call test_gui_event('findrepl', args)
|
||||
call assert_equal([2, 10], [line('.'), col('.')])
|
||||
|
||||
" Find previous occurances of a string (in a find dialog)
|
||||
" Find previous occurrences of a string (in a find dialog)
|
||||
call cursor(1, 11)
|
||||
let args = #{find_text: 'TWO', repl_text: '', flags: 0x11, forward: 0}
|
||||
call test_gui_event('findrepl', args)
|
||||
call assert_equal([1, 5], [line('.'), col('.')])
|
||||
|
||||
" Find next occurance of a string (in a replace dialog)
|
||||
" Find next occurrence of a string (in a replace dialog)
|
||||
call cursor(1, 1)
|
||||
let args = #{find_text: 'Twoo', repl_text: '', flags: 0x2, forward: 1}
|
||||
call test_gui_event('findrepl', args)
|
||||
call assert_equal([2, 1], [line('.'), col('.')])
|
||||
|
||||
" Replace only the next occurance of a string (once)
|
||||
" Replace only the next occurrence of a string (once)
|
||||
call cursor(1, 5)
|
||||
let args = #{find_text: 'TWO', repl_text: 'two', flags: 0x3, forward: 1}
|
||||
call test_gui_event('findrepl', args)
|
||||
|
||||
@@ -1208,11 +1208,21 @@ func Test_lua_debug()
|
||||
call WaitForAssert({-> assert_equal('42', term_getline(buf, 9))})
|
||||
call WaitForAssert({-> assert_equal('lua_debug> ', term_getline(buf, 10))})
|
||||
|
||||
call term_sendkeys(buf, "-\n")
|
||||
call WaitForAssert({-> assert_equal("(debug command):1: unexpected symbol near '-'",
|
||||
\ term_getline(buf, 9))})
|
||||
call WaitForAssert({-> assert_equal('lua_debug> ', term_getline(buf, 10))})
|
||||
|
||||
call term_sendkeys(buf, "cont\n")
|
||||
call WaitForAssert({-> assert_match(' All$', term_getline(buf, 10))})
|
||||
|
||||
" Entering an empty line also exits the debugger.
|
||||
call term_sendkeys(buf, ":lua debug.debug()\n")
|
||||
call WaitForAssert({-> assert_equal('lua_debug> ', term_getline(buf, 10))})
|
||||
call term_sendkeys(buf, "\n")
|
||||
call WaitForAssert({-> assert_match(' All$', term_getline(buf, 10))})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('XtestLuaDebug.vim')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -6202,4 +6202,39 @@ func Test_getqflist_wiped_out_buffer()
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for the status message that is displayed when opening a new quickfix
|
||||
" list
|
||||
func Test_qflist_statusmsg()
|
||||
cexpr "1\n2"
|
||||
cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"
|
||||
call assert_equal('(4 of 4): msg', v:statusmsg)
|
||||
call setqflist([], 'f')
|
||||
%bw!
|
||||
|
||||
" When creating a new quickfix list, if an autocmd changes the quickfix list
|
||||
" in the stack, then an error message should be displayed.
|
||||
augroup QF_Test
|
||||
au!
|
||||
au BufEnter test_quickfix.vim colder
|
||||
augroup END
|
||||
cexpr "1\n2"
|
||||
call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
|
||||
call setqflist([], 'f')
|
||||
augroup QF_Test
|
||||
au!
|
||||
augroup END
|
||||
%bw!
|
||||
|
||||
augroup QF_Test
|
||||
au!
|
||||
au BufEnter test_quickfix.vim caddexpr "4"
|
||||
augroup END
|
||||
call assert_fails('cexpr "1\n2\n3\ntest_quickfix.vim:1:msg"', 'E925:')
|
||||
call setqflist([], 'f')
|
||||
augroup QF_Test
|
||||
au!
|
||||
augroup END
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -799,7 +799,7 @@ func Test_matchstr_with_ze()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Check a pattern with a look beind crossing a line boundary
|
||||
" Check a pattern with a look behind crossing a line boundary
|
||||
func Test_lookbehind_across_line()
|
||||
new
|
||||
call append(0, ['Behind:', 'asdfasd<yyy', 'xxstart1', 'asdfasd<yy',
|
||||
|
||||
@@ -99,8 +99,8 @@ func Test_signal_INT()
|
||||
call term_sendkeys(buf, ":while 1 | endwhile\n")
|
||||
call WaitForAssert({-> assert_equal(':while 1 | endwhile', term_getline(buf, 6))})
|
||||
exe 'silent !kill -s INT ' .. pid_vim
|
||||
call term_sendkeys(buf, ":call setline(1, 'INTERUPTED')\n")
|
||||
call WaitForAssert({-> assert_equal('INTERUPTED', term_getline(buf, 1))})
|
||||
call term_sendkeys(buf, ":call setline(1, 'INTERRUPTED')\n")
|
||||
call WaitForAssert({-> assert_equal('INTERRUPTED', term_getline(buf, 1))})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
@@ -146,6 +146,23 @@ func Test_source_buffer()
|
||||
2,3source
|
||||
call assert_equal(90, g:a)
|
||||
|
||||
" Make sure the script line number is correct when sourcing a range of
|
||||
" lines.
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
Line 1
|
||||
Line 2
|
||||
func Xtestfunc()
|
||||
return expand("<sflnum>")
|
||||
endfunc
|
||||
Line 3
|
||||
Line 4
|
||||
END
|
||||
call setline(1, lines)
|
||||
3,5source
|
||||
call assert_equal('4', Xtestfunc())
|
||||
delfunc Xtestfunc
|
||||
|
||||
" Source a script with line continuation lines
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
@@ -327,6 +344,63 @@ func Test_source_buffer()
|
||||
call assert_equal("three", Xtestfunc())
|
||||
delfunc Xtestfunc
|
||||
|
||||
" test for using try/catch
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
let Trace = '1'
|
||||
try
|
||||
let a1 = b1
|
||||
catch
|
||||
let Trace ..= '2'
|
||||
finally
|
||||
let Trace ..= '3'
|
||||
endtry
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal("123", g:Trace)
|
||||
|
||||
" test with the finish command
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
let g:Color = 'blue'
|
||||
finish
|
||||
let g:Color = 'green'
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal('blue', g:Color)
|
||||
|
||||
" Test for the SourcePre and SourcePost autocmds
|
||||
augroup Xtest
|
||||
au!
|
||||
au SourcePre * let g:XsourcePre=4
|
||||
\ | let g:XsourcePreFile = expand("<afile>")
|
||||
au SourcePost * let g:XsourcePost=6
|
||||
\ | let g:XsourcePostFile = expand("<afile>")
|
||||
augroup END
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
let a = 1
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal(4, g:XsourcePre)
|
||||
call assert_equal(6, g:XsourcePost)
|
||||
call assert_equal(':source buffer=' .. bufnr(), g:XsourcePreFile)
|
||||
call assert_equal(':source buffer=' .. bufnr(), g:XsourcePostFile)
|
||||
augroup Xtest
|
||||
au!
|
||||
augroup END
|
||||
augroup! Xtest
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for sourcing a Vim9 script from the current buffer
|
||||
func Test_source_buffer_vim9()
|
||||
new
|
||||
|
||||
" test for sourcing a Vim9 script
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
@@ -342,6 +416,226 @@ func Test_source_buffer()
|
||||
source
|
||||
call assert_equal(10, Xtestfunc())
|
||||
|
||||
" test for sourcing a vim9 script with line continuation
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
|
||||
g:Str1 = "hello "
|
||||
.. "world"
|
||||
.. ", how are you?"
|
||||
g:Colors = [
|
||||
'red',
|
||||
# comment
|
||||
'blue'
|
||||
]
|
||||
g:Dict = {
|
||||
a: 22,
|
||||
# comment
|
||||
b: 33
|
||||
}
|
||||
|
||||
# calling a function with line continuation
|
||||
def Sum(...values: list<number>): number
|
||||
var sum: number = 0
|
||||
for v in values
|
||||
sum += v
|
||||
endfor
|
||||
return sum
|
||||
enddef
|
||||
g:Total1 = Sum(10,
|
||||
20,
|
||||
30)
|
||||
|
||||
var i: number = 0
|
||||
while i < 10
|
||||
# while loop
|
||||
i +=
|
||||
1
|
||||
endwhile
|
||||
g:Count1 = i
|
||||
|
||||
# for loop
|
||||
g:Count2 = 0
|
||||
for j in range(10, 20)
|
||||
g:Count2 +=
|
||||
i
|
||||
endfor
|
||||
|
||||
g:Total2 = 10 +
|
||||
20 -
|
||||
5
|
||||
|
||||
g:Result1 = g:Total2 > 1
|
||||
? 'red'
|
||||
: 'blue'
|
||||
|
||||
g:Str2 = 'x'
|
||||
->repeat(10)
|
||||
->trim()
|
||||
->strpart(4)
|
||||
|
||||
g:Result2 = g:Dict
|
||||
.a
|
||||
|
||||
augroup Test
|
||||
au!
|
||||
au BufNewFile Xfile g:readFile = 1
|
||||
| g:readExtra = 2
|
||||
augroup END
|
||||
g:readFile = 0
|
||||
g:readExtra = 0
|
||||
new Xfile
|
||||
bwipe!
|
||||
augroup Test
|
||||
au!
|
||||
augroup END
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal("hello world, how are you?", g:Str1)
|
||||
call assert_equal(['red', 'blue'], g:Colors)
|
||||
call assert_equal(#{a: 22, b: 33}, g:Dict)
|
||||
call assert_equal(60, g:Total1)
|
||||
call assert_equal(10, g:Count1)
|
||||
call assert_equal(110, g:Count2)
|
||||
call assert_equal(25, g:Total2)
|
||||
call assert_equal('red', g:Result1)
|
||||
call assert_equal('xxxxxx', g:Str2)
|
||||
call assert_equal(22, g:Result2)
|
||||
call assert_equal(1, g:readFile)
|
||||
call assert_equal(2, g:readExtra)
|
||||
|
||||
" test for sourcing the same buffer multiple times after changing a function
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
def g:Xtestfunc(): string
|
||||
return "one"
|
||||
enddef
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal("one", Xtestfunc())
|
||||
call setline(3, ' return "two"')
|
||||
source
|
||||
call assert_equal("two", Xtestfunc())
|
||||
call setline(3, ' return "three"')
|
||||
source
|
||||
call assert_equal("three", Xtestfunc())
|
||||
delfunc Xtestfunc
|
||||
|
||||
" Test for sourcing a range of lines. Make sure the script line number is
|
||||
" correct.
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
Line 1
|
||||
Line 2
|
||||
vim9script
|
||||
def g:Xtestfunc(): string
|
||||
return expand("<sflnum>")
|
||||
enddef
|
||||
Line 3
|
||||
Line 4
|
||||
END
|
||||
call setline(1, lines)
|
||||
3,6source
|
||||
call assert_equal('5', Xtestfunc())
|
||||
delfunc Xtestfunc
|
||||
|
||||
" test for sourcing a heredoc
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
var a = 1
|
||||
g:heredoc =<< trim DATA
|
||||
red
|
||||
green
|
||||
blue
|
||||
DATA
|
||||
var b = 2
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal(['red', ' green', 'blue'], g:heredoc)
|
||||
|
||||
" test for using the :vim9cmd modifier
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
first line
|
||||
g:Math = {
|
||||
pi: 3.12,
|
||||
e: 2.71828
|
||||
}
|
||||
g:Editors = [
|
||||
'vim',
|
||||
# comment
|
||||
'nano'
|
||||
]
|
||||
last line
|
||||
END
|
||||
call setline(1, lines)
|
||||
vim9cmd :2,10source
|
||||
call assert_equal(#{pi: 3.12, e: 2.71828}, g:Math)
|
||||
call assert_equal(['vim', 'nano'], g:Editors)
|
||||
|
||||
" test for using try/catch
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
g:Trace = '1'
|
||||
try
|
||||
a1 = b1
|
||||
catch
|
||||
g:Trace ..= '2'
|
||||
finally
|
||||
g:Trace ..= '3'
|
||||
endtry
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal('123', g:Trace)
|
||||
|
||||
" test with the finish command
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
g:Color = 'red'
|
||||
finish
|
||||
g:Color = 'blue'
|
||||
END
|
||||
call setline(1, lines)
|
||||
source
|
||||
call assert_equal('red', g:Color)
|
||||
|
||||
" test for ++clear argument to clear all the functions/variables
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
g:ScriptVarFound = exists("color")
|
||||
g:MyFuncFound = exists('*Myfunc')
|
||||
if g:MyFuncFound
|
||||
finish
|
||||
endif
|
||||
var color = 'blue'
|
||||
def Myfunc()
|
||||
enddef
|
||||
END
|
||||
call setline(1, lines)
|
||||
vim9cmd source
|
||||
call assert_false(g:MyFuncFound)
|
||||
call assert_false(g:ScriptVarFound)
|
||||
vim9cmd source
|
||||
call assert_true(g:MyFuncFound)
|
||||
call assert_true(g:ScriptVarFound)
|
||||
vim9cmd source ++clear
|
||||
call assert_false(g:MyFuncFound)
|
||||
call assert_false(g:ScriptVarFound)
|
||||
vim9cmd source ++clear
|
||||
call assert_false(g:MyFuncFound)
|
||||
call assert_false(g:ScriptVarFound)
|
||||
call assert_fails('vim9cmd source ++clearx', 'E475:')
|
||||
call assert_fails('vim9cmd source ++abcde', 'E484:')
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
|
||||
@@ -417,7 +417,7 @@ func Test_spellsuggest_option_expr()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test for 'spellsuggest' expr errrors
|
||||
" Test for 'spellsuggest' expr errors
|
||||
func Test_spellsuggest_expr_errors()
|
||||
" 'spellsuggest'
|
||||
func MySuggest()
|
||||
|
||||
@@ -260,7 +260,7 @@ func Test_statusline()
|
||||
call assert_match('^vimLineComment\s*$', s:get_statusline())
|
||||
syntax off
|
||||
|
||||
"%{%expr%}: evaluates enxpressions present in result of expr
|
||||
"%{%expr%}: evaluates expressions present in result of expr
|
||||
func! Inner_eval()
|
||||
return '%n some other text'
|
||||
endfunc
|
||||
|
||||
@@ -798,4 +798,40 @@ func Test_multibyte_in_usercmd()
|
||||
delcommand SubJapanesePeriodToDot
|
||||
endfunc
|
||||
|
||||
" Declaring a variable in a {} uses Vim9 script rules, even when defined in a
|
||||
" legacy script.
|
||||
func Test_block_declaration_legacy_script()
|
||||
let lines =<< trim END
|
||||
command -range Rename {
|
||||
var save = @a
|
||||
@a = 'something'
|
||||
g:someExpr = @a
|
||||
@a = save
|
||||
}
|
||||
END
|
||||
call writefile(lines, 'Xlegacy')
|
||||
source Xlegacy
|
||||
|
||||
let lines =<< trim END
|
||||
let @a = 'saved'
|
||||
Rename
|
||||
call assert_equal('something', g:someExpr)
|
||||
call assert_equal('saved', @a)
|
||||
|
||||
let g:someExpr = 'xxx'
|
||||
let @a = 'also'
|
||||
Rename
|
||||
call assert_equal('something', g:someExpr)
|
||||
call assert_equal('also', @a)
|
||||
END
|
||||
call writefile(lines, 'Xother')
|
||||
source Xother
|
||||
|
||||
unlet g:someExpr
|
||||
call delete('Xlegacy')
|
||||
call delete('Xother')
|
||||
delcommand Rename
|
||||
endfunc
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -1178,8 +1178,19 @@ def Test_map_command()
|
||||
nnoremap <F3> :echo 'hit F3 #'<CR>
|
||||
assert_equal(":echo 'hit F3 #'<CR>", maparg("<F3>", "n"))
|
||||
END
|
||||
v9.CheckDefSuccess(lines)
|
||||
v9.CheckScriptSuccess(['vim9script'] + lines)
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
|
||||
# backslash before bar is not removed
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
|
||||
def Init()
|
||||
noremap <buffer> <F5> <ScriptCmd>MyFunc('a') \| MyFunc('b')<CR>
|
||||
enddef
|
||||
Init()
|
||||
unmap <buffer> <F5>
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_normal_command()
|
||||
|
||||
@@ -2004,7 +2004,7 @@ def s:FalsyOp()
|
||||
echo "" ?? "empty string"
|
||||
enddef
|
||||
|
||||
def Test_dsassemble_falsy_op()
|
||||
def Test_disassemble_falsy_op()
|
||||
var res = execute('disass s:FalsyOp')
|
||||
assert_match('\<SNR>\d*_FalsyOp\_s*' ..
|
||||
'echo g:flag ?? "yes"\_s*' ..
|
||||
|
||||
@@ -563,7 +563,7 @@ let ablob = 0z01ab
|
||||
let alist = [2, 3, 4]
|
||||
let adict = #{aaa: 2, bbb: 8}
|
||||
|
||||
" test == comperator
|
||||
" test == comparator
|
||||
def Test_expr4_equal()
|
||||
var lines =<< trim END
|
||||
var trueVar = true
|
||||
@@ -902,7 +902,7 @@ def Test_expr4_wrong_type()
|
||||
'echo n < true'], 'E1072:', 2)
|
||||
enddef
|
||||
|
||||
" test != comperator
|
||||
" test != comparator
|
||||
def Test_expr4_notequal()
|
||||
var lines =<< trim END
|
||||
var trueVar = true
|
||||
@@ -987,7 +987,7 @@ def Test_expr4_notequal()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test > comperator
|
||||
" test > comparator
|
||||
def Test_expr4_greater()
|
||||
var lines =<< trim END
|
||||
assert_true(2 > 0)
|
||||
@@ -1013,7 +1013,7 @@ def Test_expr4_greater()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test >= comperator
|
||||
" test >= comparator
|
||||
def Test_expr4_greaterequal()
|
||||
var lines =<< trim END
|
||||
assert_true(2 >= 0)
|
||||
@@ -1034,7 +1034,7 @@ def Test_expr4_greaterequal()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test < comperator
|
||||
" test < comparator
|
||||
def Test_expr4_smaller()
|
||||
var lines =<< trim END
|
||||
assert_false(2 < 0)
|
||||
@@ -1056,7 +1056,7 @@ def Test_expr4_smaller()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test <= comperator
|
||||
" test <= comparator
|
||||
def Test_expr4_smallerequal()
|
||||
var lines =<< trim END
|
||||
assert_false(2 <= 0)
|
||||
@@ -1081,7 +1081,7 @@ def Test_expr4_smallerequal()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test =~ comperator
|
||||
" test =~ comparator
|
||||
def Test_expr4_match()
|
||||
var lines =<< trim END
|
||||
assert_equal(false, '2' =~ '0')
|
||||
@@ -1098,7 +1098,7 @@ def Test_expr4_match()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test !~ comperator
|
||||
" test !~ comparator
|
||||
def Test_expr4_nomatch()
|
||||
var lines =<< trim END
|
||||
assert_equal(true, '2' !~ '0')
|
||||
@@ -1110,7 +1110,7 @@ def Test_expr4_nomatch()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test is comperator
|
||||
" test is comparator
|
||||
def Test_expr4_is()
|
||||
var lines =<< trim END
|
||||
var mylist = [2]
|
||||
@@ -1128,7 +1128,7 @@ def Test_expr4_is()
|
||||
v9.CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" test isnot comperator
|
||||
" test isnot comparator
|
||||
def Test_expr4_isnot()
|
||||
var lines =<< trim END
|
||||
var mylist = [2]
|
||||
|
||||
@@ -876,6 +876,25 @@ def Test_nested_function()
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
# nested function with recursive call
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
|
||||
def MyFunc(): number
|
||||
def Fib(n: number): number
|
||||
if n < 2
|
||||
return 1
|
||||
endif
|
||||
return Fib(n - 2) + Fib(n - 1)
|
||||
enddef
|
||||
|
||||
return Fib(5)
|
||||
enddef
|
||||
|
||||
assert_equal(8, MyFunc())
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
def Outer()
|
||||
|
||||
@@ -2156,7 +2156,7 @@ def Test_vim9script_autoload_duplicate()
|
||||
export var Func = 'asdf'
|
||||
END
|
||||
writefile(lines, 'Xdir/autoload/dup3func.vim')
|
||||
assert_fails('source Xdir/autoload/dup3func.vim', 'E1041: Redefining script item Func')
|
||||
assert_fails('source Xdir/autoload/dup3func.vim', 'E1041: Redefining script item: "Func"')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
@@ -2189,7 +2189,7 @@ def Test_vim9script_autoload_duplicate()
|
||||
var Func = 'asdf'
|
||||
END
|
||||
writefile(lines, 'Xdir/autoload/dup6func.vim')
|
||||
assert_fails('source Xdir/autoload/dup6func.vim', 'E1041: Redefining script item Func')
|
||||
assert_fails('source Xdir/autoload/dup6func.vim', 'E1041: Redefining script item: "Func"')
|
||||
|
||||
delete('Xdir', 'rf')
|
||||
enddef
|
||||
|
||||
@@ -3631,7 +3631,7 @@ endfunc
|
||||
" exceptions.
|
||||
"-------------------------------------------------------------------------------
|
||||
|
||||
func Test_execption_info_for_error()
|
||||
func Test_exception_info_for_error()
|
||||
CheckEnglish
|
||||
|
||||
let test =<< trim [CODE]
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef struct ucmd
|
||||
int uc_compl; // completion type
|
||||
cmd_addr_T uc_addr_type; // The command's address type
|
||||
sctx_T uc_script_ctx; // SCTX where the command was defined
|
||||
int uc_flags; // some UC_ flags
|
||||
# ifdef FEAT_EVAL
|
||||
char_u *uc_compl_arg; // completion argument if any
|
||||
# endif
|
||||
@@ -92,6 +93,7 @@ static struct
|
||||
{EXPAND_USER_VARS, "var"},
|
||||
#if defined(FEAT_EVAL)
|
||||
{EXPAND_BREAKPOINT, "breakpoint"},
|
||||
{EXPAND_SCRIPTNAMES, "scriptnames"},
|
||||
#endif
|
||||
{0, NULL}
|
||||
};
|
||||
@@ -1038,6 +1040,7 @@ uc_add_command(
|
||||
cmd->uc_script_ctx = current_sctx;
|
||||
if (flags & UC_VIM9)
|
||||
cmd->uc_script_ctx.sc_version = SCRIPT_VERSION_VIM9;
|
||||
cmd->uc_flags = flags & UC_VIM9;
|
||||
#ifdef FEAT_EVAL
|
||||
cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
cmd->uc_compl_arg = compl_arg;
|
||||
@@ -1725,6 +1728,9 @@ do_ucmd(exarg_T *eap)
|
||||
ucmd_T *cmd;
|
||||
sctx_T save_current_sctx;
|
||||
int restore_current_sctx = FALSE;
|
||||
#ifdef FEAT_EVAL
|
||||
int restore_script_version = 0;
|
||||
#endif
|
||||
|
||||
if (eap->cmdidx == CMD_USER)
|
||||
cmd = USER_CMD(eap->useridx);
|
||||
@@ -1830,6 +1836,14 @@ do_ucmd(exarg_T *eap)
|
||||
current_sctx.sc_version = cmd->uc_script_ctx.sc_version;
|
||||
#ifdef FEAT_EVAL
|
||||
current_sctx.sc_sid = cmd->uc_script_ctx.sc_sid;
|
||||
if (cmd->uc_flags & UC_VIM9)
|
||||
{
|
||||
// In a {} block variables use Vim9 script rules, even in a legacy
|
||||
// script.
|
||||
restore_script_version =
|
||||
SCRIPT_ITEM(current_sctx.sc_sid)->sn_version;
|
||||
SCRIPT_ITEM(current_sctx.sc_sid)->sn_version = SCRIPT_VERSION_VIM9;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1839,7 +1853,14 @@ do_ucmd(exarg_T *eap)
|
||||
// Careful: Do not use "cmd" here, it may have become invalid if a user
|
||||
// command was added.
|
||||
if (restore_current_sctx)
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
if (restore_script_version != 0)
|
||||
SCRIPT_ITEM(current_sctx.sc_sid)->sn_version =
|
||||
restore_script_version;
|
||||
#endif
|
||||
current_sctx = save_current_sctx;
|
||||
}
|
||||
vim_free(buf);
|
||||
vim_free(split_buf);
|
||||
}
|
||||
|
||||
@@ -765,6 +765,44 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
4621,
|
||||
/**/
|
||||
4620,
|
||||
/**/
|
||||
4619,
|
||||
/**/
|
||||
4618,
|
||||
/**/
|
||||
4617,
|
||||
/**/
|
||||
4616,
|
||||
/**/
|
||||
4615,
|
||||
/**/
|
||||
4614,
|
||||
/**/
|
||||
4613,
|
||||
/**/
|
||||
4612,
|
||||
/**/
|
||||
4611,
|
||||
/**/
|
||||
4610,
|
||||
/**/
|
||||
4609,
|
||||
/**/
|
||||
4608,
|
||||
/**/
|
||||
4607,
|
||||
/**/
|
||||
4606,
|
||||
/**/
|
||||
4605,
|
||||
/**/
|
||||
4604,
|
||||
/**/
|
||||
4603,
|
||||
/**/
|
||||
4602,
|
||||
/**/
|
||||
|
||||
@@ -809,7 +809,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
||||
#define EXPAND_DIFF_BUFFERS 49
|
||||
#define EXPAND_DISASSEMBLE 50
|
||||
#define EXPAND_BREAKPOINT 51
|
||||
#define EXPAND_MACACTION 52
|
||||
#define EXPAND_SCRIPTNAMES 52
|
||||
#define EXPAND_MACACTION 53
|
||||
|
||||
// Values for exmode_active (0 is no exmode)
|
||||
#define EXMODE_NORMAL 1
|
||||
|
||||
+2
-3
@@ -1613,8 +1613,7 @@ compile_endtry(char_u *arg, cctx_T *cctx)
|
||||
// End :catch or :finally scope: set instruction index in ISN_TRY
|
||||
// instruction
|
||||
try_isn->isn_arg.tryref.try_ref->try_endtry = instr->ga_len;
|
||||
if (cctx->ctx_skip != SKIP_YES
|
||||
&& generate_instr(cctx, ISN_ENDTRY) == NULL)
|
||||
if (generate_instr(cctx, ISN_ENDTRY) == NULL)
|
||||
return NULL;
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_compile_type == CT_PROFILE)
|
||||
@@ -1849,7 +1848,7 @@ compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
|
||||
if ((argt & EX_TRLBAR) && !usefilter)
|
||||
{
|
||||
eap->argt = argt;
|
||||
separate_nextcmd(eap);
|
||||
separate_nextcmd(eap, TRUE);
|
||||
if (eap->nextcmd != NULL)
|
||||
nextcmd = eap->nextcmd;
|
||||
}
|
||||
|
||||
+25
-18
@@ -818,6 +818,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
|
||||
ufunc_T *ufunc;
|
||||
int r = FAIL;
|
||||
compiletype_T compile_type;
|
||||
isn_T *funcref_isn = NULL;
|
||||
|
||||
if (eap->forceit)
|
||||
{
|
||||
@@ -913,6 +914,27 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
|
||||
}
|
||||
}
|
||||
|
||||
// Define the funcref before compiling, so that it is found by any
|
||||
// recursive call.
|
||||
if (is_global)
|
||||
{
|
||||
r = generate_NEWFUNC(cctx, lambda_name, func_name);
|
||||
func_name = NULL;
|
||||
lambda_name = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Define a local variable for the function reference.
|
||||
lvar_T *lvar = reserve_local(cctx, func_name, name_end - name_start,
|
||||
TRUE, ufunc->uf_func_type);
|
||||
|
||||
if (lvar == NULL)
|
||||
goto theend;
|
||||
if (generate_FUNCREF(cctx, ufunc, &funcref_isn) == FAIL)
|
||||
goto theend;
|
||||
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
||||
}
|
||||
|
||||
compile_type = get_compile_type(ufunc);
|
||||
#ifdef FEAT_PROFILE
|
||||
// If the outer function is profiled, also compile the nested function for
|
||||
@@ -934,24 +956,9 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
|
||||
compile_def_function(ufunc, FALSE, CT_NONE, cctx);
|
||||
#endif
|
||||
|
||||
if (is_global)
|
||||
{
|
||||
r = generate_NEWFUNC(cctx, lambda_name, func_name);
|
||||
func_name = NULL;
|
||||
lambda_name = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Define a local variable for the function reference.
|
||||
lvar_T *lvar = reserve_local(cctx, func_name, name_end - name_start,
|
||||
TRUE, ufunc->uf_func_type);
|
||||
|
||||
if (lvar == NULL)
|
||||
goto theend;
|
||||
if (generate_FUNCREF(cctx, ufunc) == FAIL)
|
||||
goto theend;
|
||||
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
||||
}
|
||||
// If a FUNCREF instruction was generated, set the index after compiling.
|
||||
if (funcref_isn != NULL && ufunc->uf_def_status == UF_COMPILED)
|
||||
funcref_isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx;
|
||||
|
||||
theend:
|
||||
vim_free(lambda_name);
|
||||
|
||||
+1
-1
@@ -1040,7 +1040,7 @@ compile_lambda(char_u **arg, cctx_T *cctx)
|
||||
// The function reference count will be 1. When the ISN_FUNCREF
|
||||
// instruction is deleted the reference count is decremented and the
|
||||
// function is freed.
|
||||
return generate_FUNCREF(cctx, ufunc);
|
||||
return generate_FUNCREF(cctx, ufunc, NULL);
|
||||
}
|
||||
|
||||
func_ptr_unref(ufunc);
|
||||
|
||||
+4
-1
@@ -1172,9 +1172,10 @@ generate_NEWDICT(cctx_T *cctx, int count)
|
||||
|
||||
/*
|
||||
* Generate an ISN_FUNCREF instruction.
|
||||
* "isnp" is set to the instruction, so that fr_dfunc_idx can be set later.
|
||||
*/
|
||||
int
|
||||
generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
|
||||
generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc, isn_T **isnp)
|
||||
{
|
||||
isn_T *isn;
|
||||
type_T *type;
|
||||
@@ -1182,6 +1183,8 @@ generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
|
||||
RETURN_OK_IF_SKIP(cctx);
|
||||
if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL)
|
||||
return FAIL;
|
||||
if (isnp != NULL)
|
||||
*isnp = isn;
|
||||
if (ufunc->uf_def_status == UF_NOT_COMPILED)
|
||||
isn->isn_arg.funcref.fr_func_name = vim_strsave(ufunc->uf_name);
|
||||
else
|
||||
|
||||
+19
-10
@@ -59,6 +59,24 @@ current_script_is_vim9(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
/*
|
||||
* Clear Vim9 script-local variables and functions.
|
||||
*/
|
||||
void
|
||||
clear_vim9_scriptlocal_vars(int sid)
|
||||
{
|
||||
hashtab_T *ht = &SCRIPT_VARS(sid);
|
||||
|
||||
hashtab_free_contents(ht);
|
||||
hash_init(ht);
|
||||
delete_script_functions(sid);
|
||||
|
||||
// old imports and script variables are no longer valid
|
||||
free_imports_and_script_vars(sid);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ":vim9script".
|
||||
*/
|
||||
@@ -103,18 +121,9 @@ ex_vim9script(exarg_T *eap UNUSED)
|
||||
}
|
||||
|
||||
if (si->sn_state == SN_STATE_RELOAD && !found_noclear)
|
||||
{
|
||||
hashtab_T *ht = &SCRIPT_VARS(sid);
|
||||
|
||||
// Reloading a script without the "noclear" argument: clear
|
||||
// script-local variables and functions.
|
||||
hashtab_free_contents(ht);
|
||||
hash_init(ht);
|
||||
delete_script_functions(sid);
|
||||
|
||||
// old imports and script variables are no longer valid
|
||||
free_imports_and_script_vars(sid);
|
||||
}
|
||||
clear_vim9_scriptlocal_vars(sid);
|
||||
si->sn_state = SN_STATE_HAD_COMMAND;
|
||||
|
||||
// Store the prefix with the script, it is used to find exported functions.
|
||||
|
||||
+3
-6
@@ -43,7 +43,6 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin);
|
||||
static int may_open_tabpage(void);
|
||||
static int win_enter_ext(win_T *wp, int flags);
|
||||
static void win_free(win_T *wp, tabpage_T *tp);
|
||||
static int win_unlisted(win_T *wp);
|
||||
static void win_append(win_T *after, win_T *wp);
|
||||
static void frame_append(frame_T *after, frame_T *frp);
|
||||
static void frame_insert(frame_T *before, frame_T *frp);
|
||||
@@ -5238,7 +5237,7 @@ win_free(
|
||||
* Return TRUE if "wp" is not in the list of windows: the autocmd window or a
|
||||
* popup window.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
win_unlisted(win_T *wp)
|
||||
{
|
||||
return wp == aucmd_win || WIN_IS_POPUP(wp);
|
||||
@@ -5697,8 +5696,7 @@ frame_setheight(frame_T *curfrp, int height)
|
||||
break;
|
||||
if (run == 2 || curfrp->fr_width == Columns)
|
||||
{
|
||||
if (height > room + room_cmdline)
|
||||
height = room + room_cmdline;
|
||||
height = room + room_cmdline;
|
||||
break;
|
||||
}
|
||||
frame_setheight(curfrp->fr_parent, height
|
||||
@@ -5882,8 +5880,7 @@ frame_setwidth(frame_T *curfrp, int width)
|
||||
break;
|
||||
if (run == 2 || curfrp->fr_height >= ROWS_AVAIL)
|
||||
{
|
||||
if (width > room)
|
||||
width = room;
|
||||
width = room;
|
||||
break;
|
||||
}
|
||||
frame_setwidth(curfrp->fr_parent, width
|
||||
|
||||
Reference in New Issue
Block a user