diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-04-27 20:37:57 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-04-27 20:37:57 +0200 |
commit | 00aa069db8132851a91cfc5ca7f58ef945c75c73 (patch) | |
tree | 54e88e9f1c4a981eb265015eabdc2cde2931cc5e /src | |
parent | 2155a6abaa5d065ad7b580229321860591126f2e (diff) |
patch 8.1.1218: cannot set a directory for a tab pagev8.1.1218
Problem: Cannot set a directory for a tab page.
Solution: Add the tab-local directory. (Yegappan Lakshmanan, closes #4212)
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 18 | ||||
-rw-r--r-- | src/evalfunc.c | 41 | ||||
-rw-r--r-- | src/ex_cmdidxs.h | 16 | ||||
-rw-r--r-- | src/ex_cmds.h | 6 | ||||
-rw-r--r-- | src/ex_docmd.c | 54 | ||||
-rw-r--r-- | src/if_py_both.h | 2 | ||||
-rw-r--r-- | src/proto/eval.pro | 2 | ||||
-rw-r--r-- | src/proto/ex_docmd.pro | 2 | ||||
-rw-r--r-- | src/structs.h | 3 | ||||
-rw-r--r-- | src/testdir/test_getcwd.vim | 152 | ||||
-rw-r--r-- | src/testdir/test_mksession.vim | 42 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/window.c | 24 |
13 files changed, 329 insertions, 35 deletions
diff --git a/src/eval.c b/src/eval.c index a1ad0e673b..0a16900262 100644 --- a/src/eval.c +++ b/src/eval.c @@ -8704,11 +8704,13 @@ find_win_by_nr_or_id(typval_T *vp) /* * Find window specified by "wvp" in tabpage "tvp". + * Returns the tab page in 'ptp' */ win_T * find_tabwin( - typval_T *wvp, /* VAR_UNKNOWN for current window */ - typval_T *tvp) /* VAR_UNKNOWN for current tab page */ + typval_T *wvp, // VAR_UNKNOWN for current window + typval_T *tvp, // VAR_UNKNOWN for current tab page + tabpage_T **ptp) { win_T *wp = NULL; tabpage_T *tp = NULL; @@ -8726,10 +8728,22 @@ find_tabwin( tp = curtab; if (tp != NULL) + { wp = find_win_by_nr(wvp, tp); + if (wp == NULL && wvp->v_type == VAR_NUMBER + && wvp->vval.v_number != -1) + // A window with the specified number is not found + tp = NULL; + } } else + { wp = curwin; + tp = curtab; + } + + if (ptp != NULL) + *ptp = tp; return wp; } diff --git a/src/evalfunc.c b/src/evalfunc.c index 58b8492e56..509a31f0e6 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -1529,7 +1529,7 @@ f_arglistid(typval_T *argvars, typval_T *rettv) win_T *wp; rettv->vval.v_number = -1; - wp = find_tabwin(&argvars[0], &argvars[1]); + wp = find_tabwin(&argvars[0], &argvars[1], NULL); if (wp != NULL) rettv->vval.v_number = wp->w_alist->id; } @@ -5126,25 +5126,44 @@ f_getcompletion(typval_T *argvars, typval_T *rettv) /* * "getcwd()" function + * + * Return the current working directory of a window in a tab page. + * First optional argument 'winnr' is the window number or -1 and the second + * optional argument 'tabnr' is the tab page number. + * + * If no arguments are supplied, then return the directory of the current + * window. + * If only 'winnr' is specified and is not -1 or 0 then return the directory of + * the specified window. + * If 'winnr' is 0 then return the directory of the current window. + * If both 'winnr and 'tabnr' are specified and 'winnr' is -1 then return the + * directory of the specified tab page. Otherwise return the directory of the + * specified window in the specified tab page. + * If the window or the tab page doesn't exist then return NULL. */ static void f_getcwd(typval_T *argvars, typval_T *rettv) { win_T *wp = NULL; + tabpage_T *tp = NULL; char_u *cwd; int global = FALSE; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - if (argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number == -1) + if (argvars[0].v_type == VAR_NUMBER + && argvars[0].vval.v_number == -1 + && argvars[1].v_type == VAR_UNKNOWN) global = TRUE; else - wp = find_tabwin(&argvars[0], &argvars[1]); + wp = find_tabwin(&argvars[0], &argvars[1], &tp); if (wp != NULL && wp->w_localdir != NULL) rettv->vval.v_string = vim_strsave(wp->w_localdir); - else if (wp != NULL || global) + else if (tp != NULL && tp->tp_localdir != NULL) + rettv->vval.v_string = vim_strsave(tp->tp_localdir); + else if (wp != NULL || tp != NULL || global) { if (globaldir != NULL) rettv->vval.v_string = vim_strsave(globaldir); @@ -5333,7 +5352,7 @@ f_getjumplist(typval_T *argvars, typval_T *rettv) return; #ifdef FEAT_JUMPLIST - wp = find_tabwin(&argvars[0], &argvars[1]); + wp = find_tabwin(&argvars[0], &argvars[1], NULL); if (wp == NULL) return; @@ -6824,10 +6843,18 @@ f_has_key(typval_T *argvars, typval_T *rettv) static void f_haslocaldir(typval_T *argvars, typval_T *rettv) { + tabpage_T *tp = NULL; win_T *wp = NULL; - wp = find_tabwin(&argvars[0], &argvars[1]); - rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL); + wp = find_tabwin(&argvars[0], &argvars[1], &tp); + + // Check for window-local and tab-local directories + if (wp != NULL && wp->w_localdir != NULL) + rettv->vval.v_number = 1; + else if (tp != NULL && tp->tp_localdir != NULL) + rettv->vval.v_number = 2; + else + rettv->vval.v_number = 0; } /* diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h index feea5b2bae..1531e68c1b 100644 --- a/src/ex_cmdidxs.h +++ b/src/ex_cmdidxs.h @@ -25,12 +25,12 @@ static const unsigned short cmdidxs1[26] = /* r */ 351, /* s */ 371, /* t */ 439, - /* u */ 482, - /* v */ 493, - /* w */ 511, - /* x */ 525, - /* y */ 534, - /* z */ 535 + /* u */ 484, + /* v */ 495, + /* w */ 513, + /* x */ 527, + /* y */ 536, + /* z */ 537 }; /* @@ -60,7 +60,7 @@ static const unsigned char cmdidxs2[26][26] = /* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 19, 0, 0, 0, 0 }, /* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 49, 0, 50, 0, 62, 63, 0, 64, 0 }, - /* t */ { 2, 0, 19, 0, 22, 24, 0, 25, 0, 26, 0, 27, 31, 34, 36, 37, 0, 38, 40, 0, 41, 0, 0, 0, 0, 0 }, + /* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 28, 0, 29, 33, 36, 38, 39, 0, 40, 42, 0, 43, 0, 0, 0, 0, 0 }, /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* v */ { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 12, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0 }, /* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 12, 13, 0, 0, 0, 0 }, @@ -69,4 +69,4 @@ static const unsigned char cmdidxs2[26][26] = /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; -static const int command_count = 548; +static const int command_count = 550; diff --git a/src/ex_cmds.h b/src/ex_cmds.h index ac354cda24..27029baf0b 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -1479,6 +1479,12 @@ EX(CMD_tabrewind, "tabrewind", ex_tabnext, EX(CMD_tabs, "tabs", ex_tabs, TRLBAR|CMDWIN, ADDR_TABS), +EX(CMD_tcd, "tcd", ex_cd, + BANG|FILE1|TRLBAR|CMDWIN, + ADDR_OTHER), +EX(CMD_tchdir, "tchdir", ex_cd, + BANG|FILE1|TRLBAR|CMDWIN, + ADDR_OTHER), EX(CMD_tcl, "tcl", ex_tcl, RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT, ADDR_LINES), diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 0086589342..7444697834 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3692,6 +3692,8 @@ set_one_cmd_context( break; case CMD_cd: case CMD_chdir: + case CMD_tcd: + case CMD_tchdir: case CMD_lcd: case CMD_lchdir: if (xp->xp_context == EXPAND_FILES) @@ -7435,13 +7437,17 @@ free_cd_dir(void) /* * Deal with the side effects of changing the current directory. - * When "local" is TRUE then this was after an ":lcd" command. + * When "tablocal" is TRUE then this was after an ":tcd" command. + * When "winlocal" is TRUE then this was after an ":lcd" command. */ void -post_chdir(int local) +post_chdir(int tablocal, int winlocal) { + if (!winlocal) + // Clear tab local directory for both :cd and :tcd + VIM_CLEAR(curtab->tp_localdir); VIM_CLEAR(curwin->w_localdir); - if (local) + if (winlocal || tablocal) { /* If still in global directory, need to remember current * directory as global directory. */ @@ -7449,7 +7455,12 @@ post_chdir(int local) globaldir = vim_strsave(prev_dir); /* Remember this local directory for the window. */ if (mch_dirname(NameBuff, MAXPATHL) == OK) - curwin->w_localdir = vim_strsave(NameBuff); + { + if (tablocal) + curtab->tp_localdir = vim_strsave(NameBuff); + else + curwin->w_localdir = vim_strsave(NameBuff); + } } else { @@ -7463,7 +7474,7 @@ post_chdir(int local) /* - * ":cd", ":lcd", ":chdir" and ":lchdir". + * ":cd", ":tcd", ":lcd", ":chdir" ":tchdir" and ":lchdir". */ void ex_cd(exarg_T *eap) @@ -7532,19 +7543,29 @@ ex_cd(exarg_T *eap) emsg(_(e_failed)); else { - int is_local_chdir = eap->cmdidx == CMD_lcd + char_u *acmd_fname; + int is_winlocal_chdir = eap->cmdidx == CMD_lcd || eap->cmdidx == CMD_lchdir; + int is_tablocal_chdir = eap->cmdidx == CMD_tcd + || eap->cmdidx == CMD_tchdir; - post_chdir(is_local_chdir); + post_chdir(is_tablocal_chdir, is_winlocal_chdir); /* Echo the new current directory if the command was typed. */ if (KeyTyped || p_verbose >= 5) ex_pwd(eap); if (dir_differs) - apply_autocmds(EVENT_DIRCHANGED, - is_local_chdir ? (char_u *)"window" : (char_u *)"global", + { + if (is_winlocal_chdir) + acmd_fname = (char_u *)"window"; + else if (is_tablocal_chdir) + acmd_fname = (char_u *)"tabpage"; + else + acmd_fname = (char_u *)"global"; + apply_autocmds(EVENT_DIRCHANGED, acmd_fname, new_dir, FALSE, curbuf); + } } vim_free(tofree); } @@ -9729,12 +9750,13 @@ makeopens( } for (tabnr = 1; ; ++tabnr) { + tabpage_T *tp = NULL; int need_tabnext = FALSE; int cnr = 1; if ((ssop_flags & SSOP_TABPAGES)) { - tabpage_T *tp = find_tabpage(tabnr); + tp = find_tabpage(tabnr); if (tp == NULL) break; /* done all tab pages */ @@ -9833,6 +9855,18 @@ makeopens( if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL) return FAIL; + // Restore the tab-local working directory if specified + // Do this before the windows, so that the window-local directory can + // override the tab-local directory. + if (tp != NULL && tp->tp_localdir != NULL && ssop_flags & SSOP_CURDIR) + { + if (fputs("tcd ", fd) < 0 + || ses_put_fname(fd, tp->tp_localdir, &ssop_flags) == FAIL + || put_eol(fd) == FAIL) + return FAIL; + did_lcd = TRUE; + } + /* * Restore the view of the window (options, file, cursor, etc.). */ diff --git a/src/if_py_both.h b/src/if_py_both.h index 20affe31db..ede2f5cde4 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -1032,7 +1032,7 @@ _VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs) Py_DECREF(newwd); Py_XDECREF(todecref); - post_chdir(FALSE); + post_chdir(FALSE, FALSE); if (VimTryEnd()) { diff --git a/src/proto/eval.pro b/src/proto/eval.pro index 0e6182f016..f501300a38 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -116,7 +116,7 @@ void ex_echohl(exarg_T *eap); void ex_execute(exarg_T *eap); win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp); win_T *find_win_by_nr_or_id(typval_T *vp); -win_T *find_tabwin(typval_T *wvp, typval_T *tvp); +win_T *find_tabwin(typval_T *wvp, typval_T *tvp, tabpage_T **ptp); void getwinvar(typval_T *argvars, typval_T *rettv, int off); void setwinvar(typval_T *argvars, typval_T *rettv, int off); char_u *autoload_name(char_u *name); diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro index 710f48b781..9934d60fcb 100644 --- a/src/proto/ex_docmd.pro +++ b/src/proto/ex_docmd.pro @@ -37,7 +37,7 @@ void ex_splitview(exarg_T *eap); void tabpage_new(void); void do_exedit(exarg_T *eap, win_T *old_curwin); void free_cd_dir(void); -void post_chdir(int local); +void post_chdir(int tablocal, int winlocal); void ex_cd(exarg_T *eap); void do_sleep(long msec); void ex_may_print(exarg_T *eap); diff --git a/src/structs.h b/src/structs.h index 89749e5c21..40e87d5500 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2574,6 +2574,9 @@ struct tabpage_S int tp_prev_which_scrollbars[3]; /* previous value of which_scrollbars */ #endif + + char_u *tp_localdir; // absolute path of local directory or + // NULL #ifdef FEAT_DIFF diff_T *tp_first_diff; buf_T *(tp_diffbuf[DB_COUNT]); diff --git a/src/testdir/test_getcwd.vim b/src/testdir/test_getcwd.vim index ca098781e4..50c940febe 100644 --- a/src/testdir/test_getcwd.vim +++ b/src/testdir/test_getcwd.vim @@ -97,6 +97,17 @@ function Test_GetCwd() call assert_equal("y Xdir2 1", GetCwdInfo(2, tp_nr)) call assert_equal("z Xdir3 1", GetCwdInfo(1, tp_nr)) call assert_equal(g:topdir, getcwd(-1)) + " Non existing windows and tab pages + call assert_equal('', getcwd(100)) + call assert_equal(0, haslocaldir(100)) + call assert_equal('', getcwd(10, 1)) + call assert_equal(0, haslocaldir(10, 1)) + call assert_equal('', getcwd(1, 5)) + call assert_equal(0, haslocaldir(1, 5)) + call assert_fails('call getcwd([])', 'E745:') + call assert_fails('call getcwd(1, [])', 'E745:') + call assert_fails('call haslocaldir([])', 'E745:') + call assert_fails('call haslocaldir(1, [])', 'E745:') endfunc function Test_GetCwd_lcd_shellslash() @@ -110,3 +121,144 @@ function Test_GetCwd_lcd_shellslash() call assert_equal(cwd[-1:], '\') endif endfunc + +" Test for :tcd +function Test_Tab_Local_Cwd() + enew | only | tabonly + + call mkdir('Xtabdir1') + call mkdir('Xtabdir2') + call mkdir('Xwindir1') + call mkdir('Xwindir2') + call mkdir('Xwindir3') + + " Create three tabpages with three windows each + edit a + botright new b + botright new c + tabnew m + botright new n + botright new o + tabnew x + botright new y + botright new z + + " Setup different directories for the tab pages and windows + tabrewind + 1wincmd w + lcd Xwindir1 + tabnext + tcd Xtabdir1 + 2wincmd w + lcd ../Xwindir2 + tabnext + tcd Xtabdir2 + 3wincmd w + lcd ../Xwindir3 + + " Check the directories of various windows + call assert_equal("a Xwindir1 1", GetCwdInfo(1, 1)) + call assert_equal("b Xtopdir 0", GetCwdInfo(2, 1)) + call assert_equal("c Xtopdir 0", GetCwdInfo(3, 1)) + call assert_equal("m Xtabdir1 2", GetCwdInfo(1, 2)) + call assert_equal("n Xwindir2 1", GetCwdInfo(2, 2)) + call assert_equal("o Xtabdir1 2", GetCwdInfo(3, 2)) + call assert_equal("x Xtabdir2 2", GetCwdInfo(1, 3)) + call assert_equal("y Xtabdir2 2", GetCwdInfo(2, 3)) + call assert_equal("z Xwindir3 1", GetCwdInfo(3, 3)) + + " Check the tabpage directories + call assert_equal('Xtopdir', fnamemodify(getcwd(-1, 1), ':t')) + call assert_equal('Xtabdir1', fnamemodify(getcwd(-1, 2), ':t')) + call assert_equal('Xtabdir2', fnamemodify(getcwd(-1, 3), ':t')) + call assert_equal('', fnamemodify(getcwd(-1, 4), ':t')) + + " Jump to different windows in the tab pages and check the current directory + tabrewind | 1wincmd w + call assert_equal('Xwindir1', fnamemodify(getcwd(), ':t')) + call assert_equal('Xwindir1', fnamemodify(getcwd(0), ':t')) + call assert_equal('Xwindir1', fnamemodify(getcwd(0, 0), ':t')) + call assert_true(haslocaldir(0)) + call assert_equal(0, haslocaldir(-1, 0)) + call assert_equal('Xtopdir', fnamemodify(getcwd(-1, 0), ':t')) + call assert_equal(g:topdir, getcwd(-1)) + 2wincmd w + call assert_equal('Xtopdir', fnamemodify(getcwd(), ':t')) + call assert_equal('Xtopdir', fnamemodify(getcwd(0), ':t')) + call assert_equal('Xtopdir', fnamemodify(getcwd(0, 0), ':t')) + call assert_false(haslocaldir(0)) + call assert_equal(0, haslocaldir(-1, 0)) + call assert_equal('Xtopdir', fnamemodify(getcwd(-1, 0), ':t')) + call assert_equal(g:topdir, getcwd(-1)) + tabnext | 1wincmd w + call assert_equal('Xtabdir1', fnamemodify(getcwd(), ':t')) + call assert_equal('Xtabdir1', fnamemodify(getcwd(0), ':t')) + call assert_equal('Xtabdir1', fnamemodify(getcwd(0, 0), ':t')) + call assert_true(haslocaldir(0)) + call assert_equal(2, haslocaldir(-1, 0)) + call assert_equal('Xtabdir1', fnamemodify(getcwd(-1, 0), ':t')) + call assert_equal(g:topdir, getcwd(-1)) + 2wincmd w + call assert_equal('Xwindir2', fnamemodify(getcwd(), ':t')) + call assert_equal('Xwindir2', fnamemodify(getcwd(0), ':t')) + call assert_equal('Xwindir2', fnamemodify(getcwd(0, 0), ':t')) + call assert_true(haslocaldir(0)) + call assert_equal(2, haslocaldir(-1, 0)) + call assert_equal('Xtabdir1', fnamemodify(getcwd(-1, 0), ':t')) + call assert_equal(g:topdir, getcwd(-1)) + tabnext | 1wincmd w + call assert_equal('Xtabdir2', fnamemodify(getcwd(), ':t')) + call assert_equal('Xtabdir2', fnamemodify(getcwd(0), ':t')) + call assert_equal('Xtabdir2', fnamemodify(getcwd(0, 0), ':t')) + call assert_true(haslocaldir(0)) + call assert_equal(2, haslocaldir(-1, 0)) + call assert_equal('Xtabdir2', fnamemodify(getcwd(-1, 0), ':t')) + call assert_equal(g:topdir, getcwd(-1)) + 3wincmd w + call assert_equal('Xwindir3', fnamemodify(getcwd(), ':t')) + call assert_equal('Xwindir3', fnamemodify(getcwd(0), ':t')) + call assert_equal('Xwindir3', fnamemodify(getcwd(0, 0), ':t')) + call assert_true(haslocaldir(0)) + call assert_equal(2, haslocaldir(-1, 0)) + call assert_equal('Xtabdir2', fnamemodify(getcwd(-1, 0), ':t')) + call assert_equal(g:topdir, getcwd(-1)) + + " A new tab page should inherit the directory of the current tab page + tabrewind | 1wincmd w + tabnew g + call assert_equal("g Xwindir1 1", GetCwdInfo(0, 0)) + tabclose | tabrewind + 2wincmd w + tabnew h + call assert_equal("h Xtopdir 0", GetCwdInfo(0, 0)) + tabclose + tabnext 2 | 1wincmd w + tabnew j + call assert_equal("j Xtabdir1 2", GetCwdInfo(0, 0)) + tabclose + + " Change the global directory for the first tab page + tabrewind | 1wincmd w + cd ../Xdir1 + call assert_equal("a Xdir1 0", GetCwdInfo(1, 1)) + call assert_equal("b Xdir1 0", GetCwdInfo(2, 1)) + call assert_equal("m Xtabdir1 2", GetCwdInfo(1, 2)) + call assert_equal("n Xwindir2 1", GetCwdInfo(2, 2)) + + " Change the global directory for the second tab page + tabnext | 1wincmd w + cd ../Xdir3 + call assert_equal("m Xdir3 0", GetCwdInfo(1, 2)) + call assert_equal("n Xwindir2 1", GetCwdInfo(2, 2)) + call assert_equal("o Xdir3 0", GetCwdInfo(3, 2)) + + " Change the tab-local directory for the third tab page + tabnext | 1wincmd w + cd ../Xdir1 + call assert_equal("x Xdir1 0", GetCwdInfo(1, 3)) + call assert_equal("y Xdir1 0", GetCwdInfo(2, 3)) + call assert_equal("z Xwindir3 1", GetCwdInfo(3, 3)) + + enew | only | tabonly + new +endfunc diff --git a/src/testdir/test_mksession.vim b/src/testdir/test_mksession.vim index 456cd1e423..bc413968b4 100644 --- a/src/testdir/test_mksession.vim +++ b/src/testdir/test_mksession.vim @@ -210,6 +210,48 @@ func Test_mksession_lcd_multiple_tabs() call delete('Xtest_mks.out') endfunc +" Test for tabpage-local directory +func Test_mksession_tcd_multiple_tabs() + let save_cwd = getcwd() + call mkdir('Xtopdir') + cd Xtopdir + call mkdir('Xtabdir1') + call mkdir('Xtabdir2') + call mkdir('Xtabdir3') + call mkdir('Xwindir1') + call mkdir('Xwindir2') + call mkdir('Xwindir3') + tcd Xtabdir1 + botright new + wincmd t + lcd ../Xwindir1 + tabnew + tcd ../Xtabdir2 + botright new + lcd ../Xwindir2 + tabnew + tcd ../Xtabdir3 + botright new + lcd ../Xwindir3 + tabfirst + 1wincmd w + mksession! Xtest_mks.out + only | tabonly + source Xtest_mks.out + call assert_equal('Xtabdir1', fnamemodify(getcwd(-1, 1), ':t')) + call assert_equal('Xwindir1', fnamemodify(getcwd(1, 1), ':t')) + call assert_equal('Xtabdir1', fnamemodify(getcwd(2, 1), ':t')) + call assert_equal('Xtabdir2', fnamemodify(getcwd(-1, 2), ':t')) + call assert_equal('Xtabdir2', fnamemodify(getcwd(1, 2), ':t')) + call assert_equal('Xwindir2', fnamemodify(getcwd(2, 2), ':t')) + call assert_equal('Xtabdir3', fnamemodify(getcwd(-1, 3), ':t')) + call assert_equal('Xtabdir3', fnamemodify(getcwd(1, 3), ':t')) + call assert_equal('Xwindir3', fnamemodify(getcwd(2, 3), ':t')) + only | tabonly + exe 'cd ' . save_cwd + call delete("Xtopdir", "rf") +endfunc + func Test_mksession_blank_tabs() tabnew tabnew diff --git a/src/version.c b/src/version.c index 4c2620f291..25884c3768 100644 --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1218, +/**/ 1217, /**/ 1216, diff --git a/src/window.c b/src/window.c index b132361a5a..4a92d6cb50 100644 --- a/src/window.c +++ b/src/window.c @@ -3625,6 +3625,8 @@ free_tabpage(tabpage_T *tp) unref_var_dict(tp->tp_vars); #endif + vim_free(tp->tp_localdir); + #ifdef FEAT_PYTHON python_tabpage_free(tp); #endif @@ -3662,6 +3664,8 @@ win_new_tabpage(int after) } curtab = newtp; + newtp->tp_localdir = (tp->tp_localdir == NULL) + ? NULL : vim_strsave(tp->tp_localdir); /* Create a new empty window. */ if (win_alloc_firstwin(tp->tp_curwin) == OK) { @@ -3839,6 +3843,9 @@ find_tabpage(int n) tabpage_T *tp; int i = 1; + if (n == 0) + return curtab; + for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next) ++i; return tp; @@ -4451,11 +4458,13 @@ win_enter_ext( curwin->w_cursor.coladd = 0; changed_line_abv_curs(); /* assume cursor position needs updating */ - if (curwin->w_localdir != NULL) + if (curwin->w_localdir != NULL || curtab->tp_localdir != NULL) { - /* Window has a local directory: Save current directory as global - * directory (unless that was done already) and change to the local - * directory. */ + char_u *dirname; + + // Window or tab has a local directory: Save current directory as + // global directory (unless that was done already) and change to the + // local directory. if (globaldir == NULL) { char_u cwd[MAXPATHL]; @@ -4463,7 +4472,12 @@ win_enter_ext( if (mch_dirname(cwd, MAXPATHL) == OK) globaldir = vim_strsave(cwd); } - if (mch_chdir((char *)curwin->w_localdir) == 0) + if (curwin->w_localdir != NULL) + dirname = curwin->w_localdir; + else + dirname = curtab->tp_localdir; + + if (mch_chdir((char *)dirname) == 0) shorten_fnames(TRUE); } else if (globaldir != NULL) |