0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 9.1.1556: string handling in cmdexpand.c can be improved

Problem:  string handling in cmdexpand.c can be improved
Solution: Improve string manipulation in cmdexpand.c (John Marriott).

This PR does the following:

In cmdline_fuzzy_completion_supported():
- replace the series of if tests with a switch

In expand_shellcmd_onedir():
- move the code to concatenate path and pattern to expand_shellcmd().
  This allows us to slightly simplify the argument list to pass the fully
  pathed pattern and the length of the path in the pattern (0 if no path)
- factor out calls to STRMOVE()

In expand_shellcmd():
- factor out calls to STRMOVE() in the first for loop.
- reorganise the second for loop by:
  a) only calling vim_strchr() if s is not at the end of the string
  b) making sure that when the path and pattern are concatenated they fit
     inside buf
  c) concatenating path and pattern and pass to expand_shellcmd_onedir()

In globpath():
- slightly improve logic that determines if the complete path will fit
  inside the buffer

In f_getcompletion():
- replace the series of if tests with a switch
- factor out calls to STRLEN()

In copy_substring_from_pos():
- factor out the call to STRLEN()

closes: #17742

Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
John Marriott 2025-07-16 20:09:13 +02:00 committed by Christian Brabandt
parent 78b10eab6c
commit 393d398247
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
3 changed files with 254 additions and 196 deletions

View File

