aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/os/env.c22
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/runtest.vim3
-rw-r--r--src/nvim/testdir/setup.vim11
-rw-r--r--src/nvim/testdir/test_windows_home.vim121
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