patch 9.1.1505: not possible to return completion type for :ex command

Problem:  not possible to return command-line completion type for :ex
          command
Solution: make getcmdcompltype() accept an optional and return the
          command-line completion for that arg (Shougo Matsushita).

closes: #17606

Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 00730a7..8f9c7ba 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt*	For Vim version 9.1.  Last change: 2025 Jun 28
+*builtin.txt*	For Vim version 9.1.  Last change: 2025 Jul 03
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -238,8 +238,8 @@
 getcharstr([{expr} [, {opts}]])	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
+getcmdcompltype({pat})		String	return the type of command-line
+					completion
 getcmdline()			String	return the current command-line input
 getcmdpos()			Number	return cursor position in command-line
 getcmdprompt()			String	return the current command-line prompt
@@ -4201,10 +4201,11 @@
 		Return type: |String|
 
 
-getcmdcompltype()					*getcmdcompltype()*
-		Return the type of the current command-line completion.
-		Only works when the command line is being edited, thus
-		requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
+getcmdcompltype([{pat}])				*getcmdcompltype()*
+		Return the type of command-line completion using {pat}.
+		If {pat} is omited, only works when the command line is being
+		edited, thus requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
+
 		See |:command-completion| for the return string.
 		Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
 		|getcmdprompt()|, |getcmdcomplpat()| and |setcmdline()|.
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index ffa6fcb..9b8cdc2 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1,4 +1,4 @@
-*usr_41.txt*	For Vim version 9.1.  Last change: 2025 Apr 27
+*usr_41.txt*	For Vim version 9.1.  Last change: 2025 Jul 03
 
 		     VIM USER MANUAL - by Bram Moolenaar
 
@@ -1100,8 +1100,7 @@
 Command line:					*command-line-functions*
 	getcmdcomplpat()	get completion pattern of the current command
 				line
-	getcmdcompltype()	get the type of the current command line
-				completion
+	getcmdcompltype()	get the type of the command line completion
 	getcmdline()		get the current command line input
 	getcmdprompt()		get the current command line prompt
 	getcmdpos()		get position of the cursor in the command line
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index f8ddb7f..fcd3b9f 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt*  For Vim version 9.1.  Last change: 2025 Jun 28
+*version9.txt*  For Vim version 9.1.  Last change: 2025 Jul 03
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41607,6 +41607,8 @@
 - 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()|
+- |getcompletion()| now accepts a pat and returns the completion type for the
+  {pat} argument
 - allow to complete shell commands and files using the new shellcmdline
   completion type using |:command-complete| and |getcmdcomplpat()|
 - allow to specify additional attributes in the completion menu (allows to
diff --git a/src/evalfunc.c b/src/evalfunc.c
index a31ad13..6ba698d 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -2264,7 +2264,7 @@
 			ret_string,	    f_getcharstr},
     {"getcmdcomplpat",	0, 0, 0,	    NULL,
 			ret_string,	    f_getcmdcomplpat},
-    {"getcmdcompltype",	0, 0, 0,	    NULL,
+    {"getcmdcompltype",	0, 1, FEARG_1,	    NULL,
 			ret_string,	    f_getcmdcompltype},
     {"getcmdline",	0, 0, 0,	    NULL,
 			ret_string,	    f_getcmdline},
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 324f492..044f389 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4306,25 +4306,16 @@
  * Get the current command-line completion type.
  */
     static char_u *
-get_cmdline_completion(void)
+get_cmdline_completion(expand_T *xpc)
 {
-    cmdline_info_T *p;
-    char_u	*buffer;
     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;
+    xp_context = 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;
+	set_expand_context(xpc);
+	xp_context = xpc->xp_context;
+	xpc->xp_context = EXPAND_NOTHING;
     }
     if (xp_context == EXPAND_UNSUCCESSFUL)
 	return NULL;
@@ -4335,10 +4326,12 @@
 
     if (xp_context == EXPAND_USER_LIST || xp_context == EXPAND_USER_DEFINED)
     {
-	buffer = alloc(STRLEN(cmd_compl) + STRLEN(p->xpc->xp_arg) + 2);
+	char_u	*buffer;
+
+	buffer = alloc(STRLEN(cmd_compl) + STRLEN(xpc->xp_arg) + 2);
 	if (buffer == NULL)
 	    return NULL;
-	sprintf((char *)buffer, "%s,%s", cmd_compl, p->xpc->xp_arg);
+	sprintf((char *)buffer, "%s,%s", cmd_compl, xpc->xp_arg);
 	return buffer;
     }
 
@@ -4361,8 +4354,40 @@
     void
 f_getcmdcompltype(typval_T *argvars UNUSED, typval_T *rettv)
 {
+    if (check_for_opt_string_arg(argvars, 0) == FAIL)
+	 return;
+
     rettv->v_type = VAR_STRING;
-    rettv->vval.v_string = get_cmdline_completion();
+
+    if (argvars[0].v_type != VAR_UNKNOWN)
+    {
+	 char_u		*pat;
+	 expand_T	xpc;
+	 int		cmdline_len;
+
+	pat = tv_get_string(&argvars[0]);
+	ExpandInit(&xpc);
+
+	cmdline_len = (int)STRLEN(pat);
+	set_cmd_context(&xpc, pat, cmdline_len, cmdline_len, FALSE);
+	xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+	xpc.xp_col = cmdline_len;
+
+	rettv->v_type = VAR_STRING;
+	rettv->vval.v_string = get_cmdline_completion(&xpc);
+
+	ExpandCleanup(&xpc);
+    }
+    else
+    {
+	 cmdline_info_T *p;
+
+	 p = get_ccline_ptr();
+	 if (cmdline_star > 0 || p == NULL || p->xpc == NULL)
+	     return;
+
+	 rettv->vval.v_string = get_cmdline_completion(p->xpc);
+    }
 }
 
 /*
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 59c25db..9ebeb0f 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -4589,4 +4589,14 @@
   set wildcharm=0
 endfunc
 
+func Test_getcmdcompltype_with_pat()
+  call assert_fails('call getcmdcompltype({})', 'E1174:')
+  call assert_equal(getcmdcompltype(''), 'command')
+  call assert_equal(getcmdcompltype('dummy '), '')
+  call assert_equal(getcmdcompltype('cd '), 'dir_in_path')
+  call assert_equal(getcmdcompltype('let v:n'), 'var')
+  call assert_equal(getcmdcompltype('call tag'), 'function')
+  call assert_equal(getcmdcompltype('help '), 'help')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 20243ac..48d9a44 100644
--- a/src/version.c
+++ b/src/version.c
@@ -720,6 +720,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1505,
+/**/
     1504,
 /**/
     1503,