patch 9.1.0770: current command line completion is a bit limited

Commit: 
https://github.com/vim/vim/commit/0407d621bbad020b840ffbbbd25ba023bbc05edd
Author: Ruslan Russkikh <dvru...@yandex.ru>
Date:   Tue Oct 8 22:21:05 2024 +0200

    patch 9.1.0770: current command line completion is a bit limited
    
    Problem:  current command completion is a bit limited
    Solution: Add the shellcmdline completion type and getmdcomplpat()
              function (Ruslan Russkikh).
    
    closes: #15823
    
    Signed-off-by: Ruslan Russkikh <dvru...@yandex.ru>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index fe0b9aa33..880dfcd78 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt*  For Vim version 9.1.  Last change: 2024 Sep 23
+*builtin.txt*  For Vim version 9.1.  Last change: 2024 Oct 08
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -230,6 +230,8 @@ getcharmod()                        Number  modifiers for 
the last typed character
 getcharpos({expr})             List    position of cursor, mark, etc.
 getcharsearch()                        Dict    last character search
 getcharstr([{expr}])           String  get one character from the user
+getcmdcomplpat()               String  return the completion pattern of the
+                                       current command-line completion
 getcmdcompltype()              String  return the type of the current
                                        command-line completion
 getcmdline()                   String  return the current command-line input
@@ -3973,6 +3975,16 @@ getcharstr([{expr}])                                     
*getcharstr()*
 
                Return type: |String|
 
+getcmdcomplpat()                                       *getcmdcomplpat()*
+               Return completion pattern of the current command-line.
+               Only works when the command line is being edited, thus
+               requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
+               Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
+               |getcmdprompt()|, |getcmdcompltype()| and |setcmdline()|.
+               Returns an empty string when completion is not defined.
+
+               Return type: |String|
+
 
 getcmdcompltype()                                      *getcmdcompltype()*
                Return the type of the current command-line completion.
@@ -3980,7 +3992,7 @@ getcmdcompltype()                                 
*getcmdcompltype()*
                requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
                See |:command-completion| for the return string.
                Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
-               |getcmdprompt()| and |setcmdline()|.
+               |getcmdprompt()|, |getcmdcomplpat()| and |setcmdline()|.
                Returns an empty string when completion is not defined.
 
                Return type: |String|
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 2773140c5..899b24bac 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1,4 +1,4 @@
-*map.txt*       For Vim version 9.1.  Last change: 2024 Oct 07
+*map.txt*       For Vim version 9.1.  Last change: 2024 Oct 08
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1657,6 +1657,8 @@ completion can be enabled:
        -complete=runtime       file and directory names in |'runtimepath'|
        -complete=scriptnames   sourced script names
        -complete=shellcmd      Shell command
