Mercurial > vim
comparison src/window.c @ 15814:99ebf78686a9 v8.1.0914
patch 8.1.0914: code related to findfile() is spread out
commit https://github.com/vim/vim/commit/5fd0f5052f9a312bb4cfe7b4176b1211d45127ee
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Feb 13 23:13:28 2019 +0100
patch 8.1.0914: code related to findfile() is spread out
Problem: Code related to findfile() is spread out.
Solution: Put findfile() related code into a new source file. (Yegappan
Lakshmanan, closes #3934)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 13 Feb 2019 23:15:05 +0100 |
parents | 77e97f159554 |
children | a6ca8cf07a98 |
comparison
equal
deleted
inserted
replaced
15813:ad21b64216aa | 15814:99ebf78686a9 |
---|---|
7 * See README.txt for an overview of the Vim source code. | 7 * See README.txt for an overview of the Vim source code. |
8 */ | 8 */ |
9 | 9 |
10 #include "vim.h" | 10 #include "vim.h" |
11 | 11 |
12 static int path_is_url(char_u *p); | |
13 static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, long Prenum); | 12 static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, long Prenum); |
14 static void win_init(win_T *newp, win_T *oldp, int flags); | 13 static void win_init(win_T *newp, win_T *oldp, int flags); |
15 static void win_init_some(win_T *newp, win_T *oldp); | 14 static void win_init_some(win_T *newp, win_T *oldp); |
16 static void frame_comp_pos(frame_T *topfrp, int *row, int *col); | 15 static void frame_comp_pos(frame_T *topfrp, int *row, int *col); |
17 static void frame_setheight(frame_T *curfrp, int height); | 16 static void frame_setheight(frame_T *curfrp, int height); |
58 | 57 |
59 static int frame_check_height(frame_T *topfrp, int height); | 58 static int frame_check_height(frame_T *topfrp, int height); |
60 static int frame_check_width(frame_T *topfrp, int width); | 59 static int frame_check_width(frame_T *topfrp, int width); |
61 | 60 |
62 static win_T *win_alloc(win_T *after, int hidden); | 61 static win_T *win_alloc(win_T *after, int hidden); |
63 | |
64 #define URL_SLASH 1 /* path_is_url() has found "://" */ | |
65 #define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */ | |
66 | 62 |
67 #define NOWIN (win_T *)-1 /* non-existing window */ | 63 #define NOWIN (win_T *)-1 /* non-existing window */ |
68 | 64 |
69 #define ROWS_AVAIL (Rows - p_ch - tabline_height()) | 65 #define ROWS_AVAIL (Rows - p_ch - tabline_height()) |
70 | 66 |
6096 case 1: return (first_tabpage->tp_next == NULL) ? 0 : 1; | 6092 case 1: return (first_tabpage->tp_next == NULL) ? 0 : 1; |
6097 } | 6093 } |
6098 return 1; | 6094 return 1; |
6099 } | 6095 } |
6100 | 6096 |
6101 #if defined(FEAT_SEARCHPATH) || defined(PROTO) | |
6102 /* | |
6103 * Get the file name at the cursor. | |
6104 * If Visual mode is active, use the selected text if it's in one line. | |
6105 * Returns the name in allocated memory, NULL for failure. | |
6106 */ | |
6107 char_u * | |
6108 grab_file_name(long count, linenr_T *file_lnum) | |
6109 { | |
6110 int options = FNAME_MESS|FNAME_EXP|FNAME_REL|FNAME_UNESC; | |
6111 | |
6112 if (VIsual_active) | |
6113 { | |
6114 int len; | |
6115 char_u *ptr; | |
6116 | |
6117 if (get_visual_text(NULL, &ptr, &len) == FAIL) | |
6118 return NULL; | |
6119 return find_file_name_in_path(ptr, len, options, | |
6120 count, curbuf->b_ffname); | |
6121 } | |
6122 return file_name_at_cursor(options | FNAME_HYP, count, file_lnum); | |
6123 } | |
6124 | |
6125 /* | |
6126 * Return the file name under or after the cursor. | |
6127 * | |
6128 * The 'path' option is searched if the file name is not absolute. | |
6129 * The string returned has been alloc'ed and should be freed by the caller. | |
6130 * NULL is returned if the file name or file is not found. | |
6131 * | |
6132 * options: | |
6133 * FNAME_MESS give error messages | |
6134 * FNAME_EXP expand to path | |
6135 * FNAME_HYP check for hypertext link | |
6136 * FNAME_INCL apply "includeexpr" | |
6137 */ | |
6138 char_u * | |
6139 file_name_at_cursor(int options, long count, linenr_T *file_lnum) | |
6140 { | |
6141 return file_name_in_line(ml_get_curline(), | |
6142 curwin->w_cursor.col, options, count, curbuf->b_ffname, | |
6143 file_lnum); | |
6144 } | |
6145 | |
6146 /* | |
6147 * Return the name of the file under or after ptr[col]. | |
6148 * Otherwise like file_name_at_cursor(). | |
6149 */ | |
6150 char_u * | |
6151 file_name_in_line( | |
6152 char_u *line, | |
6153 int col, | |
6154 int options, | |
6155 long count, | |
6156 char_u *rel_fname, /* file we are searching relative to */ | |
6157 linenr_T *file_lnum) /* line number after the file name */ | |
6158 { | |
6159 char_u *ptr; | |
6160 int len; | |
6161 int in_type = TRUE; | |
6162 int is_url = FALSE; | |
6163 | |
6164 /* | |
6165 * search forward for what could be the start of a file name | |
6166 */ | |
6167 ptr = line + col; | |
6168 while (*ptr != NUL && !vim_isfilec(*ptr)) | |
6169 MB_PTR_ADV(ptr); | |
6170 if (*ptr == NUL) /* nothing found */ | |
6171 { | |
6172 if (options & FNAME_MESS) | |
6173 emsg(_("E446: No file name under cursor")); | |
6174 return NULL; | |
6175 } | |
6176 | |
6177 /* | |
6178 * Search backward for first char of the file name. | |
6179 * Go one char back to ":" before "//" even when ':' is not in 'isfname'. | |
6180 */ | |
6181 while (ptr > line) | |
6182 { | |
6183 if (has_mbyte && (len = (*mb_head_off)(line, ptr - 1)) > 0) | |
6184 ptr -= len + 1; | |
6185 else if (vim_isfilec(ptr[-1]) | |
6186 || ((options & FNAME_HYP) && path_is_url(ptr - 1))) | |
6187 --ptr; | |
6188 else | |
6189 break; | |
6190 } | |
6191 | |
6192 /* | |
6193 * Search forward for the last char of the file name. | |
6194 * Also allow "://" when ':' is not in 'isfname'. | |
6195 */ | |
6196 len = 0; | |
6197 while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') | |
6198 || ((options & FNAME_HYP) && path_is_url(ptr + len)) | |
6199 || (is_url && vim_strchr((char_u *)"?&=", ptr[len]) != NULL)) | |
6200 { | |
6201 /* After type:// we also include ?, & and = as valid characters, so that | |
6202 * http://google.com?q=this&that=ok works. */ | |
6203 if ((ptr[len] >= 'A' && ptr[len] <= 'Z') || (ptr[len] >= 'a' && ptr[len] <= 'z')) | |
6204 { | |
6205 if (in_type && path_is_url(ptr + len + 1)) | |
6206 is_url = TRUE; | |
6207 } | |
6208 else | |
6209 in_type = FALSE; | |
6210 | |
6211 if (ptr[len] == '\\') | |
6212 /* Skip over the "\" in "\ ". */ | |
6213 ++len; | |
6214 if (has_mbyte) | |
6215 len += (*mb_ptr2len)(ptr + len); | |
6216 else | |
6217 ++len; | |
6218 } | |
6219 | |
6220 /* | |
6221 * If there is trailing punctuation, remove it. | |
6222 * But don't remove "..", could be a directory name. | |
6223 */ | |
6224 if (len > 2 && vim_strchr((char_u *)".,:;!", ptr[len - 1]) != NULL | |
6225 && ptr[len - 2] != '.') | |
6226 --len; | |
6227 | |
6228 if (file_lnum != NULL) | |
6229 { | |
6230 char_u *p; | |
6231 | |
6232 /* Get the number after the file name and a separator character */ | |
6233 p = ptr + len; | |
6234 p = skipwhite(p); | |
6235 if (*p != NUL) | |
6236 { | |
6237 if (!isdigit(*p)) | |
6238 ++p; /* skip the separator */ | |
6239 p = skipwhite(p); | |
6240 if (isdigit(*p)) | |
6241 *file_lnum = (int)getdigits(&p); | |
6242 } | |
6243 } | |
6244 | |
6245 return find_file_name_in_path(ptr, len, options, count, rel_fname); | |
6246 } | |
6247 | |
6248 # if defined(FEAT_FIND_ID) && defined(FEAT_EVAL) | |
6249 static char_u * | |
6250 eval_includeexpr(char_u *ptr, int len) | |
6251 { | |
6252 char_u *res; | |
6253 | |
6254 set_vim_var_string(VV_FNAME, ptr, len); | |
6255 res = eval_to_string_safe(curbuf->b_p_inex, NULL, | |
6256 was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL)); | |
6257 set_vim_var_string(VV_FNAME, NULL, 0); | |
6258 return res; | |
6259 } | |
6260 #endif | |
6261 | |
6262 /* | |
6263 * Return the name of the file ptr[len] in 'path'. | |
6264 * Otherwise like file_name_at_cursor(). | |
6265 */ | |
6266 char_u * | |
6267 find_file_name_in_path( | |
6268 char_u *ptr, | |
6269 int len, | |
6270 int options, | |
6271 long count, | |
6272 char_u *rel_fname) /* file we are searching relative to */ | |
6273 { | |
6274 char_u *file_name; | |
6275 int c; | |
6276 # if defined(FEAT_FIND_ID) && defined(FEAT_EVAL) | |
6277 char_u *tofree = NULL; | |
6278 | |
6279 if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) | |
6280 { | |
6281 tofree = eval_includeexpr(ptr, len); | |
6282 if (tofree != NULL) | |
6283 { | |
6284 ptr = tofree; | |
6285 len = (int)STRLEN(ptr); | |
6286 } | |
6287 } | |
6288 # endif | |
6289 | |
6290 if (options & FNAME_EXP) | |
6291 { | |
6292 file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, | |
6293 TRUE, rel_fname); | |
6294 | |
6295 # if defined(FEAT_FIND_ID) && defined(FEAT_EVAL) | |
6296 /* | |
6297 * If the file could not be found in a normal way, try applying | |
6298 * 'includeexpr' (unless done already). | |
6299 */ | |
6300 if (file_name == NULL | |
6301 && !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL) | |
6302 { | |
6303 tofree = eval_includeexpr(ptr, len); | |
6304 if (tofree != NULL) | |
6305 { | |
6306 ptr = tofree; | |
6307 len = (int)STRLEN(ptr); | |
6308 file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, | |
6309 TRUE, rel_fname); | |
6310 } | |
6311 } | |
6312 # endif | |
6313 if (file_name == NULL && (options & FNAME_MESS)) | |
6314 { | |
6315 c = ptr[len]; | |
6316 ptr[len] = NUL; | |
6317 semsg(_("E447: Can't find file \"%s\" in path"), ptr); | |
6318 ptr[len] = c; | |
6319 } | |
6320 | |
6321 /* Repeat finding the file "count" times. This matters when it | |
6322 * appears several times in the path. */ | |
6323 while (file_name != NULL && --count > 0) | |
6324 { | |
6325 vim_free(file_name); | |
6326 file_name = find_file_in_path(ptr, len, options, FALSE, rel_fname); | |
6327 } | |
6328 } | |
6329 else | |
6330 file_name = vim_strnsave(ptr, len); | |
6331 | |
6332 # if defined(FEAT_FIND_ID) && defined(FEAT_EVAL) | |
6333 vim_free(tofree); | |
6334 # endif | |
6335 | |
6336 return file_name; | |
6337 } | |
6338 #endif /* FEAT_SEARCHPATH */ | |
6339 | |
6340 /* | |
6341 * Check if the "://" of a URL is at the pointer, return URL_SLASH. | |
6342 * Also check for ":\\", which MS Internet Explorer accepts, return | |
6343 * URL_BACKSLASH. | |
6344 */ | |
6345 static int | |
6346 path_is_url(char_u *p) | |
6347 { | |
6348 if (STRNCMP(p, "://", (size_t)3) == 0) | |
6349 return URL_SLASH; | |
6350 else if (STRNCMP(p, ":\\\\", (size_t)3) == 0) | |
6351 return URL_BACKSLASH; | |
6352 return 0; | |
6353 } | |
6354 | |
6355 /* | |
6356 * Check if "fname" starts with "name://". Return URL_SLASH if it does. | |
6357 * Return URL_BACKSLASH for "name:\\". | |
6358 * Return zero otherwise. | |
6359 */ | |
6360 int | |
6361 path_with_url(char_u *fname) | |
6362 { | |
6363 char_u *p; | |
6364 | |
6365 for (p = fname; isalpha(*p); ++p) | |
6366 ; | |
6367 return path_is_url(p); | |
6368 } | |
6369 | |
6370 /* | |
6371 * Return TRUE if "name" is a full (absolute) path name or URL. | |
6372 */ | |
6373 int | |
6374 vim_isAbsName(char_u *name) | |
6375 { | |
6376 return (path_with_url(name) != 0 || mch_isFullName(name)); | |
6377 } | |
6378 | |
6379 /* | |
6380 * Get absolute file name into buffer "buf[len]". | |
6381 * | |
6382 * return FAIL for failure, OK otherwise | |
6383 */ | |
6384 int | |
6385 vim_FullName( | |
6386 char_u *fname, | |
6387 char_u *buf, | |
6388 int len, | |
6389 int force) /* force expansion even when already absolute */ | |
6390 { | |
6391 int retval = OK; | |
6392 int url; | |
6393 | |
6394 *buf = NUL; | |
6395 if (fname == NULL) | |
6396 return FAIL; | |
6397 | |
6398 url = path_with_url(fname); | |
6399 if (!url) | |
6400 retval = mch_FullName(fname, buf, len, force); | |
6401 if (url || retval == FAIL) | |
6402 { | |
6403 /* something failed; use the file name (truncate when too long) */ | |
6404 vim_strncpy(buf, fname, len - 1); | |
6405 } | |
6406 #if defined(MSWIN) | |
6407 slash_adjust(buf); | |
6408 #endif | |
6409 return retval; | |
6410 } | |
6411 | |
6412 /* | 6097 /* |
6413 * Return the minimal number of rows that is needed on the screen to display | 6098 * Return the minimal number of rows that is needed on the screen to display |
6414 * the current number of windows. | 6099 * the current number of windows. |
6415 */ | 6100 */ |
6416 int | 6101 int |