commit 1a1c766049826b6049610edda8f72eac1f75b38d
parent 948f2beed4ea55a9c2cce3cff894359b94fba748
Author: Rafael Kitover <rkitover@gmail.com>
Date: Tue, 18 Jun 2024 03:23:52 +0000
refactor: Windows tilde expansion followup (#29380)
Followup to #28515:
Rename the static os_homedir() to os_uv_homedir() to emphasize that it
is a wrapper around a libuv function.
Add the function os_get_homedir() to os/env.c to return the cached
homedir value as a const. Must be called after homedir is initialized or
it fails.
The difference between this function and the static os_uv_homedir() is
that the latter gets the homedir from libuv and is used to initialize
homedir in init_homedir(), while os_get_homedir() just returns homedir
as a const if it's initialized and is public.
Use the os_get_homedir() accessor for ~/ expansion on Windows to make
the code more concise.
Add a Windows section to main_spec.lua with tests for expanding ~/ and
~\ prefixes for files passed in on the command-line.
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
Diffstat:
3 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/src/nvim/main.c b/src/nvim/main.c
@@ -1437,12 +1437,10 @@ scripterror:
// On Windows expand "~\" or "~/" prefix in file names to profile directory.
#ifdef MSWIN
if (*p == '~' && (p[1] == '\\' || p[1] == '/')) {
- char *profile_dir = vim_getenv("HOME");
- size_t size = strlen(profile_dir) + strlen(p);
+ size_t size = strlen(os_get_homedir()) + strlen(p);
char *tilde_expanded = xmalloc(size);
- snprintf(tilde_expanded, size, "%s%s", profile_dir, p + 1);
+ snprintf(tilde_expanded, size, "%s%s", os_get_homedir(), p + 1);
xfree(p);
- xfree(profile_dir);
p = tilde_expanded;
}
#endif
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
@@ -400,17 +400,28 @@ void os_get_hostname(char *hostname, size_t size)
/// 2. if $HOME is not set, try the following
/// For Windows:
/// 1. assemble homedir using HOMEDRIVE and HOMEPATH
-/// 2. try os_homedir()
+/// 2. try os_uv_homedir()
/// 3. resolve a direct reference to another system variable
/// 4. guess C drive
/// For Unix:
-/// 1. try os_homedir()
+/// 1. try os_uv_homedir()
/// 2. go to that directory
/// This also works with mounts and links.
/// Don't do this for Windows, it will change the "current dir" for a drive.
/// 3. fall back to current working directory as a last resort
static char *homedir = NULL;
-static char *os_homedir(void);
+static char *os_uv_homedir(void);
+
+/// Public accessor for the cached "real", resolved user home directory. See
+/// comment on `homedir`.
+const char *os_get_homedir(void)
+{
+ if (!homedir) {
+ emsg("os_get_homedir failed: homedir not initialized");
+ return NULL;
+ }
+ return homedir;
+}
void init_homedir(void)
{
@@ -440,7 +451,7 @@ void init_homedir(void)
}
}
if (var == NULL) {
- var = os_homedir();
+ var = os_uv_homedir();
}
// Weird but true: $HOME may contain an indirect reference to another
@@ -471,7 +482,7 @@ void init_homedir(void)
#ifdef UNIX
if (var == NULL) {
- var = os_homedir();
+ var = os_uv_homedir();
}
// Get the actual path. This resolves links.
@@ -492,7 +503,7 @@ void init_homedir(void)
static char homedir_buf[MAXPATHL];
-static char *os_homedir(void)
+static char *os_uv_homedir(void)
{
homedir_buf[0] = NUL;
size_t homedir_size = MAXPATHL;
diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua
@@ -193,4 +193,26 @@ describe('command-line option', function()
matches('Run "nvim %-V1 %-v"', fn.system({ nvim_prog_abs(), '-v' }))
matches('Compilation: .*Run :checkhealth', fn.system({ nvim_prog_abs(), '-V1', '-v' }))
end)
+
+ if is_os('win') then
+ for _, prefix in ipairs({ '~/', '~\\' }) do
+ it('expands ' .. prefix .. ' on Windows', function()
+ local fname = os.getenv('USERPROFILE') .. '\\nvim_test.txt'
+ finally(function()
+ os.remove(fname)
+ end)
+ write_file(fname, 'some text')
+ eq(
+ 'some text',
+ fn.system({
+ nvim_prog_abs(),
+ '-es',
+ '+%print',
+ '+q',
+ prefix .. 'nvim_test.txt',
+ }):gsub('\n', '')
+ )
+ end)
+ end
+ end
end)