mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-07 15:37:14 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -3262,6 +3262,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
stlnc:c ' ' or '=' statusline of the non-current windows
|
||||
vert:c '|' vertical separators |:vsplit|
|
||||
fold:c '-' filling 'foldtext'
|
||||
foldopen:c '-' mark the beginning of a fold
|
||||
foldclose:c '+' show a closed fold
|
||||
foldsep:c '|' open fold middle character
|
||||
diff:c '-' deleted lines of the 'diff' option
|
||||
eob:c '~' empty lines below the end of a buffer
|
||||
|
||||
@@ -4949,7 +4952,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|
||||
*'listchars'* *'lcs'*
|
||||
'listchars' 'lcs' string (default "eol:$")
|
||||
global
|
||||
global or local to window |global-local|
|
||||
Strings to use in 'list' mode and for the |:list| command. It is a
|
||||
comma separated list of string settings.
|
||||
*lcs-eol*
|
||||
|
||||
@@ -354,13 +354,15 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
|
||||
Vim version, or update Vim to a newer version. See
|
||||
|vimscript-version| for what changed between versions.
|
||||
|
||||
:vim9[script] [noclear] *:vim9* *:vim9script*
|
||||
:vim9s[cript] [noclear] *:vim9s* *:vim9script*
|
||||
Marks a script file as containing |Vim9-script|
|
||||
commands. Also see |vim9-namespace|.
|
||||
Must be the first command in the file.
|
||||
For [noclear] see |vim9-reload|.
|
||||
Without the |+eval| feature this changes the syntax
|
||||
for some commands.
|
||||
See |:vim9cmd| for executing one command with Vim9
|
||||
syntax and semantics.
|
||||
|
||||
*:scr* *:scriptnames*
|
||||
:scr[iptnames] List all sourced script names, in the order they were
|
||||
|
||||
+31
-3
@@ -51,6 +51,7 @@ The Vim9 script syntax and semantics are used in:
|
||||
- a function defined with the `:def` command
|
||||
- a script file where the first command is `vim9script`
|
||||
- an autocommand defined in the context of the above
|
||||
- a command prefixed with the `vim9cmd` command modifier
|
||||
|
||||
When using `:function` in a Vim9 script file the legacy syntax is used, with
|
||||
the highest |scriptversion|. However, this can be confusing and is therefore
|
||||
@@ -60,6 +61,12 @@ Vim9 script and legacy Vim script can be mixed. There is no requirement to
|
||||
rewrite old scripts, they keep working as before. You may want to use a few
|
||||
`:def` functions for code that needs to be fast.
|
||||
|
||||
*:vim9* *:vim9cmd*
|
||||
:vim9[cmd] {cmd}
|
||||
Execute {cmd} using Vim9 script syntax and semantics.
|
||||
Useful when typing a command and in a legacy script or
|
||||
function.
|
||||
|
||||
==============================================================================
|
||||
|
||||
2. Differences from legacy Vim script *vim9-differences*
|
||||
@@ -1044,9 +1051,9 @@ that you don't do that.
|
||||
Namespace ~
|
||||
*vim9-namespace*
|
||||
To recognize a file that can be imported the `vim9script` statement must
|
||||
appear as the first statement in the file. It tells Vim to interpret the
|
||||
script in its own namespace, instead of the global namespace. If a file
|
||||
starts with: >
|
||||
appear as the first statement in the file (see |vim9-mix| for an exception).
|
||||
It tells Vim to interpret the script in its own namespace, instead of the
|
||||
global namespace. If a file starts with: >
|
||||
vim9script
|
||||
var myvar = 'yes'
|
||||
Then "myvar" will only exist in this file. While without `vim9script` it would
|
||||
@@ -1066,6 +1073,27 @@ Vim default value, like with: >
|
||||
One of the effects is that |line-continuation| is always enabled.
|
||||
The original value of 'cpoptions' is restored at the end of the script.
|
||||
|
||||
*vim9-mix*
|
||||
There is one way to use both legacy and Vim9 syntax in one script file: >
|
||||
" comments may go here
|
||||
if !has('vim9script')
|
||||
" legacy script commands go here
|
||||
finish
|
||||
endif
|
||||
vim9script
|
||||
# Vim9 script commands go here
|
||||
This allows for writing a script that takes advantage of the Vim9 script
|
||||
syntax if possible, but will also work on an Vim version without it.
|
||||
|
||||
This can only work in two ways:
|
||||
1. The "if" statement evaluates to false, the commands up to `endif` are
|
||||
skipped and `vim9script` is then the first command actually executed.
|
||||
2. The "if" statement evaluates to true, the commands up to `endif` are
|
||||
executed and `finish` bails out before reaching `vim9script`.
|
||||
|
||||
TODO: The "vim9script" feature does not exist yet, it will only be added once
|
||||
the Vim9 script syntax has been fully implemented.
|
||||
|
||||
|
||||
Export ~
|
||||
*:export* *:exp*
|
||||
|
||||
@@ -216,6 +216,9 @@ au BufNewFile,BufRead *.bc setf bc
|
||||
" BDF font
|
||||
au BufNewFile,BufRead *.bdf setf bdf
|
||||
|
||||
" Beancount
|
||||
au BufNewFile,BufRead *.beancount setf beancount
|
||||
|
||||
" BibTeX bibliography database file
|
||||
au BufNewFile,BufRead *.bib setf bib
|
||||
|
||||
@@ -1488,6 +1491,9 @@ au BufNewFile,BufRead *.sdl,*.pr setf sdl
|
||||
" sed
|
||||
au BufNewFile,BufRead *.sed setf sed
|
||||
|
||||
" svelte
|
||||
au BufNewFile,BufRead *.svelte setf svelte
|
||||
|
||||
" Sieve (RFC 3028, 5228)
|
||||
au BufNewFile,BufRead *.siv,*.sieve setf sieve
|
||||
|
||||
|
||||
+1
-1
@@ -4559,7 +4559,7 @@ build_stl_str_hl(
|
||||
case STL_VIRTCOL_ALT:
|
||||
// In list mode virtcol needs to be recomputed
|
||||
virtcol = wp->w_virtcol;
|
||||
if (wp->w_p_list && lcs_tab1 == NUL)
|
||||
if (wp->w_p_list && wp->w_lcs_chars.tab1 == NUL)
|
||||
{
|
||||
wp->w_p_list = FALSE;
|
||||
getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
|
||||
|
||||
+4
-4
@@ -753,7 +753,7 @@ vim_strnsize(char_u *s, int len)
|
||||
|
||||
#ifdef FEAT_VARTABS
|
||||
# define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
|
||||
if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
|
||||
if (*(p) == TAB && (!(wp)->w_p_list || wp->w_lcs_chars.tab1)) \
|
||||
{ \
|
||||
return tabstop_padding(col, (buf)->b_p_ts, (buf)->b_p_vts_array); \
|
||||
} \
|
||||
@@ -761,7 +761,7 @@ vim_strnsize(char_u *s, int len)
|
||||
return ptr2cells(p);
|
||||
#else
|
||||
# define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
|
||||
if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
|
||||
if (*(p) == TAB && (!(wp)->w_p_list || wp->w_lcs_chars.tab1)) \
|
||||
{ \
|
||||
int ts; \
|
||||
ts = (buf)->b_p_ts; \
|
||||
@@ -1153,7 +1153,7 @@ win_nolbr_chartabsize(
|
||||
{
|
||||
int n;
|
||||
|
||||
if (*s == TAB && (!wp->w_p_list || lcs_tab1))
|
||||
if (*s == TAB && (!wp->w_p_list || wp->w_lcs_chars.tab1))
|
||||
{
|
||||
# ifdef FEAT_VARTABS
|
||||
return tabstop_padding(col, wp->w_buffer->b_p_ts,
|
||||
@@ -1248,7 +1248,7 @@ getvcol(
|
||||
* use a simple loop.
|
||||
* Also use this when 'list' is set but tabs take their normal size.
|
||||
*/
|
||||
if ((!wp->w_p_list || lcs_tab1 != NUL)
|
||||
if ((!wp->w_p_list || wp->w_lcs_chars.tab1 != NUL)
|
||||
#ifdef FEAT_LINEBREAK
|
||||
&& !wp->w_p_lbr && *get_showbreak_value(wp) == NUL && !wp->w_p_bri
|
||||
#endif
|
||||
|
||||
+47
-37
@@ -248,9 +248,9 @@ win_line(
|
||||
int c_final = NUL; // final char, mandatory if set
|
||||
int extra_attr = 0; // attributes when n_extra != 0
|
||||
static char_u *at_end_str = (char_u *)""; // used for p_extra when
|
||||
// displaying lcs_eol at end-of-line
|
||||
int lcs_eol_one = lcs_eol; // lcs_eol until it's been used
|
||||
int lcs_prec_todo = lcs_prec; // lcs_prec until it's been used
|
||||
// displaying eol at end-of-line
|
||||
int lcs_eol_one = wp->w_lcs_chars.eol; // eol until it's been used
|
||||
int lcs_prec_todo = wp->w_lcs_chars.prec; // prec until it's been used
|
||||
|
||||
// saved "extra" items for when draw_state becomes WL_LINE (again)
|
||||
int saved_n_extra = 0;
|
||||
@@ -735,11 +735,14 @@ win_line(
|
||||
|
||||
if (wp->w_p_list)
|
||||
{
|
||||
if (lcs_space || lcs_trail || lcs_lead || lcs_nbsp)
|
||||
if (wp->w_lcs_chars.space
|
||||
|| wp->w_lcs_chars.trail
|
||||
|| wp->w_lcs_chars.lead
|
||||
|| wp->w_lcs_chars.nbsp)
|
||||
extra_check = TRUE;
|
||||
|
||||
// find start of trailing whitespace
|
||||
if (lcs_trail)
|
||||
if (wp->w_lcs_chars.trail)
|
||||
{
|
||||
trailcol = (colnr_T)STRLEN(ptr);
|
||||
while (trailcol > (colnr_T)0 && VIM_ISWHITE(ptr[trailcol - 1]))
|
||||
@@ -747,7 +750,7 @@ win_line(
|
||||
trailcol += (colnr_T) (ptr - line);
|
||||
}
|
||||
// find end of leading whitespace
|
||||
if (lcs_lead)
|
||||
if (wp->w_lcs_chars.lead)
|
||||
{
|
||||
leadcol = 0;
|
||||
while (VIM_ISWHITE(ptr[leadcol]))
|
||||
@@ -2000,22 +2003,23 @@ win_line(
|
||||
}
|
||||
#endif
|
||||
|
||||
// 'list': Change char 160 to lcs_nbsp and space to lcs_space.
|
||||
// But not when the character is followed by a composing
|
||||
// character (use mb_l to check that).
|
||||
// 'list': Change char 160 to 'nbsp' and space to 'space'
|
||||
// setting in 'listchars'. But not when the character is
|
||||
// followed by a composing character (use mb_l to check that).
|
||||
if (wp->w_p_list
|
||||
&& ((((c == 160 && mb_l == 1)
|
||||
|| (mb_utf8
|
||||
&& ((mb_c == 160 && mb_l == 2)
|
||||
|| (mb_c == 0x202f && mb_l == 3))))
|
||||
&& lcs_nbsp)
|
||||
&& wp->w_lcs_chars.nbsp)
|
||||
|| (c == ' '
|
||||
&& mb_l == 1
|
||||
&& lcs_space
|
||||
&& wp->w_lcs_chars.space
|
||||
&& ptr - line >= leadcol
|
||||
&& ptr - line <= trailcol)))
|
||||
{
|
||||
c = (c == ' ') ? lcs_space : lcs_nbsp;
|
||||
c = (c == ' ') ? wp->w_lcs_chars.space :
|
||||
wp->w_lcs_chars.nbsp;
|
||||
if (area_attr == 0 && search_attr == 0)
|
||||
{
|
||||
n_attr = 1;
|
||||
@@ -2036,7 +2040,8 @@ win_line(
|
||||
if ((trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
|
||||
|| (leadcol != 0 && ptr < line + leadcol && c == ' '))
|
||||
{
|
||||
c = (ptr > line + trailcol) ? lcs_trail : lcs_lead;
|
||||
c = (ptr > line + trailcol) ? wp->w_lcs_chars.trail
|
||||
: wp->w_lcs_chars.lead;
|
||||
if (!attr_pri)
|
||||
{
|
||||
n_attr = 1;
|
||||
@@ -2061,7 +2066,7 @@ win_line(
|
||||
// when getting a character from the file, we may have to
|
||||
// turn it into something else on the way to putting it
|
||||
// into "ScreenLines".
|
||||
if (c == TAB && (!wp->w_p_list || lcs_tab1))
|
||||
if (c == TAB && (!wp->w_p_list || wp->w_lcs_chars.tab1))
|
||||
{
|
||||
int tab_len = 0;
|
||||
long vcol_adjusted = vcol; // removed showbreak length
|
||||
@@ -2101,18 +2106,19 @@ win_line(
|
||||
// there are characters to conceal
|
||||
tab_len += vcol_off;
|
||||
// boguscols before FIX_FOR_BOGUSCOLS macro from above
|
||||
if (wp->w_p_list && lcs_tab1 && old_boguscols > 0
|
||||
&& n_extra > tab_len)
|
||||
if (wp->w_p_list && wp->w_lcs_chars.tab1
|
||||
&& old_boguscols > 0
|
||||
&& n_extra > tab_len)
|
||||
tab_len += n_extra - tab_len;
|
||||
#endif
|
||||
|
||||
// if n_extra > 0, it gives the number of chars, to
|
||||
// use for a tab, else we need to calculate the width
|
||||
// for a tab
|
||||
len = (tab_len * mb_char2len(lcs_tab2));
|
||||
len = (tab_len * mb_char2len(wp->w_lcs_chars.tab2));
|
||||
if (n_extra > 0)
|
||||
len += n_extra - tab_len;
|
||||
c = lcs_tab1;
|
||||
c = wp->w_lcs_chars.tab1;
|
||||
p = alloc(len + 1);
|
||||
vim_memset(p, ' ', len);
|
||||
p[len] = NUL;
|
||||
@@ -2120,7 +2126,7 @@ win_line(
|
||||
p_extra_free = p;
|
||||
for (i = 0; i < tab_len; i++)
|
||||
{
|
||||
int lcs = lcs_tab2;
|
||||
int lcs = wp->w_lcs_chars.tab2;
|
||||
|
||||
if (*p == NUL)
|
||||
{
|
||||
@@ -2128,10 +2134,10 @@ win_line(
|
||||
break;
|
||||
}
|
||||
|
||||
// if lcs_tab3 is given, need to change the char
|
||||
// if tab3 is given, need to change the char
|
||||
// for tab
|
||||
if (lcs_tab3 && i == tab_len - 1)
|
||||
lcs = lcs_tab3;
|
||||
if (wp->w_lcs_chars.tab3 && i == tab_len - 1)
|
||||
lcs = wp->w_lcs_chars.tab3;
|
||||
mb_char2bytes(lcs, p);
|
||||
p += mb_char2len(lcs);
|
||||
n_extra += mb_char2len(lcs)
|
||||
@@ -2162,21 +2168,23 @@ win_line(
|
||||
// correctly set further below (effectively reverts the
|
||||
// FIX_FOR_BOGSUCOLS macro
|
||||
if (n_extra == tab_len + vc_saved && wp->w_p_list
|
||||
&& lcs_tab1)
|
||||
&& wp->w_lcs_chars.tab1)
|
||||
tab_len += vc_saved;
|
||||
}
|
||||
#endif
|
||||
mb_utf8 = FALSE; // don't draw as UTF-8
|
||||
if (wp->w_p_list)
|
||||
{
|
||||
c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
|
||||
c = (n_extra == 0 && wp->w_lcs_chars.tab3)
|
||||
? wp->w_lcs_chars.tab3
|
||||
: wp->w_lcs_chars.tab1;
|
||||
#ifdef FEAT_LINEBREAK
|
||||
if (wp->w_p_lbr)
|
||||
c_extra = NUL; // using p_extra from above
|
||||
else
|
||||
#endif
|
||||
c_extra = lcs_tab2;
|
||||
c_final = lcs_tab3;
|
||||
c_extra = wp->w_lcs_chars.tab2;
|
||||
c_final = wp->w_lcs_chars.tab3;
|
||||
n_attr = tab_len + 1;
|
||||
extra_attr = hl_combine_attr(win_attr, HL_ATTR(HLF_8));
|
||||
saved_attr2 = char_attr; // save current attr
|
||||
@@ -2241,8 +2249,8 @@ win_line(
|
||||
c_final = NUL;
|
||||
}
|
||||
}
|
||||
if (wp->w_p_list && lcs_eol > 0)
|
||||
c = lcs_eol;
|
||||
if (wp->w_p_list && wp->w_lcs_chars.eol > 0)
|
||||
c = wp->w_lcs_chars.eol;
|
||||
else
|
||||
c = ' ';
|
||||
lcs_eol_one = -1;
|
||||
@@ -2344,7 +2352,8 @@ win_line(
|
||||
// don't do search HL for the rest of the line
|
||||
if (line_attr != 0 && char_attr == search_attr
|
||||
&& (did_line_attr > 1
|
||||
|| (wp->w_p_list && lcs_eol > 0)))
|
||||
|| (wp->w_p_list &&
|
||||
wp->w_lcs_chars.eol > 0)))
|
||||
char_attr = line_attr;
|
||||
# ifdef FEAT_DIFF
|
||||
if (diff_hlf == HLF_TXD)
|
||||
@@ -2404,8 +2413,8 @@ win_line(
|
||||
c = match_conc;
|
||||
else if (syn_get_sub_char() != NUL)
|
||||
c = syn_get_sub_char();
|
||||
else if (lcs_conceal != NUL)
|
||||
c = lcs_conceal;
|
||||
else if (wp->w_lcs_chars.conceal != NUL)
|
||||
c = wp->w_lcs_chars.conceal;
|
||||
else
|
||||
c = ' ';
|
||||
|
||||
@@ -2552,7 +2561,7 @@ win_line(
|
||||
&& draw_state > WL_NR
|
||||
&& c != NUL)
|
||||
{
|
||||
c = lcs_prec;
|
||||
c = wp->w_lcs_chars.prec;
|
||||
lcs_prec_todo = NUL;
|
||||
if (has_mbyte && (*mb_char2cells)(mb_c) > 1)
|
||||
{
|
||||
@@ -2598,7 +2607,7 @@ win_line(
|
||||
// highlight match at end of line. If it's beyond the last
|
||||
// char on the screen, just overwrite that one (tricky!) Not
|
||||
// needed when a '$' was displayed for 'list'.
|
||||
if (lcs_eol == lcs_eol_one
|
||||
if (wp->w_lcs_chars.eol == lcs_eol_one
|
||||
&& ((area_attr != 0 && vcol == fromcol
|
||||
&& (VIsual_mode != Ctrl_V
|
||||
|| lnum == VIsual.lnum
|
||||
@@ -2768,7 +2777,7 @@ win_line(
|
||||
|
||||
// Show "extends" character from 'listchars' if beyond the line end and
|
||||
// 'list' is set.
|
||||
if (lcs_ext != NUL
|
||||
if (wp->w_lcs_chars.ext != NUL
|
||||
&& wp->w_p_list
|
||||
&& !wp->w_p_wrap
|
||||
#ifdef FEAT_DIFF
|
||||
@@ -2783,7 +2792,7 @@ win_line(
|
||||
|| (wp->w_p_list && lcs_eol_one > 0)
|
||||
|| (n_extra && (c_extra != NUL || *p_extra != NUL))))
|
||||
{
|
||||
c = lcs_ext;
|
||||
c = wp->w_lcs_chars.ext;
|
||||
char_attr = hl_combine_attr(win_attr, HL_ATTR(HLF_AT));
|
||||
mb_c = c;
|
||||
if (enc_utf8 && utf_char2len(c) > 1)
|
||||
@@ -3040,7 +3049,8 @@ win_line(
|
||||
#ifdef FEAT_DIFF
|
||||
|| filler_todo > 0
|
||||
#endif
|
||||
|| (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
|
||||
|| (wp->w_p_list && wp->w_lcs_chars.eol != NUL
|
||||
&& p_extra != at_end_str)
|
||||
|| (n_extra != 0 && (c_extra != NUL || *p_extra != NUL)))
|
||||
)
|
||||
{
|
||||
@@ -3165,7 +3175,7 @@ win_line(
|
||||
#endif
|
||||
saved_char_attr = 0;
|
||||
n_extra = 0;
|
||||
lcs_prec_todo = lcs_prec;
|
||||
lcs_prec_todo = wp->w_lcs_chars.prec;
|
||||
#ifdef FEAT_LINEBREAK
|
||||
# ifdef FEAT_DIFF
|
||||
if (filler_todo <= 0)
|
||||
|
||||
+1
-1
@@ -696,7 +696,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
|
||||
|
||||
// In list mode virtcol needs to be recomputed
|
||||
virtcol = wp->w_virtcol;
|
||||
if (wp->w_p_list && lcs_tab1 == NUL)
|
||||
if (wp->w_p_list && wp->w_lcs_chars.tab1 == NUL)
|
||||
{
|
||||
wp->w_p_list = FALSE;
|
||||
getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
|
||||
|
||||
@@ -363,3 +363,5 @@ EXTERN char e_register_name_must_be_one_char_str[]
|
||||
INIT(= N_("E1162: Register name must be one character: %s"));
|
||||
EXTERN char e_variable_nr_type_mismatch_expected_str_but_got_str[]
|
||||
INIT(= N_("E1163: Variable %d: type mismatch, expected %s but got %s"));
|
||||
EXTERN char e_vim9cmd_must_be_followed_by_command[]
|
||||
INIT(= N_("E1164: vim9cmd must be followed by a command"));
|
||||
|
||||
+14
@@ -3421,7 +3421,21 @@ eval7(
|
||||
*/
|
||||
case '(': ret = NOTDONE;
|
||||
if (in_vim9script())
|
||||
{
|
||||
ret = get_lambda_tv(arg, rettv, TRUE, evalarg);
|
||||
if (ret == OK && evaluate)
|
||||
{
|
||||
ufunc_T *ufunc = rettv->vval.v_partial->pt_func;
|
||||
|
||||
// compile it here to get the return type
|
||||
if (compile_def_function(ufunc,
|
||||
TRUE, PROFILING(ufunc), NULL) == FAIL)
|
||||
{
|
||||
clear_tv(rettv);
|
||||
ret = FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == NOTDONE)
|
||||
{
|
||||
*arg = skipwhite_and_linebreak(*arg + 1, evalarg);
|
||||
|
||||
+2
-1
@@ -9771,7 +9771,8 @@ f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
{
|
||||
cchar = syn_get_sub_char();
|
||||
if (cchar == NUL && curwin->w_p_cole == 1)
|
||||
cchar = (lcs_conceal == NUL) ? ' ' : lcs_conceal;
|
||||
cchar = (curwin->w_lcs_chars.conceal == NUL) ? ' '
|
||||
: curwin->w_lcs_chars.conceal;
|
||||
if (cchar != NUL)
|
||||
{
|
||||
if (has_mbyte)
|
||||
|
||||
@@ -2778,7 +2778,6 @@ get_script_local_ht(void)
|
||||
lookup_scriptvar(
|
||||
char_u *name,
|
||||
size_t len,
|
||||
void *lvar UNUSED,
|
||||
cctx_T *dummy UNUSED)
|
||||
{
|
||||
hashtab_T *ht = get_script_local_ht();
|
||||
|
||||
+6
-6
@@ -27,10 +27,10 @@ static const unsigned short cmdidxs1[26] =
|
||||
/* t */ 460,
|
||||
/* u */ 505,
|
||||
/* v */ 516,
|
||||
/* w */ 536,
|
||||
/* x */ 550,
|
||||
/* y */ 560,
|
||||
/* z */ 561
|
||||
/* w */ 537,
|
||||
/* x */ 551,
|
||||
/* y */ 561,
|
||||
/* z */ 562
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -62,11 +62,11 @@ static const unsigned char cmdidxs2[26][26] =
|
||||
/* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 63, 64, 0, 65, 0 },
|
||||
/* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 28, 0, 29, 33, 36, 38, 39, 0, 40, 42, 0, 43, 0, 0, 0, 0, 0 },
|
||||
/* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 11, 14, 0, 0, 0, 0, 17, 0, 18, 0, 0, 0, 0, 0 },
|
||||
/* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 12, 15, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0 },
|
||||
/* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 12, 13, 0, 0, 0, 0 },
|
||||
/* x */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0 },
|
||||
/* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static const int command_count = 576;
|
||||
static const int command_count = 577;
|
||||
|
||||
@@ -1685,6 +1685,9 @@ EXCMD(CMD_vimgrep, "vimgrep", ex_vimgrep,
|
||||
EXCMD(CMD_vimgrepadd, "vimgrepadd", ex_vimgrep,
|
||||
EX_RANGE|EX_BANG|EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM|EX_TRLBAR|EX_XFILE|EX_LOCK_OK,
|
||||
ADDR_OTHER),
|
||||
EXCMD(CMD_vim9cmd, "vim9cmd", ex_wrongmodifier,
|
||||
EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_vim9script, "vim9script", ex_vim9script,
|
||||
EX_WORD1|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
|
||||
+31
-10
@@ -1743,7 +1743,7 @@ do_one_cmd(
|
||||
int starts_with_colon = FALSE;
|
||||
#ifdef FEAT_EVAL
|
||||
int may_have_range;
|
||||
int vim9script = in_vim9script();
|
||||
int vim9script;
|
||||
int did_set_expr_line = FALSE;
|
||||
#endif
|
||||
int sourcing = flags & DOCMD_VERBOSE;
|
||||
@@ -1791,7 +1791,9 @@ do_one_cmd(
|
||||
if (parse_command_modifiers(&ea, &errormsg, &cmdmod, FALSE) == FAIL)
|
||||
goto doend;
|
||||
apply_cmdmod(&cmdmod);
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
vim9script = in_vim9script();
|
||||
#endif
|
||||
after_modifier = ea.cmd;
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
@@ -1961,12 +1963,16 @@ do_one_cmd(
|
||||
/*
|
||||
* strange vi behaviour:
|
||||
* ":3" jumps to line 3
|
||||
* ":3|..." prints line 3
|
||||
* ":|" prints current line
|
||||
* ":3|..." prints line 3 (not in Vim9 script)
|
||||
* ":|" prints current line (not in Vim9 script)
|
||||
*/
|
||||
if (ea.skip) // skip this if inside :if
|
||||
goto doend;
|
||||
if (*ea.cmd == '|' || (exmode_active && ea.line1 != ea.line2))
|
||||
if ((*ea.cmd == '|' || (exmode_active && ea.line1 != ea.line2))
|
||||
#ifdef FEAT_EVAL
|
||||
&& !vim9script
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ea.cmdidx = CMD_print;
|
||||
ea.argt = EX_RANGE+EX_COUNT+EX_TRLBAR;
|
||||
@@ -2595,8 +2601,12 @@ 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)
|
||||
&& current_sctx.sc_sid > 0)
|
||||
&& current_sctx.sc_sid > 0
|
||||
&& ea.cmdidx != CMD_endif
|
||||
&& (cstack->cs_idx < 0
|
||||
|| (cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)))
|
||||
SCRIPT_ITEM(current_sctx.sc_sid)->sn_state = SN_STATE_HAD_COMMAND;
|
||||
|
||||
/*
|
||||
@@ -2939,6 +2949,17 @@ parse_command_modifiers(
|
||||
cmod->cmod_split |= WSP_VERT;
|
||||
continue;
|
||||
}
|
||||
if (checkforcmd(&eap->cmd, "vim9cmd", 4))
|
||||
{
|
||||
if (ends_excmd2(p, eap->cmd))
|
||||
{
|
||||
*errormsg =
|
||||
_(e_vim9cmd_must_be_followed_by_command);
|
||||
return FAIL;
|
||||
}
|
||||
cmod->cmod_flags |= CMOD_VIM9CMD;
|
||||
continue;
|
||||
}
|
||||
if (!checkforcmd(&p, "verbose", 4))
|
||||
break;
|
||||
if (vim_isdigit(*eap->cmd))
|
||||
@@ -3296,7 +3317,7 @@ skip_option_env_lead(char_u *start)
|
||||
find_ex_command(
|
||||
exarg_T *eap,
|
||||
int *full UNUSED,
|
||||
int (*lookup)(char_u *, size_t, void *, cctx_T *) UNUSED,
|
||||
int (*lookup)(char_u *, size_t, cctx_T *) UNUSED,
|
||||
cctx_T *cctx UNUSED)
|
||||
{
|
||||
int len;
|
||||
@@ -3405,7 +3426,7 @@ find_ex_command(
|
||||
|
||||
// Recognize an assignment if we recognize the variable name:
|
||||
// "g:var = expr"
|
||||
// "var = expr" where "var" is a local var name.
|
||||
// "var = expr" where "var" is a variable name.
|
||||
if (*eap->cmd == '@')
|
||||
p = eap->cmd + 2;
|
||||
oplen = assignment_len(skipwhite(p), &heredoc);
|
||||
@@ -3415,7 +3436,7 @@ find_ex_command(
|
||||
|| *eap->cmd == '&'
|
||||
|| *eap->cmd == '$'
|
||||
|| *eap->cmd == '@'
|
||||
|| lookup(eap->cmd, p - eap->cmd, NULL, cctx) == OK)
|
||||
|| lookup(eap->cmd, p - eap->cmd, cctx) == OK)
|
||||
{
|
||||
eap->cmdidx = CMD_var;
|
||||
return eap->cmd;
|
||||
@@ -3434,7 +3455,7 @@ find_ex_command(
|
||||
// If it is an ID it might be a variable with an operator on the next
|
||||
// line, if the variable exists it can't be an Ex command.
|
||||
if (p > eap->cmd && ends_excmd(*skipwhite(p))
|
||||
&& (lookup(eap->cmd, p - eap->cmd, NULL, cctx) == OK
|
||||
&& (lookup(eap->cmd, p - eap->cmd, cctx) == OK
|
||||
|| (ASCII_ISALPHA(eap->cmd[0]) && eap->cmd[1] == ':')))
|
||||
{
|
||||
eap->cmdidx = CMD_eval;
|
||||
|
||||
+3
-15
@@ -1344,26 +1344,14 @@ EXTERN char_u *homedir INIT(= NULL);
|
||||
// directory is not a local directory, globaldir is NULL.
|
||||
EXTERN char_u *globaldir INIT(= NULL);
|
||||
|
||||
// Characters from 'listchars' option
|
||||
EXTERN int lcs_eol INIT(= '$');
|
||||
EXTERN int lcs_ext INIT(= NUL);
|
||||
EXTERN int lcs_prec INIT(= NUL);
|
||||
EXTERN int lcs_nbsp INIT(= NUL);
|
||||
EXTERN int lcs_space INIT(= NUL);
|
||||
EXTERN int lcs_tab1 INIT(= NUL);
|
||||
EXTERN int lcs_tab2 INIT(= NUL);
|
||||
EXTERN int lcs_tab3 INIT(= NUL);
|
||||
EXTERN int lcs_trail INIT(= NUL);
|
||||
EXTERN int lcs_lead INIT(= NUL);
|
||||
#ifdef FEAT_CONCEAL
|
||||
EXTERN int lcs_conceal INIT(= ' ');
|
||||
#endif
|
||||
|
||||
// Characters from 'fillchars' option
|
||||
EXTERN int fill_stl INIT(= ' ');
|
||||
EXTERN int fill_stlnc INIT(= ' ');
|
||||
EXTERN int fill_vert INIT(= ' ');
|
||||
EXTERN int fill_fold INIT(= '-');
|
||||
EXTERN int fill_foldopen INIT(= '-');
|
||||
EXTERN int fill_foldclosed INIT(= '+');
|
||||
EXTERN int fill_foldsep INIT(= '|');
|
||||
EXTERN int fill_diff INIT(= '-');
|
||||
EXTERN int fill_eob INIT(= '~');
|
||||
|
||||
|
||||
+3
-2
@@ -432,7 +432,8 @@ get_indent_str(
|
||||
{
|
||||
if (*ptr == TAB)
|
||||
{
|
||||
if (!list || lcs_tab1) // count a tab for what it is worth
|
||||
if (!list || curwin->w_lcs_chars.tab1)
|
||||
// count a tab for what it is worth
|
||||
count += ts - (count % ts);
|
||||
else
|
||||
// In list mode, when tab is not set, count screen char width
|
||||
@@ -462,7 +463,7 @@ get_indent_str_vtab(char_u *ptr, int ts, int *vts, int list)
|
||||
{
|
||||
if (*ptr == TAB) // count a tab for what it is worth
|
||||
{
|
||||
if (!list || lcs_tab1)
|
||||
if (!list || curwin->w_lcs_chars.tab1)
|
||||
count += tabstop_padding(count, ts, vts);
|
||||
else
|
||||
// In list mode, when tab is not set, count screen char width
|
||||
|
||||
+26
-17
@@ -248,6 +248,13 @@ trunc_string(
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if (*s == NUL)
|
||||
{
|
||||
if (buflen > 0)
|
||||
*buf = NUL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (room_in < 3)
|
||||
room = 0;
|
||||
half = room / 2;
|
||||
@@ -1846,14 +1853,14 @@ msg_prt_line(char_u *s, int list)
|
||||
if (list)
|
||||
{
|
||||
// find start of trailing whitespace
|
||||
if (lcs_trail)
|
||||
if (curwin->w_lcs_chars.trail)
|
||||
{
|
||||
trail = s + STRLEN(s);
|
||||
while (trail > s && VIM_ISWHITE(trail[-1]))
|
||||
--trail;
|
||||
}
|
||||
// find end of leading whitespace
|
||||
if (lcs_lead)
|
||||
if (curwin->w_lcs_chars.lead)
|
||||
{
|
||||
lead = s;
|
||||
while (VIM_ISWHITE(lead[0]))
|
||||
@@ -1866,7 +1873,7 @@ msg_prt_line(char_u *s, int list)
|
||||
|
||||
// output a space for an empty line, otherwise the line will be
|
||||
// overwritten
|
||||
if (*s == NUL && !(list && lcs_eol != NUL))
|
||||
if (*s == NUL && !(list && curwin->w_lcs_chars.eol != NUL))
|
||||
msg_putchar(' ');
|
||||
|
||||
while (!got_int)
|
||||
@@ -1888,11 +1895,11 @@ msg_prt_line(char_u *s, int list)
|
||||
{
|
||||
STRCPY(buf, "?");
|
||||
}
|
||||
else if (lcs_nbsp != NUL && list
|
||||
else if (curwin->w_lcs_chars.nbsp != NUL && list
|
||||
&& (mb_ptr2char(s) == 160
|
||||
|| mb_ptr2char(s) == 0x202f))
|
||||
{
|
||||
mb_char2bytes(lcs_nbsp, buf);
|
||||
mb_char2bytes(curwin->w_lcs_chars.nbsp, buf);
|
||||
buf[(*mb_ptr2len)(buf)] = NUL;
|
||||
}
|
||||
else
|
||||
@@ -1908,7 +1915,7 @@ msg_prt_line(char_u *s, int list)
|
||||
{
|
||||
attr = 0;
|
||||
c = *s++;
|
||||
if (c == TAB && (!list || lcs_tab1))
|
||||
if (c == TAB && (!list || curwin->w_lcs_chars.tab1))
|
||||
{
|
||||
// tab amount depends on current column
|
||||
#ifdef FEAT_VARTABS
|
||||
@@ -1925,24 +1932,26 @@ msg_prt_line(char_u *s, int list)
|
||||
}
|
||||
else
|
||||
{
|
||||
c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
|
||||
c_extra = lcs_tab2;
|
||||
c_final = lcs_tab3;
|
||||
c = (n_extra == 0 && curwin->w_lcs_chars.tab3)
|
||||
? curwin->w_lcs_chars.tab3
|
||||
: curwin->w_lcs_chars.tab1;
|
||||
c_extra = curwin->w_lcs_chars.tab2;
|
||||
c_final = curwin->w_lcs_chars.tab3;
|
||||
attr = HL_ATTR(HLF_8);
|
||||
}
|
||||
}
|
||||
else if (c == 160 && list && lcs_nbsp != NUL)
|
||||
else if (c == 160 && list && curwin->w_lcs_chars.nbsp != NUL)
|
||||
{
|
||||
c = lcs_nbsp;
|
||||
c = curwin->w_lcs_chars.nbsp;
|
||||
attr = HL_ATTR(HLF_8);
|
||||
}
|
||||
else if (c == NUL && list && lcs_eol != NUL)
|
||||
else if (c == NUL && list && curwin->w_lcs_chars.eol != NUL)
|
||||
{
|
||||
p_extra = (char_u *)"";
|
||||
c_extra = NUL;
|
||||
c_final = NUL;
|
||||
n_extra = 1;
|
||||
c = lcs_eol;
|
||||
c = curwin->w_lcs_chars.eol;
|
||||
attr = HL_ATTR(HLF_AT);
|
||||
--s;
|
||||
}
|
||||
@@ -1959,17 +1968,17 @@ msg_prt_line(char_u *s, int list)
|
||||
}
|
||||
else if (c == ' ' && lead != NULL && s <= lead)
|
||||
{
|
||||
c = lcs_lead;
|
||||
c = curwin->w_lcs_chars.lead;
|
||||
attr = HL_ATTR(HLF_8);
|
||||
}
|
||||
else if (c == ' ' && trail != NULL && s > trail)
|
||||
{
|
||||
c = lcs_trail;
|
||||
c = curwin->w_lcs_chars.trail;
|
||||
attr = HL_ATTR(HLF_8);
|
||||
}
|
||||
else if (c == ' ' && list && lcs_space != NUL)
|
||||
else if (c == ' ' && list && curwin->w_lcs_chars.space != NUL)
|
||||
{
|
||||
c = lcs_space;
|
||||
c = curwin->w_lcs_chars.space;
|
||||
attr = HL_ATTR(HLF_8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,15 @@ test_trunc_string(void)
|
||||
char_u *buf; /*allocated every time to find uninit errors */
|
||||
char_u *s;
|
||||
|
||||
// Should not write anything to destination if buflen is 0.
|
||||
trunc_string((char_u *)"", NULL, 1, 0);
|
||||
|
||||
// Truncating an empty string does nothing.
|
||||
buf = alloc(1);
|
||||
trunc_string((char_u *)"", buf, 1, 1);
|
||||
assert(buf[0] == NUL);
|
||||
vim_free(buf);
|
||||
|
||||
// in place
|
||||
buf = alloc(40);
|
||||
STRCPY(buf, "text");
|
||||
|
||||
+3
-2
@@ -403,7 +403,7 @@ plines_win_nofold(win_T *wp, linenr_T lnum)
|
||||
* If list mode is on, then the '$' at the end of the line may take up one
|
||||
* extra column.
|
||||
*/
|
||||
if (wp->w_p_list && lcs_eol != NUL)
|
||||
if (wp->w_p_list && wp->w_lcs_chars.eol != NUL)
|
||||
col += 1;
|
||||
|
||||
/*
|
||||
@@ -460,7 +460,8 @@ plines_win_col(win_T *wp, linenr_T lnum, long column)
|
||||
* from one screen line to the next (when 'columns' is not a multiple of
|
||||
* 'ts') -- webb.
|
||||
*/
|
||||
if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1))
|
||||
if (*s == TAB && (State & NORMAL) && (!wp->w_p_list ||
|
||||
wp->w_lcs_chars.tab1))
|
||||
col += win_lbr_chartabsize(wp, line, s, (colnr_T)col, NULL) - 1;
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -2009,7 +2009,7 @@ retnomove:
|
||||
count |= CURSOR_MOVED; // Cursor has moved
|
||||
|
||||
# ifdef FEAT_FOLDING
|
||||
if (mouse_char == '+')
|
||||
if (mouse_char == fill_foldclosed)
|
||||
count |= MOUSE_FOLD_OPEN;
|
||||
else if (mouse_char != ' ')
|
||||
count |= MOUSE_FOLD_CLOSE;
|
||||
|
||||
+17
-2
@@ -2359,9 +2359,11 @@ didset_options2(void)
|
||||
// Parse default for 'wildmode'
|
||||
check_opt_wim();
|
||||
|
||||
(void)set_chars_option(&p_lcs);
|
||||
// Parse default for 'listchars'.
|
||||
(void)set_chars_option(curwin, &curwin->w_p_lcs);
|
||||
|
||||
// Parse default for 'fillchars'.
|
||||
(void)set_chars_option(&p_fcs);
|
||||
(void)set_chars_option(curwin, &p_fcs);
|
||||
|
||||
#ifdef FEAT_CLIPBOARD
|
||||
// Parse default for 'clipboard'
|
||||
@@ -5171,6 +5173,11 @@ unset_global_local_option(char_u *name, void *from)
|
||||
case PV_MENC:
|
||||
clear_string_option(&buf->b_p_menc);
|
||||
break;
|
||||
case PV_LCS:
|
||||
clear_string_option(&((win_T *)from)->w_p_lcs);
|
||||
set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs);
|
||||
redraw_later(NOT_VALID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -5229,6 +5236,8 @@ get_varp_scope(struct vimoption *p, int opt_flags)
|
||||
#endif
|
||||
case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
|
||||
case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
|
||||
case PV_LCS: return (char_u *)&(curwin->w_p_lcs);
|
||||
|
||||
}
|
||||
return NULL; // "cannot happen"
|
||||
}
|
||||
@@ -5326,6 +5335,8 @@ get_varp(struct vimoption *p)
|
||||
case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
|
||||
#endif
|
||||
case PV_LIST: return (char_u *)&(curwin->w_p_list);
|
||||
case PV_LCS: return *curwin->w_p_lcs != NUL
|
||||
? (char_u *)&(curwin->w_p_lcs) : p->var;
|
||||
#ifdef FEAT_SPELL
|
||||
case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
|
||||
#endif
|
||||
@@ -5556,6 +5567,7 @@ after_copy_winopt(win_T *wp UNUSED)
|
||||
fill_culopt_flags(NULL, wp);
|
||||
check_colorcolumn(wp);
|
||||
#endif
|
||||
set_chars_option(wp, &wp->w_p_lcs);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5571,6 +5583,7 @@ copy_winopt(winopt_T *from, winopt_T *to)
|
||||
to->wo_arab = from->wo_arab;
|
||||
#endif
|
||||
to->wo_list = from->wo_list;
|
||||
to->wo_lcs = vim_strsave(from->wo_lcs);
|
||||
to->wo_nu = from->wo_nu;
|
||||
to->wo_rnu = from->wo_rnu;
|
||||
#ifdef FEAT_LINEBREAK
|
||||
@@ -5705,6 +5718,7 @@ check_winopt(winopt_T *wop UNUSED)
|
||||
check_string_option(&wop->wo_briopt);
|
||||
#endif
|
||||
check_string_option(&wop->wo_wcr);
|
||||
check_string_option(&wop->wo_lcs);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5750,6 +5764,7 @@ clear_winopt(winopt_T *wop UNUSED)
|
||||
clear_string_option(&wop->wo_twk);
|
||||
clear_string_option(&wop->wo_tws);
|
||||
#endif
|
||||
clear_string_option(&wop->wo_lcs);
|
||||
}
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
|
||||
@@ -1260,6 +1260,7 @@ enum
|
||||
enum
|
||||
{
|
||||
WV_LIST = 0
|
||||
, WV_LCS
|
||||
#ifdef FEAT_ARABIC
|
||||
, WV_ARAB
|
||||
#endif
|
||||
|
||||
+2
-1
@@ -188,6 +188,7 @@
|
||||
#ifdef FEAT_LINEBREAK
|
||||
# define PV_LBR OPT_WIN(WV_LBR)
|
||||
#endif
|
||||
#define PV_LCS OPT_BOTH(OPT_WIN(WV_LCS))
|
||||
#define PV_NU OPT_WIN(WV_NU)
|
||||
#define PV_RNU OPT_WIN(WV_RNU)
|
||||
#ifdef FEAT_LINEBREAK
|
||||
@@ -1683,7 +1684,7 @@ static struct vimoption options[] =
|
||||
(char_u *)VAR_WIN, PV_LIST,
|
||||
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
|
||||
{"listchars", "lcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP,
|
||||
(char_u *)&p_lcs, PV_NONE,
|
||||
(char_u *)&p_lcs, PV_LCS,
|
||||
{(char_u *)"eol:$", (char_u *)0L} SCTX_INIT},
|
||||
{"loadplugins", "lpl", P_BOOL|P_VI_DEF,
|
||||
(char_u *)&p_lpl, PV_NONE,
|
||||
|
||||
+41
-6
@@ -862,10 +862,24 @@ did_set_string_option(
|
||||
{
|
||||
if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
|
||||
errmsg = e_invarg;
|
||||
else if (set_chars_option(&p_lcs) != NULL)
|
||||
errmsg = _("E834: Conflicts with value of 'listchars'");
|
||||
else if (set_chars_option(&p_fcs) != NULL)
|
||||
else if (set_chars_option(curwin, &p_fcs) != NULL)
|
||||
errmsg = _("E835: Conflicts with value of 'fillchars'");
|
||||
else
|
||||
{
|
||||
tabpage_T *tp;
|
||||
win_T *wp;
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||
{
|
||||
if (set_chars_option(wp, &wp->w_p_lcs) != NULL)
|
||||
{
|
||||
errmsg = _("E834: Conflicts with value of 'listchars'");
|
||||
goto ambw_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
ambw_end:
|
||||
{}
|
||||
}
|
||||
|
||||
// 'background'
|
||||
@@ -1302,16 +1316,37 @@ did_set_string_option(
|
||||
}
|
||||
}
|
||||
|
||||
// 'listchars'
|
||||
// global 'listchars'
|
||||
else if (varp == &p_lcs)
|
||||
{
|
||||
errmsg = set_chars_option(varp);
|
||||
errmsg = set_chars_option(curwin, varp);
|
||||
if (errmsg == NULL)
|
||||
{
|
||||
tabpage_T *tp;
|
||||
win_T *wp;
|
||||
|
||||
// The current window is set to use the global 'listchars' value.
|
||||
// So clear the window-local value.
|
||||
if (!(opt_flags & OPT_GLOBAL))
|
||||
clear_string_option(&curwin->w_p_lcs);
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||
{
|
||||
errmsg = set_chars_option(wp, &wp->w_p_lcs);
|
||||
if (errmsg)
|
||||
break;
|
||||
}
|
||||
redraw_all_later(NOT_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
// local 'listchars'
|
||||
else if (varp == &curwin->w_p_lcs)
|
||||
errmsg = set_chars_option(curwin, varp);
|
||||
|
||||
// 'fillchars'
|
||||
else if (varp == &p_fcs)
|
||||
{
|
||||
errmsg = set_chars_option(varp);
|
||||
errmsg = set_chars_option(curwin, varp);
|
||||
}
|
||||
|
||||
#ifdef FEAT_CMDWIN
|
||||
|
||||
@@ -60,7 +60,7 @@ void check_vars(char_u *name, int len);
|
||||
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
|
||||
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
|
||||
hashtab_T *get_script_local_ht(void);
|
||||
int lookup_scriptvar(char_u *name, size_t len, void *lvar, cctx_T *dummy);
|
||||
int lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy);
|
||||
hashtab_T *find_var_ht(char_u *name, char_u **varname);
|
||||
char_u *get_var_value(char_u *name);
|
||||
void new_script_vars(scid_T id);
|
||||
|
||||
@@ -13,9 +13,10 @@ void undo_cmdmod(cmdmod_T *cmod);
|
||||
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
|
||||
int checkforcmd(char_u **pp, char *cmd, int len);
|
||||
char_u *skip_option_env_lead(char_u *start);
|
||||
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, void *, cctx_T *), cctx_T *cctx);
|
||||
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, cctx_T *), cctx_T *cctx);
|
||||
int modifier_len(char_u *cmd);
|
||||
int cmd_exists(char_u *name);
|
||||
void f_fullcommand(typval_T *argvars, typval_T *rettv);
|
||||
cmdidx_T excmd_get_cmdidx(char_u *cmd, int len);
|
||||
long excmd_get_argt(cmdidx_T idx);
|
||||
char_u *skip_range(char_u *cmd, int skip_star, int *ctx);
|
||||
|
||||
@@ -55,5 +55,5 @@ void comp_col(void);
|
||||
int number_width(win_T *wp);
|
||||
int screen_screencol(void);
|
||||
int screen_screenrow(void);
|
||||
char *set_chars_option(char_u **varp);
|
||||
char *set_chars_option(win_T *wp, char_u **varp);
|
||||
/* vim: set ft=c : */
|
||||
|
||||
+45
-31
@@ -272,9 +272,9 @@ fill_foldcolumn(
|
||||
{
|
||||
if (win_foldinfo.fi_lnum == lnum
|
||||
&& first_level + i >= win_foldinfo.fi_low_level)
|
||||
p[i] = '-';
|
||||
p[i] = fill_foldopen;
|
||||
else if (first_level == 1)
|
||||
p[i] = '|';
|
||||
p[i] = fill_foldsep;
|
||||
else if (first_level + i <= 9)
|
||||
p[i] = '0' + first_level + i;
|
||||
else
|
||||
@@ -284,7 +284,7 @@ fill_foldcolumn(
|
||||
}
|
||||
}
|
||||
if (closed)
|
||||
p[i >= fdc ? i - 1 : i] = '+';
|
||||
p[i >= fdc ? i - 1 : i] = fill_foldclosed;
|
||||
}
|
||||
#endif // FEAT_FOLDING
|
||||
|
||||
@@ -4786,10 +4786,11 @@ screen_screenrow(void)
|
||||
|
||||
/*
|
||||
* Handle setting 'listchars' or 'fillchars'.
|
||||
* Assume monocell characters.
|
||||
* Returns error message, NULL if it's OK.
|
||||
*/
|
||||
char *
|
||||
set_chars_option(char_u **varp)
|
||||
set_chars_option(win_T *wp, char_u **varp)
|
||||
{
|
||||
int round, i, len, entries;
|
||||
char_u *p, *s;
|
||||
@@ -4801,35 +4802,42 @@ set_chars_option(char_u **varp)
|
||||
};
|
||||
static struct charstab filltab[] =
|
||||
{
|
||||
{&fill_stl, "stl"},
|
||||
{&fill_stlnc, "stlnc"},
|
||||
{&fill_vert, "vert"},
|
||||
{&fill_fold, "fold"},
|
||||
{&fill_diff, "diff"},
|
||||
{&fill_eob, "eob"},
|
||||
{&fill_stl, "stl"},
|
||||
{&fill_stlnc, "stlnc"},
|
||||
{&fill_vert, "vert"},
|
||||
{&fill_fold, "fold"},
|
||||
{&fill_foldopen, "foldopen"},
|
||||
{&fill_foldclosed, "foldclose"},
|
||||
{&fill_foldsep, "foldsep"},
|
||||
{&fill_diff, "diff"},
|
||||
{&fill_eob, "eob"},
|
||||
};
|
||||
static struct charstab lcstab[] =
|
||||
static lcs_chars_T lcs_chars;
|
||||
struct charstab lcstab[] =
|
||||
{
|
||||
{&lcs_eol, "eol"},
|
||||
{&lcs_ext, "extends"},
|
||||
{&lcs_nbsp, "nbsp"},
|
||||
{&lcs_prec, "precedes"},
|
||||
{&lcs_space, "space"},
|
||||
{&lcs_tab2, "tab"},
|
||||
{&lcs_trail, "trail"},
|
||||
{&lcs_lead, "lead"},
|
||||
{&lcs_chars.eol, "eol"},
|
||||
{&lcs_chars.ext, "extends"},
|
||||
{&lcs_chars.nbsp, "nbsp"},
|
||||
{&lcs_chars.prec, "precedes"},
|
||||
{&lcs_chars.space, "space"},
|
||||
{&lcs_chars.tab2, "tab"},
|
||||
{&lcs_chars.trail, "trail"},
|
||||
{&lcs_chars.lead, "lead"},
|
||||
#ifdef FEAT_CONCEAL
|
||||
{&lcs_conceal, "conceal"},
|
||||
{&lcs_chars.conceal, "conceal"},
|
||||
#else
|
||||
{NULL, "conceal"},
|
||||
{NULL, "conceal"},
|
||||
#endif
|
||||
};
|
||||
struct charstab *tab;
|
||||
|
||||
if (varp == &p_lcs)
|
||||
if (varp == &p_lcs || varp == &wp->w_p_lcs)
|
||||
{
|
||||
tab = lcstab;
|
||||
CLEAR_FIELD(lcs_chars);
|
||||
entries = sizeof(lcstab) / sizeof(struct charstab);
|
||||
if (varp == &wp->w_p_lcs && wp->w_p_lcs[0] == NUL)
|
||||
varp = &p_lcs;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4846,16 +4854,20 @@ set_chars_option(char_u **varp)
|
||||
// 'fillchars', NUL for 'listchars'
|
||||
for (i = 0; i < entries; ++i)
|
||||
if (tab[i].cp != NULL)
|
||||
*(tab[i].cp) = (varp == &p_lcs ? NUL : ' ');
|
||||
*(tab[i].cp) =
|
||||
((varp == &p_lcs || varp == &wp->w_p_lcs) ? NUL : ' ');
|
||||
|
||||
if (varp == &p_lcs)
|
||||
if (varp == &p_lcs || varp == &wp->w_p_lcs)
|
||||
{
|
||||
lcs_tab1 = NUL;
|
||||
lcs_tab3 = NUL;
|
||||
lcs_chars.tab1 = NUL;
|
||||
lcs_chars.tab3 = NUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_diff = '-';
|
||||
fill_foldopen = '-';
|
||||
fill_foldclosed = '+';
|
||||
fill_foldsep = '|';
|
||||
fill_eob = '~';
|
||||
}
|
||||
}
|
||||
@@ -4874,7 +4886,7 @@ set_chars_option(char_u **varp)
|
||||
c1 = mb_ptr2char_adv(&s);
|
||||
if (mb_char2cells(c1) > 1)
|
||||
continue;
|
||||
if (tab[i].cp == &lcs_tab2)
|
||||
if (tab[i].cp == &lcs_chars.tab2)
|
||||
{
|
||||
if (*s == NUL)
|
||||
continue;
|
||||
@@ -4893,11 +4905,11 @@ set_chars_option(char_u **varp)
|
||||
{
|
||||
if (round)
|
||||
{
|
||||
if (tab[i].cp == &lcs_tab2)
|
||||
if (tab[i].cp == &lcs_chars.tab2)
|
||||
{
|
||||
lcs_tab1 = c1;
|
||||
lcs_tab2 = c2;
|
||||
lcs_tab3 = c3;
|
||||
lcs_chars.tab1 = c1;
|
||||
lcs_chars.tab2 = c2;
|
||||
lcs_chars.tab3 = c3;
|
||||
}
|
||||
else if (tab[i].cp != NULL)
|
||||
*(tab[i].cp) = c1;
|
||||
@@ -4915,6 +4927,8 @@ set_chars_option(char_u **varp)
|
||||
++p;
|
||||
}
|
||||
}
|
||||
if (tab == lcstab)
|
||||
wp->w_lcs_chars = lcs_chars;
|
||||
|
||||
return NULL; // no error
|
||||
}
|
||||
|
||||
@@ -225,6 +225,8 @@ typedef struct
|
||||
#endif
|
||||
int wo_list;
|
||||
#define w_p_list w_onebuf_opt.wo_list // 'list'
|
||||
char_u *wo_lcs;
|
||||
#define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars'
|
||||
int wo_nu;
|
||||
#define w_p_nu w_onebuf_opt.wo_nu // 'number'
|
||||
int wo_rnu;
|
||||
@@ -642,6 +644,7 @@ typedef struct
|
||||
#define CMOD_LOCKMARKS 0x0800 // ":lockmarks"
|
||||
#define CMOD_KEEPPATTERNS 0x1000 // ":keeppatterns"
|
||||
#define CMOD_NOSWAPFILE 0x2000 // ":noswapfile"
|
||||
#define CMOD_VIM9CMD 0x4000 // ":vim9cmd"
|
||||
|
||||
int cmod_split; // flags for win_split()
|
||||
int cmod_tab; // > 0 when ":tab" was used
|
||||
@@ -3343,6 +3346,26 @@ typedef struct {
|
||||
} winbar_item_T;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Characters from the 'listchars' option
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int eol;
|
||||
int ext;
|
||||
int prec;
|
||||
int nbsp;
|
||||
int space;
|
||||
int tab1;
|
||||
int tab2;
|
||||
int tab3;
|
||||
int trail;
|
||||
int lead;
|
||||
#ifdef FEAT_CONCEAL
|
||||
int conceal;
|
||||
#endif
|
||||
} lcs_chars_T;
|
||||
|
||||
/*
|
||||
* Structure which contains all information that belongs to a window
|
||||
*
|
||||
@@ -3391,6 +3414,8 @@ struct window_S
|
||||
colnr_T w_old_visual_col; // last known start of visual part
|
||||
colnr_T w_old_curswant; // last known value of Curswant
|
||||
|
||||
lcs_chars_T w_lcs_chars; // 'listchars' characters
|
||||
|
||||
/*
|
||||
* "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for
|
||||
* displaying the buffer.
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|v+0#0000001#ffff4012|i|m|9|s|c|r|i|p|t| +3#0000000#ffffff0@1|v|i|m|g|r|e|p| @1|v|i|m|g|r|e|p|a|d@1| @43
|
||||
|:+0&&|v|i|m|9|s|c|r|i|p|t> @63
|
||||
|v+0#0000001#ffff4012|i|m|9|c|m|d| +3#0000000#ffffff0@1|v|i|m|9|s|c|r|i|p|t| @1|v|i|m|g|r|e|p| @1|v|i|m|g|r|e|p|a|d@1| @34
|
||||
|:+0&&|v|i|m|9|c|m|d> @66
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|v+3#0000000&|i|m|9|s|c|r|i|p|t| @1|v+0#0000001#ffff4012|i|m|g|r|e|p| +3#0000000#ffffff0@1|v|i|m|g|r|e|p|a|d@1| @43
|
||||
|:+0&&|v|i|m|g|r|e|p> @66
|
||||
|v+3#0000000&|i|m|9|c|m|d| @1|v+0#0000001#ffff4012|i|m|9|s|c|r|i|p|t| +3#0000000#ffffff0@1|v|i|m|g|r|e|p| @1|v|i|m|g|r|e|p|a|d@1| @34
|
||||
|:+0&&|v|i|m|9|s|c|r|i|p|t> @63
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|v+3#0000000&|i|m|9|s|c|r|i|p|t| @1|v|i|m|g|r|e|p| @1|v+0#0000001#ffff4012|i|m|g|r|e|p|a|d@1| +3#0000000#ffffff0@43
|
||||
|:+0&&|v|i|m|g|r|e|p|a|d@1> @63
|
||||
|v+3#0000000&|i|m|9|c|m|d| @1|v|i|m|9|s|c|r|i|p|t| @1|v+0#0000001#ffff4012|i|m|g|r|e|p| +3#0000000#ffffff0@1|v|i|m|g|r|e|p|a|d@1| @34
|
||||
|:+0&&|v|i|m|g|r|e|p> @66
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|v+3#0000000&|i|m|9|s|c|r|i|p|t| @1|v|i|m|g|r|e|p| @1|v|i|m|g|r|e|p|a|d@1| @43
|
||||
|v+3#0000000&|i|m|9|c|m|d| @1|v|i|m|9|s|c|r|i|p|t| @1|v|i|m|g|r|e|p| @1|v|i|m|g|r|e|p|a|d@1| @34
|
||||
|:+0&&|v|i|m> @70
|
||||
|
||||
@@ -179,5 +179,9 @@ func Run_shell_in_terminal(options)
|
||||
return buf
|
||||
endfunc
|
||||
|
||||
" Return concatenated lines in terminal.
|
||||
func Term_getlines(buf, lines)
|
||||
return join(map(a:lines, 'term_getline(a:buf, v:val)'), '')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -119,7 +119,7 @@ func Test_wildmenu_screendump()
|
||||
call term_sendkeys(buf, "\<Tab>")
|
||||
call VerifyScreenDump(buf, 'Test_wildmenu_3', {})
|
||||
|
||||
call term_sendkeys(buf, "\<Tab>")
|
||||
call term_sendkeys(buf, "\<Tab>\<Tab>")
|
||||
call VerifyScreenDump(buf, 'Test_wildmenu_4', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
|
||||
@@ -279,4 +279,58 @@ func Test_eob_fillchars()
|
||||
close
|
||||
endfunc
|
||||
|
||||
" Test for 'foldopen', 'foldclose' and 'foldsep' in 'fillchars'
|
||||
func Test_fold_fillchars()
|
||||
new
|
||||
set fdc=2 foldenable foldmethod=manual
|
||||
call setline(1, ['one', 'two', 'three', 'four', 'five'])
|
||||
2,4fold
|
||||
" First check for the default setting for a closed fold
|
||||
let lines = ScreenLines([1, 3], 8)
|
||||
let expected = [
|
||||
\ ' one ',
|
||||
\ '+ +-- 3',
|
||||
\ ' five '
|
||||
\ ]
|
||||
call assert_equal(expected, lines)
|
||||
normal 2Gzo
|
||||
" check the characters for an open fold
|
||||
let lines = ScreenLines([1, 5], 8)
|
||||
let expected = [
|
||||
\ ' one ',
|
||||
\ '- two ',
|
||||
\ '| three ',
|
||||
\ '| four ',
|
||||
\ ' five '
|
||||
\ ]
|
||||
call assert_equal(expected, lines)
|
||||
|
||||
" change the setting
|
||||
set fillchars=vert:\|,fold:-,eob:~,foldopen:[,foldclose:],foldsep:-
|
||||
|
||||
" check the characters for an open fold
|
||||
let lines = ScreenLines([1, 5], 8)
|
||||
let expected = [
|
||||
\ ' one ',
|
||||
\ '[ two ',
|
||||
\ '- three ',
|
||||
\ '- four ',
|
||||
\ ' five '
|
||||
\ ]
|
||||
call assert_equal(expected, lines)
|
||||
|
||||
" check the characters for a closed fold
|
||||
normal 2Gzc
|
||||
let lines = ScreenLines([1, 3], 8)
|
||||
let expected = [
|
||||
\ ' one ',
|
||||
\ '] +-- 3',
|
||||
\ ' five '
|
||||
\ ]
|
||||
call assert_equal(expected, lines)
|
||||
|
||||
%bw!
|
||||
set fillchars& fdc& foldmethod& foldenable&
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -79,6 +79,7 @@ let s:filename_checks = {
|
||||
\ 'bzl': ['file.bazel', 'file.bzl', 'WORKSPACE'],
|
||||
\ 'bc': ['file.bc'],
|
||||
\ 'bdf': ['file.bdf'],
|
||||
\ 'beancount': ['file.beancount'],
|
||||
\ 'bib': ['file.bib'],
|
||||
\ 'bindzone': ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file'],
|
||||
\ 'blank': ['file.bl'],
|
||||
@@ -426,6 +427,7 @@ let s:filename_checks = {
|
||||
\ 'sdc': ['file.sdc'],
|
||||
\ 'sdl': ['file.sdl', 'file.pr'],
|
||||
\ 'sed': ['file.sed'],
|
||||
\ 'svelte': ['file.svelte'],
|
||||
\ 'sensors': ['/etc/sensors.conf', '/etc/sensors3.conf', 'any/etc/sensors.conf', 'any/etc/sensors3.conf'],
|
||||
\ 'services': ['/etc/services', 'any/etc/services'],
|
||||
\ 'setserial': ['/etc/serial.conf', 'any/etc/serial.conf'],
|
||||
|
||||
@@ -234,4 +234,130 @@ func Test_listchars_composing()
|
||||
set listchars& ff&
|
||||
endfunction
|
||||
|
||||
" Check for the value of the 'listchars' option
|
||||
func s:CheckListCharsValue(expected)
|
||||
call assert_equal(a:expected, &listchars)
|
||||
call assert_equal(a:expected, getwinvar(0, '&listchars'))
|
||||
endfunc
|
||||
|
||||
" Test for using a window local value for 'listchars'
|
||||
func Test_listchars_window_local()
|
||||
%bw!
|
||||
set list listchars&
|
||||
new
|
||||
" set a local value for 'listchars'
|
||||
setlocal listchars=tab:+-,eol:#
|
||||
call s:CheckListCharsValue('tab:+-,eol:#')
|
||||
" When local value is reset, global value should be used
|
||||
setlocal listchars=
|
||||
call s:CheckListCharsValue('eol:$')
|
||||
" Use 'setlocal <' to copy global value
|
||||
setlocal listchars=space:.,extends:>
|
||||
setlocal listchars<
|
||||
call s:CheckListCharsValue('eol:$')
|
||||
" Use 'set <' to copy global value
|
||||
setlocal listchars=space:.,extends:>
|
||||
set listchars<
|
||||
call s:CheckListCharsValue('eol:$')
|
||||
" Changing global setting should not change the local setting
|
||||
setlocal listchars=space:.,extends:>
|
||||
setglobal listchars=tab:+-,eol:#
|
||||
call s:CheckListCharsValue('space:.,extends:>')
|
||||
" when split opening a new window, local value should be copied
|
||||
split
|
||||
call s:CheckListCharsValue('space:.,extends:>')
|
||||
" clearing local value in one window should not change the other window
|
||||
set listchars&
|
||||
call s:CheckListCharsValue('eol:$')
|
||||
close
|
||||
call s:CheckListCharsValue('space:.,extends:>')
|
||||
|
||||
" use different values for 'listchars' items in two different windows
|
||||
call setline(1, ["\t one two "])
|
||||
setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
|
||||
split
|
||||
setlocal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
|
||||
split
|
||||
set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
|
||||
call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
" changing the global setting should not change the local value
|
||||
setglobal listchars=tab:[.],lead:#,space:_,trail:.,eol:&
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
set listchars<
|
||||
call assert_equal(['[......]##one__two..&'], ScreenLines(1, virtcol('$')))
|
||||
|
||||
" Using setglobal in a window with local setting should not affect the
|
||||
" window. But should impact other windows using the global setting.
|
||||
enew! | only
|
||||
call setline(1, ["\t one two "])
|
||||
set listchars=tab:[.],lead:#,space:_,trail:.,eol:&
|
||||
split
|
||||
setlocal listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
|
||||
split
|
||||
setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
|
||||
setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
|
||||
|
||||
" Setting the global setting to the default value should not impact a window
|
||||
" using a local setting
|
||||
split
|
||||
setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
|
||||
setglobal listchars&vim
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$')))
|
||||
|
||||
" Setting the local setting to the default value should not impact a window
|
||||
" using a global setting
|
||||
set listchars=tab:{.},lead:-,space:=,trail:#,eol:$
|
||||
split
|
||||
setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
setlocal listchars&vim
|
||||
call assert_equal(['^I one two $'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['{......}--one==two##$'], ScreenLines(1, virtcol('$')))
|
||||
|
||||
" Using set in a window with a local setting should change it to use the
|
||||
" global setting and also impact other windows using the global setting
|
||||
split
|
||||
setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
set listchars=tab:+-+,lead:^,space:>,trail:<,eol:%
|
||||
call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
|
||||
|
||||
" Setting invalid value for a local setting should not impact the local and
|
||||
" global settings
|
||||
split
|
||||
setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
|
||||
let cmd = 'setlocal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x'
|
||||
call assert_fails(cmd, 'E474:')
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
|
||||
|
||||
" Setting invalid value for a global setting should not impact the local and
|
||||
" global settings
|
||||
split
|
||||
setlocal listchars=tab:<->,lead:_,space:.,trail:@,eol:#
|
||||
let cmd = 'setglobal listchars=tab:{.},lead:-,space:=,trail:#,eol:$,x'
|
||||
call assert_fails(cmd, 'E474:')
|
||||
call assert_equal(['<------>__one..two@@#'], ScreenLines(1, virtcol('$')))
|
||||
close
|
||||
call assert_equal(['+------+^^one>>two<<%'], ScreenLines(1, virtcol('$')))
|
||||
|
||||
%bw!
|
||||
set list& listchars&
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -43,6 +43,7 @@ func Test_set_linebreak()
|
||||
endfunc
|
||||
|
||||
func Test_linebreak_with_list()
|
||||
set listchars=
|
||||
call s:test_windows('setl ts=4 sbr=+ list listchars=')
|
||||
call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
|
||||
let lines = s:screen_lines([1, 4], winwidth(0))
|
||||
@@ -54,6 +55,7 @@ func Test_linebreak_with_list()
|
||||
\ ]
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows()
|
||||
set listchars&vim
|
||||
endfunc
|
||||
|
||||
func Test_linebreak_with_nolist()
|
||||
|
||||
@@ -709,7 +709,7 @@ def Test_helpgrep_vim9_restore_cpo()
|
||||
var dir = 'Xruntime/after'
|
||||
&rtp ..= ',' .. dir
|
||||
mkdir(dir .. '/ftplugin', 'p')
|
||||
writefile(['vim9'], dir .. '/ftplugin/qf.vim')
|
||||
writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
|
||||
filetype plugin on
|
||||
silent helpgrep grail
|
||||
cwindow
|
||||
|
||||
@@ -1108,6 +1108,8 @@ def Test_assign_lambda()
|
||||
assert_equal(123, FuncRef_Func())
|
||||
var FuncRef_Any: any = () => 123
|
||||
assert_equal(123, FuncRef_Any())
|
||||
var FuncRef_Number: func(): number = () => 321
|
||||
assert_equal(321, FuncRef_Number())
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
@@ -1115,8 +1117,12 @@ def Test_assign_lambda()
|
||||
var Ref: func(number)
|
||||
Ref = (j) => !j
|
||||
END
|
||||
CheckDefFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(any): bool')
|
||||
CheckScriptFailure(['vim9script'] + lines, 'E1012: Type mismatch; expected func(number) but got func(any): any')
|
||||
CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(any): bool')
|
||||
|
||||
lines =<< trim END
|
||||
echo filter([1, 2, 3], (_, v: string) => v + 1)
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1051:')
|
||||
enddef
|
||||
|
||||
def Test_heredoc()
|
||||
|
||||
@@ -5,6 +5,16 @@ source vim9.vim
|
||||
source term_util.vim
|
||||
source view_util.vim
|
||||
|
||||
def Test_vim9cmd()
|
||||
var lines =<< trim END
|
||||
vim9cmd var x = 123
|
||||
let s:y = 'yes'
|
||||
vim9c assert_equal(123, x)
|
||||
vim9cm assert_equal('yes', y)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_edit_wildcards()
|
||||
var filename = 'Xtest'
|
||||
edit `=filename`
|
||||
@@ -313,6 +323,11 @@ def Test_for_linebreak()
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def MethodAfterLinebreak(arg: string)
|
||||
arg
|
||||
->setline(1)
|
||||
enddef
|
||||
|
||||
def Test_method_call_linebreak()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
@@ -351,6 +366,11 @@ def Test_method_call_linebreak()
|
||||
g:shortlist = [1, 2]
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
unlet g:shortlist
|
||||
|
||||
new
|
||||
MethodAfterLinebreak('foobar')
|
||||
assert_equal('foobar', getline(1))
|
||||
bwipe!
|
||||
enddef
|
||||
|
||||
def Test_method_call_whitespace()
|
||||
|
||||
@@ -31,18 +31,8 @@ def TestCompilingError()
|
||||
call writefile(lines, 'XTest_compile_error')
|
||||
var buf = RunVimInTerminal('-S XTest_compile_error',
|
||||
{rows: 10, wait_for_ruler: 0})
|
||||
var text = ''
|
||||
for loop in range(100)
|
||||
text = ''
|
||||
for i in range(1, 9)
|
||||
text ..= term_getline(buf, i)
|
||||
endfor
|
||||
if text =~ 'Variable not found: nothing'
|
||||
break
|
||||
endif
|
||||
sleep 20m
|
||||
endfor
|
||||
assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', text)
|
||||
call WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing',
|
||||
Term_getlines(buf, range(1, 9))))
|
||||
|
||||
# clean up
|
||||
call StopVimInTerminal(buf)
|
||||
|
||||
@@ -22,6 +22,17 @@ def Test_range_only()
|
||||
:3
|
||||
list
|
||||
assert_equal('three$', Screenline(&lines))
|
||||
|
||||
# missing command does not print the line
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
:1|
|
||||
assert_equal('three$', Screenline(&lines))
|
||||
:|
|
||||
assert_equal('three$', Screenline(&lines))
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
bwipe!
|
||||
|
||||
# won't generate anything
|
||||
@@ -724,6 +735,27 @@ def Test_try_catch_fails()
|
||||
CheckDefFailure(['throw xxx'], 'E1001:')
|
||||
enddef
|
||||
|
||||
def Try_catch_skipped()
|
||||
var l = []
|
||||
try
|
||||
finally
|
||||
endtry
|
||||
|
||||
if 1
|
||||
else
|
||||
try
|
||||
endtry
|
||||
endif
|
||||
enddef
|
||||
|
||||
" The skipped try/endtry was updating the wrong instruction.
|
||||
def Test_try_catch_skipped()
|
||||
var instr = execute('disassemble Try_catch_skipped')
|
||||
assert_match("NEWLIST size 0\n", instr)
|
||||
enddef
|
||||
|
||||
|
||||
|
||||
def Test_throw_vimscript()
|
||||
# only checks line continuation
|
||||
var lines =<< trim END
|
||||
@@ -755,7 +787,7 @@ def Test_throw_vimscript()
|
||||
enddef
|
||||
|
||||
def Test_error_in_nested_function()
|
||||
# an error in a nested :function aborts executin in the calling :def function
|
||||
# an error in a nested :function aborts executing in the calling :def function
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def Func()
|
||||
@@ -1230,6 +1262,27 @@ def Test_use_import_in_mapping()
|
||||
nunmap <F3>
|
||||
enddef
|
||||
|
||||
def Test_vim9script_mix()
|
||||
var lines =<< trim END
|
||||
if has(g:feature)
|
||||
" legacy script
|
||||
let g:legacy = 1
|
||||
finish
|
||||
endif
|
||||
vim9script
|
||||
g:legacy = 0
|
||||
END
|
||||
g:feature = 'eval'
|
||||
g:legacy = -1
|
||||
CheckScriptSuccess(lines)
|
||||
assert_equal(1, g:legacy)
|
||||
|
||||
g:feature = 'noteval'
|
||||
g:legacy = -1
|
||||
CheckScriptSuccess(lines)
|
||||
assert_equal(0, g:legacy)
|
||||
enddef
|
||||
|
||||
def Test_vim9script_fails()
|
||||
CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
|
||||
CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
|
||||
|
||||
@@ -765,6 +765,44 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2529,
|
||||
/**/
|
||||
2528,
|
||||
/**/
|
||||
2527,
|
||||
/**/
|
||||
2526,
|
||||
/**/
|
||||
2525,
|
||||
/**/
|
||||
2524,
|
||||
/**/
|
||||
2523,
|
||||
/**/
|
||||
2522,
|
||||
/**/
|
||||
2521,
|
||||
/**/
|
||||
2520,
|
||||
/**/
|
||||
2519,
|
||||
/**/
|
||||
2518,
|
||||
/**/
|
||||
2517,
|
||||
/**/
|
||||
2516,
|
||||
/**/
|
||||
2515,
|
||||
/**/
|
||||
2514,
|
||||
/**/
|
||||
2513,
|
||||
/**/
|
||||
2512,
|
||||
/**/
|
||||
2511,
|
||||
/**/
|
||||
2510,
|
||||
/**/
|
||||
|
||||
@@ -1796,6 +1796,12 @@ typedef struct timeval proftime_T;
|
||||
typedef int proftime_T; // dummy for function prototypes
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
# define PROFILING(ufunc) (do_profiling == PROF_YES && (ufunc)->uf_profiling)
|
||||
#else
|
||||
# define PROFILING(ufunc) FALSE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When compiling with 32 bit Perl time_t is 32 bits in the Perl code but 64
|
||||
* bits elsewhere. That causes memory corruption. Define time_T and use it
|
||||
|
||||
@@ -418,11 +418,9 @@ extern garray_T def_functions;
|
||||
#define LNUM_VARIABLE_RANGE_ABOVE -888
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
# define PROFILING(ufunc) (do_profiling == PROF_YES && (ufunc)->uf_profiling)
|
||||
# define INSTRUCTIONS(dfunc) \
|
||||
((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
|
||||
? (dfunc)->df_instr_prof : (dfunc)->df_instr)
|
||||
#else
|
||||
# define PROFILING(ufunc) FALSE
|
||||
# define INSTRUCTIONS(dfunc) ((dfunc)->df_instr)
|
||||
#endif
|
||||
|
||||
+25
-11
@@ -372,6 +372,19 @@ script_var_exists(char_u *name, size_t len, int vim9script, cctx_T *cctx)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "name" is a local variable, argument, script variable or
|
||||
* imported.
|
||||
*/
|
||||
static int
|
||||
variable_exists(char_u *name, size_t len, cctx_T *cctx)
|
||||
{
|
||||
return lookup_local(name, len, NULL, cctx) == OK
|
||||
|| arg_exists(name, len, NULL, NULL, NULL, cctx) == OK
|
||||
|| script_var_exists(name, len, FALSE, cctx) == OK
|
||||
|| find_imported(name, len, cctx) != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if "p[len]" is already defined, either in script "import_sid" or in
|
||||
* compilation context "cctx". "cctx" is NULL at the script level.
|
||||
@@ -6444,10 +6457,7 @@ may_compile_assignment(exarg_T *eap, char_u **line, cctx_T *cctx)
|
||||
|| *eap->cmd == '$'
|
||||
|| *eap->cmd == '@'
|
||||
|| ((len) > 2 && eap->cmd[1] == ':')
|
||||
|| lookup_local(eap->cmd, len, NULL, cctx) == OK
|
||||
|| arg_exists(eap->cmd, len, NULL, NULL, NULL, cctx) == OK
|
||||
|| script_var_exists(eap->cmd, len, FALSE, cctx) == OK
|
||||
|| find_imported(eap->cmd, len, cctx) != NULL)
|
||||
|| variable_exists(eap->cmd, len, cctx))
|
||||
{
|
||||
*line = compile_assignment(eap->cmd, eap, CMD_SIZE, cctx);
|
||||
if (*line == NULL || *line == eap->cmd)
|
||||
@@ -7719,17 +7729,21 @@ compile_endtry(char_u *arg, cctx_T *cctx)
|
||||
|
||||
compile_endblock(cctx);
|
||||
|
||||
if (try_isn->isn_arg.try.try_finally == 0)
|
||||
// No :finally encountered, use the try_finaly field to point to
|
||||
// ENDTRY, so that TRYCONT can jump there.
|
||||
try_isn->isn_arg.try.try_finally = cctx->ctx_instr.ga_len;
|
||||
if (cctx->ctx_skip != SKIP_YES)
|
||||
{
|
||||
if (try_isn->isn_arg.try.try_finally == 0)
|
||||
// No :finally encountered, use the try_finaly field to point to
|
||||
// ENDTRY, so that TRYCONT can jump there.
|
||||
try_isn->isn_arg.try.try_finally = instr->ga_len;
|
||||
|
||||
if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_ENDTRY) == NULL)
|
||||
return NULL;
|
||||
if (cctx->ctx_skip != SKIP_YES
|
||||
&& generate_instr(cctx, ISN_ENDTRY) == NULL)
|
||||
return NULL;
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling)
|
||||
generate_instr(cctx, ISN_PROF_START);
|
||||
#endif
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -8328,7 +8342,7 @@ compile_def_function(
|
||||
}
|
||||
}
|
||||
p = find_ex_command(&ea, NULL, starts_with_colon ? NULL
|
||||
: (int (*)(char_u *, size_t, void *, cctx_T *))lookup_local,
|
||||
: (int (*)(char_u *, size_t, cctx_T *))variable_exists,
|
||||
&cctx);
|
||||
|
||||
if (p == NULL)
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@ in_vim9script(void)
|
||||
// Do not go up the stack, a ":function" inside vim9script uses legacy
|
||||
// syntax. "sc_version" is also set when compiling a ":def" function in
|
||||
// legacy script.
|
||||
return current_sctx.sc_version == SCRIPT_VERSION_VIM9;
|
||||
return current_sctx.sc_version == SCRIPT_VERSION_VIM9
|
||||
|| (cmdmod.cmod_flags & CMOD_VIM9CMD);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user