vim-patch:partial:8.1.0914: code related to findfile() is spread out (#30000)

Problem:    Code related to findfile() is spread out.
Solution:   Put findfile() related code into a new source file. (Yegappan
            Lakshmanan, closes vim/vim#3934)

5fd0f5052f

Keep functions related to wildcard expansion in path.c, as in Vim they
are now spread out among multiple files, which isn't really ideal.
This commit is contained in:
zeertzjq
2024-08-07 09:12:33 +08:00
committed by GitHub
parent 0c99ce0e89
commit 11a6f3c930
8 changed files with 238 additions and 236 deletions

View File

@@ -6837,142 +6837,6 @@ static void frame_add_height(frame_T *frp, int n)
}
}
// Get the file name at the cursor.
// If Visual mode is active, use the selected text if it's in one line.
// Returns the name in allocated memory, NULL for failure.
char *grab_file_name(int count, linenr_T *file_lnum)
{
int options = FNAME_MESS | FNAME_EXP | FNAME_REL | FNAME_UNESC;
if (VIsual_active) {
size_t len;
char *ptr;
if (get_visual_text(NULL, &ptr, &len) == FAIL) {
return NULL;
}
// Only recognize ":123" here
if (file_lnum != NULL && ptr[len] == ':' && isdigit((uint8_t)ptr[len + 1])) {
char *p = ptr + len + 1;
*file_lnum = getdigits_int32(&p, false, 0);
}
return find_file_name_in_path(ptr, len, options, count, curbuf->b_ffname);
}
return file_name_at_cursor(options | FNAME_HYP, count, file_lnum);
}
// Return the file name under or after the cursor.
//
// The 'path' option is searched if the file name is not absolute.
// The string returned has been alloc'ed and should be freed by the caller.
// NULL is returned if the file name or file is not found.
//
// options:
// FNAME_MESS give error messages
// FNAME_EXP expand to path
// FNAME_HYP check for hypertext link
// FNAME_INCL apply "includeexpr"
char *file_name_at_cursor(int options, int count, linenr_T *file_lnum)
{
return file_name_in_line(get_cursor_line_ptr(),
curwin->w_cursor.col, options, count, curbuf->b_ffname,
file_lnum);
}
/// @param rel_fname file we are searching relative to
/// @param file_lnum line number after the file name
///
/// @return the name of the file under or after ptr[col]. Otherwise like file_name_at_cursor().
char *file_name_in_line(char *line, int col, int options, int count, char *rel_fname,
linenr_T *file_lnum)
{
// search forward for what could be the start of a file name
char *ptr = line + col;
while (*ptr != NUL && !vim_isfilec((uint8_t)(*ptr))) {
MB_PTR_ADV(ptr);
}
if (*ptr == NUL) { // nothing found
if (options & FNAME_MESS) {
emsg(_("E446: No file name under cursor"));
}
return NULL;
}
size_t len;
bool in_type = true;
bool is_url = false;
// Search backward for first char of the file name.
// Go one char back to ":" before "//", or to the drive letter before ":\" (even if ":"
// is not in 'isfname').
while (ptr > line) {
if ((len = (size_t)(utf_head_off(line, ptr - 1))) > 0) {
ptr -= len + 1;
} else if (vim_isfilec((uint8_t)ptr[-1]) || ((options & FNAME_HYP) && path_is_url(ptr - 1))) {
ptr--;
} else {
break;
}
}
// Search forward for the last char of the file name.
// Also allow ":/" when ':' is not in 'isfname'.
len = path_has_drive_letter(ptr) ? 2 : 0;
while (vim_isfilec((uint8_t)ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ')
|| ((options & FNAME_HYP) && path_is_url(ptr + len))
|| (is_url && vim_strchr(":?&=", (uint8_t)ptr[len]) != NULL)) {
// After type:// we also include :, ?, & and = as valid characters, so that
// http://google.com:8080?q=this&that=ok works.
if ((ptr[len] >= 'A' && ptr[len] <= 'Z') || (ptr[len] >= 'a' && ptr[len] <= 'z')) {
if (in_type && path_is_url(ptr + len + 1)) {
is_url = true;
}
} else {
in_type = false;
}
if (ptr[len] == '\\' && ptr[len + 1] == ' ') {
// Skip over the "\" in "\ ".
len++;
}
len += (size_t)(utfc_ptr2len(ptr + len));
}
// If there is trailing punctuation, remove it.
// But don't remove "..", could be a directory name.
if (len > 2 && vim_strchr(".,:;!", (uint8_t)ptr[len - 1]) != NULL
&& ptr[len - 2] != '.') {
len--;
}
if (file_lnum != NULL) {
const char *line_english = " line ";
const char *line_transl = _(line_msg);
// Get the number after the file name and a separator character.
// Also accept " line 999" with and without the same translation as
// used in last_set_msg().
char *p = ptr + len;
if (strncmp(p, line_english, strlen(line_english)) == 0) {
p += strlen(line_english);
} else if (strncmp(p, line_transl, strlen(line_transl)) == 0) {
p += strlen(line_transl);
} else {
p = skipwhite(p);
}
if (*p != NUL) {
if (!isdigit((uint8_t)(*p))) {
p++; // skip the separator
}
p = skipwhite(p);
if (isdigit((uint8_t)(*p))) {
*file_lnum = (linenr_T)getdigits_long(&p, false, 0);
}
}
}
return find_file_name_in_path(ptr, len, options, count, rel_fname);
}
/// Add or remove a status line from window(s), according to the
/// value of 'laststatus'.
///