0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 9.1.1159: $MYVIMDIR may not always be set

Problem:  $MYVIMDIR may not always be set (after 9.1.0718)
          (sandwm)
Solution: always set $MYVIMDIR to first item in runtimepath
          (except when using --clean), update it when changing &rtp

fixes: #16609
closes: #16709

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt 2025-02-28 17:34:46 +01:00
parent 5e8b2268e1
commit 3e2affc324
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
5 changed files with 69 additions and 61 deletions

View File

@ -1,4 +1,4 @@
*starting.txt* For Vim version 9.1. Last change: 2024 Dec 19 *starting.txt* For Vim version 9.1. Last change: 2025 Feb 27
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -828,8 +828,9 @@ accordingly. Vim proceeds in this order:
easy to copy it to another system. easy to copy it to another system.
If Vim was started with "-u filename", the file "filename" is used. If Vim was started with "-u filename", the file "filename" is used.
All following initializations until 4. are skipped. $MYVIMRC and All following initializations until 4. are skipped. `$MYVIMRC` and
$MYVIMDIR are not set. `$MYVIMDIR` are not set (but `$MYVIMDIR` will be set, if 'rtp' is
updated).
"vim -u NORC" can be used to skip these initializations without "vim -u NORC" can be used to skip these initializations without
reading a file. "vim -u NONE" also skips loading plugins. |-u| reading a file. "vim -u NONE" also skips loading plugins. |-u|
@ -850,9 +851,9 @@ accordingly. Vim proceeds in this order:
*VIMINIT* *.vimrc* *_vimrc* *EXINIT* *.exrc* *_exrc* *VIMINIT* *.vimrc* *_vimrc* *EXINIT* *.exrc* *_exrc*
*$MYVIMRC* *$MYVIMDIR* *$MYVIMRC* *$MYVIMDIR*
c. Five places are searched for initializations. The first that exists c. Five places are searched for initializations. The first that exists
is used, the others are ignored. The $MYVIMRC environment variable is is used, the others are ignored. The `$MYVIMRC` environment variable is
set to the file that was first found, unless $MYVIMRC was already set set to the file that was first found, unless `$MYVIMRC` was already set
and when using VIMINIT. The $MYVIMDIR environment variable is when using VIMINIT. The `$MYVIMDIR` environment variable is
set to the personal 'rtp' directory, however it is not verified set to the personal 'rtp' directory, however it is not verified
that the directory actually exists. that the directory actually exists.
I The environment variable VIMINIT (see also |compatible-default|) (*) I The environment variable VIMINIT (see also |compatible-default|) (*)
@ -973,9 +974,10 @@ accordingly. Vim proceeds in this order:
The |v:vim_did_enter| variable is set to 1. The |v:vim_did_enter| variable is set to 1.
The |VimEnter| autocommands are executed. The |VimEnter| autocommands are executed.
The $MYVIMRC or $MYGVIMRC environment variable will be set to the first found The `$MYVIMRC` or `$MYGVIMRC` environment variable will be set to the first found
vimrc and/or gvimrc file while $MYVIMDIR is set to the users personal runtime vimrc and/or gvimrc file while `$MYVIMDIR` is set to the users personal runtime
directory 'rtp' (typically the first entry in 'runtimepath'). directory 'rtp' (typically the first entry in 'runtimepath'). If 'rtp'
changes, `$MYVIMDIR` will be updated.
Note: These environment variables resolve symbolic links, but 'rtp' does not. Note: These environment variables resolve symbolic links, but 'rtp' does not.

View File

