Patch 8.2.0961
Problem: MS-Windows: no completion for locales.
Solution: Use the directories in $VIMRUNTIME/lang to complete locales.
(Christian Brabandt, closes 36248)
Files: src/cmdexpand.c, src/ex_cmds2.c, src/testdir/test_cmdline.vim
*** ../vim-8.2.0960/src/cmdexpand.c 2020-06-07 20:49:02.073891895 +0200
--- src/cmdexpand.c 2020-06-12 19:31:05.539367496 +0200
***************
*** 273,278 ****
--- 273,279 ----
* options = WILD_SILENT: don't print warning messages
* options = WILD_ESCAPE: put backslash before special chars
* options = WILD_ICASE: ignore case for files
+ * options = WILD_ALLLINKS; keep broken links
*
* The variables xp->xp_context and xp->xp_backslash must have been set!
*/
*** ../vim-8.2.0960/src/ex_cmds2.c 2020-05-28 21:30:06.359300208 +0200
--- src/ex_cmds2.c 2020-06-12 19:34:47.274710716 +0200
***************
*** 1188,1194 ****
}
#endif
! #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) \
/*
* ":language": Set the language (locale).
*/
--- 1188,1194 ----
}
#endif
! #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
/*
* ":language": Set the language (locale).
*/
***************
*** 1200,1210 ****
char_u *name;
int what = LC_ALL;
char *whatstr = "";
! #ifdef LC_MESSAGES
! # define VIM_LC_MESSAGES LC_MESSAGES
! #else
! # define VIM_LC_MESSAGES 6789
! #endif
name = eap->arg;
--- 1200,1210 ----
char_u *name;
int what = LC_ALL;
char *whatstr = "";
! # ifdef LC_MESSAGES
! # define VIM_LC_MESSAGES LC_MESSAGES
! # else
! # define VIM_LC_MESSAGES 6789
! # endif
name = eap->arg;
***************
*** 1236,1246 ****
if (*name == NUL)
{
! #ifndef LC_MESSAGES
if (what == VIM_LC_MESSAGES)
p = get_mess_env();
else
! #endif
p = (char_u *)setlocale(what, NULL);
if (p == NULL || *p == NUL)
p = (char_u *)"Unknown";
--- 1236,1246 ----
if (*name == NUL)
{
! # ifndef LC_MESSAGES
if (what == VIM_LC_MESSAGES)
p = get_mess_env();
else
! # endif
p = (char_u *)setlocale(what, NULL);
if (p == NULL || *p == NUL)
p = (char_u *)"Unknown";
***************
*** 1248,1276 ****
}
else
{
! #ifndef LC_MESSAGES
if (what == VIM_LC_MESSAGES)
loc = "";
else
! #endif
{
loc = setlocale(what, (char *)name);
! #if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
// Make sure strtod() uses a decimal point, not a comma.
setlocale(LC_NUMERIC, "C");
! #endif
}
if (loc == NULL)
semsg(_("E197: Cannot set language to \"%s\""), name);
else
{
! #ifdef HAVE_NL_MSG_CAT_CNTR
// Need to do this for GNU gettext, otherwise cached translations
// will be used again.
extern int _nl_msg_cat_cntr;
++_nl_msg_cat_cntr;
! #endif
// Reset $LC_ALL, otherwise it would overrule everything.
vim_setenv((char_u *)"LC_ALL", (char_u *)"");
--- 1248,1276 ----
}
else
{
! # ifndef LC_MESSAGES
if (what == VIM_LC_MESSAGES)
loc = "";
else
! # endif
{
loc = setlocale(what, (char *)name);
! # if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
// Make sure strtod() uses a decimal point, not a comma.
setlocale(LC_NUMERIC, "C");
! # endif
}
if (loc == NULL)
semsg(_("E197: Cannot set language to \"%s\""), name);
else
{
! # ifdef HAVE_NL_MSG_CAT_CNTR
// Need to do this for GNU gettext, otherwise cached translations
// will be used again.
extern int _nl_msg_cat_cntr;
++_nl_msg_cat_cntr;
! # endif
// Reset $LC_ALL, otherwise it would overrule everything.
vim_setenv((char_u *)"LC_ALL", (char_u *)"");
***************
*** 1296,1310 ****
if (what != LC_CTYPE)
{
char_u *mname;
! #ifdef MSWIN
mname = gettext_lang(name);
! #else
mname = name;
! #endif
vim_setenv((char_u *)"LC_MESSAGES", mname);
! #ifdef FEAT_MULTI_LANG
set_helplang_default(mname);
! #endif
}
}
--- 1296,1310 ----
if (what != LC_CTYPE)
{
char_u *mname;
! # ifdef MSWIN
mname = gettext_lang(name);
! # else
mname = name;
! # endif
vim_setenv((char_u *)"LC_MESSAGES", mname);
! # ifdef FEAT_MULTI_LANG
set_helplang_default(mname);
! # endif
}
}
***************
*** 1321,1327 ****
static char_u **locales = NULL; // Array of all available locales
- # ifndef MSWIN
static int did_init_locales = FALSE;
/*
--- 1321,1326 ----
***************
*** 1333,1363 ****
{
garray_T locales_ga;
char_u *loc;
// Find all available locales by running command "locale -a". If this
// doesn't work we won't have completion.
! char_u *locale_a = get_cmd_output((char_u *)"locale -a",
NULL, SHELL_SILENT, NULL);
! if (locale_a == NULL)
return NULL;
ga_init2(&locales_ga, sizeof(char_u *), 20);
! // Transform locale_a string where each locale is separated by "\n"
// into an array of locale strings.
! loc = (char_u *)strtok((char *)locale_a, "\n");
while (loc != NULL)
{
! if (ga_grow(&locales_ga, 1) == FAIL)
! break;
! loc = vim_strsave(loc);
! if (loc == NULL)
! break;
! ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc;
loc = (char_u *)strtok(NULL, "\n");
}
! vim_free(locale_a);
if (ga_grow(&locales_ga, 1) == FAIL)
{
ga_clear(&locales_ga);
--- 1332,1418 ----
{
garray_T locales_ga;
char_u *loc;
+ char_u *locale_list;
+ # ifdef MSWIN
+ size_t len = 0;
+ # endif
// Find all available locales by running command "locale -a". If this
// doesn't work we won't have completion.
! # ifndef MSWIN
! locale_list = get_cmd_output((char_u *)"locale -a",
NULL, SHELL_SILENT, NULL);
! # else
! // Find all available locales by examining the directories in
! // $VIMRUNTIME/lang/
! {
! int options = WILD_SILENT|WILD_USE_NL|WILD_KEEP_ALL;
! expand_T xpc;
! char_u *p;
!
! ExpandInit(&xpc);
! xpc.xp_context = EXPAND_DIRECTORIES;
! locale_list = ExpandOne(&xpc, (char_u *)"$VIMRUNTIME/lang/*",
! NULL, options, WILD_ALL);
! ExpandCleanup(&xpc);
! if (locale_list == NULL)
! // Add a dummy input, that will be skipped lated but we need to
! // have something in locale_list so that the C locale is added at
! // the end.
! locale_list = vim_strsave((char_u *)".\n");
! p = locale_list;
! // find the last directory delimiter
! while (p != NULL && *p != NUL)
! {
! if (*p == '\n')
! break;
! if (*p == '\\')
! len = p - locale_list;
! p++;
! }
! }
! # endif
! if (locale_list == NULL)
return NULL;
ga_init2(&locales_ga, sizeof(char_u *), 20);
! // Transform locale_list string where each locale is separated by "\n"
// into an array of locale strings.
! loc = (char_u *)strtok((char *)locale_list, "\n");
while (loc != NULL)
{
! int ignore = FALSE;
!
! # ifdef MSWIN
! if (len > 0)
! loc += len + 1;
! // skip locales with a dot (which indicates the charset)
! if (vim_strchr(loc, '.') != NULL)
! ignore = TRUE;
! # endif
! if (!ignore)
! {
! if (ga_grow(&locales_ga, 1) == FAIL)
! break;
!
! loc = vim_strsave(loc);
! if (loc == NULL)
! break;
! ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc;
! }
loc = (char_u *)strtok(NULL, "\n");
}
!
! # ifdef MSWIN
! // Add the C locale
! if (ga_grow(&locales_ga, 1) == OK)
! ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] =
! vim_strsave((char_u *)"C");
! # endif
!
! vim_free(locale_list);
if (ga_grow(&locales_ga, 1) == FAIL)
{
ga_clear(&locales_ga);
***************
*** 1366,1372 ****
((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
return (char_u **)locales_ga.ga_data;
}
- # endif
/*
* Lazy initialization of all available locales.
--- 1421,1426 ----
***************
*** 1374,1389 ****
static void
init_locales(void)
{
- # ifndef MSWIN
if (!did_init_locales)
{
did_init_locales = TRUE;
locales = find_locales();
}
- # endif
}
! # if defined(EXITFREE) || defined(PROTO)
void
free_locales(void)
{
--- 1428,1441 ----
static void
init_locales(void)
{
if (!did_init_locales)
{
did_init_locales = TRUE;
locales = find_locales();
}
}
! # if defined(EXITFREE) || defined(PROTO)
void
free_locales(void)
{
***************
*** 1395,1401 ****
VIM_CLEAR(locales);
}
}
! # endif
/*
* Function given to ExpandGeneric() to obtain the possible arguments of the
--- 1447,1453 ----
VIM_CLEAR(locales);
}
}
! # endif
/*
* Function given to ExpandGeneric() to obtain the possible arguments of the
*** ../vim-8.2.0960/src/testdir/test_cmdline.vim 2020-06-07 19:38:07.319278755 +0200
--- src/testdir/test_cmdline.vim 2020-06-12 19:28:54.851945042 +0200
***************
*** 609,628 ****
call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx')
call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:)
! if has('unix')
! " TODO: these tests don't work on Windows. lang appears to be 'C'
! " but C does not appear in the completion. Why?
! call assert_match('^"language .*\<' . lang . '\>', @:)
! call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx')
! call assert_match('^"language .*\<' . lang . '\>', @:)
! call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx')
! call assert_match('^"language .*\<' . lang . '\>', @:)
! call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx')
! call assert_match('^"language .*\<' . lang . '\>', @:)
! endif
endfunc
func Test_cmdline_complete_env_variable()
--- 609,624 ----
call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx')
call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:)
! call assert_match('^"language .*\<' . lang . '\>', @:)
! call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx')
! call assert_match('^"language .*\<' . lang . '\>', @:)
! call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx')
! call assert_match('^"language .*\<' . lang . '\>', @:)
! call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx')
! call assert_match('^"language .*\<' . lang . '\>', @:)
endfunc
func Test_cmdline_complete_env_variable()
*** ../vim-8.2.0960/src/version.c 2020-06-11 23:10:42.126363525 +0200
--- src/version.c 2020-06-12 19:30:48.583442336 +0200
***************
*** 756,757 ****
--- 756,759 ----
{ /* Add new patch number below this line */
+ /**/
+ 961,
/**/
--
MORTICIAN: Bring out your dead!
[clang]
Bring out your dead!
[clang]
Bring out your dead!
CUSTOMER: Here's one -- nine pence.
DEAD PERSON: I'm not dead!
The Quest for the Holy Grail (Monty Python)
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///