]> granicus.if.org Git - vim/commitdiff
patch 8.0.0405: v:progpath may become invalid after :cd v8.0.0405
authorBram Moolenaar <Bram@vim.org>
Sat, 4 Mar 2017 13:37:18 +0000 (14:37 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 4 Mar 2017 13:37:18 +0000 (14:37 +0100)
Problem:    v:progpath may become invalid after ":cd".
Solution:   Turn v:progpath into a full path if needed.

runtime/doc/eval.txt
src/main.c
src/testdir/test_startup.vim
src/version.c

index 272c5ea1f838b328abcd80a41532634474f6f6d5..49c955da47149e65333178b74d7935aa57432694 100644 (file)
@@ -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*
index 387221c9d704752cc3e7f8e97fc69e5cacc55794..1da2b84c5b28105e8906f32aba578177a93f2958 100644 (file)
@@ -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)
 
 /*
index 8e3238ca1ecdab4c2d2932591b82e1fc2cfb4276..9d591385fbf2b0c1ef3fd761c75a50877d8e3f61 100644 (file)
@@ -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
index 71d22de51ee90461c9f5f978e984296abc33a3a6..c4ef6ace0d0273712955bd32d0d8a7cb3083b733 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    405,
 /**/
     404,
 /**/