Mercurial > vim
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 |