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(&regmatch, p, (colnr_T)0)) 3182 && (vim_regexec(&regmatch, p, (colnr_T)0)
3183 || (p_alt != NULL
3184 && vim_regexec(&regmatch, 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);