summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-03-04 14:37:18 +0100
committerBram Moolenaar <Bram@vim.org>2017-03-04 14:37:18 +0100
commit08cab9608781c975b4acbad875862b842b29258d (patch)
treee29281ee0634fe4d3405873b87dfbfd360c145b4
parent391b1dd040af204b150d43c5a1c97477ee450a28 (diff)
patch 8.0.0405: v:progpath may become invalid after :cdv8.0.0405
Problem: v:progpath may become invalid after ":cd". Solution: Turn v:progpath into a full path if needed.
-rw-r--r--runtime/doc/eval.txt7
-rw-r--r--src/main.c31
-rw-r--r--src/testdir/test_startup.vim14
-rw-r--r--src/version.c2
4 files changed, 50 insertions, 4 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 272c5ea1f8..49c955da47 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1789,8 +1789,11 @@ v:progpath Contains the command with which Vim was invoked, including the
|--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*
diff --git a/src/main.c b/src/main.c
index 387221c9d7..1da2b84c5b 100644
--- 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)
/*
diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim
index 8e3238ca1e..9d591385fb 100644
--- 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
diff --git a/src/version.c b/src/version.c
index 71d22de51e..c4ef6ace0d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 405,
+/**/
404,
/**/
403,