mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
Fix <afile>
getting prepended with a slash on WinClosed (#14515)
It is wrong to assume that you can't shorten a path if it's in `/`: you can always shorten it by removing the forward slash. Closes #14512
This commit is contained in:
parent
c1120ad0e1
commit
ad9c2c069a
@ -180,6 +180,34 @@ const char *path_next_component(const char *fname)
|
||||
return fname;
|
||||
}
|
||||
|
||||
/// Returns the length of the path head on the current platform.
|
||||
/// @return
|
||||
/// - 3 on windows
|
||||
/// - 1 otherwise
|
||||
int path_head_length(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return 3;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Returns true if path begins with characters denoting the head of a path
|
||||
/// (e.g. '/' on linux and 'D:' on windows).
|
||||
/// @param path The path to be checked.
|
||||
/// @return
|
||||
/// - True if path begins with a path head
|
||||
/// - False otherwise
|
||||
bool is_path_head(const char_u *path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return isalpha(path[0]) && path[1] == ':';
|
||||
#else
|
||||
return vim_ispathsep(*path);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Get a pointer to one character past the head of a path name.
|
||||
/// Unix: after "/"; Win: after "c:\"
|
||||
/// If there is no head, path is returned.
|
||||
@ -189,7 +217,7 @@ char_u *get_past_head(const char_u *path)
|
||||
|
||||
#ifdef WIN32
|
||||
// May skip "c:"
|
||||
if (isalpha(path[0]) && path[1] == ':') {
|
||||
if (is_path_head(path)) {
|
||||
retval = path + 2;
|
||||
}
|
||||
#endif
|
||||
@ -1991,10 +2019,24 @@ char_u *path_shorten_fname(char_u *full_path, char_u *dir_name)
|
||||
|
||||
assert(dir_name != NULL);
|
||||
size_t len = strlen((char *)dir_name);
|
||||
|
||||
// If dir_name is a path head, full_path can always be made relative.
|
||||
if (len == (size_t)path_head_length() && is_path_head(dir_name)) {
|
||||
return full_path + len;
|
||||
}
|
||||
|
||||
// If full_path and dir_name do not match, it's impossible to make one
|
||||
// relative to the other.
|
||||
if (fnamencmp(dir_name, full_path, len) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char_u *p = full_path + len;
|
||||
|
||||
if (fnamencmp(dir_name, full_path, len) != 0
|
||||
|| !vim_ispathsep(*p)) {
|
||||
// If *p is not pointing to a path separator, this means that full_path's
|
||||
// last directory name is longer than *dir_name's last directory, so they
|
||||
// don't actually match.
|
||||
if (!vim_ispathsep(*p)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,17 @@ describe('autocmd', function()
|
||||
}, eval('g:evs'))
|
||||
end)
|
||||
|
||||
it('WinClosed from root directory', function()
|
||||
command('cd /')
|
||||
command('let g:evs = []')
|
||||
command('autocmd WinClosed * :call add(g:evs, ["WinClosed", expand("<afile>")])')
|
||||
command('new')
|
||||
command('close')
|
||||
eq({
|
||||
{'WinClosed', '1001'},
|
||||
}, eval('g:evs'))
|
||||
end)
|
||||
|
||||
it('v:vim_did_enter is 1 after VimEnter', function()
|
||||
eq(1, eval('v:vim_did_enter'))
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user