Skip to content

Commit c983e6f

Browse files
committed
updated for version 7.3.631
Problem: Cannot complete user names. Solution: Add user name completion. (Dominique Pelle)
1 parent 438dec3 commit c983e6f

File tree

11 files changed

+120
-2
lines changed

11 files changed

+120
-2
lines changed

runtime/doc/map.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,7 @@ completion can be enabled:
12441244
-complete=syntax syntax file names |'syntax'|
12451245
-complete=tag tags
12461246
-complete=tag_listfiles tags, file names are shown when CTRL-D is hit
1247+
-complete=user user names
12471248
-complete=var user variables
12481249
-complete=custom,{func} custom completion, defined via {func}
12491250
-complete=customlist,{func} custom completion, defined via {func}

src/auto/configure

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10631,7 +10631,7 @@ if test "x$vim_cv_getcwd_broken" = "xyes" ; then
1063110631
fi
1063210632

1063310633
for ac_func in bcmp fchdir fchown fsync getcwd getpseudotty \
10634-
getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
10634+
getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
1063510635
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
1063610636
setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
1063710637
sigvec strcasecmp strerror strftime stricmp strncasecmp \

src/config.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
#undef HAVE_FSYNC
162162
#undef HAVE_GETCWD
163163
#undef HAVE_GETPSEUDOTTY
164+
#undef HAVE_GETPWENT
164165
#undef HAVE_GETPWNAM
165166
#undef HAVE_GETPWUID
166167
#undef HAVE_GETRLIMIT

src/configure.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2994,7 +2994,7 @@ fi
29942994
dnl Check for functions in one big call, to reduce the size of configure.
29952995
dnl Can only be used for functions that do not require any include.
29962996
AC_CHECK_FUNCS(bcmp fchdir fchown fsync getcwd getpseudotty \
2997-
getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
2997+
getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
29982998
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
29992999
setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
30003000
sigvec strcasecmp strerror strftime stricmp strncasecmp \

src/ex_docmd.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,6 +3515,23 @@ set_one_cmd_context(xp, buff)
35153515
#endif
35163516
}
35173517
}
3518+
#if defined(FEAT_CMDL_COMPL)
3519+
/* Check for user names */
3520+
if (*xp->xp_pattern == '~')
3521+
{
3522+
for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; ++p)
3523+
;
3524+
/* Complete ~user only if it partially matches a user name.
3525+
* A full match ~user<Tab> will be replaced by user's home
3526+
* directory i.e. something like ~user<Tab> -> /home/user/ */
3527+
if (*p == NUL && p > xp->xp_pattern + 1
3528+
&& match_user(xp->xp_pattern + 1) == 1)
3529+
{
3530+
xp->xp_context = EXPAND_USER;
3531+
++xp->xp_pattern;
3532+
}
3533+
}
3534+
#endif
35183535
}
35193536

35203537
/*
@@ -5396,6 +5413,7 @@ static struct
53965413
#endif
53975414
{EXPAND_TAGS, "tag"},
53985415
{EXPAND_TAGS_LISTFILES, "tag_listfiles"},
5416+
{EXPAND_USER, "user"},
53995417
{EXPAND_USER_VARS, "var"},
54005418
{0, NULL}
54015419
};

src/ex_getln.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4336,6 +4336,7 @@ addstar(fname, len, context)
43364336
* EXPAND_EXPRESSION Complete internal or user defined function/variable
43374337
* names in expressions, eg :while s^I
43384338
* EXPAND_ENV_VARS Complete environment variable names
4339+
* EXPAND_USER Complete user names
43394340
*/
43404341
static void
43414342
set_expand_context(xp)
@@ -4681,6 +4682,7 @@ ExpandFromContext(xp, pat, num_file, file, options)
46814682
{EXPAND_LOCALES, get_locales, TRUE, FALSE},
46824683
#endif
46834684
{EXPAND_ENV_VARS, get_env_name, TRUE, TRUE},
4685+
{EXPAND_USER, get_users, TRUE, FALSE},
46844686
};
46854687
int i;
46864688

src/misc1.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ static char_u *vim_version_dir __ARGS((char_u *vimdir));
1818
static char_u *remove_tail __ARGS((char_u *p, char_u *pend, char_u *name));
1919
static int copy_indent __ARGS((int size, char_u *src));
2020

