On Thu, Aug 5, 2010 at 12:25 AM, Ajit Thakkar <[email protected]> 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 <[email protected]>
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