Merge pull request #15312 from janlazo/vim-8.2.2639

vim-patch:8.1.{1818},8.2.{1464,2639,2814,2947,2976,2986,3114,3141,3160,3198}
This commit is contained in:
Jan Edmund Lazo 2021-08-09 08:28:36 -04:00 committed by GitHub
commit 9ef7003c38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 198 additions and 27 deletions

View File

@ -1038,7 +1038,12 @@ A jump table for the options with a short description can be found at |Q_op|.
continuation (positive). continuation (positive).
sbr Display the 'showbreak' value before applying the sbr Display the 'showbreak' value before applying the
additional indent. additional indent.
The default value for min is 20 and shift is 0. list:{n} Adds an additional indent for lines that match a
numbered or bulleted list (using the
'formatlistpat' setting).
list:-1 Uses the length of a match with 'formatlistpat'
for indentation.
The default value for min is 20, shift and list is 0.
*'browsedir'* *'bsdir'* *'browsedir'* *'bsdir'*
'browsedir' 'bsdir' string (default: "last") 'browsedir' 'bsdir' string (default: "last")

View File

@ -1395,6 +1395,7 @@ struct window_S {
int w_briopt_min; // minimum width for breakindent int w_briopt_min; // minimum width for breakindent
int w_briopt_shift; // additional shift for breakindent int w_briopt_shift; // additional shift for breakindent
bool w_briopt_sbr; // sbr in 'briopt' bool w_briopt_sbr; // sbr in 'briopt'
int w_briopt_list; // additional indent for lists
// transform a pointer to a "onebuf" option into a "allbuf" option // transform a pointer to a "onebuf" option into a "allbuf" option
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T)) #define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))

View File

@ -5514,6 +5514,9 @@ invalid_count:
return OK; return OK;
} }
static char e_complete_used_without_nargs[] = N_(
"E1208: -complete used without -nargs");
/* /*
* ":command ..." * ":command ..."
*/ */
@ -5565,10 +5568,10 @@ static void ex_command(exarg_T *eap)
uc_list(name, end - name); uc_list(name, end - name);
} else if (!ASCII_ISUPPER(*name)) { } else if (!ASCII_ISUPPER(*name)) {
EMSG(_("E183: User defined commands must start with an uppercase letter")); EMSG(_("E183: User defined commands must start with an uppercase letter"));
return;
} else if (name_len <= 4 && STRNCMP(name, "Next", name_len) == 0) { } else if (name_len <= 4 && STRNCMP(name, "Next", name_len) == 0) {
EMSG(_("E841: Reserved name, cannot be used for user defined command")); EMSG(_("E841: Reserved name, cannot be used for user defined command"));
return; } else if (compl > 0 && (argt & EX_EXTRA) == 0) {
EMSG(_(e_complete_used_without_nargs));
} else { } else {
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg, uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
addr_type_arg, eap->forceit); addr_type_arg, eap->forceit);

View File

