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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202006121736.05CHaSXV372411%40masaka.moolenaar.net.

Raspunde prin e-mail lui