+       -complete=shellcmdline  First is a shell command and subsequent ones
+                               are filenames. The same behavior as |:!cmd|
        -complete=sign          |:sign| suboptions
        -complete=syntax        syntax file names |'syntax'|
        -complete=syntime       |:syntime| suboptions
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 42c7c649e..246ea96ce 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -7827,6 +7827,7 @@ getcharmod()      builtin.txt     /*getcharmod()*
 getcharpos()   builtin.txt     /*getcharpos()*
 getcharsearch()        builtin.txt     /*getcharsearch()*
 getcharstr()   builtin.txt     /*getcharstr()*
+getcmdcomplpat()       builtin.txt     /*getcmdcomplpat()*
 getcmdcompltype()      builtin.txt     /*getcmdcompltype()*
 getcmdline()   builtin.txt     /*getcmdline()*
 getcmdpos()    builtin.txt     /*getcmdpos()*
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 123dcbb68..af67429ec 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1068,6 +1068,8 @@ Buffers, windows and the argument list:
        swapname()              get the swap file path of a buffer
 
 Command line:                                  *command-line-functions*
+       getcmdcomplpat()        get completion pattern of the current command
+                               line
        getcmdcompltype()       get the type of the current command line
                                completion
        getcmdline()            get the current command line input
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 56bb7e21d..a9434335c 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt*  For Vim version 9.1.  Last change: 2024 Oct 05
+*version9.txt*  For Vim version 9.1.  Last change: 2024 Oct 08
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41589,6 +41589,8 @@ Changed~
 - allow to complete directories from 'cdpath' for |:cd| and similar commands,
   add the "cd_in_path" completion type for e.g. |:command-complete| and
   |getcompletion()|
+- allow to complete shell commands and files using the new shellcmdline
+  completion type using |:command-complete| and |getcmdcomplpat()|
 - add 'cpoptions' flag "z" |cpo-z|, to disable some (traditional) vi
   behaviour/inconsistency (see |d-special| and |cw|).
 - allow to specify additional attributes in the completion menu (allows to
@@ -41608,6 +41610,7 @@ Functions: ~
 |diff()|               diff two Lists of strings
 |filecopy()|           copy a file {from} to {to}
 |foreach()|            apply function to List items
+|getcmdcomplpat()|     Shell command line completion
 |getcmdprompt()|       get prompt for input()/confirm()
 |getregion()|          get a region of text from a buffer
 |getregionpos()|       get a list of positions for a region
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index 2598cae56..28fdda521 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -2,7 +2,7 @@
 " Language:       Vim script
 " Maintainer:     Hirohito Higashi <h.east.727 ATMARK gmail.com>
 "         Doug Kearns <dougkea...@gmail.com>
-" Last Change:    2024 Oct 05
+" Last Change:    2024 Oct 08
 " Former Maintainer: Charles E. Campbell
 
 " DO NOT CHANGE DIRECTLY.
@@ -103,11 +103,11 @@ syn case match
 " GEN_SYN_VIM: vimFuncName, START_STR='syn keyword vimFuncName contained', 
END_STR=''
 syn keyword vimFuncName contained abs acos add and append appendbufline argc 
argidx arglistid argv asin assert_beeps assert_equal assert_equalfile 
assert_exception assert_fails assert_false assert_inrange assert_match 
assert_nobeep assert_notequal assert_notmatch assert_report assert_true atan 
atan2 autocmd_add autocmd_delete autocmd_get balloon_gettext balloon_show 
balloon_split bindtextdomain blob2list browse browsedir bufadd bufexists 
buflisted bufload bufloaded bufname bufnr bufwinid bufwinnr byte2line byteidx 
byteidxcomp call ceil ch_canread ch_close ch_close_in ch_evalexpr ch_evalraw 
ch_getbufnr ch_getjob ch_info ch_log ch_logfile ch_open ch_read ch_readblob 
ch_readraw ch_sendexpr ch_sendraw ch_setoptions ch_status changenr char2nr 
charclass charcol charidx
 syn keyword vimFuncName contained chdir cindent clearmatches col complete 
complete_add complete_check complete_info confirm copy cos cosh count 
cscope_connection cursor debugbreak deepcopy delete deletebufline did_filetype 
diff diff_filler diff_hlID digraph_get digraph_getlist digraph_set 
digraph_setlist echoraw empty environ err_teapot escape eval eventhandler 
executable execute exepath exists exists_compiled exp expand expandcmd extend 
extendnew feedkeys filecopy filereadable filewritable filter finddir findfile 
flatten flattennew float2nr floor fmod fnameescape fnamemodify foldclosed 
foldclosedend foldlevel foldtext foldtextresult foreach foreground fullcommand 
funcref function garbagecollect get getbufinfo getbufline getbufoneline 
getbufvar getcellwidths getchangelist
-syn keyword vimFuncName contained getchar getcharmod getcharpos getcharsearch 
getcharstr getcmdcompltype getcmdline getcmdpos getcmdprompt getcmdscreenpos 
getcmdtype getcmdwintype getcompletion getcurpos getcursorcharpos getcwd getenv 
getfontname getfperm getfsize getftime getftype getimstatus getjumplist getline 
getloclist getmarklist getmatches getmousepos getmouseshape getpid getpos 
getqflist getreg getreginfo getregion getregionpos getregtype getscriptinfo 
gettabinfo gettabvar gettabwinvar gettagstack gettext getwininfo getwinpos 
getwinposx getwinposy getwinvar glob glob2regpat globpath has has_key 
haslocaldir hasmapto histadd histdel histget histnr hlID hlexists hlget hlset 
hostname iconv id indent index indexof input inputdialog inputlist inputrestore 
inputsave
-syn keyword vimFuncName contained inputsecret insert instanceof interrupt 
invert isabsolutepath isdirectory isinf islocked isnan items job_getchannel 
job_info job_setoptions job_start job_status job_stop join js_decode js_encode 
json_decode json_encode keys keytrans len libcall libcallnr line line2byte 
lispindent list2blob list2str listener_add listener_flush listener_remove 
localtime log log10 luaeval map maparg mapcheck maplist mapnew mapset match 
matchadd matchaddpos matcharg matchbufline matchdelete matchend matchfuzzy 
matchfuzzypos matchlist matchstr matchstrlist matchstrpos max menu_info min 
mkdir mode mzeval nextnonblank nr2char or pathshorten perleval popup_atcursor 
popup_beval popup_clear popup_close popup_create popup_dialog popup_filter_menu 
popup_filter_yesno
-syn keyword vimFuncName contained popup_findecho popup_findinfo 
popup_findpreview popup_getoptions popup_getpos popup_hide popup_list 
popup_locate popup_menu popup_move popup_notification popup_setbuf 
popup_setoptions popup_settext popup_show pow prevnonblank printf 
prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt 
prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add 
prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos 
pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex 
readfile reduce reg_executing reg_recording reltime reltimefloat reltimestr 
remote_expr remote_foreground remote_peek remote_read remote_send 
remote_startserver remove rename repeat resolve reverse round
-syn keyword vimFuncName contained rubyeval screenattr screenchar screenchars 
screencol screenpos screenrow screenstring search searchcount searchdecl 
searchpair searchpairpos searchpos server2client serverlist setbufline 
setbufvar setcellwidths setcharpos setcharsearch setcmdline setcmdpos 
setcursorcharpos setenv setfperm setline setloclist setmatches setpos setqflist 
setreg settabvar settabwinvar settagstack setwinvar sha256 shellescape 
shiftwidth sign_define sign_getdefined sign_getplaced sign_jump sign_place 
sign_placelist sign_undefine sign_unplace sign_unplacelist simplify sin sinh 
slice sort sound_clear sound_playevent sound_playfile sound_stop soundfold 
spellbadword spellsuggest split sqrt srand state str2float str2list str2nr 
strcharlen strcharpart strchars
-syn keyword vimFuncName contained strdisplaywidth strftime strgetchar stridx 
string strlen strpart strptime strridx strtrans strutf16len strwidth submatch 
substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans 
synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr 
tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite 
term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob 
term_getline term_getscrolled term_getsize term_getstatus term_gettitle 
term_gettty term_list term_scrape term_sendkeys term_setansicolors term_setapi 
term_setkill term_setrestore term_setsize term_start term_wait terminalprops 
test_alloc_fail test_autochdir test_feedinput test_garbagecollect_now 
test_garbagecollect_soon
+syn keyword vimFuncName contained getchar getcharmod getcharpos getcharsearch 
getcharstr getcmdcomplpat getcmdcompltype getcmdline getcmdpos getcmdprompt 
getcmdscreenpos getcmdtype getcmdwintype getcompletion getcurpos 
getcursorcharpos getcwd getenv getfontname getfperm getfsize getftime getftype 
getimstatus getjumplist getline getloclist getmarklist getmatches getmousepos 
getmouseshape getpid getpos getqflist getreg getreginfo getregion getregionpos 
getregtype getscriptinfo gettabinfo gettabvar gettabwinvar gettagstack gettext 
getwininfo getwinpos getwinposx getwinposy getwinvar glob glob2regpat globpath 
has has_key haslocaldir hasmapto histadd histdel histget histnr hlID hlexists 
hlget hlset hostname iconv id indent index indexof input inputdialog inputlist
+syn keyword vimFuncName contained inputrestore inputsave inputsecret insert 
instanceof interrupt invert isabsolutepath isdirectory isinf islocked isnan 
items job_getchannel job_info job_setoptions job_start job_status job_stop join 
js_decode js_encode json_decode json_encode keys keytrans len libcall libcallnr 
line line2byte lispindent list2blob list2str listener_add listener_flush 
listener_remove localtime log log10 luaeval map maparg mapcheck maplist mapnew 
mapset match matchadd matchaddpos matcharg matchbufline matchdelete matchend 
matchfuzzy matchfuzzypos matchlist matchstr matchstrlist matchstrpos max 
menu_info min mkdir mode mzeval nextnonblank nr2char or pathshorten perleval 
popup_atcursor popup_beval popup_clear popup_close popup_create popup_dialog 
popup_filter_menu
+syn keyword vimFuncName contained popup_filter_yesno popup_findecho 
popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide 
popup_list popup_locate popup_menu popup_move popup_notification popup_setbuf 
popup_setoptions popup_settext popup_show pow prevnonblank printf 
prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt 
prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add 
prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos 
pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex 
readfile reduce reg_executing reg_recording reltime reltimefloat reltimestr 
remote_expr remote_foreground remote_peek remote_read remote_send 
remote_startserver remove rename repeat resolve
+syn keyword vimFuncName contained reverse round rubyeval screenattr screenchar 
screenchars screencol screenpos screenrow screenstring search searchcount 
searchdecl searchpair searchpairpos searchpos server2client serverlist 
setbufline setbufvar setcellwidths setcharpos setcharsearch setcmdline 
setcmdpos setcursorcharpos setenv setfperm setline setloclist setmatches setpos 
setqflist setreg settabvar settabwinvar settagstack setwinvar sha256 
shellescape shiftwidth sign_define sign_getdefined sign_getplaced sign_jump 
sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist simplify 
sin sinh slice sort sound_clear sound_playevent sound_playfile sound_stop 
soundfold spellbadword spellsuggest split sqrt srand state str2float str2list 
str2nr strcharlen strcharpart
+syn keyword vimFuncName contained strchars strdisplaywidth strftime strgetchar 
stridx string strlen strpart strptime strridx strtrans strutf16len strwidth 
submatch substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans 
synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr 
tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite 
term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob 
term_getline term_getscrolled term_getsize term_getstatus term_gettitle 
term_gettty term_list term_scrape term_sendkeys term_setansicolors term_setapi 
term_setkill term_setrestore term_setsize term_start term_wait terminalprops 
test_alloc_fail test_autochdir test_feedinput test_garbagecollect_now 
test_garbagecollect_soon
 syn keyword vimFuncName contained test_getvalue test_gui_event 
test_ignore_error test_mswin_event test_null_blob test_null_channel 
test_null_dict test_null_function test_null_job test_null_list 
test_null_partial test_null_string test_option_not_set test_override 
test_refcount test_setmouse test_settime test_srand_seed test_unknown test_void 
timer_info timer_pause timer_start timer_stop timer_stopall tolower toupper tr 
trim trunc type typename undofile undotree uniq utf16idx values virtcol 
virtcol2col visualmode wildmenumode win_execute win_findbuf win_getid 
win_gettype win_gotoid win_id2tabwin win_id2win win_move_separator 
win_move_statusline win_screenpos win_splitmove winbufnr wincol windowsversion 
winheight winlayout winline winnr winrestcmd winrestview winsaveview
 syn keyword vimFuncName contained winwidth wordcount writefile xor
 
@@ -542,7 +542,7 @@ endif
 syn case ignore
 syn keyword    vimUserCmdAttrKey   contained   a[ddr] ban[g] bar bu[ffer] 
com[plete] cou[nt] k[eepscript] n[args] ra[nge] re[gister]
 " GEN_SYN_VIM: vimUserCmdAttrCmplt, START_STR='syn keyword vimUserCmdAttrCmplt 
contained', END_STR=''
-syn keyword vimUserCmdAttrCmplt contained arglist augroup behave breakpoint 
buffer color command compiler cscope diff_buffer dir dir_in_path environment 
event expression file file_in_path filetype function help highlight history 
keymap locale mapclear mapping menu messages option packadd runtime scriptnames 
shellcmd sign syntax syntime tag tag_listfiles user var
+syn keyword vimUserCmdAttrCmplt contained arglist augroup behave breakpoint 
buffer color command compiler cscope diff_buffer dir dir_in_path environment 
event expression file file_in_path filetype function help highlight history 
keymap locale mapclear mapping menu messages option packadd runtime scriptnames 
shellcmd shellcmdline sign syntax syntime tag tag_listfiles user var
 syn keyword    vimUserCmdAttrCmplt     contained       custom customlist 
nextgroup=vimUserCmdAttrCmpltFunc,vimUserCmdError
 syn match      vimUserCmdAttrCmpltFunc contained       
",\%([sS]:\|<[sS][iI][dD]>\)\=\%(\h\w*\%([.#]\h\w*\)\+\|\h\w*\)"hs=s+1 
nextgroup=vimUserCmdError
 " GEN_SYN_VIM: vimUserCmdAttrAddr, START_STR='syn keyword vimUserCmdAttrAddr 
contained', END_STR=''
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index c1ed03b78..c7c42abff 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -59,6 +59,7 @@ cmdline_fuzzy_completion_supported(expand_T *xp)
            && xp->xp_context != EXPAND_PACKADD
            && xp->xp_context != EXPAND_RUNTIME
            && xp->xp_context != EXPAND_SHELLCMD
+           && xp->xp_context != EXPAND_SHELLCMDLINE
            && xp->xp_context != EXPAND_TAGS
            && xp->xp_context != EXPAND_TAGS_LISTFILES
            && xp->xp_context != EXPAND_USER_LIST);
@@ -1754,7 +1755,7 @@ set_context_for_wildcard_arg(
     xp->xp_context = EXPAND_FILES;
 
     // For a shell command more chars need to be escaped.
-    if (usefilter || eap->cmdidx == CMD_bang || eap->cmdidx == CMD_terminal)
+    if (usefilter || eap->cmdidx == CMD_bang || eap->cmdidx == CMD_terminal || 
*complp == EXPAND_SHELLCMDLINE)
     {
 #ifndef BACKSLASH_IN_FILENAME
        xp->xp_shell = TRUE;
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 67104eaf2..d902045e8 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -2091,6 +2091,8 @@ static funcentry_T global_functions[] =
                        ret_dict_any,       f_getcharsearch},
     {"getcharstr",     0, 1, 0,            arg1_bool,
                        ret_string,         f_getcharstr},
+    {"getcmdcomplpat", 0, 0, 0,            NULL,
+                       ret_string,         f_getcmdcomplpat},
     {"getcmdcompltype",        0, 0, 0,            NULL,
                        ret_string,         f_getcmdcompltype},
     {"getcmdline",     0, 0, 0,            NULL,
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 980faf856..b7804d111 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4204,6 +4204,40 @@ get_cmdline_str(void)
     return vim_strnsave(p->cmdbuff, p->cmdlen);
 }
 
+/*
+ * Get the current command-line completion pattern.
+ */
+    static char_u *
+get_cmdline_completion_pattern(void)
+{
+    cmdline_info_T *p;
+    int                xp_context;
+
+    if (cmdline_star > 0)
+       return NULL;
+
+    p = get_ccline_ptr();
+    if (p == NULL || p->xpc == NULL)
+       return NULL;
+
+    xp_context = p->xpc->xp_context;
+    if (xp_context == EXPAND_NOTHING)
+    {
+       set_expand_context(p->xpc);
+       xp_context = p->xpc->xp_context;
+       p->xpc->xp_context = EXPAND_NOTHING;
+    }
+    if (xp_context == EXPAND_UNSUCCESSFUL)
+       return NULL;
+
+    char_u *compl_pat = p->xpc->xp_pattern;
+
+    if (compl_pat == NULL)
+       return NULL;
+
+    return vim_strsave(compl_pat);
+}
+
 /*
  * Get the current command-line completion type.
  */