@ -432,7 +432,7 @@ int get_number_indent(linenr_T lnum)
// Return appropriate space number for breakindent, taking influencing // Return appropriate space number for breakindent, taking influencing
// parameters into account. Window must be specified, since it is not // parameters into account. Window must be specified, since it is not
// necessarily always the current one. // necessarily always the current one.
int get_breakindent_win(win_T *wp, const char_u *line) int get_breakindent_win(win_T *wp, char_u *line)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
static int prev_indent = 0; // Cached indent value. static int prev_indent = 0; // Cached indent value.
@ -462,13 +462,33 @@ int get_breakindent_win(win_T *wp, const char_u *line)
} }
bri = prev_indent + wp->w_briopt_shift; bri = prev_indent + wp->w_briopt_shift;
// indent minus the length of the showbreak string
if (wp->w_briopt_sbr) {
bri -= vim_strsize(p_sbr);
}
// Add offset for number column, if 'n' is in 'cpoptions' // Add offset for number column, if 'n' is in 'cpoptions'
bri += win_col_off2(wp); bri += win_col_off2(wp);
// add additional indent for numbered lists
if (wp->w_briopt_list != 0) {
regmatch_T regmatch = {
.regprog = vim_regcomp(curbuf->b_p_flp,
RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT),
};
if (regmatch.regprog != NULL) {
if (vim_regexec(&regmatch, line, 0)) {
if (wp->w_briopt_list > 0) {
bri += wp->w_briopt_list;
} else {
bri = (int)(*regmatch.endp - *regmatch.startp);
}
}
vim_regfree(regmatch.regprog);
}
}
// indent minus the length of the showbreak string
if (wp->w_briopt_sbr) {
bri -= vim_strsize(get_showbreak_value(wp));
}
// never indent past left window margin // never indent past left window margin
if (bri < 0) { if (bri < 0) {
bri = 0; bri = 0;

View File

@ -7426,6 +7426,7 @@ static bool briopt_check(win_T *wp)
int bri_shift = 0; int bri_shift = 0;
int bri_min = 20; int bri_min = 20;
bool bri_sbr = false; bool bri_sbr = false;
int bri_list = 0;
char_u *p = wp->w_p_briopt; char_u *p = wp->w_p_briopt;
while (*p != NUL) while (*p != NUL)
@ -7445,6 +7446,9 @@ static bool briopt_check(win_T *wp)
{ {
p += 3; p += 3;
bri_sbr = true; bri_sbr = true;
} else if (STRNCMP(p, "list:", 5) == 0) {
p += 5;
bri_list = (int)getdigits(&p, false, 0);
} }
if (*p != ',' && *p != NUL) { if (*p != ',' && *p != NUL) {
return false; return false;
@ -7457,6 +7461,7 @@ static bool briopt_check(win_T *wp)
wp->w_briopt_shift = bri_shift; wp->w_briopt_shift = bri_shift;
wp->w_briopt_min = bri_min; wp->w_briopt_min = bri_min;
wp->w_briopt_sbr = bri_sbr; wp->w_briopt_sbr = bri_sbr;
wp->w_briopt_list = bri_list;
return true; return true;
} }
@ -7669,6 +7674,12 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
return ret; return ret;
} }
// Get the local or global value of 'showbreak'.
char_u *get_showbreak_value(win_T *win FUNC_ATTR_UNUSED)
{
return p_sbr;
}
/// Get window or buffer local options /// Get window or buffer local options
dict_T *get_winbuf_options(const int bufopt) dict_T *get_winbuf_options(const int bufopt)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_WARN_UNUSED_RESULT

View File

