home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 7.4 / 7.4.016 < prev    next >
Encoding:
Internet Message Format  |  2013-08-29  |  5.9 KB

  1. To: vim_dev@googlegroups.com
  2. Subject: Patch 7.4.016
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 7.4.016
  11. Problem:    MS-Windows: File name completion doesn't work properly with
  12.         Chinese characters. (Yue Wu)
  13. Solution:   Add fname_casew(). (Ken Takata)
  14. Files:        src/os_win32.c
  15.  
  16.  
  17. *** ../vim-7.4.015/src/os_win32.c    2013-08-30 17:11:29.000000000 +0200
  18. --- src/os_win32.c    2013-08-30 17:28:30.000000000 +0200
  19. ***************
  20. *** 2500,2508 ****
  21. --- 2500,2624 ----
  22.   }
  23.   
  24.   
  25. + #ifdef FEAT_MBYTE
  26. + /*
  27. +  * fname_casew(): Wide version of fname_case().  Set the case of the file name,
  28. +  * if it already exists.  When "len" is > 0, also expand short to long
  29. +  * filenames.
  30. +  * Return FAIL if wide functions are not available, OK otherwise.
  31. +  * NOTE: much of this is identical to fname_case(), keep in sync!
  32. +  */
  33. +     static int
  34. + fname_casew(
  35. +     WCHAR    *name,
  36. +     int        len)
  37. + {
  38. +     WCHAR        szTrueName[_MAX_PATH + 2];
  39. +     WCHAR        szTrueNameTemp[_MAX_PATH + 2];
  40. +     WCHAR        *ptrue, *ptruePrev;
  41. +     WCHAR        *porig, *porigPrev;
  42. +     int            flen;
  43. +     WIN32_FIND_DATAW    fb;
  44. +     HANDLE        hFind;
  45. +     int            c;
  46. +     int            slen;
  47. +     flen = (int)wcslen(name);
  48. +     if (flen > _MAX_PATH)
  49. +     return OK;
  50. +     /* slash_adjust(name) not needed, already adjusted by fname_case(). */
  51. +     /* Build the new name in szTrueName[] one component at a time. */
  52. +     porig = name;
  53. +     ptrue = szTrueName;
  54. +     if (iswalpha(porig[0]) && porig[1] == L':')
  55. +     {
  56. +     /* copy leading drive letter */
  57. +     *ptrue++ = *porig++;
  58. +     *ptrue++ = *porig++;
  59. +     *ptrue = NUL;        /* in case nothing follows */
  60. +     }
  61. +     while (*porig != NUL)
  62. +     {
  63. +     /* copy \ characters */
  64. +     while (*porig == psepc)
  65. +         *ptrue++ = *porig++;
  66. +     ptruePrev = ptrue;
  67. +     porigPrev = porig;
  68. +     while (*porig != NUL && *porig != psepc)
  69. +     {
  70. +         *ptrue++ = *porig++;
  71. +     }
  72. +     *ptrue = NUL;
  73. +     /* To avoid a slow failure append "\*" when searching a directory,
  74. +      * server or network share. */
  75. +     wcscpy(szTrueNameTemp, szTrueName);
  76. +     slen = (int)wcslen(szTrueNameTemp);
  77. +     if (*porig == psepc && slen + 2 < _MAX_PATH)
  78. +         wcscpy(szTrueNameTemp + slen, L"\\*");
  79. +     /* Skip "", "." and "..". */
  80. +     if (ptrue > ptruePrev
  81. +         && (ptruePrev[0] != L'.'
  82. +             || (ptruePrev[1] != NUL
  83. +             && (ptruePrev[1] != L'.' || ptruePrev[2] != NUL)))
  84. +         && (hFind = FindFirstFileW(szTrueNameTemp, &fb))
  85. +                               != INVALID_HANDLE_VALUE)
  86. +     {
  87. +         c = *porig;
  88. +         *porig = NUL;
  89. +         /* Only use the match when it's the same name (ignoring case) or
  90. +          * expansion is allowed and there is a match with the short name
  91. +          * and there is enough room. */
  92. +         if (_wcsicoll(porigPrev, fb.cFileName) == 0
  93. +             || (len > 0
  94. +             && (_wcsicoll(porigPrev, fb.cAlternateFileName) == 0
  95. +                 && (int)(ptruePrev - szTrueName)
  96. +                        + (int)wcslen(fb.cFileName) < len)))
  97. +         {
  98. +         wcscpy(ptruePrev, fb.cFileName);
  99. +         /* Look for exact match and prefer it if found.  Must be a
  100. +          * long name, otherwise there would be only one match. */
  101. +         while (FindNextFileW(hFind, &fb))
  102. +         {
  103. +             if (*fb.cAlternateFileName != NUL
  104. +                 && (wcscoll(porigPrev, fb.cFileName) == 0
  105. +                 || (len > 0
  106. +                     && (_wcsicoll(porigPrev,
  107. +                            fb.cAlternateFileName) == 0
  108. +                     && (int)(ptruePrev - szTrueName)
  109. +                      + (int)wcslen(fb.cFileName) < len))))
  110. +             {
  111. +             wcscpy(ptruePrev, fb.cFileName);
  112. +             break;
  113. +             }
  114. +         }
  115. +         }
  116. +         FindClose(hFind);
  117. +         *porig = c;
  118. +         ptrue = ptruePrev + wcslen(ptruePrev);
  119. +     }
  120. +     else if (hFind == INVALID_HANDLE_VALUE
  121. +         && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
  122. +         return FAIL;
  123. +     }
  124. +     wcscpy(name, szTrueName);
  125. +     return OK;
  126. + }
  127. + #endif
  128.   /*
  129.    * fname_case(): Set the case of the file name, if it already exists.
  130.    * When "len" is > 0, also expand short to long filenames.
  131. +  * NOTE: much of this is identical to fname_casew(), keep in sync!
  132.    */
  133.       void
  134.   fname_case(
  135. ***************
  136. *** 2520,2530 ****
  137.       int            slen;
  138.   
  139.       flen = (int)STRLEN(name);
  140. !     if (flen == 0 || flen > _MAX_PATH)
  141.       return;
  142.   
  143.       slash_adjust(name);
  144.   
  145.       /* Build the new name in szTrueName[] one component at a time. */
  146.       porig = name;
  147.       ptrue = szTrueName;
  148. --- 2636,2679 ----
  149.       int            slen;
  150.   
  151.       flen = (int)STRLEN(name);
  152. !     if (flen == 0)
  153.       return;
  154.   
  155.       slash_adjust(name);
  156.   
  157. + #ifdef FEAT_MBYTE
  158. +     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
  159. +     {
  160. +     WCHAR    *p = enc_to_utf16(name, NULL);
  161. +     if (p != NULL)
  162. +     {
  163. +         char_u    *q;
  164. +         WCHAR    buf[_MAX_PATH + 2];
  165. +         wcscpy(buf, p);
  166. +         vim_free(p);
  167. +         if (fname_casew(buf, (len > 0) ? _MAX_PATH : 0) == OK)
  168. +         {
  169. +         q = utf16_to_enc(buf, NULL);
  170. +         if (q != NULL)
  171. +         {
  172. +             vim_strncpy(name, q, (len > 0) ? len - 1 : flen);
  173. +             vim_free(q);
  174. +             return;
  175. +         }
  176. +         }
  177. +     }
  178. +     /* Retry with non-wide function (for Windows 98). */
  179. +     }
  180. + #endif
  181. +     /* If 'enc' is utf-8, flen can be larger than _MAX_PATH.
  182. +      * So we should check this after calling wide function. */
  183. +     if (flen > _MAX_PATH)
  184. +     return;
  185.       /* Build the new name in szTrueName[] one component at a time. */
  186.       porig = name;
  187.       ptrue = szTrueName;
  188. *** ../vim-7.4.015/src/version.c    2013-08-30 17:11:29.000000000 +0200
  189. --- src/version.c    2013-08-30 17:15:06.000000000 +0200
  190. ***************
  191. *** 740,741 ****
  192. --- 740,743 ----
  193.   {   /* Add new patch number below this line */
  194. + /**/
  195. +     16,
  196.   /**/
  197.  
  198. -- 
  199. Fingers not found - Pound head on keyboard to continue.
  200.  
  201.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  202. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  203. \\\  an exciting new programming language -- http://www.Zimbu.org        ///
  204.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  205.