forked from aniani/vim
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)
This commit is contained in:
parent
688b3983d8
commit
5fd0f5052f
2
Filelist
2
Filelist
@ -41,6 +41,7 @@ SRC_ALL = \
|
||||
src/farsi.h \
|
||||
src/feature.h \
|
||||
src/fileio.c \
|
||||
src/findfile.c \
|
||||
src/fold.c \
|
||||
src/getchar.c \
|
||||
src/globals.h \
|
||||
@ -170,6 +171,7 @@ SRC_ALL = \
|
||||
src/proto/ex_getln.pro \
|
||||
src/proto/farsi.pro \
|
||||
src/proto/fileio.pro \
|
||||
src/proto/findfile.pro \
|
||||
src/proto/fold.pro \
|
||||
src/proto/getchar.pro \
|
||||
src/proto/gui.pro \
|
||||
|
@ -544,6 +544,7 @@ vimobj = \
|
||||
$(OBJDIR)\ex_getln.obj \
|
||||
$(OBJDIR)\farsi.obj \
|
||||
$(OBJDIR)\fileio.obj \
|
||||
$(OBJDIR)\findfile.obj \
|
||||
$(OBJDIR)\fold.obj \
|
||||
$(OBJDIR)\getchar.obj \
|
||||
$(OBJDIR)\hardcopy.obj \
|
||||
|
@ -716,6 +716,7 @@ OBJ = \
|
||||
$(OUTDIR)/ex_getln.o \
|
||||
$(OUTDIR)/farsi.o \
|
||||
$(OUTDIR)/fileio.o \
|
||||
$(OUTDIR)/findfile.o \
|
||||
$(OUTDIR)/fold.o \
|
||||
$(OUTDIR)/getchar.o \
|
||||
$(OUTDIR)/hardcopy.o \
|
||||
|
@ -46,6 +46,7 @@ SRC = \
|
||||
ex_getln.c \
|
||||
farsi.c \
|
||||
fileio.c \
|
||||
findfile.c \
|
||||
fold.c \
|
||||
getchar.c \
|
||||
hardcopy.c \
|
||||
@ -105,6 +106,7 @@ OBJ = o/arabic.o \
|
||||
o/ex_getln.o \
|
||||
o/farsi.o \
|
||||
o/fileio.o \
|
||||
o/findfile.o \
|
||||
o/fold.o \
|
||||
o/getchar.o \
|
||||
o/hardcopy.o \
|
||||
@ -203,6 +205,8 @@ o/farsi.o: farsi.c $(SYMS)
|
||||
|
||||
o/fileio.o: fileio.c $(SYMS)
|
||||
|
||||
o/findfile.o: findfile.c $(SYMS)
|
||||
|
||||
o/fold.o: fold.c $(SYMS)
|
||||
|
||||
o/getchar.o: getchar.c $(SYMS)
|
||||
|
@ -230,6 +230,7 @@ LINK32_OBJS= \
|
||||
"$(INTDIR)/ex_getln.obj" \
|
||||
"$(INTDIR)/farsi.obj" \
|
||||
"$(INTDIR)/fileio.obj" \
|
||||
"$(INTDIR)/findfile.obj" \
|
||||
"$(INTDIR)/fold.obj" \
|
||||
"$(INTDIR)/getchar.obj" \
|
||||
"$(INTDIR)/hardcopy.obj" \
|
||||
@ -419,6 +420,10 @@ SOURCE=.\farsi.c
|
||||
SOURCE=.\fileio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
#
|
||||
SOURCE=.\findfile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\fold.c
|
||||
# End Source File
|
||||
|
@ -56,6 +56,7 @@ SRC = arabic.c \
|
||||
ex_getln.c \
|
||||
farsi.c \
|
||||
fileio.c \
|
||||
findfile.c \
|
||||
fold.c \
|
||||
getchar.c \
|
||||
hardcopy.c \
|
||||
@ -117,6 +118,7 @@ OBJ = obj/arabic.o \
|
||||
obj/ex_getln.o \
|
||||
obj/farsi.o \
|
||||
obj/fileio.o \
|
||||
obj/findfile.o \
|
||||
obj/fold.o \
|
||||
obj/getchar.o \
|
||||
obj/hardcopy.o \
|
||||
@ -176,6 +178,7 @@ PRO = proto/arabic.pro \
|
||||
proto/ex_getln.pro \
|
||||
proto/farsi.pro \
|
||||
proto/fileio.pro \
|
||||
proto/findfile.pro \
|
||||
proto/fold.pro \
|
||||
proto/getchar.pro \
|
||||
proto/hardcopy.pro \
|
||||
@ -320,6 +323,9 @@ obj/farsi.o: farsi.c
|
||||
obj/fileio.o: fileio.c
|
||||
$(CCSYM) $@ fileio.c
|
||||
|
||||
obj/findfile.o: findfile.c
|
||||
$(CCSYM) $@ findfile.c
|
||||
|
||||
obj/fold.o: fold.c
|
||||
$(CCSYM) $@ fold.c
|
||||
|
||||
|
@ -44,6 +44,7 @@ SRC = arabic.c \
|
||||
ex_getln.c \
|
||||
farsi.c \
|
||||
fileio.c \
|
||||
findfile.c \
|
||||
fold.c \
|
||||
getchar.c \
|
||||
hardcopy.c \
|
||||
|
@ -721,6 +721,7 @@ OBJ = \
|
||||
$(OUTDIR)\ex_getln.obj \
|
||||
$(OUTDIR)\farsi.obj \
|
||||
$(OUTDIR)\fileio.obj \
|
||||
$(OUTDIR)\findfile.obj \
|
||||
$(OUTDIR)\fold.obj \
|
||||
$(OUTDIR)\getchar.obj \
|
||||
$(OUTDIR)\hardcopy.obj \
|
||||
@ -1407,6 +1408,8 @@ $(OUTDIR)/farsi.obj: $(OUTDIR) farsi.c $(INCL)
|
||||
|
||||
$(OUTDIR)/fileio.obj: $(OUTDIR) fileio.c $(INCL)
|
||||
|
||||
$(OUTDIR)/findfile.obj: $(OUTDIR) findfile.c $(INCL)
|
||||
|
||||
$(OUTDIR)/fold.obj: $(OUTDIR) fold.c $(INCL)
|
||||
|
||||
$(OUTDIR)/getchar.obj: $(OUTDIR) getchar.c $(INCL)
|
||||
@ -1645,6 +1648,7 @@ proto.h: \
|
||||
proto/ex_getln.pro \
|
||||
proto/farsi.pro \
|
||||
proto/fileio.pro \
|
||||
proto/findfile.pro \
|
||||
proto/getchar.pro \
|
||||
proto/hardcopy.pro \
|
||||
proto/hashtab.pro \
|
||||
|
@ -109,6 +109,7 @@ SRC = \
|
||||
ex_getln.c \
|
||||
farsi.c \
|
||||
fileio.c \
|
||||
findfile.c \
|
||||
fold.c \
|
||||
getchar.c \
|
||||
hardcopy.c \
|
||||
@ -169,6 +170,7 @@ OBJ = \
|
||||
ex_getln.o \
|
||||
farsi.o \
|
||||
fileio.o \
|
||||
findfile.o \
|
||||
fold.o \
|
||||
getchar.o \
|
||||
hardcopy.o \
|
||||
@ -229,6 +231,7 @@ PRO = \
|
||||
proto/ex_getln.pro \
|
||||
proto/farsi.pro \
|
||||
proto/fileio.pro \
|
||||
proto/findfile.pro \
|
||||
proto/fold.pro \
|
||||
proto/getchar.pro \
|
||||
proto/hardcopy.pro \
|
||||
@ -363,6 +366,8 @@ farsi.o: farsi.c
|
||||
proto/farsi.pro: farsi.c
|
||||
fileio.o: fileio.c
|
||||
proto/fileio.pro: fileio.c
|
||||
findfile.o: findfile.c
|
||||
proto/findfile.pro: findfile.c
|
||||
fold.o: fold.c
|
||||
proto/fold.pro: fold.c
|
||||
getchar.o: getchar.c
|
||||
|
@ -312,23 +312,31 @@ ALL_CFLAGS_VER = /def=($(MODEL_DEF)$(DEFS)$(DEBUG_DEF)$(PERL_DEF)$(PYTHON_DEF) -
|
||||
ALL_LIBS = $(LIBS) $(GUI_LIB_DIR) $(GUI_LIB) \
|
||||
$(PERL_LIB) $(PYTHON_LIB) $(TCL_LIB) $(RUBY_LIB)
|
||||
|
||||
SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c \
|
||||
evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c if_xcmdsrv.c farsi.c fileio.c fold.c \
|
||||
getchar.c hardcopy.c hashtab.c indent.c json.c list.c main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \
|
||||
misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c search.c sha256.c sign.c \
|
||||
spell.c spellfile.c syntax.c tag.c term.c termlib.c textprop.c ui.c undo.c userfunc.c version.c screen.c \
|
||||
window.c os_unix.c os_vms.c pathdef.c \
|
||||
SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c charset.c \
|
||||
crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c evalfunc.c \
|
||||
ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c \
|
||||
if_xcmdsrv.c farsi.c fileio.c findfile.c fold.c getchar.c hardcopy.c \
|
||||
hashtab.c indent.c json.c list.c main.c mark.c menu.c mbyte.c \
|
||||
memfile.c memline.c message.c misc1.c misc2.c move.c normal.c ops.c \
|
||||
option.c popupmnu.c quickfix.c regexp.c search.c sha256.c sign.c \
|
||||
spell.c spellfile.c syntax.c tag.c term.c termlib.c textprop.c ui.c \
|
||||
undo.c userfunc.c version.c screen.c window.c os_unix.c os_vms.c \
|
||||
pathdef.c
|
||||
$(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \
|
||||
$(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC)
|
||||
|
||||
OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj charset.obj crypt.obj crypt_zip.obj dict.obj diff.obj digraph.obj \
|
||||
edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj \
|
||||
if_xcmdsrv.obj farsi.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj indent.obj json.obj list.obj main.obj mark.obj \
|
||||
menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \
|
||||
move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj quickfix.obj \
|
||||
regexp.obj search.obj sha256.obj sign.obj spell.obj spellfile.obj syntax.obj tag.obj term.obj termlib.obj textprop.obj \
|
||||
ui.obj undo.obj userfunc.obj screen.obj version.obj window.obj os_unix.obj \
|
||||
os_vms.obj pathdef.obj if_mzsch.obj\
|
||||
OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj \
|
||||
charset.obj crypt.obj crypt_zip.obj dict.obj diff.obj digraph.obj \
|
||||
edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj ex_docmd.obj \
|
||||
ex_eval.obj ex_getln.obj if_cscope.obj if_xcmdsrv.obj farsi.obj \
|
||||
fileio.obj findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \
|
||||
indent.obj json.obj list.obj main.obj mark.obj menu.obj memfile.obj \
|
||||
memline.obj message.obj misc1.obj misc2.obj move.obj mbyte.obj \
|
||||
normal.obj ops.obj option.obj popupmnu.obj quickfix.obj regexp.obj \
|
||||
search.obj sha256.obj sign.obj spell.obj spellfile.obj syntax.obj \
|
||||
tag.obj term.obj termlib.obj textprop.obj ui.obj undo.obj \
|
||||
userfunc.obj screen.obj version.obj window.obj os_unix.obj os_vms.obj \
|
||||
pathdef.obj if_mzsch.obj \
|
||||
$(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \
|
||||
$(RUBY_OBJ) $(HANGULIN_OBJ) $(MZSCH_OBJ) $(XDIFF_OBJ)
|
||||
|
||||
@ -568,6 +576,10 @@ fileio.obj : fileio.c vim.h [.auto]config.h feature.h os_unix.h \
|
||||
ascii.h keymap.h term.h macros.h structs.h regexp.h \
|
||||
gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
|
||||
globals.h farsi.h arabic.h
|
||||
findfile.obj : findfile.c vim.h [.auto]config.h feature.h os_unix.h \
|
||||
ascii.h keymap.h term.h macros.h structs.h regexp.h \
|
||||
gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
|
||||
globals.h farsi.h arabic.h
|
||||
fold.obj : fold.c vim.h [.auto]config.h feature.h os_unix.h \
|
||||
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
|
||||
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h farsi.h \
|
||||
|
11
src/Makefile
11
src/Makefile
@ -1592,6 +1592,7 @@ BASIC_SRC = \
|
||||
ex_getln.c \
|
||||
farsi.c \
|
||||
fileio.c \
|
||||
findfile.c \
|
||||
fold.c \
|
||||
getchar.c \
|
||||
hardcopy.c \
|
||||
@ -1705,6 +1706,7 @@ OBJ_COMMON = \
|
||||
objects/ex_getln.o \
|
||||
objects/farsi.o \
|
||||
objects/fileio.o \
|
||||
objects/findfile.o \
|
||||
objects/fold.o \
|
||||
objects/getchar.o \
|
||||
objects/hardcopy.o \
|
||||
@ -1831,6 +1833,7 @@ PRO_AUTO = \
|
||||
ex_getln.pro \
|
||||
farsi.pro \
|
||||
fileio.pro \
|
||||
findfile.pro \
|
||||
fold.pro \
|
||||
getchar.pro \
|
||||
hardcopy.pro \
|
||||
@ -2999,6 +3002,9 @@ objects/farsi.o: farsi.c
|
||||
objects/fileio.o: fileio.c
|
||||
$(CCC) -o $@ fileio.c
|
||||
|
||||
objects/findfile.o: findfile.c
|
||||
$(CCC) -o $@ findfile.c
|
||||
|
||||
objects/fold.o: fold.c
|
||||
$(CCC) -o $@ fold.c
|
||||
|
||||
@ -3471,6 +3477,11 @@ objects/fileio.o: fileio.c vim.h protodef.h auto/config.h feature.h os_unix.h \
|
||||
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
|
||||
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
||||
proto.h globals.h farsi.h arabic.h
|
||||
objects/findfile.o: findfile.c vim.h protodef.h auto/config.h feature.h \
|
||||
os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
|
||||
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
||||
proto.h globals.h farsi.h arabic.h libvterm/include/vterm.h \
|
||||
libvterm/include/vterm_keycodes.h
|
||||
objects/fold.o: fold.c vim.h protodef.h auto/config.h feature.h os_unix.h \
|
||||
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
|
||||
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
||||
|
@ -22,8 +22,10 @@ Most code can be found in a file with an obvious name (incomplete list):
|
||||
diff.c diff mode (vimdiff)
|
||||
eval.c expression evaluation
|
||||
fileio.c reading and writing files
|
||||
findfile.c search for files in 'path'
|
||||
fold.c folding
|
||||
getchar.c getting characters and key mapping
|
||||
indent.c C and Lisp indentation
|
||||
mark.c marks
|
||||
mbyte.c multi-byte character handling
|
||||
memfile.c storing lines for buffers in a swapfile
|
||||
|
2607
src/findfile.c
Normal file
2607
src/findfile.c
Normal file
File diff suppressed because it is too large
Load Diff
528
src/misc1.c
528
src/misc1.c
@ -21,6 +21,9 @@
|
||||
static char_u *vim_version_dir(char_u *vimdir);
|
||||
static char_u *remove_tail(char_u *p, char_u *pend, char_u *name);
|
||||
|
||||
#define URL_SLASH 1 /* path_is_url() has found "://" */
|
||||
#define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */
|
||||
|
||||
/* All user names (for ~user completion as done by shell). */
|
||||
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
|
||||
static garray_T ga_users;
|
||||
@ -5023,43 +5026,6 @@ gettail(char_u *fname)
|
||||
return p1;
|
||||
}
|
||||
|
||||
#if defined(FEAT_SEARCHPATH)
|
||||
/*
|
||||
* Return the end of the directory name, on the first path
|
||||
* separator:
|
||||
* "/path/file", "/path/dir/", "/path//dir", "/file"
|
||||
* ^ ^ ^ ^
|
||||
*/
|
||||
static char_u *
|
||||
gettail_dir(char_u *fname)
|
||||
{
|
||||
char_u *dir_end = fname;
|
||||
char_u *next_dir_end = fname;
|
||||
int look_for_sep = TRUE;
|
||||
char_u *p;
|
||||
|
||||
for (p = fname; *p != NUL; )
|
||||
{
|
||||
if (vim_ispathsep(*p))
|
||||
{
|
||||
if (look_for_sep)
|
||||
{
|
||||
next_dir_end = p;
|
||||
look_for_sep = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!look_for_sep)
|
||||
dir_end = next_dir_end;
|
||||
look_for_sep = TRUE;
|
||||
}
|
||||
MB_PTR_ADV(p);
|
||||
}
|
||||
return dir_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get pointer to tail of "fname", including path separators. Putting a NUL
|
||||
* here leaves the directory name. Takes care of "c:/" and "//".
|
||||
@ -5165,21 +5131,6 @@ vim_ispathsep_nocolon(int c)
|
||||
;
|
||||
}
|
||||
|
||||
#if defined(FEAT_SEARCHPATH) || defined(PROTO)
|
||||
/*
|
||||
* return TRUE if 'c' is a path list separator.
|
||||
*/
|
||||
int
|
||||
vim_ispathlistsep(int c)
|
||||
{
|
||||
#ifdef UNIX
|
||||
return (c == ':');
|
||||
#else
|
||||
return (c == ';'); /* might not be right for every system... */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname"
|
||||
* It's done in-place.
|
||||
@ -6183,407 +6134,6 @@ unix_expandpath(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_SEARCHPATH)
|
||||
/*
|
||||
* Moves "*psep" back to the previous path separator in "path".
|
||||
* Returns FAIL is "*psep" ends up at the beginning of "path".
|
||||
*/
|
||||
static int
|
||||
find_previous_pathsep(char_u *path, char_u **psep)
|
||||
{
|
||||
/* skip the current separator */
|
||||
if (*psep > path && vim_ispathsep(**psep))
|
||||
--*psep;
|
||||
|
||||
/* find the previous separator */
|
||||
while (*psep > path)
|
||||
{
|
||||
if (vim_ispathsep(**psep))
|
||||
return OK;
|
||||
MB_PTR_BACK(path, *psep);
|
||||
}
|
||||
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if "maybe_unique" is unique wrt other_paths in "gap".
|
||||
* "maybe_unique" is the end portion of "((char_u **)gap->ga_data)[i]".
|
||||
*/
|
||||
static int
|
||||
is_unique(char_u *maybe_unique, garray_T *gap, int i)
|
||||
{
|
||||
int j;
|
||||
int candidate_len;
|
||||
int other_path_len;
|
||||
char_u **other_paths = (char_u **)gap->ga_data;
|
||||
char_u *rival;
|
||||
|
||||
for (j = 0; j < gap->ga_len; j++)
|
||||
{
|
||||
if (j == i)
|
||||
continue; /* don't compare it with itself */
|
||||
|
||||
candidate_len = (int)STRLEN(maybe_unique);
|
||||
other_path_len = (int)STRLEN(other_paths[j]);
|
||||
if (other_path_len < candidate_len)
|
||||
continue; /* it's different when it's shorter */
|
||||
|
||||
rival = other_paths[j] + other_path_len - candidate_len;
|
||||
if (fnamecmp(maybe_unique, rival) == 0
|
||||
&& (rival == other_paths[j] || vim_ispathsep(*(rival - 1))))
|
||||
return FALSE; /* match */
|
||||
}
|
||||
|
||||
return TRUE; /* no match found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Split the 'path' option into an array of strings in garray_T. Relative
|
||||
* paths are expanded to their equivalent fullpath. This includes the "."
|
||||
* (relative to current buffer directory) and empty path (relative to current
|
||||
* directory) notations.
|
||||
*
|
||||
* TODO: handle upward search (;) and path limiter (**N) notations by
|
||||
* expanding each into their equivalent path(s).
|
||||
*/
|
||||
static void
|
||||
expand_path_option(char_u *curdir, garray_T *gap)
|
||||
{
|
||||
char_u *path_option = *curbuf->b_p_path == NUL
|
||||
? p_path : curbuf->b_p_path;
|
||||
char_u *buf;
|
||||
char_u *p;
|
||||
int len;
|
||||
|
||||
if ((buf = alloc((int)MAXPATHL)) == NULL)
|
||||
return;
|
||||
|
||||
while (*path_option != NUL)
|
||||
{
|
||||
copy_option_part(&path_option, buf, MAXPATHL, " ,");
|
||||
|
||||
if (buf[0] == '.' && (buf[1] == NUL || vim_ispathsep(buf[1])))
|
||||
{
|
||||
/* Relative to current buffer:
|
||||
* "/path/file" + "." -> "/path/"
|
||||
* "/path/file" + "./subdir" -> "/path/subdir" */
|
||||
if (curbuf->b_ffname == NULL)
|
||||
continue;
|
||||
p = gettail(curbuf->b_ffname);
|
||||
len = (int)(p - curbuf->b_ffname);
|
||||
if (len + (int)STRLEN(buf) >= MAXPATHL)
|
||||
continue;
|
||||
if (buf[1] == NUL)
|
||||
buf[len] = NUL;
|
||||
else
|
||||
STRMOVE(buf + len, buf + 2);
|
||||
mch_memmove(buf, curbuf->b_ffname, len);
|
||||
simplify_filename(buf);
|
||||
}
|
||||
else if (buf[0] == NUL)
|
||||
/* relative to current directory */
|
||||
STRCPY(buf, curdir);
|
||||
else if (path_with_url(buf))
|
||||
/* URL can't be used here */
|
||||
continue;
|
||||
else if (!mch_isFullName(buf))
|
||||
{
|
||||
/* Expand relative path to their full path equivalent */
|
||||
len = (int)STRLEN(curdir);
|
||||
if (len + (int)STRLEN(buf) + 3 > MAXPATHL)
|
||||
continue;
|
||||
STRMOVE(buf + len + 1, buf);
|
||||
STRCPY(buf, curdir);
|
||||
buf[len] = PATHSEP;
|
||||
simplify_filename(buf);
|
||||
}
|
||||
|
||||
if (ga_grow(gap, 1) == FAIL)
|
||||
break;
|
||||
|
||||
# if defined(MSWIN)
|
||||
/* Avoid the path ending in a backslash, it fails when a comma is
|
||||
* appended. */
|
||||
len = (int)STRLEN(buf);
|
||||
if (buf[len - 1] == '\\')
|
||||
buf[len - 1] = '/';
|
||||
# endif
|
||||
|
||||
p = vim_strsave(buf);
|
||||
if (p == NULL)
|
||||
break;
|
||||
((char_u **)gap->ga_data)[gap->ga_len++] = p;
|
||||
}
|
||||
|
||||
vim_free(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a pointer to the file or directory name in "fname" that matches the
|
||||
* longest path in "ga"p, or NULL if there is no match. For example:
|
||||
*
|
||||
* path: /foo/bar/baz
|
||||
* fname: /foo/bar/baz/quux.txt
|
||||
* returns: ^this
|
||||
*/
|
||||
static char_u *
|
||||
get_path_cutoff(char_u *fname, garray_T *gap)
|
||||
{
|
||||
int i;
|
||||
int maxlen = 0;
|
||||
char_u **path_part = (char_u **)gap->ga_data;
|
||||
char_u *cutoff = NULL;
|
||||
|
||||
for (i = 0; i < gap->ga_len; i++)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
while ((fname[j] == path_part[i][j]
|
||||
# if defined(MSWIN)
|
||||
|| (vim_ispathsep(fname[j]) && vim_ispathsep(path_part[i][j]))
|
||||
#endif
|
||||
) && fname[j] != NUL && path_part[i][j] != NUL)
|
||||
j++;
|
||||
if (j > maxlen)
|
||||
{
|
||||
maxlen = j;
|
||||
cutoff = &fname[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* skip to the file or directory name */
|
||||
if (cutoff != NULL)
|
||||
while (vim_ispathsep(*cutoff))
|
||||
MB_PTR_ADV(cutoff);
|
||||
|
||||
return cutoff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sorts, removes duplicates and modifies all the fullpath names in "gap" so
|
||||
* that they are unique with respect to each other while conserving the part
|
||||
* that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
|
||||
*/
|
||||
static void
|
||||
uniquefy_paths(garray_T *gap, char_u *pattern)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
char_u **fnames = (char_u **)gap->ga_data;
|
||||
int sort_again = FALSE;
|
||||
char_u *pat;
|
||||
char_u *file_pattern;
|
||||
char_u *curdir;
|
||||
regmatch_T regmatch;
|
||||
garray_T path_ga;
|
||||
char_u **in_curdir = NULL;
|
||||
char_u *short_name;
|
||||
|
||||
remove_duplicates(gap);
|
||||
ga_init2(&path_ga, (int)sizeof(char_u *), 1);
|
||||
|
||||
/*
|
||||
* We need to prepend a '*' at the beginning of file_pattern so that the
|
||||
* regex matches anywhere in the path. FIXME: is this valid for all
|
||||
* possible patterns?
|
||||
*/
|
||||
len = (int)STRLEN(pattern);
|
||||
file_pattern = alloc(len + 2);
|
||||
if (file_pattern == NULL)
|
||||
return;
|
||||
file_pattern[0] = '*';
|
||||
file_pattern[1] = NUL;
|
||||
STRCAT(file_pattern, pattern);
|
||||
pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, TRUE);
|
||||
vim_free(file_pattern);
|
||||
if (pat == NULL)
|
||||
return;
|
||||
|
||||
regmatch.rm_ic = TRUE; /* always ignore case */
|
||||
regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
|
||||
vim_free(pat);
|
||||
if (regmatch.regprog == NULL)
|
||||
return;
|
||||
|
||||
if ((curdir = alloc((int)(MAXPATHL))) == NULL)
|
||||
goto theend;
|
||||
mch_dirname(curdir, MAXPATHL);
|
||||
expand_path_option(curdir, &path_ga);
|
||||
|
||||
in_curdir = (char_u **)alloc_clear(gap->ga_len * sizeof(char_u *));
|
||||
if (in_curdir == NULL)
|
||||
goto theend;
|
||||
|
||||
for (i = 0; i < gap->ga_len && !got_int; i++)
|
||||
{
|
||||
char_u *path = fnames[i];
|
||||
int is_in_curdir;
|
||||
char_u *dir_end = gettail_dir(path);
|
||||
char_u *pathsep_p;
|
||||
char_u *path_cutoff;
|
||||
|
||||
len = (int)STRLEN(path);
|
||||
is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
|
||||
&& curdir[dir_end - path] == NUL;
|
||||
if (is_in_curdir)
|
||||
in_curdir[i] = vim_strsave(path);
|
||||
|
||||
/* Shorten the filename while maintaining its uniqueness */
|
||||
path_cutoff = get_path_cutoff(path, &path_ga);
|
||||
|
||||
/* Don't assume all files can be reached without path when search
|
||||
* pattern starts with star star slash, so only remove path_cutoff
|
||||
* when possible. */
|
||||
if (pattern[0] == '*' && pattern[1] == '*'
|
||||
&& vim_ispathsep_nocolon(pattern[2])
|
||||
&& path_cutoff != NULL
|
||||
&& vim_regexec(®match, path_cutoff, (colnr_T)0)
|
||||
&& is_unique(path_cutoff, gap, i))
|
||||
{
|
||||
sort_again = TRUE;
|
||||
mch_memmove(path, path_cutoff, STRLEN(path_cutoff) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Here all files can be reached without path, so get shortest
|
||||
* unique path. We start at the end of the path. */
|
||||
pathsep_p = path + len - 1;
|
||||
|
||||
while (find_previous_pathsep(path, &pathsep_p))
|
||||
if (vim_regexec(®match, pathsep_p + 1, (colnr_T)0)
|
||||
&& is_unique(pathsep_p + 1, gap, i)
|
||||
&& path_cutoff != NULL && pathsep_p + 1 >= path_cutoff)
|
||||
{
|
||||
sort_again = TRUE;
|
||||
mch_memmove(path, pathsep_p + 1, STRLEN(pathsep_p));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mch_isFullName(path))
|
||||
{
|
||||
/*
|
||||
* Last resort: shorten relative to curdir if possible.
|
||||
* 'possible' means:
|
||||
* 1. It is under the current directory.
|
||||
* 2. The result is actually shorter than the original.
|
||||
*
|
||||
* Before curdir After
|
||||
* /foo/bar/file.txt /foo/bar ./file.txt
|
||||
* c:\foo\bar\file.txt c:\foo\bar .\file.txt
|
||||
* /file.txt / /file.txt
|
||||
* c:\file.txt c:\ .\file.txt
|
||||
*/
|
||||
short_name = shorten_fname(path, curdir);
|
||||
if (short_name != NULL && short_name > path + 1
|
||||
#if defined(MSWIN)
|
||||
/* On windows,
|
||||
* shorten_fname("c:\a\a.txt", "c:\a\b")
|
||||
* returns "\a\a.txt", which is not really the short
|
||||
* name, hence: */
|
||||
&& !vim_ispathsep(*short_name)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
STRCPY(path, ".");
|
||||
add_pathsep(path);
|
||||
STRMOVE(path + STRLEN(path), short_name);
|
||||
}
|
||||
}
|
||||
ui_breakcheck();
|
||||
}
|
||||
|
||||
/* Shorten filenames in /in/current/directory/{filename} */
|
||||
for (i = 0; i < gap->ga_len && !got_int; i++)
|
||||
{
|
||||
char_u *rel_path;
|
||||
char_u *path = in_curdir[i];
|
||||
|
||||
if (path == NULL)
|
||||
continue;
|
||||
|
||||
/* If the {filename} is not unique, change it to ./{filename}.
|
||||
* Else reduce it to {filename} */
|
||||
short_name = shorten_fname(path, curdir);
|
||||
if (short_name == NULL)
|
||||
short_name = path;
|
||||
if (is_unique(short_name, gap, i))
|
||||
{
|
||||
STRCPY(fnames[i], short_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
rel_path = alloc((int)(STRLEN(short_name) + STRLEN(PATHSEPSTR) + 2));
|
||||
if (rel_path == NULL)
|
||||
goto theend;
|
||||
STRCPY(rel_path, ".");
|
||||
add_pathsep(rel_path);
|
||||
STRCAT(rel_path, short_name);
|
||||
|
||||
vim_free(fnames[i]);
|
||||
fnames[i] = rel_path;
|
||||
sort_again = TRUE;
|
||||
ui_breakcheck();
|
||||
}
|
||||
|
||||
theend:
|
||||
vim_free(curdir);
|
||||
if (in_curdir != NULL)
|
||||
{
|
||||
for (i = 0; i < gap->ga_len; i++)
|
||||
vim_free(in_curdir[i]);
|
||||
vim_free(in_curdir);
|
||||
}
|
||||
ga_clear_strings(&path_ga);
|
||||
vim_regfree(regmatch.regprog);
|
||||
|
||||
if (sort_again)
|
||||
remove_duplicates(gap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calls globpath() with 'path' values for the given pattern and stores the
|
||||
* result in "gap".
|
||||
* Returns the total number of matches.
|
||||
*/
|
||||
static int
|
||||
expand_in_path(
|
||||
garray_T *gap,
|
||||
char_u *pattern,
|
||||
int flags) /* EW_* flags */
|
||||
{
|
||||
char_u *curdir;
|
||||
garray_T path_ga;
|
||||
char_u *paths = NULL;
|
||||
int glob_flags = 0;
|
||||
|
||||
if ((curdir = alloc((unsigned)MAXPATHL)) == NULL)
|
||||
return 0;
|
||||
mch_dirname(curdir, MAXPATHL);
|
||||
|
||||
ga_init2(&path_ga, (int)sizeof(char_u *), 1);
|
||||
expand_path_option(curdir, &path_ga);
|
||||
vim_free(curdir);
|
||||
if (path_ga.ga_len == 0)
|
||||
return 0;
|
||||
|
||||
paths = ga_concat_strings(&path_ga, ",");
|
||||
ga_clear_strings(&path_ga);
|
||||
if (paths == NULL)
|
||||
return 0;
|
||||
|
||||
if (flags & EW_ICASE)
|
||||
glob_flags |= WILD_ICASE;
|
||||
if (flags & EW_ADDSLASH)
|
||||
glob_flags |= WILD_ADD_SLASH;
|
||||
globpath(paths, pattern, gap, glob_flags);
|
||||
vim_free(paths);
|
||||
|
||||
return gap->ga_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_SEARCHPATH) || defined(FEAT_CMDL_COMPL) || defined(PROTO)
|
||||
/*
|
||||
* Sort "gap" and remove duplicate entries. "gap" is expected to contain a
|
||||
@ -7120,3 +6670,75 @@ get_isolated_shell_name(void)
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the "://" of a URL is at the pointer, return URL_SLASH.
|
||||
* Also check for ":\\", which MS Internet Explorer accepts, return
|
||||
* URL_BACKSLASH.
|
||||
*/
|
||||
int
|
||||
path_is_url(char_u *p)
|
||||
{
|
||||
if (STRNCMP(p, "://", (size_t)3) == 0)
|
||||
return URL_SLASH;
|
||||
else if (STRNCMP(p, ":\\\\", (size_t)3) == 0)
|
||||
return URL_BACKSLASH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if "fname" starts with "name://". Return URL_SLASH if it does.
|
||||
* Return URL_BACKSLASH for "name:\\".
|
||||
* Return zero otherwise.
|
||||
*/
|
||||
int
|
||||
path_with_url(char_u *fname)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
for (p = fname; isalpha(*p); ++p)
|
||||
;
|
||||
return path_is_url(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "name" is a full (absolute) path name or URL.
|
||||
*/
|
||||
int
|
||||
vim_isAbsName(char_u *name)
|
||||
{
|
||||
return (path_with_url(name) != 0 || mch_isFullName(name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get absolute file name into buffer "buf[len]".
|
||||
*
|
||||
* return FAIL for failure, OK otherwise
|
||||
*/
|
||||
int
|
||||
vim_FullName(
|
||||
char_u *fname,
|
||||
char_u *buf,
|
||||
int len,
|
||||
int force) /* force expansion even when already absolute */
|
||||
{
|
||||
int retval = OK;
|
||||
int url;
|
||||
|
||||
*buf = NUL;
|
||||
if (fname == NULL)
|
||||
return FAIL;
|
||||
|
||||
url = path_with_url(fname);
|
||||
if (!url)
|
||||
retval = mch_FullName(fname, buf, len, force);
|
||||
if (url || retval == FAIL)
|
||||
{
|
||||
/* something failed; use the file name (truncate when too long) */
|
||||
vim_strncpy(buf, fname, len - 1);
|
||||
}
|
||||
#if defined(MSWIN)
|
||||
slash_adjust(buf);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
1926
src/misc2.c
1926
src/misc2.c
File diff suppressed because it is too large
Load Diff
@ -80,6 +80,7 @@ extern int _stricoll(char *a, char *b);
|
||||
# include "ex_eval.pro"
|
||||
# include "ex_getln.pro"
|
||||
# include "fileio.pro"
|
||||
# include "findfile.pro"
|
||||
# include "fold.pro"
|
||||
# include "getchar.pro"
|
||||
# ifdef FEAT_HANGULIN
|
||||
|
18
src/proto/findfile.pro
Normal file
18
src/proto/findfile.pro
Normal file
@ -0,0 +1,18 @@
|
||||
/* findfile.c */
|
||||
void *vim_findfile_init(char_u *path, char_u *filename, char_u *stopdirs, int level, int free_visited, int find_what, void *search_ctx_arg, int tagfile, char_u *rel_fname);
|
||||
char_u *vim_findfile_stopdir(char_u *buf);
|
||||
void vim_findfile_cleanup(void *ctx);
|
||||
char_u *vim_findfile(void *search_ctx_arg);
|
||||
void vim_findfile_free_visited(void *search_ctx_arg);
|
||||
char_u *find_file_in_path(char_u *ptr, int len, int options, int first, char_u *rel_fname);
|
||||
void free_findfile(void);
|
||||
char_u *find_directory_in_path(char_u *ptr, int len, int options, char_u *rel_fname);
|
||||
char_u *find_file_in_path_option(char_u *ptr, int len, int options, int first, char_u *path_option, int find_what, char_u *rel_fname, char_u *suffixes);
|
||||
char_u *grab_file_name(long count, linenr_T *file_lnum);
|
||||
char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum);
|
||||
char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum);
|
||||
char_u *find_file_name_in_path(char_u *ptr, int len, int options, long count, char_u *rel_fname);
|
||||
int vim_ispathlistsep(int c);
|
||||
void uniquefy_paths(garray_T *gap, char_u *pattern);
|
||||
int expand_in_path(garray_T *gap, char_u *pattern, int flags);
|
||||
/* vim: set ft=c : */
|
@ -74,7 +74,6 @@ char_u *getnextcomp(char_u *fname);
|
||||
char_u *get_past_head(char_u *path);
|
||||
int vim_ispathsep(int c);
|
||||
int vim_ispathsep_nocolon(int c);
|
||||
int vim_ispathlistsep(int c);
|
||||
void shorten_dir(char_u *str);
|
||||
int dir_of_file_exists(char_u *fname);
|
||||
int vim_fnamecmp(char_u *x, char_u *y);
|
||||
@ -99,4 +98,8 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, int flags, int *ret_len);
|
||||
void FreeWild(int count, char_u **files);
|
||||
int goto_im(void);
|
||||
char_u *get_isolated_shell_name(void);
|
||||
int path_is_url(char_u *p);
|
||||
int path_with_url(char_u *fname);
|
||||
int vim_isAbsName(char_u *name);
|
||||
int vim_FullName(char_u *fname, char_u *buf, int len, int force);
|
||||
/* vim: set ft=c : */
|
||||
|
@ -90,14 +90,6 @@ int vim_stat(const char *name, stat_T *stp);
|
||||
char *parse_shape_opt(int what);
|
||||
int get_shape_idx(int mouse);
|
||||
void update_mouseshape(int shape_idx);
|
||||
void *vim_findfile_init(char_u *path, char_u *filename, char_u *stopdirs, int level, int free_visited, int find_what, void *search_ctx_arg, int tagfile, char_u *rel_fname);
|
||||
char_u *vim_findfile_stopdir(char_u *buf);
|
||||
void vim_findfile_cleanup(void *ctx);
|
||||
char_u *vim_findfile(void *search_ctx_arg);
|
||||
void vim_findfile_free_visited(void *search_ctx_arg);
|
||||
char_u *find_file_in_path(char_u *ptr, int len, int options, int first, char_u *rel_fname);
|
||||
char_u *find_directory_in_path(char_u *ptr, int len, int options, char_u *rel_fname);
|
||||
char_u *find_file_in_path_option(char_u *ptr, int len, int options, int first, char_u *path_option, int find_what, char_u *rel_fname, char_u *suffixes);
|
||||
int vim_chdir(char_u *new_dir);
|
||||
int get_user_name(char_u *buf, int len);
|
||||
void sort_strings(char_u **files, int count);
|
||||
|
@ -65,13 +65,6 @@ void win_comp_scroll(win_T *wp);
|
||||
void command_height(void);
|
||||
void last_status(int morewin);
|
||||
int tabline_height(void);
|
||||
char_u *grab_file_name(long count, linenr_T *file_lnum);
|
||||
char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum);
|
||||
char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum);
|
||||
char_u *find_file_name_in_path(char_u *ptr, int len, int options, long count, char_u *rel_fname);
|
||||
int path_with_url(char_u *fname);
|
||||
int vim_isAbsName(char_u *name);
|
||||
int vim_FullName(char_u *fname, char_u *buf, int len, int force);
|
||||
int min_rows(void);
|
||||
int only_one_window(void);
|
||||
void check_lnums(int do_curwin);
|
||||
|
@ -783,6 +783,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
914,
|
||||
/**/
|
||||
913,
|
||||
/**/
|
||||
|
315
src/window.c
315
src/window.c
@ -9,7 +9,6 @@
|
||||
|
||||
#include "vim.h"
|
||||
|
||||
static int path_is_url(char_u *p);
|
||||
static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, long Prenum);
|
||||
static void win_init(win_T *newp, win_T *oldp, int flags);
|
||||
static void win_init_some(win_T *newp, win_T *oldp);
|
||||
@ -61,9 +60,6 @@ static int frame_check_width(frame_T *topfrp, int width);
|
||||
|
||||
static win_T *win_alloc(win_T *after, int hidden);
|
||||
|
||||
#define URL_SLASH 1 /* path_is_url() has found "://" */
|
||||
#define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */
|
||||
|
||||
#define NOWIN (win_T *)-1 /* non-existing window */
|
||||
|
||||
#define ROWS_AVAIL (Rows - p_ch - tabline_height())
|
||||
@ -6098,317 +6094,6 @@ tabline_height(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(FEAT_SEARCHPATH) || defined(PROTO)
|
||||
/*
|
||||
* 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_u *
|
||||
grab_file_name(long count, linenr_T *file_lnum)
|
||||
{
|
||||
int options = FNAME_MESS|FNAME_EXP|FNAME_REL|FNAME_UNESC;
|
||||
|
||||
if (VIsual_active)
|
||||
{
|
||||
int len;
|
||||
char_u *ptr;
|
||||
|
||||
if (get_visual_text(NULL, &ptr, &len) == FAIL)
|
||||
return NULL;
|
||||
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_u *
|
||||
file_name_at_cursor(int options, long count, linenr_T *file_lnum)
|
||||
{
|
||||
return file_name_in_line(ml_get_curline(),
|
||||
curwin->w_cursor.col, options, count, curbuf->b_ffname,
|
||||
file_lnum);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the name of the file under or after ptr[col].
|
||||
* Otherwise like file_name_at_cursor().
|
||||
*/
|
||||
char_u *
|
||||
file_name_in_line(
|
||||
char_u *line,
|
||||
int col,
|
||||
int options,
|
||||
long count,
|
||||
char_u *rel_fname, /* file we are searching relative to */
|
||||
linenr_T *file_lnum) /* line number after the file name */
|
||||
{
|
||||
char_u *ptr;
|
||||
int len;
|
||||
int in_type = TRUE;
|
||||
int is_url = FALSE;
|
||||
|
||||
/*
|
||||
* search forward for what could be the start of a file name
|
||||
*/
|
||||
ptr = line + col;
|
||||
while (*ptr != NUL && !vim_isfilec(*ptr))
|
||||
MB_PTR_ADV(ptr);
|
||||
if (*ptr == NUL) /* nothing found */
|
||||
{
|
||||
if (options & FNAME_MESS)
|
||||
emsg(_("E446: No file name under cursor"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search backward for first char of the file name.
|
||||
* Go one char back to ":" before "//" even when ':' is not in 'isfname'.
|
||||
*/
|
||||
while (ptr > line)
|
||||
{
|
||||
if (has_mbyte && (len = (*mb_head_off)(line, ptr - 1)) > 0)
|
||||
ptr -= len + 1;
|
||||
else if (vim_isfilec(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 = 0;
|
||||
while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ')
|
||||
|| ((options & FNAME_HYP) && path_is_url(ptr + len))
|
||||
|| (is_url && vim_strchr((char_u *)"?&=", ptr[len]) != NULL))
|
||||
{
|
||||
/* After type:// we also include ?, & and = as valid characters, so that
|
||||
* http://google.com?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] == '\\')
|
||||
/* Skip over the "\" in "\ ". */
|
||||
++len;
|
||||
if (has_mbyte)
|
||||
len += (*mb_ptr2len)(ptr + len);
|
||||
else
|
||||
++len;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is trailing punctuation, remove it.
|
||||
* But don't remove "..", could be a directory name.
|
||||
*/
|
||||
if (len > 2 && vim_strchr((char_u *)".,:;!", ptr[len - 1]) != NULL
|
||||
&& ptr[len - 2] != '.')
|
||||
--len;
|
||||
|
||||
if (file_lnum != NULL)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
/* Get the number after the file name and a separator character */
|
||||
p = ptr + len;
|
||||
p = skipwhite(p);
|
||||
if (*p != NUL)
|
||||
{
|
||||
if (!isdigit(*p))
|
||||
++p; /* skip the separator */
|
||||
p = skipwhite(p);
|
||||
if (isdigit(*p))
|
||||
*file_lnum = (int)getdigits(&p);
|
||||
}
|
||||
}
|
||||
|
||||
return find_file_name_in_path(ptr, len, options, count, rel_fname);
|
||||
}
|
||||
|
||||
# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
|
||||
static char_u *
|
||||
eval_includeexpr(char_u *ptr, int len)
|
||||
{
|
||||
char_u *res;
|
||||
|
||||
set_vim_var_string(VV_FNAME, ptr, len);
|
||||
res = eval_to_string_safe(curbuf->b_p_inex, NULL,
|
||||
was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL));
|
||||
set_vim_var_string(VV_FNAME, NULL, 0);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the name of the file ptr[len] in 'path'.
|
||||
* Otherwise like file_name_at_cursor().
|
||||
*/
|
||||
char_u *
|
||||
find_file_name_in_path(
|
||||
char_u *ptr,
|
||||
int len,
|
||||
int options,
|
||||
long count,
|
||||
char_u *rel_fname) /* file we are searching relative to */
|
||||
{
|
||||
char_u *file_name;
|
||||
int c;
|
||||
# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
|
||||
char_u *tofree = NULL;
|
||||
|
||||
if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL)
|
||||
{
|
||||
tofree = eval_includeexpr(ptr, len);
|
||||
if (tofree != NULL)
|
||||
{
|
||||
ptr = tofree;
|
||||
len = (int)STRLEN(ptr);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
if (options & FNAME_EXP)
|
||||
{
|
||||
file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
|
||||
TRUE, rel_fname);
|
||||
|
||||
# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
|
||||
/*
|
||||
* If the file could not be found in a normal way, try applying
|
||||
* 'includeexpr' (unless done already).
|
||||
*/
|
||||
if (file_name == NULL
|
||||
&& !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL)
|
||||
{
|
||||
tofree = eval_includeexpr(ptr, len);
|
||||
if (tofree != NULL)
|
||||
{
|
||||
ptr = tofree;
|
||||
len = (int)STRLEN(ptr);
|
||||
file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
|
||||
TRUE, rel_fname);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
if (file_name == NULL && (options & FNAME_MESS))
|
||||
{
|
||||
c = ptr[len];
|
||||
ptr[len] = NUL;
|
||||
semsg(_("E447: Can't find file \"%s\" in path"), ptr);
|
||||
ptr[len] = c;
|
||||
}
|
||||
|
||||
/* Repeat finding the file "count" times. This matters when it
|
||||
* appears several times in the path. */
|
||||
while (file_name != NULL && --count > 0)
|
||||
{
|
||||
vim_free(file_name);
|
||||
file_name = find_file_in_path(ptr, len, options, FALSE, rel_fname);
|
||||
}
|
||||
}
|
||||
else
|
||||
file_name = vim_strnsave(ptr, len);
|
||||
|
||||
# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
|
||||
vim_free(tofree);
|
||||
# endif
|
||||
|
||||
return file_name;
|
||||
}
|
||||
#endif /* FEAT_SEARCHPATH */
|
||||
|
||||
/*
|
||||
* Check if the "://" of a URL is at the pointer, return URL_SLASH.
|
||||
* Also check for ":\\", which MS Internet Explorer accepts, return
|
||||
* URL_BACKSLASH.
|
||||
*/
|
||||
static int
|
||||
path_is_url(char_u *p)
|
||||
{
|
||||
if (STRNCMP(p, "://", (size_t)3) == 0)
|
||||
return URL_SLASH;
|
||||
else if (STRNCMP(p, ":\\\\", (size_t)3) == 0)
|
||||
return URL_BACKSLASH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if "fname" starts with "name://". Return URL_SLASH if it does.
|
||||
* Return URL_BACKSLASH for "name:\\".
|
||||
* Return zero otherwise.
|
||||
*/
|
||||
int
|
||||
path_with_url(char_u *fname)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
for (p = fname; isalpha(*p); ++p)
|
||||
;
|
||||
return path_is_url(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "name" is a full (absolute) path name or URL.
|
||||
*/
|
||||
int
|
||||
vim_isAbsName(char_u *name)
|
||||
{
|
||||
return (path_with_url(name) != 0 || mch_isFullName(name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get absolute file name into buffer "buf[len]".
|
||||
*
|
||||
* return FAIL for failure, OK otherwise
|
||||
*/
|
||||
int
|
||||
vim_FullName(
|
||||
char_u *fname,
|
||||
char_u *buf,
|
||||
int len,
|
||||
int force) /* force expansion even when already absolute */
|
||||
{
|
||||
int retval = OK;
|
||||
int url;
|
||||
|
||||
*buf = NUL;
|
||||
if (fname == NULL)
|
||||
return FAIL;
|
||||
|
||||
url = path_with_url(fname);
|
||||
if (!url)
|
||||
retval = mch_FullName(fname, buf, len, force);
|
||||
if (url || retval == FAIL)
|
||||
{
|
||||
/* something failed; use the file name (truncate when too long) */
|
||||
vim_strncpy(buf, fname, len - 1);
|
||||
}
|
||||
#if defined(MSWIN)
|
||||
slash_adjust(buf);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the minimal number of rows that is needed on the screen to display
|
||||
* the current number of windows.
|
||||
|
Loading…
x
Reference in New Issue
Block a user