Windows: vim_getenv(): Find runtime relative to nvim. #3303 (#5929)

In Windows we cannot rely on absolute install paths to point to the
location of the runtime. Vim uses the path of the current binary as
a possible location for the runtime folder. In Neovim the install
location places the runtime folder in ../share/nvim/runtime.

In Vim this logic is guarded by USE_EXE_NAME, which is defined for win32
and macOS.

TODO: We may need to incorporate similar logic for macOS:
0cdb72aa38/src/misc1.c (L4287-L4308)
This commit is contained in:
Justin M. Keyes 2017-01-11 06:00:55 +01:00 committed by GitHub
parent a08d2f54a0
commit 207ba359b0
2 changed files with 35 additions and 2 deletions

View File

@ -560,8 +560,8 @@ const void *vim_colon_env_iter_rev(const char *const val,
/// Vim's version of getenv().
/// Special handling of $HOME, $VIM and $VIMRUNTIME, allowing the user to
/// override the vim runtime directory at runtime. Also does ACP to 'enc'
/// conversion for Win32. Results must be freed by the calling function.
/// @param name Name of environment variable to expand
/// conversion for Win32. Result must be freed by the caller.
/// @param name Environment variable to expand
char *vim_getenv(const char *name)
{
const char *kos_env_path = os_getenv(name);
@ -598,6 +598,27 @@ char *vim_getenv(const char *name)
if (p_hf != NULL && vim_strchr(p_hf, '$') == NULL) {
vim_path = (char *)p_hf;
}
#ifdef WIN32
// Find runtime path relative to the nvim binary i.e. ../share/runtime
if (vim_path == NULL) {
char exe_name[MAXPATHL];
size_t exe_name_len = MAXPATHL;
if (os_exepath(exe_name, &exe_name_len) == 0) {
char *path_end = (char *)path_tail_with_sep((char_u *)exe_name);
*path_end = '\0'; // remove the trailing "nvim.exe"
path_end = (char *)path_tail((char_u *)exe_name);
*path_end = '\0'; // remove the trailing "bin/"
if (append_path(
exe_name,
"share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR,
MAXPATHL) == OK) {
vim_path = exe_name;
}
}
}
#endif
if (vim_path != NULL) {
// remove the file name
char *vim_path_end = (char *)path_tail((char_u *)vim_path);

View File

@ -192,6 +192,18 @@ int os_nodetype(const char *name)
return nodetype;
}
/// Gets the absolute path of the currently running executable.
///
/// @param[out] buffer Returns the path string.
/// @param[in] size Size of `buffer`.
///
/// @return `0` on success, or libuv error code on failure.
int os_exepath(char *buffer, size_t *size)
FUNC_ATTR_NONNULL_ALL
{
return uv_exepath(buffer, size);
}
/// Checks if the given path represents an executable file.
///
/// @param[in] name Name of the executable.