diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/os/env.c | 22 | ||||
-rw-r--r-- | src/nvim/testdir/Makefile | 1 | ||||
-rw-r--r-- | src/nvim/testdir/runtest.vim | 3 | ||||
-rw-r--r-- | src/nvim/testdir/setup.vim | 11 | ||||
-rw-r--r-- | src/nvim/testdir/test_windows_home.vim | 121 |
5 files changed, 153 insertions, 5 deletions
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 0df857352b..6997156d4c 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -196,16 +196,19 @@ void init_homedir(void) const char *homedrive = os_getenv("HOMEDRIVE"); const char *homepath = os_getenv("HOMEPATH"); if (homepath == NULL) { - homepath = "\\"; + homepath = "\\"; } - if (homedrive != NULL && strlen(homedrive) + strlen(homepath) < MAXPATHL) { + if (homedrive != NULL + && strlen(homedrive) + strlen(homepath) < MAXPATHL) { snprintf(os_buf, MAXPATHL, "%s%s", homedrive, homepath); if (os_buf[0] != NUL) { var = os_buf; - vim_setenv("HOME", os_buf); } } } + if (var == NULL) { + var = os_getenv("USERPROFILE"); + } #endif if (var != NULL) { @@ -608,6 +611,12 @@ char *vim_getenv(const char *name) return xstrdup(kos_env_path); } +#ifdef WIN32 + if (strcmp(name, "HOME") == 0) { + return xstrdup(homedir); + } +#endif + bool vimruntime = (strcmp(name, "VIMRUNTIME") == 0); if (!vimruntime && strcmp(name, "VIM") != 0) { return NULL; @@ -758,7 +767,12 @@ size_t home_replace(const buf_T *const buf, const char_u *src, dirlen = strlen(homedir); } - const char *const homedir_env = os_getenv("HOME"); + const char *homedir_env = os_getenv("HOME"); +#ifdef WIN32 + if (homedir_env == NULL) { + homedir_env = os_getenv("USERPROFILE"); + } +#endif char *homedir_env_mod = (char *)homedir_env; bool must_free = false; diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 87d7ff5bad..0379235ec0 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -116,6 +116,7 @@ NEW_TESTS ?= \ test_visual.res \ test_winbuf_close.res \ test_window_id.res \ + test_windows_home.res \ test_wordcount.res \ test_writefile.res \ test_alot_latin.res \ diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index f2cd84f556..8014b76af7 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -173,6 +173,9 @@ func FinishTesting() " Don't write viminfo on exit. set viminfo= + " Clean up files created by setup.vim + call delete('XfakeHOME', 'rf') + if s:fail == 0 " Success, create the .res file so that make knows it's done. exe 'split ' . fnamemodify(g:testname, ':r') . '.res' diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim index aac9fefef4..f3cc7da70f 100644 --- a/src/nvim/testdir/setup.vim +++ b/src/nvim/testdir/setup.vim @@ -1,5 +1,11 @@ " Common preparations for running tests. +" Only load this once. +if exists('s:did_load') + finish +endif +let s:did_load = 1 + " Align Nvim defaults to Vim. set sidescroll=0 set directory^=. @@ -16,7 +22,10 @@ set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after let &packpath = &rtp " Make sure $HOME does not get read or written. -let $HOME = '/does/not/exist' +let $HOME = expand(getcwd() . '/XfakeHOME') +if !isdirectory($HOME) + call mkdir($HOME) +endif " Use default shell on Windows to avoid segfault, caused by TUI if has('win32') diff --git a/src/nvim/testdir/test_windows_home.vim b/src/nvim/testdir/test_windows_home.vim new file mode 100644 index 0000000000..bbcbf96050 --- /dev/null +++ b/src/nvim/testdir/test_windows_home.vim @@ -0,0 +1,121 @@ +" Test for $HOME on Windows. + +if !has('win32') + finish +endif + +let s:env = {} + +func s:restore_env() + for i in keys(s:env) + exe 'let ' . i . '=s:env["' . i . '"]' + endfor +endfunc + +func s:save_env(...) + for i in a:000 + exe 'let s:env["' . i . '"]=' . i + endfor +endfunc + +func s:unlet_env(...) + for i in a:000 + exe 'let ' . i . '=""' + endfor +endfunc + +func CheckHomeIsMissingFromSubprocessEnvironment() + silent! let out = system('set') + let env = filter(split(out, "\n"), 'v:val=~"^HOME="') + call assert_equal(0, len(env)) +endfunc + +func CheckHomeIsInSubprocessEnvironment(exp) + silent! let out = system('set') + let env = filter(split(out, "\n"), 'v:val=~"^HOME="') + let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '') + call assert_equal(a:exp, home) +endfunc + +func CheckHome(exp, ...) + call assert_equal(a:exp, $HOME) + call assert_equal(a:exp, expand('~', ':p')) + if !a:0 + call CheckHomeIsMissingFromSubprocessEnvironment() + else + call CheckHomeIsInSubprocessEnvironment(a:1) + endif +endfunc + +func Test_WindowsHome() + command! -nargs=* SaveEnv call <SID>save_env(<f-args>) + command! -nargs=* RestoreEnv call <SID>restore_env() + command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>) + set noshellslash + + let save_home = $HOME + SaveEnv $USERPROFILE $HOMEDRIVE $HOMEPATH + try + " Normal behavior: use $HOMEDRIVE and $HOMEPATH, ignore $USERPROFILE + let $USERPROFILE = 'unused' + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\foobar' + let $HOME = '' " Force recomputing "homedir" + call CheckHome('C:\foobar') + + " Same, but with $HOMEPATH not set + UnletEnv $HOMEPATH + let $HOME = '' " Force recomputing "homedir" + call CheckHome('C:\') + + " Use $USERPROFILE if $HOMEPATH and $HOMEDRIVE are empty + UnletEnv $HOMEDRIVE $HOMEPATH + let $USERPROFILE = 'C:\foo' + let $HOME = '' " Force recomputing "homedir" + call CheckHome('C:\foo') + + " If $HOME is set the others don't matter + let $HOME = 'C:\bar' + let $USERPROFILE = 'unused' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + call CheckHome('C:\bar', 'C:\bar') + + " If $HOME contains %USERPROFILE% it is expanded + let $USERPROFILE = 'C:\foo' + let $HOME = '%USERPROFILE%\bar' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + " call CheckHome('C:\foo\bar', '%USERPROFILE%\bar') + + " Invalid $HOME is kept + let $USERPROFILE = 'C:\foo' + let $HOME = '%USERPROFILE' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + call CheckHome('%USERPROFILE', '%USERPROFILE') + + " %USERPROFILE% not at start of $HOME is not expanded + let $USERPROFILE = 'unused' + let $HOME = 'C:\%USERPROFILE%' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + call CheckHome('C:\%USERPROFILE%', 'C:\%USERPROFILE%') + + if has('channel') + RestoreEnv + let $HOME = save_home + let env = '' + let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}}) + sleep 1 + let env = filter(split(env, "\n"), 'v:val=="HOME"') + let home = len(env) == 0 ? "" : env[0] + call assert_equal('', home) + endif + finally + RestoreEnv + delcommand SaveEnv + delcommand RestoreEnv + delcommand UnletEnv + endtry +endfunc |