@@ -4247,6 +4281,16 @@ get_cmdline_completion(void)
     return vim_strsave(cmd_compl);
 }
 
+/*
+ * "getcmdcomplpat()" function
+ */
+    void
+f_getcmdcomplpat(typval_T *argvars UNUSED, typval_T *rettv)
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = get_cmdline_completion_pattern();
+}
+
 /*
  * "getcmdcompltype()" function
  */
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index 1ab3b1cca..cc8723ad7 100644
--- a/src/proto/ex_getln.pro
+++ b/src/proto/ex_getln.pro
@@ -30,6 +30,7 @@ char_u *vim_strsave_fnameescape(char_u *fname, int what);
 void escape_fname(char_u **pp);
 void tilde_replace(char_u *orig_pat, int num_files, char_u **files);
 cmdline_info_T *get_cmdline_info(void);
+void f_getcmdcomplpat(typval_T *argvars, typval_T *rettv);
 void f_getcmdcompltype(typval_T *argvars, typval_T *rettv);
 void f_getcmdline(typval_T *argvars, typval_T *rettv);
 void f_getcmdpos(typval_T *argvars, typval_T *rettv);
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 790efaadd..418dafadc 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -1078,6 +1078,16 @@ func Test_cmdline_complete_user_names()
   endif
 endfunc
 
