On Thu, Aug 5, 2010 at 12:25 AM, Ajit Thakkar <a...@unb.ca> wrote:
> Nazri, for the future, you may want to try and add path completion for :cd
>
> Ajit

Here's a toy patch if you would like to try it out. Thanks for the suggestion.
I've never used 'cdpath' before.

The implementation reuses the same mechanism as the find completion.

>From my cursory tests it seems to work fine on unix for 'cdpath' values set
to default (",,"), empty (set cdpath=), and recursive (set cdpath=~/foo/**).

I'll do a quick test on windows XP ...

It doesn't work as smooth as on unix because completion list have
trailing path separators for all the directories that it found:

        :cd somedirincdpath\

fails, while

        :cd somedirincdpath

or

        :cd somedirincdpath/

works fine.

To fix this the trailing path must be stripped for each completion item
when they are added to the completion list.  Search for the comment
"/* Copy each path in files into gap */" to see where this happen.

I'm running out of time here so I'm attaching the patch as it is now,
warts and all.

nazri.

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
From 6ca0e09bd86271f59efe1a26d815589f284cd857 Mon Sep 17 00:00:00 2001
From: Nazri Ramliy <ayieh...@gmail.com>
Date: Fri, 6 Aug 2010 17:20:00 +0800
Subject: [PATCH] cd, lcd, chdir, and lchdir completion based on 'cdpath'

---
 src/ex_docmd.c |    3 +--
 src/ex_getln.c |    6 +++++-
 src/misc1.c    |   29 +++++++++++++++++++----------
 src/vim.h      |    2 ++
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 0d91a0b..900577d 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3472,8 +3472,7 @@ set_one_cmd_context(xp, buff)
 	case CMD_chdir:
 	case CMD_lcd:
 	case CMD_lchdir:
-	    if (xp->xp_context == EXPAND_FILES)
-		xp->xp_context = EXPAND_DIRECTORIES;
+	    xp->xp_context = EXPAND_DIR_IN_CDPATH;
 	    break;
 	case CMD_help:
 	    xp->xp_context = EXPAND_HELP;
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 8a18a4c..b726e71 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4102,6 +4102,7 @@ addstar(fname, len, context)
 
     if (context != EXPAND_FILES
 	    && context != EXPAND_FILES_IN_PATH
+	    && context != EXPAND_DIR_IN_CDPATH
 	    && context != EXPAND_SHELLCMD
 	    && context != EXPAND_DIRECTORIES)
     {
@@ -4429,7 +4430,8 @@ ExpandFromContext(xp, pat, num_file, file, options)
 
     if (xp->xp_context == EXPAND_FILES
 	    || xp->xp_context == EXPAND_DIRECTORIES
-	    || xp->xp_context == EXPAND_FILES_IN_PATH)
+	    || xp->xp_context == EXPAND_FILES_IN_PATH
+	    || xp->xp_context == EXPAND_DIR_IN_CDPATH)
     {
 	/*
 	 * Expand file or directory names.
@@ -4461,6 +4463,8 @@ ExpandFromContext(xp, pat, num_file, file, options)
 	    flags |= EW_FILE;
 	else if (xp->xp_context == EXPAND_FILES_IN_PATH)
 	    flags |= (EW_FILE | EW_PATH);
+	else if (xp->xp_context == EXPAND_DIR_IN_CDPATH)
+	    flags |= (EW_DIR | EW_CDPATH);
 	else
 	    flags = (flags | EW_DIR) & ~EW_FILE;
 	/* Expand wildcards, supporting %:h and the like. */
diff --git a/src/misc1.c b/src/misc1.c
index ef7c10c..a0bbc8c 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -9238,9 +9238,9 @@ unix_expandpath(gap, path, wildoff, flags, didstar)
 #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 expand_path_option __ARGS((char_u *curdir, garray_T	*gap));
+static void expand_option __ARGS((char_u *curdir, garray_T	*gap, char_u *option));
 static char_u *get_path_cutoff __ARGS((char_u *fname, garray_T *gap));
-static void uniquefy_paths __ARGS((garray_T *gap, char_u *pattern));
+static void uniquefy_paths __ARGS((garray_T *gap, char_u *pattern, char_u *option));
 static int expand_in_path __ARGS((garray_T *gap, char_u	*pattern, int flags));
 
 /*
@@ -9310,12 +9310,11 @@ is_unique(maybe_unique, gap, i)
  * expanding each into their equivalent path(s).
  */
     static void
-expand_path_option(curdir, gap)
+expand_option(curdir, gap, path_option)
     char_u	*curdir;
     garray_T	*gap;
+    char_u	*path_option;
 {
-    char_u	*path_option = *curbuf->b_p_path == NUL
-						  ? p_path : curbuf->b_p_path;
     char_u	*buf;
     char_u	*p;
 
@@ -9424,9 +9423,10 @@ get_path_cutoff(fname, gap)
  * matches the pattern. Beware, this is at least O(n^2) wrt gap->ga_len.
  */
     static void
-uniquefy_paths(gap, pattern)
+uniquefy_paths(gap, pattern, path_option)
     garray_T	*gap;
     char_u	*pattern;
+    char_u	*path_option;
 {
     int		i;
     int		len;
@@ -9468,7 +9468,7 @@ uniquefy_paths(gap, pattern)
 	return;
     mch_dirname(curdir, MAXPATHL);
 
-    expand_path_option(curdir, &path_ga);
+    expand_option(curdir, &path_ga, path_option);
 
     for (i = 0; i < gap->ga_len; i++)
     {
@@ -9582,12 +9582,17 @@ expand_in_path(gap, pattern, flags)
     char_u	*s;	/* start */
     char_u	*e;	/* end */
     char_u	*paths = NULL;
+    char_u	*path_option;
 
     if ((curdir = alloc((unsigned)MAXPATHL)) == NULL)
 	return 0;
     mch_dirname(curdir, MAXPATHL);
 
-    expand_path_option(curdir, &path_ga);
+    if (flags & EW_FILE)
+	path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
+    else if (flags & EW_DIR)
+	path_option = p_cdpath;
+    expand_option(curdir, &path_ga, path_option);
     vim_free(curdir);
     if (path_ga.ga_len == 0)
 	return 0;
@@ -9762,7 +9767,8 @@ gen_expand_wildcards(num_pat, pat, num_file, file, flags)
 	    if (mch_has_exp_wildcard(p))
 	    {
 #if defined(FEAT_SEARCHPATH)
-		if (*p != '.' && !vim_ispathsep(*p) && (flags & EW_PATH))
+		if (*p != '.' && !vim_ispathsep(*p) && (flags & EW_PATH
+							  || flags & EW_CDPATH))
 		{
 		    /* recursiveness is OK here */
 		    recursive = FALSE;
@@ -9793,7 +9799,10 @@ gen_expand_wildcards(num_pat, pat, num_file, file, flags)
 
 #if defined(FEAT_SEARCHPATH)
 	if (flags & EW_PATH)
-	    uniquefy_paths(&ga, p);
+	    uniquefy_paths(&ga, p, *curbuf->b_p_path == NUL ? p_path :
+							      curbuf->b_p_path);
+	else if (flags & EW_CDPATH)
+	    uniquefy_paths(&ga, p, p_cdpath);
 #endif
 	if (p != pat[i])
 	    vim_free(p);
diff --git a/src/vim.h b/src/vim.h
index b9ce325..8b07b2c 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -776,6 +776,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 #define EXPAND_FILETYPE		37
 #define EXPAND_FILES_IN_PATH	38
 #define EXPAND_OWNSYNTAX	39
+#define EXPAND_DIR_IN_CDPATH	40
 
 /* Values for exmode_active (0 is no exmode) */
 #define EXMODE_NORMAL		1
@@ -808,6 +809,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 #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 */
+#define EW_CDPATH	0x100	/* search in 'cdpath' */
 /* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
  * is used when executing commands and EW_SILENT for interactive expanding. */
 
-- 
1.7.2.1.6.g61bf12

Raspunde prin e-mail lui