@ -47,30 +47,38 @@ static char_u *cmdline_orig = NULL;
static int
cmdline_fuzzy_completion_supported(expand_T *xp)
{
return (vim_strchr(p_wop, WOP_FUZZY) != NULL
&& xp->xp_context != EXPAND_BOOL_SETTINGS
&& xp->xp_context != EXPAND_COLORS
&& xp->xp_context != EXPAND_COMPILER
&& xp->xp_context != EXPAND_DIRECTORIES
&& xp->xp_context != EXPAND_DIRS_IN_CDPATH
&& xp->xp_context != EXPAND_FILES
&& xp->xp_context != EXPAND_FILES_IN_PATH
&& xp->xp_context != EXPAND_FILETYPE
&& xp->xp_context != EXPAND_FILETYPECMD
&& xp->xp_context != EXPAND_FINDFUNC
&& xp->xp_context != EXPAND_HELP
&& xp->xp_context != EXPAND_KEYMAP
&& xp->xp_context != EXPAND_OLD_SETTING
&& xp->xp_context != EXPAND_STRING_SETTING
&& xp->xp_context != EXPAND_SETTING_SUBTRACT
&& xp->xp_context != EXPAND_OWNSYNTAX
&& xp->xp_context != EXPAND_PACKADD
&& xp->xp_context != EXPAND_RUNTIME
&& xp->xp_context != EXPAND_SHELLCMD
&& xp->xp_context != EXPAND_SHELLCMDLINE
&& xp->xp_context != EXPAND_TAGS
&& xp->xp_context != EXPAND_TAGS_LISTFILES
&& xp->xp_context != EXPAND_USER_LIST);
switch (xp->xp_context)
{
case EXPAND_BOOL_SETTINGS:
case EXPAND_COLORS:
case EXPAND_COMPILER:
case EXPAND_DIRECTORIES:
case EXPAND_DIRS_IN_CDPATH:
case EXPAND_FILES:
case EXPAND_FILES_IN_PATH:
case EXPAND_FILETYPE:
case EXPAND_FILETYPECMD:
case EXPAND_FINDFUNC:
case EXPAND_HELP:
case EXPAND_KEYMAP:
case EXPAND_OLD_SETTING:
case EXPAND_STRING_SETTING:
case EXPAND_SETTING_SUBTRACT:
case EXPAND_OWNSYNTAX:
case EXPAND_PACKADD:
case EXPAND_RUNTIME:
case EXPAND_SHELLCMD:
case EXPAND_SHELLCMDLINE:
case EXPAND_TAGS:
case EXPAND_TAGS_LISTFILES:
case EXPAND_USER_LIST:
return FALSE;
default:
break;
}
return vim_strchr(p_wop, WOP_FUZZY) != NULL;
}
/*
@ -3710,28 +3718,16 @@ ExpandGenericExt(
*/
static void
expand_shellcmd_onedir(
char_u *buf,
char_u *s,
size_t l,
char_u *pat,
size_t pathlen, // length of the path portion of pat.
char_u ***matches,
int *numMatches,
int flags,
hashtab_T *ht,
garray_T *gap)
{
int ret;
hash_T hash;
hashitem_T *hi;
vim_strncpy(buf, s, l);
add_pathsep(buf);
l = STRLEN(buf);
vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
// Expand matches in one directory of $PATH.
ret = expand_wildcards(1, &buf, numMatches, matches, flags);
if (ret != OK)
if (expand_wildcards(1, &pat, numMatches, matches, flags) != OK)
return;
if (ga_grow(gap, *numMatches) == FAIL)
@ -3742,17 +3738,22 @@ expand_shellcmd_onedir(
for (int i = 0; i < *numMatches; ++i)
{
char_u *name = (*matches)[i];
char_u *name = (*matches)[i];
size_t namelen = STRLEN(name);
if (STRLEN(name) > l)
if (namelen > pathlen)
{
hash_T hash;
hashitem_T *hi;
// Check if this name was already found.
hash = hash_hash(name + l);
hi = hash_lookup(ht, name + l, hash);
hash = hash_hash(name + pathlen);
hi = hash_lookup(ht, name + pathlen, hash);
if (HASHITEM_EMPTY(hi))
{
// Remove the path that was prepended.
STRMOVE(name, name + l);
mch_memmove(name, name + pathlen,
(size_t)(namelen - pathlen) + 1); // +1 for NUL
((char_u **)gap->ga_data)[gap->ga_len++] = name;
hash_add_item(ht, hi, name, hash);
name = NULL;
@ -3775,12 +3776,11 @@ expand_shellcmd(
int flagsarg) // EW_ flags
{
char_u *pat;
int i;
size_t patlen;
char_u *path = NULL;
int mustfree = FALSE;
garray_T ga;
char_u *buf;
size_t l;
char_u *s, *e;
int flags = flagsarg;
int did_curdir = FALSE;
@ -3791,16 +3791,31 @@ expand_shellcmd(
return FAIL;
// for ":set path=" and ":set tags=" halve backslashes for escaped space
pat = vim_strsave(filepat);
patlen = STRLEN(filepat);
pat = vim_strnsave(filepat, patlen);
if (pat == NULL)
{
vim_free(buf);
return FAIL;
}
for (i = 0; pat[i]; ++i)
if (pat[i] == '\\' && pat[i + 1] == ' ')
STRMOVE(pat + i, pat + i + 1);
// Replace "\ " with " ".
e = pat + patlen;
for (s = pat; *s != NUL; ++s)
{
char_u *p;
if (*s != '\\')
continue;
p = s + 1;
if (*p == ' ')
{
mch_memmove(s, p, (size_t)(e - p) + 1); // +1 for NUL
--e;
}
}
patlen = (size_t)(e - pat);
flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
@ -3823,37 +3838,62 @@ expand_shellcmd(
hash_init(&found_ht);
for (s = path; ; s = e)
{
#if defined(MSWIN)
e = vim_strchr(s, ';');
#else
e = vim_strchr(s, ':');
#endif
if (e == NULL)
e = s + STRLEN(s);
size_t pathlen; // length of the path portion of buf
// (including trailing slash).
size_t seplen;
if (*s == NUL)
{
if (did_curdir)
break;
// Find directories in the current directory, path is empty.
did_curdir = TRUE;
flags |= EW_DIR;
}
else if (STRNCMP(s, ".", (int)(e - s)) == 0)
{
did_curdir = TRUE;
flags |= EW_DIR;
e = s;
pathlen = 0;
seplen = 0;
}
else
// Do not match directories inside a $PATH item.
flags &= ~EW_DIR;
{
#if defined(MSWIN)
e = vim_strchr(s, ';');
#else
e = vim_strchr(s, ':');
#endif
if (e == NULL)
e = s + STRLEN(s);
l = e - s;
if (l > MAXPATHL - 5)
break;
pathlen = (size_t)(e - s);
if (STRNCMP(s, ".", pathlen) == 0)
{
did_curdir = TRUE;
flags |= EW_DIR;
}
else
// Do not match directories inside a $PATH item.
flags &= ~EW_DIR;
expand_shellcmd_onedir(buf, s, l, pat, matches, numMatches, flags,
&found_ht, &ga);
seplen = !after_pathsep(s, e) ? STRLEN_LITERAL(PATHSEPSTR) : 0;
}
if (pathlen + seplen + patlen + 1 <= MAXPATHL)
{
if (pathlen > 0)
{
vim_strncpy(buf, s, pathlen);
if (seplen > 0)
{
STRCPY(buf + pathlen, PATHSEPSTR);
pathlen += seplen;
}
}
STRCPY(buf + pathlen, pat);
expand_shellcmd_onedir(buf, pathlen, matches, numMatches, flags,
&found_ht, &ga);
}
if (*e != NUL)
++e;
@ -4086,7 +4126,9 @@ globpath(
{
expand_T xpc;
char_u *buf;
size_t buflen;
size_t pathlen; // length of the path portion of buf
// (including trailing slash)
size_t seplen;
size_t filelen;
buf = alloc(MAXPATHL);
@ -4098,29 +4140,35 @@ globpath(
filelen = STRLEN(file);
#if defined(MSWIN)
// Using the platform's path separator (\) makes vim incorrectly
// treat it as an escape character, use '/' instead.
#define TMP_PATHSEPSTR "/"
#else
#define TMP_PATHSEPSTR PATHSEPSTR
#endif
// Loop over all entries in {path}.
while (*path != NUL)
{
// Copy one item of the path to buf[] and concatenate the file name.
buflen = (size_t)copy_option_part(&path, buf, MAXPATHL, ",");
if (buflen + filelen + 2 < MAXPATHL)
pathlen = (size_t)copy_option_part(&path, buf, MAXPATHL, ",");
seplen = (*buf != NUL && !after_pathsep(buf, buf + pathlen))
? STRLEN_LITERAL(TMP_PATHSEPSTR)
: 0;
if (pathlen + seplen + filelen + 1 <= MAXPATHL)
{
int num_p;
char_u **p;
if (*buf != NUL && !after_pathsep(buf, buf + buflen))
if (seplen > 0)
{
#if defined(MSWIN)
// Using the platform's path separator (\) makes vim incorrectly
// treat it as an escape character, use '/' instead.
STRCPY(buf + buflen, "/");
++buflen;
#else
STRCPY(buf + buflen, PATHSEPSTR);
buflen += STRLEN_LITERAL(PATHSEPSTR);
#endif
STRCPY(buf + pathlen, TMP_PATHSEPSTR);
pathlen += seplen;
}
STRCPY(buf + buflen, file);
STRCPY(buf + pathlen, file);
if (ExpandFromContext(&xpc, buf, &p, &num_p,
WILD_SILENT|expand_options) != FAIL && num_p > 0)
{
@ -4142,6 +4190,7 @@ globpath(
vim_free(buf);
}
#undef TMP_PATHSEPSTR
/*
* Translate some keys pressed when 'wildmenu' is used.
@ -4485,19 +4534,20 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
}
else
{
xpc.xp_pattern = pat;
char_u *pattern_start;
xpc.xp_pattern = pattern_start = pat;
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
xpc.xp_line = pat;
xpc.xp_context = cmdcomplete_str_to_type(type);
if (xpc.xp_context == EXPAND_NOTHING)
switch (xpc.xp_context)
{
case EXPAND_NOTHING:
semsg(_(e_invalid_argument_str), type);
return;
}
if (xpc.xp_context == EXPAND_USER_DEFINED)
{
case EXPAND_USER_DEFINED:
// Must be "custom,funcname" pattern
if (STRNCMP(type, "custom,", 7) != 0)
{
@ -4506,10 +4556,9 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
}
xpc.xp_arg = type + 7;
}
break;
if (xpc.xp_context == EXPAND_USER_LIST)
{
case EXPAND_USER_LIST:
// Must be "customlist,funcname" pattern
if (STRNCMP(type, "customlist,", 11) != 0)
{
@ -4518,48 +4567,55 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
}
xpc.xp_arg = type + 11;
}
break;
# if defined(FEAT_MENU)
if (xpc.xp_context == EXPAND_MENUS)
{
case EXPAND_MENUS:
set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, FALSE);
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
xpc.xp_pattern_len -= (int)(xpc.xp_pattern - pattern_start);
break;
# endif
# ifdef FEAT_CSCOPE
if (xpc.xp_context == EXPAND_CSCOPE)
{
case EXPAND_CSCOPE:
set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope);
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
xpc.xp_pattern_len -= (int)(xpc.xp_pattern - pattern_start);
break;
# endif
# ifdef FEAT_SIGNS
if (xpc.xp_context == EXPAND_SIGN)
{
case EXPAND_SIGN:
set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
xpc.xp_pattern_len -= (int)(xpc.xp_pattern - pattern_start);
break;
# endif
if (xpc.xp_context == EXPAND_RUNTIME)
{
case EXPAND_RUNTIME:
set_context_in_runtime_cmd(&xpc, xpc.xp_pattern);
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
if (xpc.xp_context == EXPAND_SHELLCMDLINE)
xpc.xp_pattern_len -= (int)(xpc.xp_pattern - pattern_start);
break;
case EXPAND_SHELLCMDLINE:
{
int context = EXPAND_SHELLCMDLINE;
set_context_for_wildcard_arg(NULL, xpc.xp_pattern, FALSE, &xpc,
&context);
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
&context);
xpc.xp_pattern_len -= (int)(xpc.xp_pattern - pattern_start);
break;
}
if (xpc.xp_context == EXPAND_FILETYPECMD)
case EXPAND_FILETYPECMD:
filetype_expand_what = EXP_FILETYPECMD_ALL;
break;
default:
break;
}
}
if (cmdline_fuzzy_completion_supported(&xpc))
// when fuzzy matching, don't modify the search string
pat = vim_strsave(xpc.xp_pattern);
pat = vim_strnsave(xpc.xp_pattern, xpc.xp_pattern_len);
else
pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
@ -4665,7 +4721,7 @@ copy_substring_from_pos(pos_T *start, pos_T *end, char_u **match,
int is_single_line = start->lnum == end->lnum;
segment_len = is_single_line ? (end->col - start->col)
: (int)STRLEN(start_ptr);
: (int)(ml_get_len(start->lnum) - start->col);
if (ga_grow(&ga, segment_len + 2) != OK)
return FAIL;

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-16 19:53+0200\n"
"POT-Creation-Date: 2025-07-16 20:09+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -340,11 +340,11 @@ msgstr ""
msgid "Switched to clipboard method '%s'."
msgstr ""
#: ../cmdexpand.c:1352
#: ../cmdexpand.c:1360
msgid "tagname"
msgstr ""
#: ../cmdexpand.c:1355
#: ../cmdexpand.c:1363
msgid " kind file\n"
msgstr ""
@ -4257,327 +4257,327 @@ msgstr ""
msgid "%s (%s, compiled %s)"
msgstr ""
#: ../version.c:4044
#: ../version.c:4046
msgid ""
"\n"
"MS-Windows ARM64 GUI/console version"
msgstr ""
#: ../version.c:4046
#: ../version.c:4048
msgid ""
"\n"
"MS-Windows 64-bit GUI/console version"
msgstr ""
#: ../version.c:4049
#: ../version.c:4051
msgid ""
"\n"
"MS-Windows 32-bit GUI/console version"
msgstr ""
#: ../version.c:4054
#: ../version.c:4056
msgid ""
"\n"
"MS-Windows ARM64 GUI version"
msgstr ""
#: ../version.c:4056
#: ../version.c:4058
msgid ""
"\n"
"MS-Windows 64-bit GUI version"
msgstr ""
#: ../version.c:4059
#: ../version.c:4061
msgid ""
"\n"
"MS-Windows 32-bit GUI version"
msgstr ""
#: ../version.c:4063
#: ../version.c:4065
msgid " with OLE support"
msgstr ""
#: ../version.c:4068
msgid ""
"\n"
"MS-Windows ARM64 console version"
msgstr ""
#: ../version.c:4070
msgid ""
"\n"
"MS-Windows ARM64 console version"
msgstr ""
#: ../version.c:4072
msgid ""
"\n"
"MS-Windows 64-bit console version"
msgstr ""
#: ../version.c:4073
#: ../version.c:4075
msgid ""
"\n"
"MS-Windows 32-bit console version"
msgstr ""
#: ../version.c:4079
#: ../version.c:4081
msgid ""
"\n"
"macOS version"
msgstr ""
#: ../version.c:4081
#: ../version.c:4083
msgid ""
"\n"
"macOS version w/o darwin feat."
msgstr ""
#: ../version.c:4091
#: ../version.c:4093
msgid ""
"\n"
"OpenVMS version"
msgstr ""
#: ../version.c:4106
#: ../version.c:4108
msgid ""
"\n"
"Included patches: "
msgstr ""
#: ../version.c:4131
#: ../version.c:4133
msgid ""
"\n"
"Extra patches: "
msgstr ""
#: ../version.c:4143 ../version.c:4454
#: ../version.c:4145 ../version.c:4456
msgid "Modified by "
msgstr ""
#: ../version.c:4150
#: ../version.c:4152
msgid ""
"\n"
"Compiled "
msgstr ""
#: ../version.c:4153
#: ../version.c:4155
msgid "by "
msgstr ""
#: ../version.c:4165
msgid ""
"\n"
"Huge version "
msgstr ""
#: ../version.c:4167
msgid ""
"\n"
"Normal version "
"Huge version "
msgstr ""
#: ../version.c:4169
msgid ""
"\n"
"Normal version "
msgstr ""
#: ../version.c:4171
msgid ""
"\n"
"Tiny version "
msgstr ""
#: ../version.c:4172
#: ../version.c:4174
msgid "without GUI."
msgstr ""
#: ../version.c:4175
#: ../version.c:4177
msgid "with GTK3 GUI."
msgstr ""
#: ../version.c:4177
#: ../version.c:4179
msgid "with GTK2-GNOME GUI."
msgstr ""
#: ../version.c:4179
#: ../version.c:4181
msgid "with GTK2 GUI."
msgstr ""
#: ../version.c:4182
#: ../version.c:4184
msgid "with X11-Motif GUI."
msgstr ""
#: ../version.c:4184
#: ../version.c:4186
msgid "with Haiku GUI."
msgstr ""
#: ../version.c:4186
#: ../version.c:4188
msgid "with Photon GUI."
msgstr ""
#: ../version.c:4188
#: ../version.c:4190
msgid "with GUI."
msgstr ""
#: ../version.c:4190
#: ../version.c:4192
msgid " Features included (+) or not (-):\n"
msgstr ""
#: ../version.c:4197
#: ../version.c:4199
msgid " system vimrc file: \""
msgstr ""
#: ../version.c:4202
#: ../version.c:4204
msgid " user vimrc file: \""
msgstr ""
#: ../version.c:4207
#: ../version.c:4209
msgid " 2nd user vimrc file: \""
msgstr ""
#: ../version.c:4212 ../version.c:4219 ../version.c:4223
#: ../version.c:4214 ../version.c:4221 ../version.c:4225
msgid " 3rd user vimrc file: \""
msgstr ""
#: ../version.c:4215
#: ../version.c:4217
msgid " 4th user vimrc file: \""
msgstr ""
#: ../version.c:4228
#: ../version.c:4230
msgid " user exrc file: \""
msgstr ""
#: ../version.c:4233
#: ../version.c:4235
msgid " 2nd user exrc file: \""
msgstr ""
#: ../version.c:4239
#: ../version.c:4241
msgid " system gvimrc file: \""
msgstr ""
#: ../version.c:4243
#: ../version.c:4245
msgid " user gvimrc file: \""
msgstr ""
#: ../version.c:4247
#: ../version.c:4249
msgid "2nd user gvimrc file: \""
msgstr ""
#: ../version.c:4252
#: ../version.c:4254
msgid "3rd user gvimrc file: \""
msgstr ""
#: ../version.c:4257
#: ../version.c:4259
msgid " defaults file: \""
msgstr ""
#: ../version.c:4262
#: ../version.c:4264
msgid " system menu file: \""
msgstr ""
#: ../version.c:4270
#: ../version.c:4272
msgid " fall-back for $VIM: \""
msgstr ""
#: ../version.c:4276
#: ../version.c:4278
msgid " f-b for $VIMRUNTIME: \""
msgstr ""
#: ../version.c:4280
#: ../version.c:4282
msgid "Compilation: "
msgstr ""
#: ../version.c:4286
#: ../version.c:4288
msgid "Compiler: "
msgstr ""
#: ../version.c:4291
#: ../version.c:4293
msgid "Linking: "
msgstr ""
#: ../version.c:4296
#: ../version.c:4298
msgid " DEBUG BUILD"
msgstr ""
#: ../version.c:4332
#: ../version.c:4334
msgid "VIM - Vi IMproved"
msgstr ""
#: ../version.c:4334
#: ../version.c:4336
msgid "version "
msgstr ""
#: ../version.c:4335
#: ../version.c:4337
msgid "by Bram Moolenaar et al."
msgstr ""
#: ../version.c:4339
#: ../version.c:4341
msgid "Vim is open source and freely distributable"
msgstr ""
#: ../version.c:4341
#: ../version.c:4343
msgid "Help poor children in Uganda!"
msgstr ""
#: ../version.c:4342
#: ../version.c:4344
msgid "type :help iccf<Enter> for information "
msgstr ""
#: ../version.c:4344
#: ../version.c:4346
msgid "type :q<Enter> to exit "
msgstr ""
#: ../version.c:4345
#: ../version.c:4347
msgid "type :help<Enter> or <F1> for on-line help"
msgstr ""
#: ../version.c:4346
#: ../version.c:4348
msgid "type :help version9<Enter> for version info"
msgstr ""
#: ../version.c:4349
#: ../version.c:4351
msgid "Running in Vi compatible mode"
msgstr ""
#: ../version.c:4350
#: ../version.c:4352
msgid "type :set nocp<Enter> for Vim defaults"
msgstr ""
#: ../version.c:4351
#: ../version.c:4353
msgid "type :help cp-default<Enter> for info on this"
msgstr ""
#: ../version.c:4366
#: ../version.c:4368
msgid "menu Help->Orphans for information "
msgstr ""
#: ../version.c:4368
#: ../version.c:4370
msgid "Running modeless, typed text is inserted"
msgstr ""
#: ../version.c:4369
#: ../version.c:4371
msgid "menu Edit->Global Settings->Toggle Insert Mode "
msgstr ""
#: ../version.c:4370
#: ../version.c:4372
msgid " for two modes "
msgstr ""
#: ../version.c:4374
#: ../version.c:4376
msgid "menu Edit->Global Settings->Toggle Vi Compatible"
msgstr ""
#: ../version.c:4375
#: ../version.c:4377
msgid " for Vim defaults "
msgstr ""
#: ../version.c:4416
#: ../version.c:4418
msgid "Sponsor Vim development!"
msgstr ""
#: ../version.c:4417
#: ../version.c:4419
msgid "Become a registered Vim user!"
msgstr ""
#: ../version.c:4420
#: ../version.c:4422
msgid "type :help sponsor<Enter> for information "
msgstr ""
#: ../version.c:4421
#: ../version.c:4423
msgid "type :help register<Enter> for information "
msgstr ""
#: ../version.c:4423
#: ../version.c:4425
msgid "menu Help->Sponsor/Register for information "
msgstr ""

View File

@ -719,6 +719,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1556,
/**/
1555,
/**/