comparison src/ex_docmd.c @ 28185:dcb449ae45c9 v8.2.4618

patch 8.2.4618: cmdline completion does not recognize single letter commands Commit: https://github.com/vim/vim/commit/f4f0525c34d2aa32f214155b0dadcd274ed05dd1 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 24 13:08:36 2022 +0000 patch 8.2.4618: cmdline completion does not recognize single letter commands Problem: Command line completion does not recognize single letter commands. Solution: Use the condition from find_ex_command().
author Bram Moolenaar <Bram@vim.org>
date Thu, 24 Mar 2022 14:15:02 +0100
parents 49631bf057d3
children 7456bc6bf077
comparison
equal deleted inserted replaced
28184:b67e3db70515 28185:dcb449ae45c9
3419 return name; 3419 return name;
3420 } 3420 }
3421 #endif 3421 #endif
3422 3422
3423 /* 3423 /*
3424 * Return TRUE and set "*idx" if "p" points to a one letter command.
3425 * If not in Vim9 script:
3426 * - The 'k' command can directly be followed by any character.
3427 * - The 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
3428 * but :sre[wind] is another command, as are :scr[iptnames],
3429 * :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
3430 */
3431 static int
3432 one_letter_cmd(char_u *p, cmdidx_T *idx)
3433 {
3434 if (!in_vim9script())
3435 return FALSE;
3436 if (*p == 'k')
3437 {
3438 *idx = CMD_k;
3439 return TRUE;
3440 }
3441 if (p[0] == 's'
3442 && ((p[1] == 'c' && (p[2] == NUL || (p[2] != 's' && p[2] != 'r'
3443 && (p[3] == NUL || (p[3] != 'i' && p[4] != 'p')))))
3444 || p[1] == 'g'
3445 || (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
3446 || p[1] == 'I'
3447 || (p[1] == 'r' && p[2] != 'e')))
3448 {
3449 *idx = CMD_substitute;
3450 return TRUE;
3451 }
3452 return FALSE;
3453 }
3454
3455 /*
3424 * Find an Ex command by its name, either built-in or user. 3456 * Find an Ex command by its name, either built-in or user.
3425 * Start of the name can be found at eap->cmd. 3457 * Start of the name can be found at eap->cmd.
3426 * Sets eap->cmdidx and returns a pointer to char after the command name. 3458 * Sets eap->cmdidx and returns a pointer to char after the command name.
3427 * "full" is set to TRUE if the whole command name matched. 3459 * "full" is set to TRUE if the whole command name matched.
3428 * 3460 *
3652 } 3684 }
3653 #endif 3685 #endif
3654 3686
3655 /* 3687 /*
3656 * Isolate the command and search for it in the command table. 3688 * Isolate the command and search for it in the command table.
3657 * Exceptions:
3658 * - The 'k' command can directly be followed by any character.
3659 * But it is not used in Vim9 script.
3660 * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
3661 * but :sre[wind] is another command, as are :scr[iptnames],
3662 * :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
3663 * - the "d" command can directly be followed by 'l' or 'p' flag.
3664 */ 3689 */
3665 p = eap->cmd; 3690 p = eap->cmd;
3666 if (!vim9 && *p == 'k') 3691 if (one_letter_cmd(p, &eap->cmdidx))
3667 { 3692 {
3668 eap->cmdidx = CMD_k;
3669 ++p;
3670 }
3671 else if (!vim9
3672 && p[0] == 's'
3673 && ((p[1] == 'c' && (p[2] == NUL || (p[2] != 's' && p[2] != 'r'
3674 && (p[3] == NUL || (p[3] != 'i' && p[4] != 'p')))))
3675 || p[1] == 'g'
3676 || (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
3677 || p[1] == 'I'
3678 || (p[1] == 'r' && p[2] != 'e')))
3679 {
3680 eap->cmdidx = CMD_substitute;
3681 ++p; 3693 ++p;
3682 } 3694 }
3683 else 3695 else
3684 { 3696 {
3685 while (ASCII_ISALPHA(*p)) 3697 while (ASCII_ISALPHA(*p))
3700 3712
3701 // check for non-alpha command 3713 // check for non-alpha command
3702 if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#}", *p) != NULL) 3714 if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#}", *p) != NULL)
3703 ++p; 3715 ++p;
3704 len = (int)(p - eap->cmd); 3716 len = (int)(p - eap->cmd);
3717 // The "d" command can directly be followed by 'l' or 'p' flag, when
3718 // not in Vim9 script.
3705 if (!vim9 && *eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p')) 3719 if (!vim9 && *eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
3706 { 3720 {
3707 // Check for ":dl", ":dell", etc. to ":deletel": that's 3721 // Check for ":dl", ":dell", etc. to ":deletel": that's
3708 // :delete with the 'l' flag. Same for 'p'. 3722 // :delete with the 'l' flag. Same for 'p'.
3709 for (i = 0; i < len; ++i) 3723 for (i = 0; i < len; ++i)
3953 cmdidx_T 3967 cmdidx_T
3954 excmd_get_cmdidx(char_u *cmd, int len) 3968 excmd_get_cmdidx(char_u *cmd, int len)
3955 { 3969 {
3956 cmdidx_T idx; 3970 cmdidx_T idx;
3957 3971
3958 for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE; 3972 if (!one_letter_cmd(cmd, &idx))
3959 idx = (cmdidx_T)((int)idx + 1)) 3973 for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE;
3960 if (STRNCMP(cmdnames[(int)idx].cmd_name, cmd, (size_t)len) == 0) 3974 idx = (cmdidx_T)((int)idx + 1))
3961 break; 3975 if (STRNCMP(cmdnames[(int)idx].cmd_name, cmd, (size_t)len) == 0)
3976 break;
3962 3977
3963 return idx; 3978 return idx;
3964 } 3979 }
3965 3980
3966 long 3981 long