@ -16,6 +16,10 @@ func s:screen_lines(lnum, width) abort
return ScreenLines([a:lnum, a:lnum + 2], a:width) return ScreenLines([a:lnum, a:lnum + 2], a:width)
endfunc endfunc
func s:screen_lines2(lnums, lnume, width) abort
return ScreenLines([a:lnums, a:lnume], a:width)
endfunc
func! s:compare_lines(expect, actual) func! s:compare_lines(expect, actual)
call assert_equal(join(a:expect, "\n"), join(a:actual, "\n")) call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
endfunc endfunc
@ -745,4 +749,123 @@ func Test_breakindent20_cpo_n_nextpage()
call s:close_windows('set breakindent& briopt& cpo& number&') call s:close_windows('set breakindent& briopt& cpo& number&')
endfunc endfunc
func Test_breakindent20_list()
call s:test_windows('setl breakindent breakindentopt= linebreak')
" default:
call setline(1, [' 1. Congress shall make no law',
\ ' 2.) Congress shall make no law',
\ ' 3.] Congress shall make no law'])
norm! 1gg
redraw!
let lines = s:screen_lines2(1, 6, 20)
let expect = [
\ " 1. Congress ",
\ "shall make no law ",
\ " 2.) Congress ",
\ "shall make no law ",
\ " 3.] Congress ",
\ "shall make no law ",
\ ]
call s:compare_lines(expect, lines)
" set mininum indent
setl briopt=min:5
redraw!
let lines = s:screen_lines2(1, 6, 20)
let expect = [
\ " 1. Congress ",
\ " shall make no law ",
\ " 2.) Congress ",
\ " shall make no law ",
\ " 3.] Congress ",
\ " shall make no law ",
\ ]
call s:compare_lines(expect, lines)
" set additional handing indent
setl briopt+=list:4
redraw!
let expect = [
\ " 1. Congress ",
\ " shall make no ",
\ " law ",
\ " 2.) Congress ",
\ " shall make no ",
\ " law ",
\ " 3.] Congress ",
\ " shall make no ",
\ " law ",
\ ]
let lines = s:screen_lines2(1, 9, 20)
call s:compare_lines(expect, lines)
" reset linebreak option
" Note: it indents by one additional
" space, because of the leading space.
setl linebreak&vim list listchars=eol:$,space:_
redraw!
let expect = [
\ "__1.__Congress_shall",
\ " _make_no_law$ ",
\ "__2.)_Congress_shall",
\ " _make_no_law$ ",
\ "__3.]_Congress_shall",
\ " _make_no_law$ ",
\ ]
let lines = s:screen_lines2(1, 6, 20)
call s:compare_lines(expect, lines)
" check formatlistpat indent
setl briopt=min:5,list:-1
setl linebreak list&vim listchars&vim
let &l:flp = '^\s*\d\+\.\?[\]:)}\t ]\s*'
redraw!
let expect = [
\ " 1. Congress ",
\ " shall make no ",
\ " law ",
\ " 2.) Congress ",
\ " shall make no ",
\ " law ",
\ " 3.] Congress ",
\ " shall make no ",
\ " law ",
\ ]
let lines = s:screen_lines2(1, 9, 20)
call s:compare_lines(expect, lines)
" check formatlistpat indent with different list levels
let &l:flp = '^\s*\*\+\s\+'
redraw!
%delete _
call setline(1, ['* Congress shall make no law',
\ '*** Congress shall make no law',
\ '**** Congress shall make no law'])
norm! 1gg
let expect = [
\ "* Congress shall ",
\ " make no law ",
\ "*** Congress shall ",
\ " make no law ",
\ "**** Congress shall ",
\ " make no law ",
\ ]
let lines = s:screen_lines2(1, 6, 20)
call s:compare_lines(expect, lines)
" check formatlistpat indent with different list level
" showbreak and sbr
setl briopt=min:5,sbr,list:-1,shift:2
setl showbreak=>
redraw!
let expect = [
\ "* Congress shall ",
\ "> make no law ",
\ "*** Congress shall ",
\ "> make no law ",
\ "**** Congress shall ",
\ "> make no law ",
\ ]
let lines = s:screen_lines2(1, 6, 20)
call s:compare_lines(expect, lines)
call s:close_windows('set breakindent& briopt& linebreak& list& listchars& showbreak&')
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -238,6 +238,8 @@ func Test_CmdErrors()
call assert_fails('com! -complete=custom DoCmd :', 'E467:') call assert_fails('com! -complete=custom DoCmd :', 'E467:')
call assert_fails('com! -complete=customlist DoCmd :', 'E467:') call assert_fails('com! -complete=customlist DoCmd :', 'E467:')
call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:') call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:')
call assert_fails('com! -complete=file DoCmd :', 'E1208:')
call assert_fails('com! -nargs=0 -complete=file DoCmd :', 'E1208:')
call assert_fails('com! -nargs=x DoCmd :', 'E176:') call assert_fails('com! -nargs=x DoCmd :', 'E176:')
call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:') call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:')
call assert_fails('com! -count=x DoCmd :', 'E178:') call assert_fails('com! -count=x DoCmd :', 'E178:')
@ -306,27 +308,33 @@ func Test_CmdCompletion()
call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx') call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com DoC', @:) call assert_equal('"com DoC', @:)
com! -complete=behave DoCmd : com! -nargs=1 -complete=behave DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd mswin xterm', @:) call assert_equal('"DoCmd mswin xterm', @:)
" This does not work. Why? com! -nargs=* -complete=custom,CustomComplete DoCmd :
"call feedkeys(":DoCmd x\<C-A>\<C-B>\"\<CR>", 'tx')
"call assert_equal('"DoCmd xterm', @:)
com! -complete=custom,CustomComplete DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd January February Mars', @:) call assert_equal('"DoCmd January February Mars', @:)
com! -complete=customlist,CustomCompleteList DoCmd : com! -nargs=? -complete=customlist,CustomCompleteList DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd Monday Tuesday Wednesday', @:) call assert_equal('"DoCmd Monday Tuesday Wednesday', @:)
com! -complete=custom,CustomCompleteList DoCmd : com! -nargs=+ -complete=custom,CustomCompleteList DoCmd :
call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:') call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:')
com! -complete=customlist,CustomComp DoCmd : com! -nargs=+ -complete=customlist,CustomComp DoCmd :
call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:') call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:')
" custom completion without a function
com! -nargs=? -complete=custom, DoCmd
call assert_beeps("call feedkeys(':DoCmd \t', 'tx')")
" custom completion failure with the wrong function
com! -nargs=? -complete=custom,min DoCmd
call assert_fails("call feedkeys(':DoCmd \t', 'tx')", 'E118:')
delcom DoCmd
endfunc endfunc
func CallExecute(A, L, P) func CallExecute(A, L, P)
@ -459,21 +467,21 @@ func Test_command_list()
\ execute('command DoCmd')) \ execute('command DoCmd'))
" Test with various -complete= argument values (non-exhaustive list) " Test with various -complete= argument values (non-exhaustive list)
command! -complete=arglist DoCmd : command! -nargs=1 -complete=arglist DoCmd :
call assert_equal("\n Name Args Address Complete Definition" call assert_equal("\n Name Args Address Complete Definition"
\ .. "\n DoCmd 0 arglist :", \ .. "\n DoCmd 1 arglist :",
\ execute('command DoCmd')) \ execute('command DoCmd'))
command! -complete=augroup DoCmd : command! -nargs=* -complete=augroup DoCmd :
call assert_equal("\n Name Args Address Complete Definition" call assert_equal("\n Name Args Address Complete Definition"
\ .. "\n DoCmd 0 augroup :", \ .. "\n DoCmd * augroup :",
\ execute('command DoCmd')) \ execute('command DoCmd'))
command! -complete=custom,CustomComplete DoCmd : command! -nargs=? -complete=custom,CustomComplete DoCmd :
call assert_equal("\n Name Args Address Complete Definition" call assert_equal("\n Name Args Address Complete Definition"
\ .. "\n DoCmd 0 custom :", \ .. "\n DoCmd ? custom :",
\ execute('command DoCmd')) \ execute('command DoCmd'))
command! -complete=customlist,CustomComplete DoCmd : command! -nargs=+ -complete=customlist,CustomComplete DoCmd :
call assert_equal("\n Name Args Address Complete Definition" call assert_equal("\n Name Args Address Complete Definition"
\ .. "\n DoCmd 0 customlist :", \ .. "\n DoCmd + customlist :",
\ execute('command DoCmd')) \ execute('command DoCmd'))
" Test with various -narg= argument values. " Test with various -narg= argument values.