@ -8418,55 +8418,6 @@ vimrc_found(char_u *fname, char_u *envname)
if (p != NULL) if (p != NULL)
{ {
vim_setenv(envname, p); vim_setenv(envname, p);
if (vim_getenv((char_u *)"MYVIMDIR", &dofree) == NULL)
{
size_t usedlen = 0;
size_t len = 0;
char_u *fbuf = NULL;
if (STRNCMP(gettail(fname), ".vimrc", 6) == 0)
{
len = STRLEN(p) - 2;
p[len] = '/';
}
else if (STRNCMP(gettail(fname), ".gvimrc", 7) == 0)
{
len = STRLEN(p);
char_u *buf = alloc(len);
if (buf != NULL)
{
mch_memmove(buf, fname, len - 7);
mch_memmove(buf + len - 7, (char_u *)".vim/", 5);
len -= 2; // decrement len, so that we can set len+1 = NUL below
vim_free(p);
p = buf;
}
}
#ifdef MSWIN
else if (STRNCMP(gettail(fname), "_vimrc", 6) == 0)
{
len = STRLEN(p) + 4; // remove _vimrc, add vimfiles/
char_u *buf = alloc(len);
if (buf != NULL)
{
mch_memmove(buf, fname, len - 10);
mch_memmove(buf + len - 10, (char_u *)"vimfiles\\", 9);
len -= 2; // decrement len, so that we can set len+1 = NUL below
vim_free(p);
p = buf;
}
}
#endif
else
(void)modify_fname((char_u *)":h", FALSE, &usedlen, &p, &fbuf, &len);
if (p != NULL)
{
// keep the directory separator
p[len + 1] = NUL;
vim_setenv((char_u *)"MYVIMDIR", p);
}
}
vim_free(p); vim_free(p);
} }
} }

View File

@ -135,6 +135,7 @@ static char *(p_sws_values[]) = {"fsync", "sync", NULL};
static int check_opt_strings(char_u *val, char **values, int list); static int check_opt_strings(char_u *val, char **values, int list);
static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, int list); static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, int list);
static void export_myvimdir(void);
/* /*
* After setting various option values: recompute variables that depend on * After setting various option values: recompute variables that depend on
@ -4652,10 +4653,13 @@ did_set_string_option(
setmouse(); // in case 'mouse' changed setmouse(); // in case 'mouse' changed
} }
#if defined(FEAT_LUA) || defined(PROTO)
if (varp == &p_rtp) if (varp == &p_rtp)
{
export_myvimdir();
#if defined(FEAT_LUA) || defined(PROTO)
update_package_paths_in_lua(); update_package_paths_in_lua();
#endif #endif
}
#if defined(FEAT_LINEBREAK) #if defined(FEAT_LINEBREAK)
// Changing Formatlistpattern when briopt includes the list setting: // Changing Formatlistpattern when briopt includes the list setting:
@ -4809,3 +4813,37 @@ restore_shm_value(void)
vim_memset(shm_buf, 0, SHM_LEN); vim_memset(shm_buf, 0, SHM_LEN);
} }
} }
/*
* Export the environment variable $MYVIMDIR to the first item in runtimepath
*/
static void
export_myvimdir()
{
int dofree = FALSE;
char_u *p;
char_u *q = p_rtp;
char_u *buf = alloc(MAXPATHL);
if (buf == NULL)
return;
(void)copy_option_part(&q, buf, MAXPATHL, ",");
p = vim_getenv((char_u *)"MYVIMDIR", &dofree);
if (p == NULL || STRCMP(p, buf) != 0)
{
add_pathsep(buf);
#ifdef MSWIN
// normalize path separators
for (q = buf; *q != NUL; q++)
if (*q == '/')
*q = '\\';
#endif
vim_setenv((char_u *)"MYVIMDIR", buf);
}
if (dofree)
vim_free(p);
vim_free(buf);
}

View File

