mirror of
https://github.com/neovim/neovim.git
synced 2025-10-07 02:16:31 +00:00
@@ -419,6 +419,7 @@ if(Iconv_LIBRARIES)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
list(APPEND NVIM_LINK_LIBRARIES netapi32)
|
||||||
list(APPEND NVIM_LINK_LIBRARIES ${WINPTY_LIBRARIES})
|
list(APPEND NVIM_LINK_LIBRARIES ${WINPTY_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -13,6 +13,25 @@
|
|||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <lm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add a user name to the list of users in garray_T *users.
|
||||||
|
// Do nothing if user name is NULL or empty.
|
||||||
|
static void add_user(garray_T *users, char *user, bool need_copy)
|
||||||
|
{
|
||||||
|
char *user_copy = (user != NULL && need_copy)
|
||||||
|
? xstrdup(user) : user;
|
||||||
|
|
||||||
|
if (user_copy == NULL || *user_copy == NUL) {
|
||||||
|
if (need_copy) {
|
||||||
|
xfree(user);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GA_APPEND(char *, users, user_copy);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize users garray and fill it with os usernames.
|
// Initialize users garray and fill it with os usernames.
|
||||||
// Return Ok for success, FAIL for failure.
|
// Return Ok for success, FAIL for failure.
|
||||||
@@ -24,16 +43,66 @@ int os_get_usernames(garray_T *users)
|
|||||||
ga_init(users, sizeof(char *), 20);
|
ga_init(users, sizeof(char *), 20);
|
||||||
|
|
||||||
# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
|
# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
|
||||||
|
{
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
setpwent();
|
setpwent();
|
||||||
while ((pw = getpwent()) != NULL) {
|
while ((pw = getpwent()) != NULL) {
|
||||||
// pw->pw_name shouldn't be NULL but just in case...
|
add_user(users, pw->pw_name, true);
|
||||||
if (pw->pw_name != NULL) {
|
|
||||||
GA_APPEND(char *, users, xstrdup(pw->pw_name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
endpwent();
|
endpwent();
|
||||||
|
}
|
||||||
|
# elif defined(WIN32)
|
||||||
|
{
|
||||||
|
DWORD nusers = 0, ntotal = 0, i;
|
||||||
|
PUSER_INFO_0 uinfo;
|
||||||
|
|
||||||
|
if (NetUserEnum(NULL, 0, 0, (LPBYTE *)&uinfo, MAX_PREFERRED_LENGTH,
|
||||||
|
&nusers, &ntotal, NULL) == NERR_Success) {
|
||||||
|
for (i = 0; i < nusers; i++) {
|
||||||
|
char *user;
|
||||||
|
int conversion_result = utf16_to_utf8(uinfo[i].usri0_name, -1, &user);
|
||||||
|
if (conversion_result != 0) {
|
||||||
|
EMSG2("utf16_to_utf8 failed: %d", conversion_result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
add_user(users, user, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetApiBufferFree(uinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# if defined(HAVE_GETPWNAM)
|
||||||
|
{
|
||||||
|
const char *user_env = os_getenv("USER");
|
||||||
|
|
||||||
|
// The $USER environment variable may be a valid remote user name (NIS,
|
||||||
|
// LDAP) not already listed by getpwent(), as getpwent() only lists
|
||||||
|
// local user names. If $USER is not already listed, check whether it
|
||||||
|
// is a valid remote user name using getpwnam() and if it is, add it to
|
||||||
|
// the list of user names.
|
||||||
|
|
||||||
|
if (user_env != NULL && *user_env != NUL) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < users->ga_len; i++) {
|
||||||
|
char *local_user = ((char **)users->ga_data)[i];
|
||||||
|
|
||||||
|
if (STRCMP(local_user, user_env) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == users->ga_len) {
|
||||||
|
struct passwd *pw = getpwnam(user_env); // NOLINT
|
||||||
|
|
||||||
|
if (pw != NULL) {
|
||||||
|
add_user(users, pw->pw_name, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
" Tests for editing the command line.
|
" Tests for editing the command line.
|
||||||
|
|
||||||
|
|
||||||
func Test_complete_tab()
|
func Test_complete_tab()
|
||||||
call writefile(['testfile'], 'Xtestfile')
|
call writefile(['testfile'], 'Xtestfile')
|
||||||
call feedkeys(":e Xtestf\t\r", "tx")
|
call feedkeys(":e Xtestf\t\r", "tx")
|
||||||
@@ -477,6 +476,50 @@ func Test_cmdline_complete_user_cmd()
|
|||||||
delcommand Foo
|
delcommand Foo
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_cmdline_complete_user_names()
|
||||||
|
if has('unix') && executable('whoami')
|
||||||
|
let whoami = systemlist('whoami')[0]
|
||||||
|
let first_letter = whoami[0]
|
||||||
|
if len(first_letter) > 0
|
||||||
|
" Trying completion of :e ~x where x is the first letter of
|
||||||
|
" the user name should complete to at least the user name.
|
||||||
|
call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx')
|
||||||
|
call assert_match('^"e \~.*\<' . whoami . '\>', @:)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
if has('win32')
|
||||||
|
" Just in case: check that the system has an Administrator account.
|
||||||
|
let names = system('net user')
|
||||||
|
if names =~ 'Administrator'
|
||||||
|
" Trying completion of :e ~A should complete to Administrator.
|
||||||
|
call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx')
|
||||||
|
call assert_match('^"e \~Administrator', @:)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
funct Test_cmdline_complete_languages()
|
||||||
|
let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '')
|
||||||
|
|
||||||
|
call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx')
|
||||||
|
call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:)
|
||||||
|
|
||||||
|
if has('unix')
|
||||||
|
" TODO: these tests don't work on Windows. lang appears to be 'C'
|
||||||
|
" but C does not appear in the completion. Why?
|
||||||
|
call assert_match('^"language .*\<' . lang . '\>', @:)
|
||||||
|
|
||||||
|
call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx')
|
||||||
|
call assert_match('^"language .*\<' . lang . '\>', @:)
|
||||||
|
|
||||||
|
call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx')
|
||||||
|
call assert_match('^"language .*\<' . lang . '\>', @:)
|
||||||
|
|
||||||
|
call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx')
|
||||||
|
call assert_match('^"language .*\<' . lang . '\>', @:)
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_cmdline_write_alternatefile()
|
func Test_cmdline_write_alternatefile()
|
||||||
new
|
new
|
||||||
call setline('.', ['one', 'two'])
|
call setline('.', ['one', 'two'])
|
||||||
|
Reference in New Issue
Block a user