To: vim_dev@googlegroups.com Subject: Patch 8.2.0961 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 \\\"\", 'tx') call assert_match('^"language .*\.*\.*\', @:) ! 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 \\\"\", 'tx') ! call assert_match('^"language .*\<' . lang . '\>', @:) ! call feedkeys(":language ctype \\\"\", 'tx') ! call assert_match('^"language .*\<' . lang . '\>', @:) ! call feedkeys(":language time \\\"\", 'tx') ! call assert_match('^"language .*\<' . lang . '\>', @:) ! endif endfunc func Test_cmdline_complete_env_variable() --- 609,624 ---- call feedkeys(":language \\\"\", 'tx') call assert_match('^"language .*\.*\.*\', @:) ! call assert_match('^"language .*\<' . lang . '\>', @:) ! call feedkeys(":language messages \\\"\", 'tx') ! call assert_match('^"language .*\<' . lang . '\>', @:) ! call feedkeys(":language ctype \\\"\", 'tx') ! call assert_match('^"language .*\<' . lang . '\>', @:) ! call feedkeys(":language time \\\"\", '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 -- Bram@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 ///