Support completion for ":find". (Nazri Ramliy)
Cleanup white space.
This commit is contained in:
@ -1098,7 +1098,6 @@ Vim 7.3:
|
|||||||
- Conceal feature: no update when moving to another window. (Dominique Pelle,
|
- Conceal feature: no update when moving to another window. (Dominique Pelle,
|
||||||
2010 Jul 5) Vince will look into it.
|
2010 Jul 5) Vince will look into it.
|
||||||
Patches to possibly include:
|
Patches to possibly include:
|
||||||
- Win32: patch for better font scaling. (George Reilly, 2009 Mar 26)
|
|
||||||
- Patch for completion of ":find" arguments. (Nazri Ramliy, 2009 Feb 22, 26)
|
- Patch for completion of ":find" arguments. (Nazri Ramliy, 2009 Feb 22, 26)
|
||||||
8 For ":find" and ":sfind" expand files found in 'path'.
|
8 For ":find" and ":sfind" expand files found in 'path'.
|
||||||
Update 2009 Mar 28.
|
Update 2009 Mar 28.
|
||||||
|
|||||||
@ -1057,8 +1057,9 @@ $(OUTDIR)/window.obj: $(OUTDIR) window.c $(INCL)
|
|||||||
$(OUTDIR)/xpm_w32.obj: $(OUTDIR) xpm_w32.c
|
$(OUTDIR)/xpm_w32.obj: $(OUTDIR) xpm_w32.c
|
||||||
$(CC) $(CFLAGS) $(XPM_INC) xpm_w32.c
|
$(CC) $(CFLAGS) $(XPM_INC) xpm_w32.c
|
||||||
|
|
||||||
$(OUTDIR)/vim.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h tools.bmp tearoff.bmp \
|
$(OUTDIR)/vim.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h tools.bmp \
|
||||||
vim.ico vim_error.ico vim_alert.ico vim_info.ico vim_quest.ico
|
tearoff.bmp vim.ico vim_error.ico \
|
||||||
|
vim_alert.ico vim_info.ico vim_quest.ico
|
||||||
$(RC) /l 0x409 /Fo$(OUTDIR)/vim.res $(RCFLAGS) vim.rc
|
$(RC) /l 0x409 /Fo$(OUTDIR)/vim.res $(RCFLAGS) vim.rc
|
||||||
|
|
||||||
iid_ole.c if_ole.h vim.tlb: if_ole.idl
|
iid_ole.c if_ole.h vim.tlb: if_ole.idl
|
||||||
|
|||||||
@ -3442,6 +3442,11 @@ set_one_cmd_context(xp, buff)
|
|||||||
*/
|
*/
|
||||||
switch (ea.cmdidx)
|
switch (ea.cmdidx)
|
||||||
{
|
{
|
||||||
|
case CMD_find:
|
||||||
|
case CMD_sfind:
|
||||||
|
case CMD_tabfind:
|
||||||
|
xp->xp_context = EXPAND_FILES_IN_PATH;
|
||||||
|
break;
|
||||||
case CMD_cd:
|
case CMD_cd:
|
||||||
case CMD_chdir:
|
case CMD_chdir:
|
||||||
case CMD_lcd:
|
case CMD_lcd:
|
||||||
|
|||||||
@ -4099,6 +4099,7 @@ addstar(fname, len, context)
|
|||||||
int ends_in_star;
|
int ends_in_star;
|
||||||
|
|
||||||
if (context != EXPAND_FILES
|
if (context != EXPAND_FILES
|
||||||
|
&& context != EXPAND_FILES_IN_PATH
|
||||||
&& context != EXPAND_SHELLCMD
|
&& context != EXPAND_SHELLCMD
|
||||||
&& context != EXPAND_DIRECTORIES)
|
&& context != EXPAND_DIRECTORIES)
|
||||||
{
|
{
|
||||||
@ -4423,7 +4424,9 @@ ExpandFromContext(xp, pat, num_file, file, options)
|
|||||||
if (options & WILD_SILENT)
|
if (options & WILD_SILENT)
|
||||||
flags |= EW_SILENT;
|
flags |= EW_SILENT;
|
||||||
|
|
||||||
if (xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES)
|
if (xp->xp_context == EXPAND_FILES
|
||||||
|
|| xp->xp_context == EXPAND_DIRECTORIES
|
||||||
|
|| xp->xp_context == EXPAND_FILES_IN_PATH)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Expand file or directory names.
|
* Expand file or directory names.
|
||||||
@ -4453,6 +4456,8 @@ ExpandFromContext(xp, pat, num_file, file, options)
|
|||||||
|
|
||||||
if (xp->xp_context == EXPAND_FILES)
|
if (xp->xp_context == EXPAND_FILES)
|
||||||
flags |= EW_FILE;
|
flags |= EW_FILE;
|
||||||
|
else if (xp->xp_context == EXPAND_FILES_IN_PATH)
|
||||||
|
flags |= (EW_FILE | EW_PATH);
|
||||||
else
|
else
|
||||||
flags = (flags | EW_DIR) & ~EW_FILE;
|
flags = (flags | EW_DIR) & ~EW_FILE;
|
||||||
/* Expand wildcards, supporting %:h and the like. */
|
/* Expand wildcards, supporting %:h and the like. */
|
||||||
|
|||||||
211
src/misc1.c
211
src/misc1.c
@ -9217,6 +9217,205 @@ unix_expandpath(gap, path, wildoff, flags, didstar)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(FEAT_SEARCHPATH)
|
||||||
|
static int find_previous_pathsep __ARGS((char_u *path, char_u **psep));
|
||||||
|
static int is_unique __ARGS((char_u *maybe_unique, garray_T *gap, int i));
|
||||||
|
static void uniquefy_paths __ARGS((garray_T *gap, char_u *pattern));
|
||||||
|
static int expand_in_path __ARGS((garray_T *gap, char_u *pattern, int flags));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Moves psep to the previous path separator in path, starting from the
|
||||||
|
* end of path.
|
||||||
|
* Returns FAIL is psep ends up at the beginning of path.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
find_previous_pathsep(path, psep)
|
||||||
|
char_u *path;
|
||||||
|
char_u **psep;
|
||||||
|
{
|
||||||
|
/* skip the current separator */
|
||||||
|
if (*psep > path && vim_ispathsep(**psep))
|
||||||
|
(*psep)--;
|
||||||
|
|
||||||
|
/* find the previous separator */
|
||||||
|
while (*psep > path && !vim_ispathsep(**psep))
|
||||||
|
(*psep)--;
|
||||||
|
|
||||||
|
if (*psep != path && vim_ispathsep(**psep))
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
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(maybe_unique, gap, i)
|
||||||
|
char_u *maybe_unique;
|
||||||
|
garray_T *gap;
|
||||||
|
int i;
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
int candidate_len;
|
||||||
|
int other_path_len;
|
||||||
|
char_u *rival;
|
||||||
|
char_u **other_paths;
|
||||||
|
|
||||||
|
other_paths = (gap->ga_data != NULL) ? (char_u **)gap->ga_data
|
||||||
|
: (char_u **)"";
|
||||||
|
|
||||||
|
for (j = 0; j < gap->ga_len && !got_int; j++)
|
||||||
|
{
|
||||||
|
ui_breakcheck();
|
||||||
|
/* don't compare it with itself */
|
||||||
|
if (j == i)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
candidate_len = STRLEN(maybe_unique);
|
||||||
|
other_path_len = STRLEN(other_paths[j]);
|
||||||
|
|
||||||
|
if (other_path_len < candidate_len)
|
||||||
|
continue; /* it's different */
|
||||||
|
|
||||||
|
rival = other_paths[j] + other_path_len - candidate_len;
|
||||||
|
|
||||||
|
if (fnamecmp(maybe_unique, rival) == 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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(gap, pattern)
|
||||||
|
garray_T *gap;
|
||||||
|
char_u *pattern;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int len;
|
||||||
|
char_u *pathsep_p;
|
||||||
|
char_u *path;
|
||||||
|
char_u **fnames = (char_u **) gap->ga_data;
|
||||||
|
|
||||||
|
int sort_again = 0;
|
||||||
|
char_u *pat;
|
||||||
|
char_u *file_pattern;
|
||||||
|
regmatch_T regmatch;
|
||||||
|
|
||||||
|
/* Remove duplicate entries */
|
||||||
|
sort_strings(fnames, gap->ga_len);
|
||||||
|
for (i = 0; i < gap->ga_len - 1; i++)
|
||||||
|
if (fnamecmp(fnames[i], fnames[i+1]) == 0)
|
||||||
|
{
|
||||||
|
vim_free(fnames[i]);
|
||||||
|
for (j = i+1; j < gap->ga_len; j++)
|
||||||
|
fnames[j-1] = fnames[j];
|
||||||
|
gap->ga_len--;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 pattern?
|
||||||
|
*/
|
||||||
|
len = STRLEN(pattern);
|
||||||
|
file_pattern = alloc(len + 2);
|
||||||
|
file_pattern[0] = '*';
|
||||||
|
file_pattern[1] = '\0';
|
||||||
|
STRCAT(file_pattern, pattern);
|
||||||
|
pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, TRUE);
|
||||||
|
vim_free(file_pattern);
|
||||||
|
regmatch.rm_ic = TRUE; /* always ignore case */
|
||||||
|
|
||||||
|
if (pat != NULL)
|
||||||
|
{
|
||||||
|
regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
|
||||||
|
vim_free(pat);
|
||||||
|
}
|
||||||
|
if (pat == NULL || regmatch.regprog == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < gap->ga_len; i++)
|
||||||
|
{
|
||||||
|
path = fnames[i];
|
||||||
|
len = STRLEN(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, gap, i))
|
||||||
|
{
|
||||||
|
sort_again = 1;
|
||||||
|
mch_memmove(path, pathsep_p + 1, STRLEN(pathsep_p));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sort_again)
|
||||||
|
sort_strings(fnames, gap->ga_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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(gap, pattern, flags)
|
||||||
|
garray_T *gap;
|
||||||
|
char_u *pattern;
|
||||||
|
int flags; /* EW_* flags */
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
char_u *path_option = *curbuf->b_p_path == NUL
|
||||||
|
? p_path : curbuf->b_p_path;
|
||||||
|
char_u *files;
|
||||||
|
char_u *s; /* start */
|
||||||
|
char_u *e; /* end */
|
||||||
|
|
||||||
|
files = globpath(path_option, pattern, 0);
|
||||||
|
if (files == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Copy each path in files into gap */
|
||||||
|
s = e = files;
|
||||||
|
while (*s != '\0')
|
||||||
|
{
|
||||||
|
while (*e != '\n' && *e != '\0')
|
||||||
|
e++;
|
||||||
|
if (*e == '\0')
|
||||||
|
{
|
||||||
|
addfile(gap, s, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* *e is '\n' */
|
||||||
|
*e = '\0';
|
||||||
|
addfile(gap, s, flags);
|
||||||
|
e++;
|
||||||
|
s = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c = gap->ga_len;
|
||||||
|
vim_free(files);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic wildcard expansion code.
|
* Generic wildcard expansion code.
|
||||||
*
|
*
|
||||||
@ -9325,8 +9524,15 @@ gen_expand_wildcards(num_pat, pat, num_file, file, flags)
|
|||||||
* when EW_NOTFOUND is given.
|
* when EW_NOTFOUND is given.
|
||||||
*/
|
*/
|
||||||
if (mch_has_exp_wildcard(p))
|
if (mch_has_exp_wildcard(p))
|
||||||
|
{
|
||||||
|
#if defined(FEAT_SEARCHPATH)
|
||||||
|
if (*p != '.' && !vim_ispathsep(*p) && (flags & EW_PATH))
|
||||||
|
add_pat = expand_in_path(&ga, p, flags);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
add_pat = mch_expandpath(&ga, p, flags);
|
add_pat = mch_expandpath(&ga, p, flags);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND)))
|
if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND)))
|
||||||
{
|
{
|
||||||
@ -9348,6 +9554,11 @@ gen_expand_wildcards(num_pat, pat, num_file, file, flags)
|
|||||||
vim_free(p);
|
vim_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(FEAT_SEARCHPATH)
|
||||||
|
if (flags & EW_PATH)
|
||||||
|
uniquefy_paths(&ga, p);
|
||||||
|
#endif
|
||||||
|
|
||||||
*num_file = ga.ga_len;
|
*num_file = ga.ga_len;
|
||||||
*file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data : (char_u **)"";
|
*file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data : (char_u **)"";
|
||||||
|
|
||||||
|
|||||||
@ -773,6 +773,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
|
|||||||
#define EXPAND_PROFILE 35
|
#define EXPAND_PROFILE 35
|
||||||
#define EXPAND_BEHAVE 36
|
#define EXPAND_BEHAVE 36
|
||||||
#define EXPAND_FILETYPE 37
|
#define EXPAND_FILETYPE 37
|
||||||
|
#define EXPAND_FILES_IN_PATH 38
|
||||||
|
|
||||||
/* Values for exmode_active (0 is no exmode) */
|
/* Values for exmode_active (0 is no exmode) */
|
||||||
#define EXMODE_NORMAL 1
|
#define EXMODE_NORMAL 1
|
||||||
@ -804,6 +805,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
|
|||||||
#define EW_KEEPALL 0x10 /* keep all matches */
|
#define EW_KEEPALL 0x10 /* keep all matches */
|
||||||
#define EW_SILENT 0x20 /* don't print "1 returned" from shell */
|
#define EW_SILENT 0x20 /* don't print "1 returned" from shell */
|
||||||
#define EW_EXEC 0x40 /* executable files */
|
#define EW_EXEC 0x40 /* executable files */
|
||||||
|
#define EW_PATH 0x80 /* search in 'path' too */
|
||||||
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
|
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
|
||||||
* is used when executing commands and EW_SILENT for interactive expanding. */
|
* is used when executing commands and EW_SILENT for interactive expanding. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user