1
0
forked from aniani/vim

updated for version 7.3.631

Problem:    Cannot complete user names.
Solution:   Add user name completion.  (Dominique Pelle)
This commit is contained in:
Bram Moolenaar 2012-08-15 14:05:05 +02:00
parent 2dac213ac6
commit 2430586629
11 changed files with 120 additions and 2 deletions

View File

@ -1244,6 +1244,7 @@ completion can be enabled:
-complete=syntax syntax file names |'syntax'| -complete=syntax syntax file names |'syntax'|
-complete=tag tags -complete=tag tags
-complete=tag_listfiles tags, file names are shown when CTRL-D is hit -complete=tag_listfiles tags, file names are shown when CTRL-D is hit
-complete=user user names
-complete=var user variables -complete=var user variables
-complete=custom,{func} custom completion, defined via {func} -complete=custom,{func} custom completion, defined via {func}
-complete=customlist,{func} custom completion, defined via {func} -complete=customlist,{func} custom completion, defined via {func}

2
src/auto/configure vendored
View File

@ -10631,7 +10631,7 @@ if test "x$vim_cv_getcwd_broken" = "xyes" ; then
fi fi
for ac_func in bcmp fchdir fchown fsync getcwd getpseudotty \ for ac_func in bcmp fchdir fchown fsync getcwd getpseudotty \
getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \ getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigvec strcasecmp strerror strftime stricmp strncasecmp \ sigvec strcasecmp strerror strftime stricmp strncasecmp \

View File

@ -161,6 +161,7 @@
#undef HAVE_FSYNC #undef HAVE_FSYNC
#undef HAVE_GETCWD #undef HAVE_GETCWD
#undef HAVE_GETPSEUDOTTY #undef HAVE_GETPSEUDOTTY
#undef HAVE_GETPWENT
#undef HAVE_GETPWNAM #undef HAVE_GETPWNAM
#undef HAVE_GETPWUID #undef HAVE_GETPWUID
#undef HAVE_GETRLIMIT #undef HAVE_GETRLIMIT

View File

@ -2994,7 +2994,7 @@ fi
dnl Check for functions in one big call, to reduce the size of configure. dnl Check for functions in one big call, to reduce the size of configure.
dnl Can only be used for functions that do not require any include. dnl Can only be used for functions that do not require any include.
AC_CHECK_FUNCS(bcmp fchdir fchown fsync getcwd getpseudotty \ AC_CHECK_FUNCS(bcmp fchdir fchown fsync getcwd getpseudotty \
getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \ getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigvec strcasecmp strerror strftime stricmp strncasecmp \ sigvec strcasecmp strerror strftime stricmp strncasecmp \

View File

@ -3515,6 +3515,23 @@ set_one_cmd_context(xp, buff)
#endif #endif
} }
} }
#if defined(FEAT_CMDL_COMPL)
/* Check for user names */
if (*xp->xp_pattern == '~')
{
for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; ++p)
;
/* Complete ~user only if it partially matches a user name.
* A full match ~user<Tab> will be replaced by user's home
* directory i.e. something like ~user<Tab> -> /home/user/ */
if (*p == NUL && p > xp->xp_pattern + 1
&& match_user(xp->xp_pattern + 1) == 1)
{
xp->xp_context = EXPAND_USER;
++xp->xp_pattern;
}
}
#endif
} }
/* /*
@ -5396,6 +5413,7 @@ static struct
#endif #endif
{EXPAND_TAGS, "tag"}, {EXPAND_TAGS, "tag"},
{EXPAND_TAGS_LISTFILES, "tag_listfiles"}, {EXPAND_TAGS_LISTFILES, "tag_listfiles"},
{EXPAND_USER, "user"},
{EXPAND_USER_VARS, "var"}, {EXPAND_USER_VARS, "var"},
{0, NULL} {0, NULL}
}; };

View File

@ -4336,6 +4336,7 @@ addstar(fname, len, context)
* EXPAND_EXPRESSION Complete internal or user defined function/variable * EXPAND_EXPRESSION Complete internal or user defined function/variable
* names in expressions, eg :while s^I * names in expressions, eg :while s^I
* EXPAND_ENV_VARS Complete environment variable names * EXPAND_ENV_VARS Complete environment variable names
* EXPAND_USER Complete user names
*/ */
static void static void
set_expand_context(xp) set_expand_context(xp)
@ -4681,6 +4682,7 @@ ExpandFromContext(xp, pat, num_file, file, options)
{EXPAND_LOCALES, get_locales, TRUE, FALSE}, {EXPAND_LOCALES, get_locales, TRUE, FALSE},
#endif #endif
{EXPAND_ENV_VARS, get_env_name, TRUE, TRUE}, {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE},
{EXPAND_USER, get_users, TRUE, FALSE},
}; };
int i; int i;

View File

