On Sun, Feb 22, 2009 at 2:17 AM, Nazri Ramliy <[email protected]> wrote:
> Attached patch correct the mentioned problem(s).
I just noticed another problem, with the patch compilation fails when
--with-features=tiny.
Attached patch fixes this problem too.
nazri.
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---
Index: ex_docmd.c
===================================================================
--- ex_docmd.c (revision 1365)
+++ ex_docmd.c (working copy)
@@ -3422,6 +3422,11 @@
*/
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_chdir:
case CMD_lcd:
Index: ex_getln.c
===================================================================
--- ex_getln.c (revision 1365)
+++ ex_getln.c (working copy)
@@ -4063,6 +4063,7 @@
char_u *tail;
if (context != EXPAND_FILES
+ && context != EXPAND_FILES_IN_PATH
&& context != EXPAND_SHELLCMD
&& context != EXPAND_DIRECTORIES)
{
@@ -4377,7 +4378,9 @@
if (options & WILD_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.
@@ -4407,6 +4410,8 @@
if (xp->xp_context == EXPAND_FILES)
flags |= EW_FILE;
+ else if (xp->xp_context == EXPAND_FILES_IN_PATH)
+ flags |= (EW_FILE | EW_PATH);
else
flags = (flags | EW_DIR) & ~EW_FILE;
ret = expand_wildcards(1, &pat, num_file, file, flags);
Index: misc1.c
===================================================================
--- misc1.c (revision 1365)
+++ misc1.c (working copy)
@@ -9097,7 +9097,254 @@
}
#endif
+#if defined(FEAT_SEARCHPATH)
+/*
+ * Expand the files matching pattern, starting from the given path, save
+ * the matches in their equivalent fullpath.
+ */
+ static int
+expand_to_fullpath(path, gap, pattern, flags)
+ char_u *path;
+ garray_T *gap;
+ char_u *pattern;
+ int flags; /* EW_* flags */
+{
+ int i;
+ int c;
+ int old_len;
+ int new_len;
+ char_u **files;
+ char_u *fullpath;
+
+ old_len = gap->ga_len;
+ c = mch_expandpath(gap, pattern, flags);
+
+ files = (gap->ga_data != NULL) ? (char_u **)gap->ga_data : (char_u **)"";
+ new_len = gap->ga_len;
+
+ for(i = old_len; i < new_len; i++)
+ {
+ fullpath = concat_fnames(path, files[i], TRUE);
+ vim_free(files[i]);
+ files[i] = fullpath;
+ }
+ return c;
+}
+
/*
+ * 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;
+{
+ /*
+ * As we're looking for the previous path separator, skip the current
+ * separator.
+ */
+ if (vim_ispathsep(**psep))
+ (*psep)--;
+
+ 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++)
+ {
+ /* 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)
+ /* It's different, */
+ continue;
+
+ 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. Beware, this is at least O(n^2)
+ * wrt gap->ga_len.
+ */
+ static void
+uniquefy_paths(gap)
+ garray_T *gap;
+{
+ int i;
+ int path_len;
+ char_u *pathsep_p;
+ char_u *path;
+ char_u **fnames = (char_u **) gap->ga_data;
+
+ int j;
+ int sort_again = 0;
+
+ /* 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--;
+ }
+
+ for (i = 0; i < gap->ga_len; i++)
+ {
+ path = fnames[i];
+ path_len = STRLEN(path);
+
+ /* We start at the end of the path */
+ pathsep_p = path + path_len - 1;
+
+ while (find_previous_pathsep(path, &pathsep_p))
+ if (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 mch_expandpath for each 'path' values for the given pattern and stores
+ * the result in gap. Returns the total number of match.
+ */
+ static int
+expand_in_path(gap, pattern, flags)
+ garray_T *gap;
+ char_u *pattern;
+ int flags; /* EW_* flags */
+{
+ /*
+ * For each expandable 'path' option values we get the list of all
+ * directories and expand the file names in each the directories.
+ */
+ int c = 0;
+ char_u *cwd = NULL;
+ char_u *cwd_orig = NULL;
+ char_u *path_opt;
+ char_u *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
+
+ if ((cwd_orig = alloc((int)(MAXPATHL))) == NULL ||
+ (cwd = alloc((int)(MAXPATHL))) == NULL ||
+ (path_opt = alloc((int)(MAXPATHL))) == NULL)
+ return 0; /* FIXME Give emsg instead? */
+
+ if (getcwd((char *)cwd_orig, MAXPATHL) == NULL)
+ /* FIXME The directory may have been deleted, is it ok to ignore it? */
+ ;
+
+ /*
+ * Search for matching files in each 'path' options.
+ * TODO Detect circular paths (symbolic links to path)
+ */
+ for(;;)
+ {
+ int i;
+ int dir_count;
+ garray_T ga_dirs;
+
+ path_opt[0] = 0;
+ copy_option_part(&path_option, path_opt, MAXPATHL, " ;,");
+
+ STRCPY(cwd, cwd_orig);
+
+ if (mch_isFullName(path_opt))
+ STRCPY(cwd, path_opt);
+ else
+ {
+ char_u *fullpath;
+
+ fullpath = concat_fnames(cwd_orig, path_opt, TRUE);
+ if (fullpath == NULL)
+ continue; /* FIXME Give emsg too? */
+
+ STRNCPY(cwd, fullpath, MAXPATHL);
+ vim_free(fullpath);
+ }
+
+ ga_init2(&ga_dirs, (int)sizeof(char_u *), 30);
+ dir_count = mch_expandpath(&ga_dirs, cwd, EW_DIR|EW_SILENT);
+
+ if (dir_count == 0)
+ {
+ if (mch_chdir(cwd) == 0)
+ c += expand_to_fullpath(cwd, gap, pattern, flags);
+ }
+ else
+ {
+ /* Add files from each expanded path. */
+ int i;
+ char_u **tmpdirs;
+ tmpdirs = (ga_dirs.ga_data != NULL) ? (char_u **)ga_dirs.ga_data
+ : (char_u **)"";
+ for (i = 0; i < dir_count && !got_int ; i++)
+ {
+ /* FIXME Skip symbolic links to avoid cycle */
+ if (mch_chdir(tmpdirs[i]) == 0)
+ c += expand_to_fullpath(tmpdirs[i], gap, pattern, flags);
+ }
+ }
+ ga_clear_strings(&ga_dirs);
+
+ if (path_option == NULL || *path_option == NUL)
+ break;
+ }
+
+ if (mch_chdir(cwd_orig) != 0)
+ /* FIXME Is it safe to ignore this? */ ;
+
+ vim_free(path_opt);
+ vim_free(cwd);
+ vim_free(cwd_orig);
+
+ return c;
+}
+#endif
+
+/*
* Generic wildcard expansion code.
*
* Characters in "pat" that should not be expanded must be preceded with a
@@ -9205,7 +9452,14 @@
* when EW_NOTFOUND is given.
*/
if (mch_has_exp_wildcard(p))
- add_pat = mch_expandpath(&ga, p, flags);
+ {
+#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);
+ }
}
if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND)))
@@ -9228,6 +9482,11 @@
vim_free(p);
}
+#if defined(FEAT_SEARCHPATH)
+ if (flags & EW_PATH)
+ uniquefy_paths(&ga);
+#endif
+
*num_file = ga.ga_len;
*file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data : (char_u **)"";
Index: vim.h
===================================================================
--- vim.h (revision 1365)
+++ vim.h (working copy)
@@ -708,6 +708,7 @@
#define EXPAND_USER_DEFINED 30
#define EXPAND_USER_LIST 31
#define EXPAND_SHELLCMD 32
+#define EXPAND_FILES_IN_PATH 33
/* Values for exmode_active (0 is no exmode) */
#define EXMODE_NORMAL 1
@@ -739,6 +740,7 @@
#define EW_KEEPALL 0x10 /* keep all matches */
#define EW_SILENT 0x20 /* don't print "1 returned" from shell */
#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
* is used when executing commands and EW_SILENT for interactive expanding. */