21+
/* All user names (for ~user completion as done by shell). */
22+
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
23+
static garray_T ga_users;
24+
#endif
25+
2126
/*
2227
* Count the size (in window cells) of the indent in the current line.
2328
*/
@@ -3782,6 +3787,14 @@ free_homedir()
37823787
{
37833788
vim_free(homedir);
37843789
}
3790+
3791+
# ifdef FEAT_CMDL_COMPL
3792+
void
3793+
free_users()
3794+
{
3795+
ga_clear_strings(&ga_users);
3796+
}
3797+
# endif
37853798
#endif
37863799

37873800
/*
@@ -4451,6 +4464,80 @@ get_env_name(xp, idx)
44514464
return name;
44524465
# endif
44534466
}
4467+
4468+
/*
4469+
* Find all user names for user completion.
4470+
* Done only once and then cached.
4471+
*/
4472+
static void
4473+
init_users() {
4474+
static int lazy_init_done = FALSE;
4475+
4476+
if (lazy_init_done)
4477+
return;
4478+
4479+
lazy_init_done = TRUE;
4480+
ga_init2(&ga_users, sizeof(char_u *), 20);
4481+
4482+
# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
4483+
{
4484+
char_u* user;
4485+
struct passwd* pw;
4486+
4487+
setpwent();
4488+
while ((pw = getpwent()) != NULL)
4489+
/* pw->pw_name shouldn't be NULL but just in case... */
4490+
if (pw->pw_name != NULL)
4491+
{
4492+
if (ga_grow(&ga_users, 1) == FAIL)
4493+
break;
4494+
user = vim_strsave((char_u*)pw->pw_name);
4495+
if (user == NULL)
4496+
break;
4497+
((char_u **)(ga_users.ga_data))[ga_users.ga_len++] = user;
4498+
}
4499+
endpwent();
4500+
}
4501+
# endif
4502+
}
4503+
4504+
/*
4505+
* Function given to ExpandGeneric() to obtain an user names.
4506+
*/
4507+
char_u*
4508+
get_users(xp, idx)
4509+
expand_T *xp UNUSED;
4510+
int idx;
4511+
{
4512+
init_users();
4513+
if (idx < ga_users.ga_len)
4514+
return ((char_u **)ga_users.ga_data)[idx];
4515+
return NULL;
4516+
}
4517+
4518+
/*
4519+
* Check whether name matches a user name. Return:
4520+
* 0 if name does not match any user name.
4521+
* 1 if name partially matches the beginning of a user name.
4522+
* 2 is name fully matches a user name.
4523+
*/
4524+
int match_user(name)
4525+
char_u* name;
4526+
{
4527+
int i;
4528+
int n = (int)STRLEN(name);
4529+
int result = 0;
4530+
4531+
init_users();
4532+
for (i = 0; i < ga_users.ga_len; i++)
4533+
{
4534+
if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0)
4535+
return 2; /* full match */
4536+
if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0)
4537+
result = 1; /* partial match */
4538+
}
4539+
return result;
4540+
}
44544541
#endif
44554542

44564543
/*

src/misc2.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,9 @@ free_all_mem()
11101110
free_all_marks();
11111111
alist_clear(&global_alist);
11121112
free_homedir();
1113+
# if defined(FEAT_CMDL_COMPL)
1114+
free_users();
1115+
# endif
11131116
free_search_patterns();
11141117
free_old_sub();
11151118
free_last_insert();

src/proto/misc1.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ void beep_flush __ARGS((void));
5050
void vim_beep __ARGS((void));
5151
void init_homedir __ARGS((void));
5252
void free_homedir __ARGS((void));
53+
void free_users __ARGS((void));
5354
char_u *expand_env_save __ARGS((char_u *src));
5455
char_u *expand_env_save_opt __ARGS((char_u *src, int one));
5556
void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
5657
void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr));
5758
char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
5859
void vim_setenv __ARGS((char_u *name, char_u *val));
5960
char_u *get_env_name __ARGS((expand_T *xp, int idx));
61+
char_u *get_users __ARGS((expand_T *xp, int idx));
62+
int match_user __ARGS((char_u* name));
6063
void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
6164
char_u *home_replace_save __ARGS((buf_T *buf, char_u *src));
6265
int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname));

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,8 @@ static char *(features[]) =
714714

715715
static int included_patches[] =
716716
{ /* Add new patch number below this line */
717+
/**/
718+
631,
717719
/**/
718720
630,
719721
/**/

0 commit comments

Comments
 (0)