vim-patch:8.2.3593: directory is wrong after executing "lcd" with win_execute() (#16314)

Problem:    Directory is wrong after executing "lcd" with win_execute().
Solution:   Correct the directory when going back to the original window.
            (closes vim/vim#9132)
7f13b24ab6
This commit is contained in:
zeertzjq 2021-11-18 10:18:55 +08:00 committed by GitHub
parent dba3590a0e
commit 1f68a21d66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 35 deletions

View File

@ -107,6 +107,18 @@ func Test_win_execute()
call win_gotoid(otherwin)
bwipe!
" check :lcd in another window does not change directory
let curid = win_getid()
let curdir = getcwd()
split Xother
lcd ..
" Use :pwd to get the actual current directory
let otherdir = execute('pwd')
call win_execute(curid, 'lcd testdir')
call assert_equal(otherdir, execute('pwd'))
bwipe!
execute 'cd ' .. curdir
endfunc
func Test_win_execute_update_ruler()

View File

@ -4523,41 +4523,7 @@ static void win_enter_ext(win_T *const wp, const int flags)
}
changed_line_abv_curs(); // assume cursor position needs updating
// New directory is either the local directory of the window, tab or NULL.
char *new_dir = (char *)(curwin->w_localdir
? curwin->w_localdir : curtab->tp_localdir);
char cwd[MAXPATHL];
if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
cwd[0] = NUL;
}
if (new_dir) {
// Window/tab has a local directory: Save current directory as global
// (unless that was done already) and change to the local directory.
if (globaldir == NULL) {
if (cwd[0] != NUL) {
globaldir = (char_u *)xstrdup(cwd);
}
}
if (os_chdir(new_dir) == 0) {
if (!p_acd && pathcmp(new_dir, cwd, -1) != 0) {
do_autocmd_dirchanged(new_dir, curwin->w_localdir
? kCdScopeWindow : kCdScopeTabpage, kCdCauseWindow);
}
shorten_fnames(true);
}
} else if (globaldir != NULL) {
// Window doesn't have a local directory and we are not in the global
// directory: Change to the global directory.
if (os_chdir((char *)globaldir) == 0) {
if (!p_acd && pathcmp((char *)globaldir, cwd, -1) != 0) {
do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow);
}
}
XFREE_CLEAR(globaldir);
shorten_fnames(true);
}
fix_current_dir();
if (flags & WEE_TRIGGER_NEW_AUTOCMDS) {
apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
@ -4602,6 +4568,44 @@ static void win_enter_ext(win_T *const wp, const int flags)
do_autochdir();
}
/// Used after making another window the current one: change directory if needed.
void fix_current_dir(void)
{
// New directory is either the local directory of the window, tab or NULL.
char *new_dir = (char *)(curwin->w_localdir
? curwin->w_localdir : curtab->tp_localdir);
char cwd[MAXPATHL];
if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
cwd[0] = NUL;
}
if (new_dir) {
// Window/tab has a local directory: Save current directory as global
// (unless that was done already) and change to the local directory.
if (globaldir == NULL) {
if (cwd[0] != NUL) {
globaldir = (char_u *)xstrdup(cwd);
}
}
if (os_chdir(new_dir) == 0) {
if (!p_acd && pathcmp(new_dir, cwd, -1) != 0) {
do_autocmd_dirchanged(new_dir, curwin->w_localdir
? kCdScopeWindow : kCdScopeTabpage, kCdCauseWindow);
}
shorten_fnames(true);
}
} else if (globaldir != NULL) {
// Window doesn't have a local directory and we are not in the global
// directory: Change to the global directory.
if (os_chdir((char *)globaldir) == 0) {
if (!p_acd && pathcmp((char *)globaldir, cwd, -1) != 0) {
do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow);
}
}
XFREE_CLEAR(globaldir);
shorten_fnames(true);
}
}
/// Jump to the first open window that contains buffer "buf", if one exists.
/// Returns a pointer to the window found, otherwise NULL.
@ -6624,6 +6628,9 @@ void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab, bool no_dis
curwin = save_curwin;
curbuf = curwin->w_buffer;
}
// If called by win_execute() and executing the command changed the
// directory, it now has to be restored.
fix_current_dir();
}
/// Make "buf" the current buffer.