@ -150,6 +150,19 @@ func Test_xdg_runtime_files()
call system($'{vimcmd} -S Xscript') call system($'{vimcmd} -S Xscript')
call assert_equal([], readfile('Xresult')) call assert_equal([], readfile('Xresult'))
" Test for $MYVIMDIR changes when updating runtimepath
let lines =<< trim END
let msg = $'HOME="{$HOME}", XDG_CONFIG_HOME="{$XDG_CONFIG_HOME}" rtp-prepend'
set rtp^=/non-existing
call assert_match('XfakeHOME/xdg/vim/vimrc', $MYVIMRC, msg)
call assert_match('/non-existing', $MYVIMDIR, msg)
call writefile(v:errors, 'Xresult')
quit
END
call writefile(lines, 'Xscript', 'D')
call system($'{vimcmd} -S Xscript')
call assert_equal([], readfile('Xresult'))
call delete(rc4) call delete(rc4)
unlet $XDG_CONFIG_HOME unlet $XDG_CONFIG_HOME
endfunc endfunc
@ -267,13 +280,14 @@ func Test_zzz_xdg_runtime_files()
call delete(rc2) call delete(rc2)
" Test for ~/.config/vim/gvimrc " Test for ~/.config/vim/gvimrc
" MYVIMDIR is only set to ~/config/.vim if ~/.config/vim/vimrc exists!
let lines =<< trim END let lines =<< trim END
" Ignore the "failed to create input context" error. " Ignore the "failed to create input context" error.
call test_ignore_error('E285') call test_ignore_error('E285')
gui -f gui -f
let msg = $'HOME="{$HOME}", ~="{expand("~")}"' let msg = $'HOME="{$HOME}", ~="{expand("~")}"'
call assert_match('Xhome/\.config/vim/gvimrc', $MYGVIMRC, msg) call assert_match('Xhome/\.config/vim/gvimrc', $MYGVIMRC, msg)
call assert_match('Xhome/\.config/vim/', $MYVIMDIR, msg) call assert_match('Xhome/\.vim/', $MYVIMDIR, msg)
call filter(g:, {idx, _ -> idx =~ '^rc'}) call filter(g:, {idx, _ -> idx =~ '^rc'})
call assert_equal(#{rc_three: 'three', rc: '.config/vim/gvimrc'}, g:) call assert_equal(#{rc_three: 'three', rc: '.config/vim/gvimrc'}, g:)
call writefile(v:errors, 'Xresult') call writefile(v:errors, 'Xresult')
@ -286,6 +300,7 @@ func Test_zzz_xdg_runtime_files()
call delete(rc3) call delete(rc3)
" Test for ~/xdg/vim/gvimrc " Test for ~/xdg/vim/gvimrc
" MYVIMDIR is only set to ~/xdg/vim if ~/xdg/vim/vimrc exists!
let $XDG_CONFIG_HOME=expand('~/xdg/') let $XDG_CONFIG_HOME=expand('~/xdg/')
let lines =<< trim END let lines =<< trim END
" Ignore the "failed to create input context" error. " Ignore the "failed to create input context" error.
@ -293,7 +308,7 @@ func Test_zzz_xdg_runtime_files()
gui -f gui -f
let msg = $'HOME="{$HOME}", XDG_CONFIG_HOME="{$XDG_CONFIG_HOME}"' let msg = $'HOME="{$HOME}", XDG_CONFIG_HOME="{$XDG_CONFIG_HOME}"'
call assert_match('Xhome/xdg/vim/gvimrc', $MYGVIMRC, msg) call assert_match('Xhome/xdg/vim/gvimrc', $MYGVIMRC, msg)
call assert_match('Xhome/xdg/vim/', $MYVIMDIR, msg) call assert_match('Xhome/\.vim/', $MYVIMDIR, msg)
call filter(g:, {idx, _ -> idx =~ '^rc'}) call filter(g:, {idx, _ -> idx =~ '^rc'})
call assert_equal(#{rc_four: 'four', rc: 'xdg/vim/gvimrc'}, g:) call assert_equal(#{rc_four: 'four', rc: 'xdg/vim/gvimrc'}, g:)
call writefile(v:errors, 'Xresult') call writefile(v:errors, 'Xresult')

View File

@ -704,6 +704,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 */
/**/
1159,
/**/ /**/
1158, 1158,
/**/ /**/