Mercurial > vim
changeset 11032:516391d8865f v8.0.0405
patch 8.0.0405: v:progpath may become invalid after :cd
commit https://github.com/vim/vim/commit/08cab9608781c975b4acbad875862b842b29258d
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 4 14:37:18 2017 +0100
patch 8.0.0405: v:progpath may become invalid after :cd
Problem: v:progpath may become invalid after ":cd".
Solution: Turn v:progpath into a full path if needed.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 04 Mar 2017 14:45:05 +0100 |
parents | 4dbc86032a4c |
children | b4517d047b29 |
files | runtime/doc/eval.txt src/main.c src/testdir/test_startup.vim src/version.c |
diffstat | 4 files changed, 50 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1789,8 +1789,11 @@ v:progpath Contains the command with whi |--remote-expr|. To get the full path use: > echo exepath(v:progpath) -< NOTE: This does not work when the command is a relative path - and the current directory has changed. +< If the path is relative it will be expanded to the full path, + so that it still works after `:cd`. Thus starting "./vim" + results in "/home/user/path/to/vim/src/vim". + On MS-Windows the executable may be called "vim.exe", but the + ".exe" is not added to v:progpath. Read-only. *v:register* *register-variable*
--- a/src/main.c +++ b/src/main.c @@ -57,6 +57,9 @@ static void main_start_gui(void); # if defined(HAS_SWAP_EXISTS_ACTION) static void check_swap_exists_action(void); # endif +# ifdef FEAT_EVAL +static void set_progpath(char_u *argv0); +# endif # if defined(FEAT_CLIENTSERVER) || defined(PROTO) static void exec_on_server(mparm_T *parmp); static void prepare_server(mparm_T *parmp); @@ -1694,7 +1697,7 @@ parse_command_name(mparm_T *parmp) #ifdef FEAT_EVAL set_vim_var_string(VV_PROGNAME, initstr, -1); - set_vim_var_string(VV_PROGPATH, (char_u *)parmp->argv[0], -1); + set_progpath((char_u *)parmp->argv[0]); #endif if (TOLOWER_ASC(initstr[0]) == 'r') @@ -3417,7 +3420,7 @@ check_swap_exists_action(void) } #endif -#endif +#endif /* NO_VIM_MAIN */ #if defined(STARTUPTIME) || defined(PROTO) static void time_diff(struct timeval *then, struct timeval *now); @@ -3525,6 +3528,30 @@ time_msg( #endif +#ifndef NO_VIM_MAIN + static void +set_progpath(char_u *argv0) +{ + char_u *val = argv0; + char_u buf[MAXPATHL]; + + /* A relative path containing a "/" will become invalid when using ":cd", + * turn it into a full path. + * On MS-Windows "vim.exe" is found in the current directory, thus also do + * it when there is no path and the file exists. */ + if ( !mch_isFullName(argv0) +# ifdef WIN32 + && mch_can_exe(argv0, NULL, TRUE) +# else + && gettail(argv0) != argv0 +# endif + && vim_FullName(argv0, buf, MAXPATHL, TRUE) != FAIL) + val = buf; + set_vim_var_string(VV_PROGPATH, val, -1); +} + +#endif /* NO_VIM_MAIN */ + #if (defined(FEAT_CLIENTSERVER) && !defined(NO_VIM_MAIN)) || defined(PROTO) /*
--- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -183,3 +183,17 @@ func Test_read_stdin() endif call delete('Xtestout') endfunc + +func Test_progpath() + " Tests normally run with "./vim" or "../vim", these must have been expanded + " to a full path. + if has('unix') + call assert_equal('/', v:progpath[0]) + elseif has('win32') + call assert_equal(':', v:progpath[1]) + call assert_match('[/\\]', v:progpath[2]) + endif + + " Only expect "vim" to appear in v:progname. + call assert_match('vim\c', v:progname) +endfunc