patch 8.2.4903: cannot get the current cmdline completion type and position

Problem:    Cannot get the current cmdline completion type and position.
Solution:   Add getcmdcompltype() and getcmdscreenpos(). (Shougo Matsushita,
            closes #10344)
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 8795337..ea8dbfa 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -15,7 +15,6 @@
 
 static int	cmd_showtail;	// Only show path tail in lists ?
 
-static void	set_expand_context(expand_T *xp);
 static int      ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch,
 			      char_u ***matches, int *numMatches,
 			      char_u *((*func)(expand_T *, int)), int escaped);
@@ -1230,7 +1229,7 @@
  *  EXPAND_ENV_VARS	    Complete environment variable names
  *  EXPAND_USER		    Complete user names
  */
-    static void
+    void
 set_expand_context(expand_T *xp)
 {
     cmdline_info_T	*ccline = get_cmdline_info();
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 55041b9..219751b 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1850,10 +1850,14 @@
 			ret_dict_any,	    f_getcharsearch},
     {"getcharstr",	0, 1, 0,	    arg1_bool,
 			ret_string,	    f_getcharstr},
+    {"getcmdcompltype",	0, 0, 0,	    NULL,
+			ret_string,	    f_getcmdcompltype},
     {"getcmdline",	0, 0, 0,	    NULL,
 			ret_string,	    f_getcmdline},
     {"getcmdpos",	0, 0, 0,	    NULL,
 			ret_number,	    f_getcmdpos},
+    {"getcmdscreenpos",	0, 0, 0,	    NULL,
+			ret_number,	    f_getcmdscreenpos},
     {"getcmdtype",	0, 0, 0,	    NULL,
 			ret_string,	    f_getcmdtype},
     {"getcmdwintype",	0, 0, 0,	    NULL,
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 7020f51..09f2842 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4119,6 +4119,42 @@
 }
 
 /*
+ * Get the current command-line completion type.
+ */
+    static char_u *
+get_cmdline_completion(void)
+{
+    cmdline_info_T *p;
+
+    if (cmdline_star > 0)
+	return NULL;
+
+    p = get_ccline_ptr();
+    if (p && p->xpc != NULL)
+    {
+	char_u *cmd_compl;
+
+	set_expand_context(p->xpc);
+
+	cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context);
+	if (cmd_compl != NULL)
+	    return vim_strnsave(cmd_compl, strlen((char *)cmd_compl));
+    }
+
+    return NULL;
+}
+
+/*
+ * "getcmdcompltype()" function
+ */
+    void
+f_getcmdcompltype(typval_T *argvars UNUSED, typval_T *rettv)
+{
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = get_cmdline_completion();
+}
+
+/*
  * "getcmdline()" function
  */
     void
@@ -4142,6 +4178,28 @@
 }
 
 /*
+ * Get the command line cursor screen position.
+ */
+    static int
+get_cmdline_screen_pos(void)
+{
+    cmdline_info_T *p = get_ccline_ptr();
+
+    if (p == NULL)
+	return -1;
+    return p->cmdspos;
+}
+
+/*
+ * "getcmdscreenpos()" function
+ */
+    void
+f_getcmdscreenpos(typval_T *argvars UNUSED, typval_T *rettv)
+{
+    rettv->vval.v_number = get_cmdline_screen_pos() + 1;
+}
+
+/*
  * Set the command line byte position to "pos".  Zero is the first position.
  * Only works when the command line is being edited.
  * Returns 1 when failed, 0 when OK.
diff --git a/src/proto/cmdexpand.pro b/src/proto/cmdexpand.pro
index 5ffab8c..924b0b4 100644
--- a/src/proto/cmdexpand.pro
+++ b/src/proto/cmdexpand.pro
@@ -13,6 +13,7 @@
 char_u *sm_gettail(char_u *s);
 char_u *addstar(char_u *fname, int len, int context);
 void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline);
+void set_expand_context(expand_T *xp);
 int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches);
 void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options);
 int wildmenu_translate_key(cmdline_info_T *cclp, int key, expand_T *xp, int did_wild_list);
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index f97719b..374b0a1 100644
--- a/src/proto/ex_getln.pro
+++ b/src/proto/ex_getln.pro
@@ -30,9 +30,11 @@
 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_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);
 void f_setcmdpos(typval_T *argvars, typval_T *rettv);
+void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv);
 void f_getcmdtype(typval_T *argvars, typval_T *rettv);
 int get_cmdline_firstc(void);
 int get_list_range(char_u **str, int *num1, int *num2);
diff --git a/src/proto/usercmd.pro b/src/proto/usercmd.pro
index c3ac79c..47ef6f0 100644
--- a/src/proto/usercmd.pro
+++ b/src/proto/usercmd.pro
@@ -1,7 +1,7 @@
 /* usercmd.c */
 char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int *complp);
-char_u *set_context_in_user_cmdarg(char_u *cmd, char_u *arg, long argt, int context, expand_T *xp, int forceit);
 char_u *set_context_in_user_cmd(expand_T *xp, char_u *arg_in);
+char_u *set_context_in_user_cmdarg(char_u *cmd, char_u *arg, long argt, int context, expand_T *xp, int forceit);
 char_u *expand_user_command_name(int idx);
 char_u *get_user_commands(expand_T *xp, int idx);
 char_u *get_user_command_name(int idx, int cmdidx);
@@ -9,6 +9,7 @@
 char_u *get_user_cmd_flags(expand_T *xp, int idx);
 char_u *get_user_cmd_nargs(expand_T *xp, int idx);
 char_u *get_user_cmd_complete(expand_T *xp, int idx);
+char_u *cmdcomplete_type_to_str(int expand);
 int cmdcomplete_str_to_type(char_u *complete_str);
 char *uc_fun_cmd(void);
 int parse_compl_arg(char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg);
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 5a849f7..e944f8d 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -3380,4 +3380,16 @@
   endfor
 endfunc
 
+func Check_completion()
+  call assert_equal('let a', getcmdline())
+  call assert_equal(6, getcmdpos())
+  call assert_equal(7, getcmdscreenpos())
+  call assert_equal('var', getcmdcompltype())
+  return ''
+endfunc
+
+func Test_screenpos_and_completion()
+  call feedkeys(":let a\<C-R>=Check_completion()\<CR>\<Esc>", "xt")
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/usercmd.c b/src/usercmd.c
index 0e9d712..e73f6f6 100644
--- a/src/usercmd.c
+++ b/src/usercmd.c
@@ -443,6 +443,25 @@
 }
 
 #ifdef FEAT_EVAL
+/*
+ * Get the name of completion type "expand" as a string.
+ */
+    char_u *
+cmdcomplete_type_to_str(int expand)
+{
+    int i;
+
+    for (i = 0; command_complete[i].expand != 0; i++)
+	if (command_complete[i].expand == expand)
+	    return (char_u *)command_complete[i].name;
+
+    return NULL;
+}
+
+/*
+ * Get the index of completion type "complete_str".
+ * Returns EXPAND_NOTHING if no match found.
+ */
     int
 cmdcomplete_str_to_type(char_u *complete_str)
 {
diff --git a/src/version.c b/src/version.c
index 5ee96b6..9ec5e31 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4903,
+/**/
     4902,
 /**/
     4901,