View File

@ -53,7 +53,7 @@ describe('nvim_get_commands', function()
end) end)
it('gets various command attributes', function() it('gets various command attributes', function()
local cmd0 = { addr='arguments', bang=false, bar=false, complete='dir', complete_arg=NIL, count='10', definition='pwd <args>', name='TestCmd', nargs='0', range='10', register=false, script_id=0, } local cmd0 = { addr='arguments', bang=false, bar=false, complete='dir', complete_arg=NIL, count='10', definition='pwd <args>', name='TestCmd', nargs='1', range='10', register=false, script_id=0, }
local cmd1 = { addr=NIL, bang=false, bar=false, complete='custom', complete_arg='ListUsers', count=NIL, definition='!finger <args>', name='Finger', nargs='+', range=NIL, register=false, script_id=1, } local cmd1 = { addr=NIL, bang=false, bar=false, complete='custom', complete_arg='ListUsers', count=NIL, definition='!finger <args>', name='Finger', nargs='+', range=NIL, register=false, script_id=1, }
local cmd2 = { addr=NIL, bang=true, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R2_foo(<q-args>)', name='Cmd2', nargs='*', range=NIL, register=false, script_id=2, } local cmd2 = { addr=NIL, bang=true, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R2_foo(<q-args>)', name='Cmd2', nargs='*', range=NIL, register=false, script_id=2, }
local cmd3 = { addr=NIL, bang=false, bar=true, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R3_ohyeah()', name='Cmd3', nargs='0', range=NIL, register=false, script_id=3, } local cmd3 = { addr=NIL, bang=false, bar=true, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R3_ohyeah()', name='Cmd3', nargs='0', range=NIL, register=false, script_id=3, }
@ -62,7 +62,7 @@ describe('nvim_get_commands', function()
command -complete=custom,ListUsers -nargs=+ Finger !finger <args> command -complete=custom,ListUsers -nargs=+ Finger !finger <args>
]]) ]])
eq({Finger=cmd1}, meths.get_commands({builtin=false})) eq({Finger=cmd1}, meths.get_commands({builtin=false}))
command('command -complete=dir -addr=arguments -count=10 TestCmd pwd <args>') command('command -nargs=1 -complete=dir -addr=arguments -count=10 TestCmd pwd <args>')
eq({Finger=cmd1, TestCmd=cmd0}, meths.get_commands({builtin=false})) eq({Finger=cmd1, TestCmd=cmd0}, meths.get_commands({builtin=false}))
source([[ source([[