patch 8.2.2468: not easy to get the full command name from a shortened one

Problem:    Not easy to get the full command name from a shortened one.
Solution:   Add fullcommand(). (Martin Tournoij, closes #7777)
diff --git a/src/evalfunc.c b/src/evalfunc.c
index f15139f..01994b0 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -978,6 +978,8 @@
 			ret_string,	    f_foldtextresult},
     {"foreground",	0, 0, 0,	    NULL,
 			ret_void,	    f_foreground},
+    {"fullcommand",	1, 1, FEARG_1,	    arg1_string,
+			ret_string,	    f_fullcommand},
     {"funcref",		1, 3, FEARG_1,	    NULL,
 			ret_func_any,	    f_funcref},
     {"function",	1, 3, FEARG_1,	    NULL,
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index d31b56c..da499c9 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3668,6 +3668,33 @@
 	return 0;	// trailing garbage
     return (ea.cmdidx == CMD_SIZE ? 0 : (full ? 2 : 1));
 }
+
+/*
+ * "fullcommand" function
+ */
+    void
+f_fullcommand(typval_T *argvars, typval_T *rettv)
+{
+    exarg_T  ea;
+    char_u   *name = argvars[0].vval.v_string;
+    char_u   *p;
+
+    while (name[0] != NUL && name[0] == ':')
+	name++;
+    name = skip_range(name, TRUE, NULL);
+
+    rettv->v_type = VAR_STRING;
+
+    ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
+    ea.cmdidx = (cmdidx_T)0;
+    p = find_ex_command(&ea, NULL, NULL, NULL);
+    if (p == NULL || ea.cmdidx == CMD_SIZE)
+	return;
+
+    rettv->vval.v_string = vim_strsave(IS_USER_CMDIDX(ea.cmdidx)
+				    ? get_user_commands(NULL, ea.useridx)
+				    : cmdnames[ea.cmdidx].cmd_name);
+}
 #endif
 
     cmdidx_T
diff --git a/src/proto/evalfunc.pro b/src/proto/evalfunc.pro
index 13dffac..2b19448 100644
--- a/src/proto/evalfunc.pro
+++ b/src/proto/evalfunc.pro
@@ -23,4 +23,5 @@
 float_T vim_round(float_T f);
 long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
 void f_string(typval_T *argvars, typval_T *rettv);
+void f_fullcommand(typval_T *argvars, typval_T *rettv);
 /* vim: set ft=c : */
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 7f62dfe..8faa25f 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -442,6 +442,43 @@
   call assert_fails('call getcompletion("abc", [])', 'E475:')
 endfunc
 
+func Test_fullcommand()
+  let tests = {
+        \ '':           '',
+        \ ':':          '',
+        \ ':::':        '',
+        \ ':::5':       '',
+        \ 'not_a_cmd':  '',
+        \ 'Check':      '',
+        \ 'syntax':     'syntax',
+        \ ':syntax':    'syntax',
+        \ '::::syntax': 'syntax',
+        \ 'sy':         'syntax',
+        \ 'syn':        'syntax',
+        \ 'synt':       'syntax',
+        \ ':sy':        'syntax',
+        \ '::::sy':     'syntax',
+        \ 'match':      'match',
+        \ '2match':     'match',
+        \ '3match':     'match',
+        \ 'aboveleft':  'aboveleft',
+        \ 'abo':        'aboveleft',
+        \ 's':          'substitute',
+        \ '5s':         'substitute',
+        \ ':5s':        'substitute',
+        \ "'<,'>s":     'substitute',
+        \ ":'<,'>s":    'substitute',
+        \ 'CheckUni':   'CheckUnix',
+        \ 'CheckUnix':  'CheckUnix',
+  \ }
+
+  for [in, want] in items(tests)
+    call assert_equal(want, fullcommand(in))
+  endfor
+
+  call assert_equal('syntax', 'syn'->fullcommand())
+endfunc
+
 func Test_shellcmd_completion()
   let save_path = $PATH
 
diff --git a/src/version.c b/src/version.c
index df206d1..e8c286b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2468,
+/**/
     2467,
 /**/
     2466,