mirror of
https://github.com/vim/vim.git
synced 2025-09-30 04:44:14 -04:00
patch 8.0.1012: MS-Windows: problem with $HOME when is was set internally
Problem: MS-Windows: Problem with $HOME when is was set internally. Solution: Only use the $HOME default internally. (Yasuhiro Matsumoto, closes #2013)
This commit is contained in:
@@ -2278,6 +2278,7 @@ test_arglist \
|
|||||||
test_visual \
|
test_visual \
|
||||||
test_window_cmd \
|
test_window_cmd \
|
||||||
test_window_id \
|
test_window_id \
|
||||||
|
test_windows_home \
|
||||||
test_writefile \
|
test_writefile \
|
||||||
test_alot_latin \
|
test_alot_latin \
|
||||||
test_alot_utf8 \
|
test_alot_utf8 \
|
||||||
|
68
src/misc1.c
68
src/misc1.c
@@ -3750,10 +3750,33 @@ init_homedir(void)
|
|||||||
var = mch_getenv((char_u *)"HOME");
|
var = mch_getenv((char_u *)"HOME");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (var != NULL && *var == NUL) /* empty is same as not set */
|
|
||||||
var = NULL;
|
|
||||||
|
|
||||||
#ifdef WIN3264
|
#ifdef WIN3264
|
||||||
|
/*
|
||||||
|
* Typically, $HOME is not defined on Windows, unless the user has
|
||||||
|
* specifically defined it for Vim's sake. However, on Windows NT
|
||||||
|
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
|
||||||
|
* each user. Try constructing $HOME from these.
|
||||||
|
*/
|
||||||
|
if (var == NULL || *var == NULL)
|
||||||
|
{
|
||||||
|
char_u *homedrive, *homepath;
|
||||||
|
|
||||||
|
homedrive = mch_getenv((char_u *)"HOMEDRIVE");
|
||||||
|
homepath = mch_getenv((char_u *)"HOMEPATH");
|
||||||
|
if (homepath == NULL || *homepath == NUL)
|
||||||
|
homepath = (char_u *)"\\";
|
||||||
|
if (homedrive != NULL
|
||||||
|
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
|
||||||
|
{
|
||||||
|
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
|
||||||
|
if (NameBuff[0] != NUL)
|
||||||
|
var = NameBuff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var == NULL)
|
||||||
|
var = mch_getenv((char_u *)"USERPROFILE");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Weird but true: $HOME may contain an indirect reference to another
|
* Weird but true: $HOME may contain an indirect reference to another
|
||||||
* variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set
|
* variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set
|
||||||
@@ -3774,40 +3797,14 @@ init_homedir(void)
|
|||||||
{
|
{
|
||||||
vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1);
|
vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1);
|
||||||
var = NameBuff;
|
var = NameBuff;
|
||||||
/* Also set $HOME, it's needed for _viminfo. */
|
|
||||||
vim_setenv((char_u *)"HOME", NameBuff);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (var != NULL && *var == NUL) /* empty is same as not set */
|
||||||
* Typically, $HOME is not defined on Windows, unless the user has
|
var = NULL;
|
||||||
* specifically defined it for Vim's sake. However, on Windows NT
|
|
||||||
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
|
|
||||||
* each user. Try constructing $HOME from these.
|
|
||||||
*/
|
|
||||||
if (var == NULL)
|
|
||||||
{
|
|
||||||
char_u *homedrive, *homepath;
|
|
||||||
|
|
||||||
homedrive = mch_getenv((char_u *)"HOMEDRIVE");
|
# ifdef FEAT_MBYTE
|
||||||
homepath = mch_getenv((char_u *)"HOMEPATH");
|
|
||||||
if (homepath == NULL || *homepath == NUL)
|
|
||||||
homepath = (char_u *)"\\";
|
|
||||||
if (homedrive != NULL
|
|
||||||
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
|
|
||||||
{
|
|
||||||
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
|
|
||||||
if (NameBuff[0] != NUL)
|
|
||||||
{
|
|
||||||
var = NameBuff;
|
|
||||||
/* Also set $HOME, it's needed for _viminfo. */
|
|
||||||
vim_setenv((char_u *)"HOME", NameBuff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# if defined(FEAT_MBYTE)
|
|
||||||
if (enc_utf8 && var != NULL)
|
if (enc_utf8 && var != NULL)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@@ -3823,9 +3820,7 @@ init_homedir(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MSWIN)
|
|
||||||
/*
|
/*
|
||||||
* Default home dir is C:/
|
* Default home dir is C:/
|
||||||
* Best assumption we can make in such a situation.
|
* Best assumption we can make in such a situation.
|
||||||
@@ -3833,6 +3828,7 @@ init_homedir(void)
|
|||||||
if (var == NULL)
|
if (var == NULL)
|
||||||
var = (char_u *)"C:/";
|
var = (char_u *)"C:/";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (var != NULL)
|
if (var != NULL)
|
||||||
{
|
{
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
@@ -4661,6 +4657,10 @@ home_replace(
|
|||||||
homedir_env_orig = homedir_env = mch_getenv((char_u *)"SYS$LOGIN");
|
homedir_env_orig = homedir_env = mch_getenv((char_u *)"SYS$LOGIN");
|
||||||
#else
|
#else
|
||||||
homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME");
|
homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME");
|
||||||
|
#endif
|
||||||
|
#ifdef WIN3264
|
||||||
|
if (homedir_env == NULL)
|
||||||
|
homedir_env_orig = homedir_env = mch_getenv((char_u *)"USERPROFILE");
|
||||||
#endif
|
#endif
|
||||||
/* Empty is the same as not set. */
|
/* Empty is the same as not set. */
|
||||||
if (homedir_env != NULL && *homedir_env == NUL)
|
if (homedir_env != NULL && *homedir_env == NUL)
|
||||||
|
@@ -205,7 +205,8 @@ NEW_TESTS = test_arabic.res \
|
|||||||
test_writefile.res \
|
test_writefile.res \
|
||||||
test_alot_latin.res \
|
test_alot_latin.res \
|
||||||
test_alot_utf8.res \
|
test_alot_utf8.res \
|
||||||
test_alot.res
|
test_alot.res \
|
||||||
|
test_windows_home.res
|
||||||
|
|
||||||
|
|
||||||
# Explicit dependencies.
|
# Explicit dependencies.
|
||||||
|
124
src/testdir/test_windows_home.vim
Normal file
124
src/testdir/test_windows_home.vim
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
" 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:exp)
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func TestWindowsHome()
|
||||||
|
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>)
|
||||||
|
|
||||||
|
SaveEnv $HOME $USERPROFILE $HOMEDRIVE $HOMEPATH
|
||||||
|
try
|
||||||
|
RestoreEnv
|
||||||
|
UnletEnv $HOME $USERPROFILE $HOMEPATH
|
||||||
|
let $HOMEDRIVE = 'C:'
|
||||||
|
call CheckHome('C:\')
|
||||||
|
|
||||||
|
RestoreEnv
|
||||||
|
UnletEnv $HOME $USERPROFILE
|
||||||
|
let $HOMEDRIVE = 'C:'
|
||||||
|
let $HOMEPATH = '\foobar'
|
||||||
|
call CheckHome('C:\foobar')
|
||||||
|
|
||||||
|
RestoreEnv
|
||||||
|
UnletEnv $HOME $HOMEDRIVE $HOMEPATH
|
||||||
|
let $USERPROFILE = 'C:\foo'
|
||||||
|
call CheckHome('C:\foo')
|
||||||
|
|
||||||
|
RestoreEnv
|
||||||
|
UnletEnv $HOME
|
||||||
|
let $USERPROFILE = 'C:\foo'
|
||||||
|
let $HOMEDRIVE = 'C:'
|
||||||
|
let $HOMEPATH = '\baz'
|
||||||
|
call CheckHome('C:\foo')
|
||||||
|
|
||||||
|
RestoreEnv
|
||||||
|
let $HOME = 'C:\bar'
|
||||||
|
let $USERPROFILE = 'C:\foo'
|
||||||
|
let $HOMEDRIVE = 'C:'
|
||||||
|
let $HOMEPATH = '\baz'
|
||||||
|
call CheckHome('C:\bar', 1)
|
||||||
|
|
||||||
|
RestoreEnv
|
||||||
|
let $HOME = '%USERPROFILE%\bar'
|
||||||
|
let $USERPROFILE = 'C:\foo'
|
||||||
|
let $HOMEDRIVE = 'C:'
|
||||||
|
let $HOMEPATH = '\baz'
|
||||||
|
call CheckHome('%USERPROFILE%\bar', 1)
|
||||||
|
|
||||||
|
RestoreEnv
|
||||||
|
let $HOME = '%USERPROFILE'
|
||||||
|
let $USERPROFILE = 'C:\foo'
|
||||||
|
let $HOMEDRIVE = 'C:'
|
||||||
|
let $HOMEPATH = '\baz'
|
||||||
|
call CheckHome('%USERPROFILE', 1)
|
||||||
|
|
||||||
|
RestoreEnv
|
||||||
|
let $HOME = 'C:\%USERPROFILE%'
|
||||||
|
let $USERPROFILE = 'C:\foo'
|
||||||
|
let $HOMEDRIVE = 'C:'
|
||||||
|
let $HOMEPATH = '\baz'
|
||||||
|
call CheckHome('C:\%USERPROFILE%', 1)
|
||||||
|
|
||||||
|
if has('channel')
|
||||||
|
RestoreEnv
|
||||||
|
UnletEnv $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
|
@@ -769,6 +769,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1012,
|
||||||
/**/
|
/**/
|
||||||
1011,
|
1011,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user