+func Test_cmdline_complete_shellcmdline()
+  CheckExecutable whoami
+  command -nargs=1 -complete=shellcmdline MyCmd
+
+  call feedkeys(":MyCmd whoam\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match('^".*\<whoami\>', @:)
+
+  delcommand MyCmd
+endfunc
+
 func Test_cmdline_complete_bang()
   CheckExecutable whoami
   call feedkeys(":!whoam\<C-A>\<C-B>\"\<CR>", 'tx')
@@ -3631,6 +3641,52 @@ func Test_cmdline_complete_substitute_short()
   endfor
 endfunc
 
+" Test for shellcmdline command argument completion
+func Test_cmdline_complete_shellcmdline_argument()
+  command -nargs=+ -complete=shellcmdline MyCmd
+
+  set wildoptions=fuzzy
+
+  call feedkeys(":MyCmd vim test_cmdline.\<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim test_cmdline.vim', @:)
+
+  call feedkeys(":MyCmd vim nonexistentfile\<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim nonexistentfile', @:)
+
+  let compl1 = getcompletion('', 'file')[0]
+  let compl2 = getcompletion('', 'file')[1]
+  call feedkeys(":MyCmd vim \<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim ' .. compl1, @:)
+
+  call feedkeys(":MyCmd vim \<Tab> \<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim ' .. compl1 .. ' ' .. compl1, @:)
+
+  let compl = getcompletion('', 'file')[1]
+  call feedkeys(":MyCmd vim \<Tab> \<Tab>\<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim ' .. compl1 .. ' ' .. compl2, @:)
+
+  set wildoptions&
+  call feedkeys(":MyCmd vim test_cmdline.\<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim test_cmdline.vim', @:)
+
+  call feedkeys(":MyCmd vim nonexistentfile\<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim nonexistentfile', @:)
+
+  let compl1 = getcompletion('', 'file')[0]
+  let compl2 = getcompletion('', 'file')[1]
+  call feedkeys(":MyCmd vim \<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim ' .. compl1, @:)
+
+  call feedkeys(":MyCmd vim \<Tab> \<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim ' .. compl1 .. ' ' .. compl1, @:)
+
+  let compl = getcompletion('', 'file')[1]
+  call feedkeys(":MyCmd vim \<Tab> \<Tab>\<Tab>\<C-B>\"\<CR>", 'xt')
+  call assert_equal('"MyCmd vim ' .. compl1 .. ' ' .. compl2, @:)
+
+  delcommand MyCmd
+endfunc
+
 " Test for :! shell command argument completion
 func Test_cmdline_complete_bang_cmd_argument()
   set wildoptions=fuzzy
@@ -3642,30 +3698,32 @@ func Test_cmdline_complete_bang_cmd_argument()
 endfunc
 
 func Call_cmd_funcs()
-  return [getcmdpos(), getcmdscreenpos(), getcmdcompltype()]
+  return [getcmdpos(), getcmdscreenpos(), getcmdcompltype(), getcmdcomplpat()]
 endfunc
 
 func Test_screenpos_and_completion()
   call assert_equal(0, getcmdpos())
   call assert_equal(0, getcmdscreenpos())
   call assert_equal('', getcmdcompltype())
+  call assert_equal('', getcmdcomplpat())
 
   cnoremap <expr> <F2> string(Call_cmd_funcs())
   call feedkeys(":let a\<F2>\<C-B>\"\<CR>", "xt")
-  call assert_equal("\"let a[6, 7, 'var']", @:)
+  call assert_equal("\"let a[6, 7, 'var', 'a']", @:)
   call feedkeys(":quit \<F2>\<C-B>\"\<CR>", "xt")
-  call assert_equal("\"quit [6, 7, '']", @:)
+  call assert_equal("\"quit [6, 7, '', '']", @:)
   call feedkeys(":nosuchcommand \<F2>\<C-B>\"\<CR>", "xt")
-  call assert_equal("\"nosuchcommand [15, 16, '']", @:)
+  call assert_equal("\"nosuchcommand [15, 16, '', '']", @:)
 
-  " Check that getcmdcompltype() doesn't interfere with cmdline completion.
+  " Check that getcmdcompltype() and getcmdcomplpat() don't interfere with
+  " cmdline completion.
   let g:results = []
   cnoremap <F2> <Cmd>let g:results += [[getcmdline()] + Call_cmd_funcs()]<CR>
   call feedkeys(":sign un\<Tab>\<F2>\<Tab>\<F2>\<Tab>\<F2>\<C-C>", "xt")
   call assert_equal([
-        \ ['sign undefine', 14, 15, 'sign'],
-        \ ['sign unplace', 13, 14, 'sign'],
-        \ ['sign un', 8, 9, 'sign']], g:results)
+        \ ['sign undefine', 14, 15, 'sign', 'undefine'],
+        \ ['sign unplace', 13, 14, 'sign', 'unplace'],
+        \ ['sign un', 8, 9, 'sign', 'un']], g:results)
 
   unlet g:results
   cunmap <F2>
diff --git a/src/usercmd.c b/src/usercmd.c
index 585ced3e7..43409ae22 100644
--- a/src/usercmd.c
+++ b/src/usercmd.c
@@ -92,6 +92,7 @@ static keyvalue_T command_complete_tab[] =
     KEYVALUE_ENTRY(EXPAND_SCRIPTNAMES, "scriptnames"),
 #endif
     KEYVALUE_ENTRY(EXPAND_SHELLCMD, "shellcmd"),
+    KEYVALUE_ENTRY(EXPAND_SHELLCMDLINE, "shellcmdline"),
 #if defined(FEAT_SIGNS)
     KEYVALUE_ENTRY(EXPAND_SIGN, "sign"),
 #endif
@@ -328,7 +329,6 @@ set_context_in_user_cmdarg(
     if (argt & EX_XFILE)
     {
        // EX_XFILE: file names are handled before this call
-       xp->xp_context = context;
        return NULL;
     }
 
@@ -850,7 +850,7 @@ parse_compl_arg(
     *complp = entry->key;
     if (*complp == EXPAND_BUFFERS)
        *argt |= EX_BUFNAME;
-    else if (*complp == EXPAND_DIRECTORIES || *complp == EXPAND_FILES)
+    else if (*complp == EXPAND_DIRECTORIES || *complp == EXPAND_FILES || 
*complp == EXPAND_SHELLCMDLINE)
        *argt |= EX_XFILE;
 
     if (
diff --git a/src/version.c b/src/version.c
index b87fc7870..e949908f0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    770,
 /**/
     769,
 /**/
diff --git a/src/vim.h b/src/vim.h
index ebca6ae85..387fe4fd9 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -844,6 +844,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
 #define EXPAND_TERMINALOPT     57
 #define EXPAND_KEYMAP          58
 #define EXPAND_DIRS_IN_CDPATH  59
+#define EXPAND_SHELLCMDLINE    60
 
 
 // Values for exmode_active (0 is no exmode)

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1syGqK-003eio-GV%40256bit.org.

Raspunde prin e-mail lui