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