comparison src/cmdexpand.c @ 31083:20390549ce2f v9.0.0876

patch 9.0.0876: code is indented more than needed Commit: https://github.com/vim/vim/commit/68353e5270fca45daffee5b5f882853cdfa40f76 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Sun Nov 13 22:38:10 2022 +0000 patch 9.0.0876: code is indented more than needed Problem: Code is indented more than needed. Solution: Split ExpandEscape() in two. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/11539)
author Bram Moolenaar <Bram@vim.org>
date Sun, 13 Nov 2022 23:45:03 +0100
parents 50405a481037
children 551ce1a137da
comparison
equal deleted inserted replaced
31082:f4347129179d 31083:20390549ce2f
90 90
91 /* 91 /*
92 * Escape special characters in the cmdline completion matches. 92 * Escape special characters in the cmdline completion matches.
93 */ 93 */
94 static void 94 static void
95 wildescape(
96 expand_T *xp,
97 char_u *str,
98 int numfiles,
99 char_u **files)
100 {
101 char_u *p;
102 int vse_what = xp->xp_context == EXPAND_BUFFERS
103 ? VSE_BUFFER : VSE_NONE;
104
105 if (xp->xp_context == EXPAND_FILES
106 || xp->xp_context == EXPAND_FILES_IN_PATH
107 || xp->xp_context == EXPAND_SHELLCMD
108 || xp->xp_context == EXPAND_BUFFERS
109 || xp->xp_context == EXPAND_DIRECTORIES)
110 {
111 // Insert a backslash into a file name before a space, \, %, #
112 // and wildmatch characters, except '~'.
113 for (int i = 0; i < numfiles; ++i)
114 {
115 // for ":set path=" we need to escape spaces twice
116 if (xp->xp_backslash == XP_BS_THREE)
117 {
118 p = vim_strsave_escaped(files[i], (char_u *)" ");
119 if (p != NULL)
120 {
121 vim_free(files[i]);
122 files[i] = p;
123 #if defined(BACKSLASH_IN_FILENAME)
124 p = vim_strsave_escaped(files[i], (char_u *)" ");
125 if (p != NULL)
126 {
127 vim_free(files[i]);
128 files[i] = p;
129 }
130 #endif
131 }
132 }
133 #ifdef BACKSLASH_IN_FILENAME
134 p = vim_strsave_fnameescape(files[i], vse_what);
135 #else
136 p = vim_strsave_fnameescape(files[i],
137 xp->xp_shell ? VSE_SHELL : vse_what);
138 #endif
139 if (p != NULL)
140 {
141 vim_free(files[i]);
142 files[i] = p;
143 }
144
145 // If 'str' starts with "\~", replace "~" at start of
146 // files[i] with "\~".
147 if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
148 escape_fname(&files[i]);
149 }
150 xp->xp_backslash = XP_BS_NONE;
151
152 // If the first file starts with a '+' escape it. Otherwise it
153 // could be seen as "+cmd".
154 if (*files[0] == '+')
155 escape_fname(&files[0]);
156 }
157 else if (xp->xp_context == EXPAND_TAGS)
158 {
159 // Insert a backslash before characters in a tag name that
160 // would terminate the ":tag" command.
161 for (int i = 0; i < numfiles; ++i)
162 {
163 p = vim_strsave_escaped(files[i], (char_u *)"\\|\"");
164 if (p != NULL)
165 {
166 vim_free(files[i]);
167 files[i] = p;
168 }
169 }
170 }
171 }
172
173 /*
174 * Escape special characters in the cmdline completion matches.
175 */
176 static void
95 ExpandEscape( 177 ExpandEscape(
96 expand_T *xp, 178 expand_T *xp,
97 char_u *str, 179 char_u *str,
98 int numfiles, 180 int numfiles,
99 char_u **files, 181 char_u **files,
100 int options) 182 int options)
101 { 183 {
102 int i;
103 char_u *p;
104 int vse_what = xp->xp_context == EXPAND_BUFFERS
105 ? VSE_BUFFER : VSE_NONE;
106
107 // May change home directory back to "~" 184 // May change home directory back to "~"
108 if (options & WILD_HOME_REPLACE) 185 if (options & WILD_HOME_REPLACE)
109 tilde_replace(str, numfiles, files); 186 tilde_replace(str, numfiles, files);
110 187
111 if (options & WILD_ESCAPE) 188 if (options & WILD_ESCAPE)
112 { 189 wildescape(xp, str, numfiles, files);
113 if (xp->xp_context == EXPAND_FILES
114 || xp->xp_context == EXPAND_FILES_IN_PATH
115 || xp->xp_context == EXPAND_SHELLCMD
116 || xp->xp_context == EXPAND_BUFFERS
117 || xp->xp_context == EXPAND_DIRECTORIES)
118 {
119 // Insert a backslash into a file name before a space, \, %, #
120 // and wildmatch characters, except '~'.
121 for (i = 0; i < numfiles; ++i)
122 {
123 // for ":set path=" we need to escape spaces twice
124 if (xp->xp_backslash == XP_BS_THREE)
125 {
126 p = vim_strsave_escaped(files[i], (char_u *)" ");
127 if (p != NULL)
128 {
129 vim_free(files[i]);
130 files[i] = p;
131 #if defined(BACKSLASH_IN_FILENAME)
132 p = vim_strsave_escaped(files[i], (char_u *)" ");
133 if (p != NULL)
134 {
135 vim_free(files[i]);
136 files[i] = p;
137 }
138 #endif
139 }
140 }
141 #ifdef BACKSLASH_IN_FILENAME
142 p = vim_strsave_fnameescape(files[i], vse_what);
143 #else
144 p = vim_strsave_fnameescape(files[i],
145 xp->xp_shell ? VSE_SHELL : vse_what);
146 #endif
147 if (p != NULL)
148 {
149 vim_free(files[i]);
150 files[i] = p;
151 }
152
153 // If 'str' starts with "\~", replace "~" at start of
154 // files[i] with "\~".
155 if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
156 escape_fname(&files[i]);
157 }
158 xp->xp_backslash = XP_BS_NONE;
159
160 // If the first file starts with a '+' escape it. Otherwise it
161 // could be seen as "+cmd".
162 if (*files[0] == '+')
163 escape_fname(&files[0]);
164 }
165 else if (xp->xp_context == EXPAND_TAGS)
166 {
167 // Insert a backslash before characters in a tag name that
168 // would terminate the ":tag" command.
169 for (i = 0; i < numfiles; ++i)
170 {
171 p = vim_strsave_escaped(files[i], (char_u *)"\\|\"");
172 if (p != NULL)
173 {
174 vim_free(files[i]);
175 files[i] = p;
176 }
177 }
178 }
179 }
180 } 190 }
181 191
182 /* 192 /*
183 * Return FAIL if this is not an appropriate context in which to do 193 * Return FAIL if this is not an appropriate context in which to do
184 * completion of anything, return OK if it is (even if there are no matches). 194 * completion of anything, return OK if it is (even if there are no matches).
3236 int flags, 3246 int flags,
3237 hashtab_T *ht, 3247 hashtab_T *ht,
3238 garray_T *gap) 3248 garray_T *gap)
3239 { 3249 {
3240 int ret; 3250 int ret;
3241 int i;
3242 hash_T hash; 3251 hash_T hash;
3243 hashitem_T *hi; 3252 hashitem_T *hi;
3244 3253
3245 vim_strncpy(buf, s, l); 3254 vim_strncpy(buf, s, l);
3246 add_pathsep(buf); 3255 add_pathsep(buf);
3247 l = STRLEN(buf); 3256 l = STRLEN(buf);
3248 vim_strncpy(buf + l, pat, MAXPATHL - 1 - l); 3257 vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
3249 3258
3250 // Expand matches in one directory of $PATH. 3259 // Expand matches in one directory of $PATH.
3251 ret = expand_wildcards(1, &buf, numMatches, matches, flags); 3260 ret = expand_wildcards(1, &buf, numMatches, matches, flags);
3252 if (ret == OK) 3261 if (ret != OK)
3253 { 3262 return;
3254 if (ga_grow(gap, *numMatches) == FAIL) 3263
3255 FreeWild(*numMatches, *matches); 3264 if (ga_grow(gap, *numMatches) == FAIL)
3256 else 3265 {
3257 { 3266 FreeWild(*numMatches, *matches);
3258 for (i = 0; i < *numMatches; ++i) 3267 return;
3268 }
3269
3270 for (int i = 0; i < *numMatches; ++i)
3271 {
3272 char_u *name = (*matches)[i];
3273
3274 if (STRLEN(name) > l)
3275 {
3276 // Check if this name was already found.
3277 hash = hash_hash(name + l);
3278 hi = hash_lookup(ht, name + l, hash);
3279 if (HASHITEM_EMPTY(hi))
3259 { 3280 {
3260 char_u *name = (*matches)[i]; 3281 // Remove the path that was prepended.
3261 3282 STRMOVE(name, name + l);
3262 if (STRLEN(name) > l) 3283 ((char_u **)gap->ga_data)[gap->ga_len++] = name;
3263 { 3284 hash_add_item(ht, hi, name, hash);
3264 // Check if this name was already found. 3285 name = NULL;
3265 hash = hash_hash(name + l);
3266 hi = hash_lookup(ht, name + l, hash);
3267 if (HASHITEM_EMPTY(hi))
3268 {
3269 // Remove the path that was prepended.
3270 STRMOVE(name, name + l);
3271 ((char_u **)gap->ga_data)[gap->ga_len++] = name;
3272 hash_add_item(ht, hi, name, hash);
3273 name = NULL;
3274 }
3275 }
3276 vim_free(name);
3277 } 3286 }
3278 vim_free(*matches); 3287 }
3279 } 3288 vim_free(name);
3280 } 3289 }
3290 vim_free(*matches);
3281 } 3291 }
3282 3292
3283 /* 3293 /*
3284 * Complete a shell command. 3294 * Complete a shell command.
3285 * Returns FAIL or OK; 3295 * Returns FAIL or OK;