0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 8.2.4617: no completion for :scriptnames

Problem:    No completion for :scriptnames.
Solution:   Implement :scriptnames completion. (Yegappan Lakshmanan,
            closes #10005)
This commit is contained in:
Yegappan Lakshmanan 2022-03-24 11:22:13 +00:00 committed by Bram Moolenaar
parent 98b7fe725e
commit 454ce6737c
9 changed files with 139 additions and 20 deletions

View File

@ -3256,6 +3256,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
messages |:messages| suboptions messages |:messages| suboptions
option options option options
packadd optional package |pack-add| names packadd optional package |pack-add| names
scriptnames sourced script names |:scriptnames|
shellcmd Shell command shellcmd Shell command
sign |:sign| suboptions sign |:sign| suboptions
syntax syntax file names |'syntax'| syntax syntax file names |'syntax'|
@ -3275,7 +3276,10 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
If the 'wildoptions' option contains 'fuzzy', then fuzzy If the 'wildoptions' option contains 'fuzzy', then fuzzy
matching is used to get the completion matches. Otherwise matching is used to get the completion matches. Otherwise
regular expression matching is used. 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 If {type} is "cmdline", then the |cmdline-completion| result is
returned. For example, to complete the possible values after returned. For example, to complete the possible values after

View File

@ -1709,6 +1709,24 @@ set_context_in_breakadd_cmd(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
return NULL; 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 #endif
/* /*
@ -2072,6 +2090,9 @@ set_context_by_cmdname(
case CMD_profdel: case CMD_profdel:
case CMD_breakdel: case CMD_breakdel:
return set_context_in_breakadd_cmd(xp, arg, cmdidx); return set_context_in_breakadd_cmd(xp, arg, cmdidx);
case CMD_scriptnames:
return set_context_in_scriptnames_cmd(xp, arg);
#endif #endif
default: default:
@ -2495,6 +2516,23 @@ get_breakadd_arg(expand_T *xp UNUSED, int idx)
} }
return NULL; 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 #endif
/* /*
@ -2584,6 +2622,7 @@ ExpandOther(
{EXPAND_ARGLIST, get_arglist_name, TRUE, FALSE}, {EXPAND_ARGLIST, get_arglist_name, TRUE, FALSE},
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
{EXPAND_BREAKPOINT, get_breakadd_arg, TRUE, TRUE}, {EXPAND_BREAKPOINT, get_breakadd_arg, TRUE, TRUE},
{EXPAND_SCRIPTNAMES, get_scriptnames_arg, TRUE, FALSE},
#endif #endif
}; };
int i; int i;
@ -2791,6 +2830,8 @@ ExpandGeneric(
int score = 0; int score = 0;
int fuzzy; int fuzzy;
int match; int match;
int sort_matches = FALSE;
int funcsort = FALSE;
fuzzy = cmdline_fuzzy_complete(pat); fuzzy = cmdline_fuzzy_complete(pat);
*matches = NULL; *matches = NULL;
@ -2878,14 +2919,25 @@ ExpandGeneric(
if (ga.ga_len == 0) if (ga.ga_len == 0)
return OK; 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 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 if (funcsort)
|| xp->xp_context == EXPAND_FUNCTIONS
|| xp->xp_context == EXPAND_USER_FUNC
|| xp->xp_context == EXPAND_DISASSEMBLE)
// <SNR> functions should be sorted to the end. // <SNR> functions should be sorted to the end.
qsort((void *)ga.ga_data, (size_t)ga.ga_len, sizeof(char_u *), qsort((void *)ga.ga_data, (size_t)ga.ga_len, sizeof(char_u *),
sort_func_compare); sort_func_compare);
@ -2900,15 +2952,6 @@ ExpandGeneric(
} }
else 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, if (fuzzymatches_to_strmatches(ga.ga_data, matches, ga.ga_len,
funcsort) == FAIL) funcsort) == FAIL)
return FAIL; return FAIL;

View File

@ -1356,7 +1356,7 @@ EXCMD(CMD_sbrewind, "sbrewind", ex_brewind,
EX_CMDARG|EX_TRLBAR, EX_CMDARG|EX_TRLBAR,
ADDR_NONE), ADDR_NONE),
EXCMD(CMD_scriptnames, "scriptnames", ex_scriptnames, 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), ADDR_OTHER),
EXCMD(CMD_scriptencoding, "scriptencoding", ex_scriptencoding, EXCMD(CMD_scriptencoding, "scriptencoding", ex_scriptencoding,
EX_WORD1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, EX_WORD1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,

View File

@ -1769,14 +1769,20 @@ ex_scriptnames(exarg_T *eap)
{ {
int i; int i;
if (eap->addr_count > 0) if (eap->addr_count > 0 || *eap->arg != NUL)
{ {
// :script {scriptId}: edit the script // :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)); emsg(_(e_invalid_argument));
else 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); do_exedit(eap, NULL);
} }
return; return;

View File

@ -3257,4 +3257,31 @@ func Test_cmdline_complete_breakdel()
call assert_equal("\"breakdel here ", @:) call assert_equal("\"breakdel here ", @:)
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -6202,4 +6202,39 @@ func Test_getqflist_wiped_out_buffer()
%bw! %bw!
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -93,6 +93,7 @@ static struct
{EXPAND_USER_VARS, "var"}, {EXPAND_USER_VARS, "var"},
#if defined(FEAT_EVAL) #if defined(FEAT_EVAL)
{EXPAND_BREAKPOINT, "breakpoint"}, {EXPAND_BREAKPOINT, "breakpoint"},
{EXPAND_SCRIPTNAMES, "scriptnames"},
#endif #endif
{0, NULL} {0, NULL}
}; };

View File

@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4617,
/**/ /**/
4616, 4616,
/**/ /**/

View File

@ -802,6 +802,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define EXPAND_DIFF_BUFFERS 49 #define EXPAND_DIFF_BUFFERS 49
#define EXPAND_DISASSEMBLE 50 #define EXPAND_DISASSEMBLE 50
#define EXPAND_BREAKPOINT 51 #define EXPAND_BREAKPOINT 51
#define EXPAND_SCRIPTNAMES 52
// Values for exmode_active (0 is no exmode) // Values for exmode_active (0 is no exmode)
#define EXMODE_NORMAL 1 #define EXMODE_NORMAL 1