Mercurial > vim
comparison src/filepath.c @ 19936:ce463840c826 v8.2.0524
patch 8.2.0524: Win32: searching for file matches is slow
Commit: https://github.com/vim/vim/commit/c74fbfedfa2df384cca5f6763e2c9e5c0ca6d513
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Apr 6 22:56:28 2020 +0200
patch 8.2.0524: Win32: searching for file matches is slow
Problem: Win32: searching for file matches is slow.
Solution: Instead of making another round to find any short filename, check
for the short name right away. Avoid using an ordinary file like a
directory. (Nir Lichtman, closes #5883)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 06 Apr 2020 23:00:29 +0200 |
parents | 80e663e91e1b |
children | f33098f1aec0 |
comparison
equal
deleted
inserted
replaced
19935:7d46edfd1c55 | 19936:ce463840c826 |
---|---|
62 l = GetShortPathNameW(wfname, newbuf, l+1); | 62 l = GetShortPathNameW(wfname, newbuf, l+1); |
63 } | 63 } |
64 if (l != 0) | 64 if (l != 0) |
65 { | 65 { |
66 char_u *p = utf16_to_enc(newbuf, NULL); | 66 char_u *p = utf16_to_enc(newbuf, NULL); |
67 | |
67 if (p != NULL) | 68 if (p != NULL) |
68 { | 69 { |
69 vim_free(*bufp); | 70 vim_free(*bufp); |
70 *fnamep = *bufp = p; | 71 *fnamep = *bufp = p; |
71 } | 72 } |
3045 HANDLE hFind = INVALID_HANDLE_VALUE; | 3046 HANDLE hFind = INVALID_HANDLE_VALUE; |
3046 WIN32_FIND_DATAW wfb; | 3047 WIN32_FIND_DATAW wfb; |
3047 WCHAR *wn = NULL; // UCS-2 name, NULL when not used. | 3048 WCHAR *wn = NULL; // UCS-2 name, NULL when not used. |
3048 char_u *matchname; | 3049 char_u *matchname; |
3049 int ok; | 3050 int ok; |
3051 char_u *p_alt; | |
3050 | 3052 |
3051 // Expanding "**" may take a long time, check for CTRL-C. | 3053 // Expanding "**" may take a long time, check for CTRL-C. |
3052 if (stardepth > 0) | 3054 if (stardepth > 0) |
3053 { | 3055 { |
3054 ui_breakcheck(); | 3056 ui_breakcheck(); |
3159 ok = (hFind != INVALID_HANDLE_VALUE); | 3161 ok = (hFind != INVALID_HANDLE_VALUE); |
3160 | 3162 |
3161 while (ok) | 3163 while (ok) |
3162 { | 3164 { |
3163 p = utf16_to_enc(wfb.cFileName, NULL); // p is allocated here | 3165 p = utf16_to_enc(wfb.cFileName, NULL); // p is allocated here |
3166 | |
3164 if (p == NULL) | 3167 if (p == NULL) |
3165 break; // out of memory | 3168 break; // out of memory |
3169 | |
3170 if (*wfb.cAlternateFileName == NUL) | |
3171 p_alt == NULL; | |
3172 else | |
3173 p_alt = utf16_to_enc(wfb.cAlternateFileName, NULL); | |
3166 | 3174 |
3167 // Ignore entries starting with a dot, unless when asked for. Accept | 3175 // Ignore entries starting with a dot, unless when asked for. Accept |
3168 // all entries found with "matchname". | 3176 // all entries found with "matchname". |
3169 if ((p[0] != '.' || starts_with_dot | 3177 if ((p[0] != '.' || starts_with_dot |
3170 || ((flags & EW_DODOT) | 3178 || ((flags & EW_DODOT) |
3171 && p[1] != NUL && (p[1] != '.' || p[2] != NUL))) | 3179 && p[1] != NUL && (p[1] != '.' || p[2] != NUL))) |
3172 && (matchname == NULL | 3180 && (matchname == NULL |
3173 || (regmatch.regprog != NULL | 3181 || (regmatch.regprog != NULL |
3174 && vim_regexec(®match, p, (colnr_T)0)) | 3182 && (vim_regexec(®match, p, (colnr_T)0) |
3183 || (p_alt != NULL | |
3184 && vim_regexec(®match, p_alt, (colnr_T)0))) | |
3185 )) | |
3175 || ((flags & EW_NOTWILD) | 3186 || ((flags & EW_NOTWILD) |
3176 && fnamencmp(path + (s - buf), p, e - s) == 0))) | 3187 && fnamencmp(path + (s - buf), p, e - s) == 0))) |
3177 { | 3188 { |
3178 STRCPY(s, p); | 3189 STRCPY(s, p); |
3179 len = (int)STRLEN(buf); | 3190 len = (int)STRLEN(buf); |
3180 | 3191 |
3181 if (starstar && stardepth < 100) | 3192 if (starstar && stardepth < 100 |
3193 && (wfb.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) | |
3182 { | 3194 { |
3183 // For "**" in the pattern first go deeper in the tree to | 3195 // For "**" in the pattern first go deeper in the tree to |
3184 // find matches. | 3196 // find matches. |
3185 STRCPY(buf + len, "/**"); | 3197 STRCPY(buf + len, "/**"); |
3186 STRCPY(buf + len + 3, path_end); | 3198 STRCPY(buf + len + 3, path_end); |
3205 if (mch_getperm(buf) >= 0) // add existing file | 3217 if (mch_getperm(buf) >= 0) // add existing file |
3206 addfile(gap, buf, flags); | 3218 addfile(gap, buf, flags); |
3207 } | 3219 } |
3208 } | 3220 } |
3209 | 3221 |
3222 vim_free(p_alt); | |
3210 vim_free(p); | 3223 vim_free(p); |
3211 ok = FindNextFileW(hFind, &wfb); | 3224 ok = FindNextFileW(hFind, &wfb); |
3212 | |
3213 // If no more matches and no match was used, try expanding the name | |
3214 // itself. Finds the long name of a short filename. | |
3215 if (!ok && matchname != NULL && gap->ga_len == start_len) | |
3216 { | |
3217 STRCPY(s, matchname); | |
3218 FindClose(hFind); | |
3219 vim_free(wn); | |
3220 wn = enc_to_utf16(buf, NULL); | |
3221 if (wn != NULL) | |
3222 hFind = FindFirstFileW(wn, &wfb); | |
3223 else | |
3224 hFind = INVALID_HANDLE_VALUE; | |
3225 ok = (hFind != INVALID_HANDLE_VALUE); | |
3226 VIM_CLEAR(matchname); | |
3227 } | |
3228 } | 3225 } |
3229 | 3226 |
3230 FindClose(hFind); | 3227 FindClose(hFind); |
3231 vim_free(wn); | 3228 vim_free(wn); |
3232 vim_free(buf); | 3229 vim_free(buf); |