From 14c611ed7788fe68f5752ed29ab295a2f0e7c21e Mon Sep 17 00:00:00 2001 From: erw7 Date: Sun, 13 Oct 2019 17:34:08 +0900 Subject: vim-patch 8.1.0084: user name completion does not work on MS-Windows Problem: User name completion does not work on MS-Windows. Solution: Use NetUserEnum() to get user names. (Yasuhiro Matsumoto) https://github.com/vim/vim/commit/828c3d70833a0689cc07581f2a67d06430675da5 --- src/nvim/CMakeLists.txt | 1 + src/nvim/os/users.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index a64944ab0d..b00ac866b7 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -419,6 +419,7 @@ if(Iconv_LIBRARIES) endif() if(WIN32) + list(APPEND NVIM_LINK_LIBRARIES netapi32) list(APPEND NVIM_LINK_LIBRARIES ${WINPTY_LIBRARIES}) endif() diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index c6463c2c92..b24232b680 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -13,6 +13,9 @@ #ifdef HAVE_PWD_H # include #endif +#ifdef WIN32 +# include +#endif // Initialize users garray and fill it with os usernames. // Return Ok for success, FAIL for failure. @@ -34,6 +37,26 @@ int os_get_usernames(garray_T *users) } } 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; + } + GA_APPEND(char *, users, user); + } + + NetApiBufferFree(uinfo); + } + } # endif return OK; -- cgit From b89e970cfb472af021e56438a5147dd698e66376 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sun, 13 Oct 2019 17:48:01 +0900 Subject: vim-patch 8.1.0085: no test for completing user name and language Problem: No test for completing user name and language. Solution: Add tests. (Dominique Pelle, closes #2978) https://github.com/vim/vim/commit/5f8f2d378a4f6d7db12806f3e35ec6f7fc6bd1f3 --- src/nvim/testdir/test_cmdline.vim | 45 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index e6aafd964b..0a3e6ae625 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -1,6 +1,5 @@ " Tests for editing the command line. - func Test_complete_tab() call writefile(['testfile'], 'Xtestfile') call feedkeys(":e Xtestf\t\r", "tx") @@ -477,6 +476,50 @@ func Test_cmdline_complete_user_cmd() delcommand Foo 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 . "\\\"\", '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' . "\\\"\", 'tx') + call assert_match('^"e \~Administrator', @:) + endif + endif +endfunc + +funct Test_cmdline_complete_languages() + let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '') + + call feedkeys(":language \\\"\", 'tx') + call assert_match('^"language .*\.*\.*\', @:) + + 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 \\\"\", 'tx') + call assert_match('^"language .*\<' . lang . '\>', @:) + + call feedkeys(":language ctype \\\"\", 'tx') + call assert_match('^"language .*\<' . lang . '\>', @:) + + call feedkeys(":language time \\\"\", 'tx') + call assert_match('^"language .*\<' . lang . '\>', @:) + endif +endfunc + func Test_cmdline_write_alternatefile() new call setline('.', ['one', 'two']) -- cgit From 8add4cb8fd39b0f6462f0dc064c7534d66326faf Mon Sep 17 00:00:00 2001 From: erw7 Date: Mon, 14 Oct 2019 14:44:18 +0900 Subject: vim-patch 8.1.0361: remote user not used for completion Problem: Remote user not used for completion. (Stucki) Solution: Use $USER too. (Dominique Pelle, closes #3407) https://github.com/vim/vim/commit/6b0b83f768cf536b34ce4d3f2de6bf62324229aa --- src/nvim/os/users.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index b24232b680..9374693550 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -17,6 +17,22 @@ # include #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. // Return Ok for success, FAIL for failure. int os_get_usernames(garray_T *users) @@ -27,16 +43,15 @@ int os_get_usernames(garray_T *users) ga_init(users, sizeof(char *), 20); # if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) - struct passwd *pw; + { + struct passwd *pw; - setpwent(); - while ((pw = getpwent()) != NULL) { - // pw->pw_name shouldn't be NULL but just in case... - if (pw->pw_name != NULL) { - GA_APPEND(char *, users, xstrdup(pw->pw_name)); + setpwent(); + while ((pw = getpwent()) != NULL) { + add_user(users, pw->pw_name, true); } + endpwent(); } - endpwent(); # elif defined(WIN32) { DWORD nusers = 0, ntotal = 0, i; @@ -51,13 +66,44 @@ int os_get_usernames(garray_T *users) EMSG2("utf16_to_utf8 failed: %d", conversion_result); break; } - GA_APPEND(char *, users, user); + 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 return OK; } -- cgit