@ -18,6 +18,11 @@ static char_u *vim_version_dir __ARGS((char_u *vimdir));
static char_u *remove_tail __ARGS((char_u *p, char_u *pend, char_u *name)); static char_u *remove_tail __ARGS((char_u *p, char_u *pend, char_u *name));
static int copy_indent __ARGS((int size, char_u *src)); static int copy_indent __ARGS((int size, char_u *src));
/* All user names (for ~user completion as done by shell). */
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
static garray_T ga_users;
#endif
/* /*
* Count the size (in window cells) of the indent in the current line. * Count the size (in window cells) of the indent in the current line.
*/ */
@ -3782,6 +3787,14 @@ free_homedir()
{ {
vim_free(homedir); vim_free(homedir);
} }
# ifdef FEAT_CMDL_COMPL
void
free_users()
{
ga_clear_strings(&ga_users);
}
# endif
#endif #endif
/* /*
@ -4451,6 +4464,80 @@ get_env_name(xp, idx)
return name; return name;
# endif # endif
} }
/*
* Find all user names for user completion.
* Done only once and then cached.
*/
static void
init_users() {
static int lazy_init_done = FALSE;
if (lazy_init_done)
return;
lazy_init_done = TRUE;
ga_init2(&ga_users, sizeof(char_u *), 20);
# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
{
char_u* user;
struct passwd* pw;
setpwent();
while ((pw = getpwent()) != NULL)
/* pw->pw_name shouldn't be NULL but just in case... */
if (pw->pw_name != NULL)
{
if (ga_grow(&ga_users, 1) == FAIL)
break;
user = vim_strsave((char_u*)pw->pw_name);
if (user == NULL)
break;
((char_u **)(ga_users.ga_data))[ga_users.ga_len++] = user;
}
endpwent();
}
# endif
}
/*
* Function given to ExpandGeneric() to obtain an user names.
*/
char_u*
get_users(xp, idx)
expand_T *xp UNUSED;
int idx;
{
init_users();
if (idx < ga_users.ga_len)
return ((char_u **)ga_users.ga_data)[idx];
return NULL;
}
/*
* Check whether name matches a user name. Return:
* 0 if name does not match any user name.
* 1 if name partially matches the beginning of a user name.
* 2 is name fully matches a user name.
*/
int match_user(name)
char_u* name;
{
int i;
int n = (int)STRLEN(name);
int result = 0;
init_users();
for (i = 0; i < ga_users.ga_len; i++)
{
if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0)
return 2; /* full match */
if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0)
result = 1; /* partial match */
}
return result;
}
#endif #endif
/* /*

View File

@ -1110,6 +1110,9 @@ free_all_mem()
free_all_marks(); free_all_marks();
alist_clear(&global_alist); alist_clear(&global_alist);
free_homedir(); free_homedir();
# if defined(FEAT_CMDL_COMPL)
free_users();
# endif
free_search_patterns(); free_search_patterns();
free_old_sub(); free_old_sub();
free_last_insert(); free_last_insert();

View File

@ -50,6 +50,7 @@ void beep_flush __ARGS((void));
void vim_beep __ARGS((void)); void vim_beep __ARGS((void));
void init_homedir __ARGS((void)); void init_homedir __ARGS((void));
void free_homedir __ARGS((void)); void free_homedir __ARGS((void));
void free_users __ARGS((void));
char_u *expand_env_save __ARGS((char_u *src)); char_u *expand_env_save __ARGS((char_u *src));
char_u *expand_env_save_opt __ARGS((char_u *src, int one)); char_u *expand_env_save_opt __ARGS((char_u *src, int one));
void expand_env __ARGS((char_u *src, char_u *dst, int dstlen)); void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
@ -57,6 +58,8 @@ void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, int
char_u *vim_getenv __ARGS((char_u *name, int *mustfree)); char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
void vim_setenv __ARGS((char_u *name, char_u *val)); void vim_setenv __ARGS((char_u *name, char_u *val));
char_u *get_env_name __ARGS((expand_T *xp, int idx)); char_u *get_env_name __ARGS((expand_T *xp, int idx));
char_u *get_users __ARGS((expand_T *xp, int idx));
int match_user __ARGS((char_u* name));
void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one)); void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
char_u *home_replace_save __ARGS((buf_T *buf, char_u *src)); char_u *home_replace_save __ARGS((buf_T *buf, char_u *src));
int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname)); int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname));

View File

@ -714,6 +714,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
631,
/**/ /**/
630, 630,
/**/ /**/

View File

@ -782,6 +782,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
#define EXPAND_OWNSYNTAX 39 #define EXPAND_OWNSYNTAX 39
#define EXPAND_LOCALES 40 #define EXPAND_LOCALES 40
#define EXPAND_HISTORY 41 #define EXPAND_HISTORY 41
#define EXPAND_USER 42
/* Values for exmode_active (0 is no exmode) */ /* Values for exmode_active (0 is no exmode) */
#define EXMODE_NORMAL 1 #define EXMODE_NORMAL 1