diff options
Diffstat (limited to 'data/vim/patches/8.1.1218')
-rw-r--r-- | data/vim/patches/8.1.1218 | 1232 |
1 files changed, 1232 insertions, 0 deletions
diff --git a/data/vim/patches/8.1.1218 b/data/vim/patches/8.1.1218 new file mode 100644 index 000000000..2532f59ee --- /dev/null +++ b/data/vim/patches/8.1.1218 @@ -0,0 +1,1232 @@ +To: vim_dev@googlegroups.com +Subject: Patch 8.1.1218 +Fcc: outbox +From: Bram Moolenaar <Bram@moolenaar.net> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 8.1.1218 +Problem: Cannot set a directory for a tab page. +Solution: Add the tab-local directory. (Yegappan Lakshmanan, closes #4212) +Files: runtime/doc/autocmd.txt, runtime/doc/editing.txt, + runtime/doc/eval.txt, runtime/doc/index.txt, + runtime/doc/options.txt, runtime/doc/usr_22.txt, + runtime/doc/usr_41.txt, src/eval.c, src/evalfunc.c, + src/ex_cmdidxs.h, src/ex_cmds.h, src/ex_docmd.c, src/if_py_both.h, + src/proto/eval.pro, src/proto/ex_docmd.pro, src/structs.h, + src/testdir/test_getcwd.vim, src/testdir/test_mksession.vim, + src/window.c + + +*** ../vim-8.1.1217/runtime/doc/autocmd.txt 2019-04-08 18:15:36.464223229 +0200 +--- runtime/doc/autocmd.txt 2019-04-27 20:06:26.758264881 +0200 +*************** +*** 686,704 **** + change or when doing |:diffupdate|. + *DirChanged* + DirChanged The working directory has changed in response +! to the |:cd| or |:lcd| commands, or as a +! result of the 'autochdir' option. + The pattern can be: +! "window" to trigger on `:lcd` +! "global" to trigger on `:cd` +! "auto" to trigger on 'autochdir'. +! "drop" to trigger on editing a file + <afile> is set to the new directory name. + *ExitPre* + ExitPre When using `:quit`, `:wq` in a way it makes + Vim exit, or using `:qall`, just after + |QuitPre|. Can be used to close any +! non-essential window. + *FileChangedShell* + FileChangedShell When Vim notices that the modification time of + a file has changed since editing started. +--- 690,712 ---- + change or when doing |:diffupdate|. + *DirChanged* + DirChanged The working directory has changed in response +! to the |:cd| or |:tcd| or |:lcd| commands, or +! as a result of the 'autochdir' option. + The pattern can be: +! "window" to trigger on `:lcd` +! "tabpage" to trigger on `:tcd` +! "global" to trigger on `:cd` +! "auto" to trigger on 'autochdir'. +! "drop" to trigger on editing a file + <afile> is set to the new directory name. + *ExitPre* + ExitPre When using `:quit`, `:wq` in a way it makes + Vim exit, or using `:qall`, just after + |QuitPre|. Can be used to close any +! non-essential window. Exiting may still be +! cancelled if there is a modified buffer that +! isn't automatically saved, use |VimLeavePre| +! for really exiting. + *FileChangedShell* + FileChangedShell When Vim notices that the modification time of + a file has changed since editing started. +*** ../vim-8.1.1217/runtime/doc/editing.txt 2018-05-17 13:40:51.000000000 +0200 +--- runtime/doc/editing.txt 2019-04-27 20:11:37.192857657 +0200 +*************** +*** 1304,1312 **** + ============================================================================== + 7. The current directory *current-directory* + +! You may use the |:cd| and |:lcd| commands to change to another directory, so +! you will not have to type that directory name in front of the file names. It +! also makes a difference for executing external commands, e.g. ":!ls". + + Changing directory fails when the current buffer is modified, the '.' flag is + present in 'cpoptions' and "!" is not used in the command. +--- 1304,1313 ---- + ============================================================================== + 7. The current directory *current-directory* + +! You can use the |:cd|, |:tcd| and |:lcd| commands to change to another +! directory, so you will not have to type that directory name in front of the +! file names. It also makes a difference for executing external commands, e.g. +! ":!ls". + + Changing directory fails when the current buffer is modified, the '.' flag is + present in 'cpoptions' and "!" is not used in the command. +*************** +*** 1334,1339 **** +--- 1335,1351 ---- + *:chd* *:chdir* + :chd[ir][!] [path] Same as |:cd|. + ++ *:tcd* ++ :tcd[!] {path} Like |:cd|, but only set the directory for the current ++ tab. The current window will also use this directory. ++ The current directory is not changed for windows in ++ other tabs and for windows in the current tab that ++ have their own window-local directory. ++ {not in Vi} ++ ++ *:tch* *:tchdir* ++ :tch[dir][!] Same as |:tcd|. {not in Vi} ++ + *:lc* *:lcd* + :lc[d][!] {path} Like |:cd|, but only set the current directory when + the cursor is in the current window. The current +*************** +*** 1348,1364 **** + :pw[d] Print the current directory name. {Vi: no pwd} + Also see |getcwd()|. + +! So long as no |:lcd| command has been used, all windows share the same current +! directory. Using a command to jump to another window doesn't change anything +! for the current directory. + When a |:lcd| command has been used for a window, the specified directory + becomes the current directory for that window. Windows where the |:lcd| +! command has not been used stick to the global current directory. When jumping +! to another window the current directory will become the last specified local +! current directory. If none was specified, the global current directory is +! used. +! When a |:cd| command is used, the current window will lose his local current +! directory and will use the global current directory from now on. + + After using |:cd| the full path name will be used for reading and writing + files. On some networked file systems this may cause problems. The result of +--- 1360,1385 ---- + :pw[d] Print the current directory name. {Vi: no pwd} + Also see |getcwd()|. + +! So long as no |:lcd| or |:tcd| command has been used, all windows share the +! same current directory. Using a command to jump to another window doesn't +! change anything for the current directory. +! + When a |:lcd| command has been used for a window, the specified directory + becomes the current directory for that window. Windows where the |:lcd| +! command has not been used stick to the global or tab-local current directory. +! When jumping to another window the current directory will become the last +! specified local current directory. If none was specified, the global or +! tab-local current directory is used. +! +! When a |:tcd| command has been used for a tab page, the specified directory +! becomes the current directory for the current tab page and the current window. +! The current directory of other tab pages is not affected. When jumping to +! another tab page, the current directory will become the last specified local +! directory for that tab page. If the current tab has no local current directory +! the global current directory is used. +! +! When a |:cd| command is used, the current window and tab page will lose the +! local current directory and will use the global current directory from now on. + + After using |:cd| the full path name will be used for reading and writing + files. On some networked file systems this may cause problems. The result of +*** ../vim-8.1.1217/runtime/doc/eval.txt 2019-04-27 13:03:20.012715914 +0200 +--- runtime/doc/eval.txt 2019-04-27 20:14:41.136007351 +0200 +*************** +*** 2377,2382 **** +--- 2398,2404 ---- + has_key({dict}, {key}) Number |TRUE| if {dict} has entry {key} + haslocaldir([{winnr} [, {tabnr}]]) + Number |TRUE| if the window executed |:lcd| ++ or |:tcd| + hasmapto({what} [, {mode} [, {abbr}]]) + Number |TRUE| if mapping to {what} exists + histadd({history}, {item}) String add an item to a history +*************** +*** 4880,4886 **** + getcwd([{winnr} [, {tabnr}]]) + The result is a String, which is the name of the current + working directory. +- Without arguments, for the current window. + + With {winnr} return the local current directory of this window + in the current tab page. {winnr} can be the window number or +--- 4911,4916 ---- +*************** +*** 4889,4897 **** + directory. See also |haslocaldir()|. + + With {winnr} and {tabnr} return the local current directory of +! the window in the specified tab page. + Return an empty string if the arguments are invalid. + + getfsize({fname}) *getfsize()* + The result is a Number, which is the size in bytes of the + given file {fname}. +--- 4919,4946 ---- + directory. See also |haslocaldir()|. + + With {winnr} and {tabnr} return the local current directory of +! the window in the specified tab page. If {winnr} is -1 return +! the working directory of the tabpage. +! If {winnr} is zero use the current window, if {tabnr} is zero +! use the current tabpage. +! Without any arguments, return the working directory of the +! current window. + Return an empty string if the arguments are invalid. + ++ Examples: > ++ " Get the working directory of the current window ++ :echo getcwd() ++ :echo getcwd(0) ++ :echo getcwd(0, 0) ++ " Get the working directory of window 3 in tabpage 2 ++ :echo getcwd(3, 2) ++ " Get the global working directory ++ :echo getcwd(-1) ++ " Get the working directory of tabpage 3 ++ :echo getcwd(-1, 3) ++ " Get the working directory of current tabpage ++ :echo getcwd(-1, 0) ++ < + getfsize({fname}) *getfsize()* + The result is a Number, which is the size in bytes of the + given file {fname}. +*************** +*** 5449,5464 **** + an entry with key {key}. Zero otherwise. + + haslocaldir([{winnr} [, {tabnr}]]) *haslocaldir()* +! The result is a Number, which is 1 when the window has set a +! local path via |:lcd|, and 0 otherwise. + + Without arguments use the current window. + With {winnr} use this window in the current tab page. + With {winnr} and {tabnr} use the window in the specified tab + page. + {winnr} can be the window number or the |window-ID|. + Return 0 if the arguments are invalid. + + hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()* + The result is a Number, which is 1 if there is a mapping that + contains {what} in somewhere in the rhs (what it is mapped to) +--- 5498,5536 ---- + an entry with key {key}. Zero otherwise. + + haslocaldir([{winnr} [, {tabnr}]]) *haslocaldir()* +! The result is a Number: +! 1 when the window has set a local directory via |:lcd| +! 2 when the tab-page has set a local directory via |:tcd| +! 0 otherwise. + + Without arguments use the current window. + With {winnr} use this window in the current tab page. + With {winnr} and {tabnr} use the window in the specified tab + page. + {winnr} can be the window number or the |window-ID|. ++ If {winnr} is -1 it is ignored and only the tabpage is used. + Return 0 if the arguments are invalid. ++ Examples: > ++ if haslocaldir() == 1 ++ " window local directory case ++ elseif haslocaldir() == 2 ++ " tab-local directory case ++ else ++ " global directory case ++ endif + ++ " current window ++ :echo haslocaldir() ++ :echo haslocaldir(0) ++ :echo haslocaldir(0, 0) ++ " window n in current tab page ++ :echo haslocaldir(n) ++ :echo haslocaldir(n, 0) ++ " window n in tab page m ++ :echo haslocaldir(n, m) ++ " tab page m ++ :echo haslocaldir(-1, m) ++ < + hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()* + The result is a Number, which is 1 if there is a mapping that + contains {what} in somewhere in the rhs (what it is mapped to) +*** ../vim-8.1.1217/runtime/doc/index.txt 2018-10-19 22:35:04.885189994 +0200 +--- runtime/doc/index.txt 2019-04-27 20:05:21.278555302 +0200 +*************** +*** 1573,1578 **** +--- 1627,1634 ---- + |:tab| :tab create new tab when opening new window + |:tag| :ta[g] jump to tag + |:tags| :tags show the contents of the tag stack ++ |:tcd| :tcd change directory for tab page ++ |:tchdir| :tch[dir] change directory for tab page + |:tcl| :tc[l] execute Tcl command + |:tcldo| :tcld[o] execute Tcl command for each line + |:tclfile| :tclf[ile] execute Tcl script file +*** ../vim-8.1.1217/runtime/doc/options.txt 2019-02-16 15:09:21.225946157 +0100 +--- runtime/doc/options.txt 2019-04-27 20:05:21.278555302 +0200 +*************** +*** 1457,1465 **** + {not available when compiled without the + |+file_in_path| feature} + This is a list of directories which will be searched when using the +! |:cd| and |:lcd| commands, provided that the directory being searched +! for has a relative path, not an absolute part starting with "/", "./" +! or "../", the 'cdpath' option is not used then. + The 'cdpath' option's value has the same form and semantics as + |'path'|. Also see |file-searching|. + The default value is taken from $CDPATH, with a "," prepended to look +--- 1455,1463 ---- + {not available when compiled without the + |+file_in_path| feature} + This is a list of directories which will be searched when using the +! |:cd|, |:tcd| and |:lcd| commands, provided that the directory being +! searched for has a relative path, not an absolute part starting with +! "/", "./" or "../", the 'cdpath' option is not used then. + The 'cdpath' option's value has the same form and semantics as + |'path'|. Also see |file-searching|. + The default value is taken from $CDPATH, with a "," prepended to look +*** ../vim-8.1.1217/runtime/doc/usr_22.txt 2018-05-17 13:42:03.000000000 +0200 +--- runtime/doc/usr_22.txt 2019-04-27 20:17:02.375349029 +0200 +*************** +*** 202,215 **** + :pwd + /home/Bram/VeryLongFileName + +! So long as no ":lcd" command has been used, all windows share the same current +! directory. Doing a ":cd" command in one window will also change the current + directory of the other window. +! For a window where ":lcd" has been used a different current directory is +! remembered. Using ":cd" or ":lcd" in other windows will not change it. +! When using a ":cd" command in a window that uses a different current + directory, it will go back to using the shared directory. + + ============================================================================== + *22.3* Finding a file + +--- 202,229 ---- + :pwd + /home/Bram/VeryLongFileName + +! So long as no `:lcd` command has been used, all windows share the same current +! directory. Doing a `:cd` command in one window will also change the current + directory of the other window. +! For a window where `:lcd` has been used a different current directory is +! remembered. Using `:cd` or `:lcd` in other windows will not change it. +! When using a `:cd` command in a window that uses a different current + directory, it will go back to using the shared directory. + ++ ++ TAB LOCAL DIRECTORY ++ ++ When you open a new tab page, it uses the directory of the window in the ++ previous tab page from which the new tab page was opened. You can change the ++ directory of the current tab page using the `:tcd` command. All the windows in ++ a tab page share this directory except for windows with a window-local ++ directory. Any new windows opened in this tab page will use this directory as ++ the current working directory. Using a `:cd` command in a tab page will not ++ change the working directory of tab pages which have a tab local directory. ++ When the global working directory is changed using the ":cd" command in a tab ++ page, it will also change the current tab page working directory. ++ ++ + ============================================================================== + *22.3* Finding a file + +*** ../vim-8.1.1217/runtime/doc/usr_41.txt 2019-04-06 13:18:06.733335092 +0200 +--- runtime/doc/usr_41.txt 2019-04-27 20:05:21.278555302 +0200 +*************** +*** 765,771 **** + isdirectory() check if a directory exists + getfsize() get the size of a file + getcwd() get the current working directory +! haslocaldir() check if current window used |:lcd| + tempname() get the name of a temporary file + mkdir() create a new directory + delete() delete a file +--- 766,772 ---- + isdirectory() check if a directory exists + getfsize() get the size of a file + getcwd() get the current working directory +! haslocaldir() check if current window used |:lcd| or |:tcd| + tempname() get the name of a temporary file + mkdir() create a new directory + delete() delete a file +*** ../vim-8.1.1217/src/eval.c 2019-04-27 13:03:20.004715961 +0200 +--- src/eval.c 2019-04-27 20:17:32.523208020 +0200 +*************** +*** 8704,8714 **** + + /* + * Find window specified by "wvp" in tabpage "tvp". + */ + win_T * + find_tabwin( +! typval_T *wvp, /* VAR_UNKNOWN for current window */ +! typval_T *tvp) /* VAR_UNKNOWN for current tab page */ + { + win_T *wp = NULL; + tabpage_T *tp = NULL; +--- 8704,8716 ---- + + /* + * 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 +! tabpage_T **ptp) + { + win_T *wp = NULL; + tabpage_T *tp = NULL; +*************** +*** 8726,8735 **** +--- 8728,8749 ---- + 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; + } +*** ../vim-8.1.1217/src/evalfunc.c 2019-04-27 13:03:20.004715961 +0200 +--- src/evalfunc.c 2019-04-27 20:05:21.282555283 +0200 +*************** +*** 1529,1535 **** + win_T *wp; + + rettv->vval.v_number = -1; +! wp = find_tabwin(&argvars[0], &argvars[1]); + if (wp != NULL) + rettv->vval.v_number = wp->w_alist->id; + } +--- 1529,1535 ---- + win_T *wp; + + rettv->vval.v_number = -1; +! wp = find_tabwin(&argvars[0], &argvars[1], NULL); + if (wp != NULL) + rettv->vval.v_number = wp->w_alist->id; + } +*************** +*** 5126,5150 **** + + /* + * "getcwd()" function + */ + static void + f_getcwd(typval_T *argvars, typval_T *rettv) + { + win_T *wp = 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) + global = TRUE; + else +! wp = find_tabwin(&argvars[0], &argvars[1]); + + if (wp != NULL && wp->w_localdir != NULL) + rettv->vval.v_string = vim_strsave(wp->w_localdir); +! else if (wp != NULL || global) + { + if (globaldir != NULL) + rettv->vval.v_string = vim_strsave(globaldir); +--- 5126,5169 ---- + + /* + * "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 +! && argvars[1].v_type == VAR_UNKNOWN) + global = TRUE; + else +! 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 (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,5339 **** + return; + + #ifdef FEAT_JUMPLIST +! wp = find_tabwin(&argvars[0], &argvars[1]); + if (wp == NULL) + return; + +--- 5352,5358 ---- + return; + + #ifdef FEAT_JUMPLIST +! wp = find_tabwin(&argvars[0], &argvars[1], NULL); + if (wp == NULL) + return; + +*************** +*** 6824,6833 **** + static void + f_haslocaldir(typval_T *argvars, typval_T *rettv) + { + win_T *wp = NULL; + +! wp = find_tabwin(&argvars[0], &argvars[1]); +! rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL); + } + + /* +--- 6843,6860 ---- + 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], &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; + } + + /* +*** ../vim-8.1.1217/src/ex_cmdidxs.h 2019-04-04 18:15:05.770857065 +0200 +--- src/ex_cmdidxs.h 2019-04-27 20:05:21.282555283 +0200 +*************** +*** 25,36 **** + /* r */ 351, + /* s */ 371, + /* t */ 439, +! /* u */ 482, +! /* v */ 493, +! /* w */ 511, +! /* x */ 525, +! /* y */ 534, +! /* z */ 535 + }; + + /* +--- 25,36 ---- + /* r */ 351, + /* s */ 371, + /* t */ 439, +! /* u */ 484, +! /* v */ 495, +! /* w */ 513, +! /* x */ 527, +! /* y */ 536, +! /* z */ 537 + }; + + /* +*************** +*** 60,66 **** + /* 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 }, + /* 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 }, +--- 60,66 ---- + /* 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, 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,72 **** + /* 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; +--- 69,72 ---- + /* 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 = 550; +*** ../vim-8.1.1217/src/ex_cmds.h 2019-04-27 13:03:20.004715961 +0200 +--- src/ex_cmds.h 2019-04-27 20:18:38.294899911 +0200 +*************** +*** 1479,1484 **** +--- 1479,1490 ---- + 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), +*** ../vim-8.1.1217/src/ex_docmd.c 2019-04-27 13:03:20.004715961 +0200 +--- src/ex_docmd.c 2019-04-27 20:05:21.282555283 +0200 +*************** +*** 3692,3697 **** +--- 3692,3699 ---- + 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,7447 **** + + /* + * Deal with the side effects of changing the current directory. +! * When "local" is TRUE then this was after an ":lcd" command. + */ + void +! post_chdir(int local) + { + VIM_CLEAR(curwin->w_localdir); +! if (local) + { + /* If still in global directory, need to remember current + * directory as global directory. */ +--- 7437,7453 ---- + + /* + * Deal with the side effects of changing the current directory. +! * 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 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 (winlocal || tablocal) + { + /* If still in global directory, need to remember current + * directory as global directory. */ +*************** +*** 7449,7455 **** + globaldir = vim_strsave(prev_dir); + /* Remember this local directory for the window. */ + if (mch_dirname(NameBuff, MAXPATHL) == OK) +! curwin->w_localdir = vim_strsave(NameBuff); + } + else + { +--- 7455,7466 ---- + globaldir = vim_strsave(prev_dir); + /* Remember this local directory for the window. */ + if (mch_dirname(NameBuff, MAXPATHL) == OK) +! { +! if (tablocal) +! curtab->tp_localdir = vim_strsave(NameBuff); +! else +! curwin->w_localdir = vim_strsave(NameBuff); +! } + } + else + { +*************** +*** 7463,7469 **** + + + /* +! * ":cd", ":lcd", ":chdir" and ":lchdir". + */ + void + ex_cd(exarg_T *eap) +--- 7474,7480 ---- + + + /* +! * ":cd", ":tcd", ":lcd", ":chdir" ":tchdir" and ":lchdir". + */ + void + ex_cd(exarg_T *eap) +*************** +*** 7532,7550 **** + emsg(_(e_failed)); + else + { +! int is_local_chdir = eap->cmdidx == CMD_lcd + || eap->cmdidx == CMD_lchdir; + +! post_chdir(is_local_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", + new_dir, FALSE, curbuf); + } + vim_free(tofree); + } +--- 7543,7571 ---- + emsg(_(e_failed)); + else + { +! 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_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) +! { +! 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,9740 **** + } + for (tabnr = 1; ; ++tabnr) + { + int need_tabnext = FALSE; + int cnr = 1; + + if ((ssop_flags & SSOP_TABPAGES)) + { +! tabpage_T *tp = find_tabpage(tabnr); + + if (tp == NULL) + break; /* done all tab pages */ +--- 9750,9762 ---- + } + for (tabnr = 1; ; ++tabnr) + { ++ tabpage_T *tp = NULL; + int need_tabnext = FALSE; + int cnr = 1; + + if ((ssop_flags & SSOP_TABPAGES)) + { +! tp = find_tabpage(tabnr); + + if (tp == NULL) + break; /* done all tab pages */ +*************** +*** 9833,9838 **** +--- 9855,9872 ---- + 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.). + */ +*** ../vim-8.1.1217/src/if_py_both.h 2019-03-30 12:51:18.626808012 +0100 +--- src/if_py_both.h 2019-04-27 20:05:21.282555283 +0200 +*************** +*** 1032,1038 **** + Py_DECREF(newwd); + Py_XDECREF(todecref); + +! post_chdir(FALSE); + + if (VimTryEnd()) + { +--- 1032,1038 ---- + Py_DECREF(newwd); + Py_XDECREF(todecref); + +! post_chdir(FALSE, FALSE); + + if (VimTryEnd()) + { +*** ../vim-8.1.1217/src/proto/eval.pro 2019-04-05 22:50:35.025737353 +0200 +--- src/proto/eval.pro 2019-04-27 20:05:21.286555269 +0200 +*************** +*** 116,122 **** + 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); + 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); +--- 116,122 ---- + 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, 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); +*** ../vim-8.1.1217/src/proto/ex_docmd.pro 2019-04-27 13:03:20.004715961 +0200 +--- src/proto/ex_docmd.pro 2019-04-27 20:05:21.286555269 +0200 +*************** +*** 37,43 **** + 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 ex_cd(exarg_T *eap); + void do_sleep(long msec); + void ex_may_print(exarg_T *eap); +--- 37,43 ---- + void tabpage_new(void); + void do_exedit(exarg_T *eap, win_T *old_curwin); + void free_cd_dir(void); +! 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); +*** ../vim-8.1.1217/src/structs.h 2019-04-27 13:03:20.008715938 +0200 +--- src/structs.h 2019-04-27 20:05:21.286555269 +0200 +*************** +*** 2574,2579 **** +--- 2574,2582 ---- + 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]); +*** ../vim-8.1.1217/src/testdir/test_getcwd.vim 2019-01-09 23:00:57.997176121 +0100 +--- src/testdir/test_getcwd.vim 2019-04-27 20:05:21.286555269 +0200 +*************** +*** 97,102 **** +--- 97,113 ---- + 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,112 **** +--- 121,264 ---- + 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 +*** ../vim-8.1.1217/src/testdir/test_mksession.vim 2019-02-03 14:52:42.505867463 +0100 +--- src/testdir/test_mksession.vim 2019-04-27 20:05:21.286555269 +0200 +*************** +*** 210,215 **** +--- 210,257 ---- + 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 +*** ../vim-8.1.1217/src/window.c 2019-04-26 20:32:57.086296530 +0200 +--- src/window.c 2019-04-27 20:05:21.286555269 +0200 +*************** +*** 3625,3630 **** +--- 3625,3632 ---- + unref_var_dict(tp->tp_vars); + #endif + ++ vim_free(tp->tp_localdir); ++ + #ifdef FEAT_PYTHON + python_tabpage_free(tp); + #endif +*************** +*** 3662,3667 **** +--- 3664,3671 ---- + } + 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,3844 **** +--- 3843,3851 ---- + 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,4461 **** + curwin->w_cursor.coladd = 0; + changed_line_abv_curs(); /* assume cursor position needs updating */ + +! if (curwin->w_localdir != NULL) + { +! /* Window 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]; +--- 4458,4470 ---- + curwin->w_cursor.coladd = 0; + changed_line_abv_curs(); /* assume cursor position needs updating */ + +! if (curwin->w_localdir != NULL || curtab->tp_localdir != NULL) + { +! 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,4469 **** + if (mch_dirname(cwd, MAXPATHL) == OK) + globaldir = vim_strsave(cwd); + } +! if (mch_chdir((char *)curwin->w_localdir) == 0) + shorten_fnames(TRUE); + } + else if (globaldir != NULL) +--- 4472,4483 ---- + if (mch_dirname(cwd, MAXPATHL) == OK) + globaldir = vim_strsave(cwd); + } +! 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) +*** ../vim-8.1.1217/src/version.c 2019-04-27 19:15:41.856806819 +0200 +--- src/version.c 2019-04-27 20:04:37.658747152 +0200 +*************** +*** 769,770 **** +--- 769,772 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 1218, + /**/ + +-- +WOMAN: Dennis, there's some lovely filth down here. Oh -- how d'you do? +ARTHUR: How do you do, good lady. I am Arthur, King of the Britons. + Who's castle is that? +WOMAN: King of the who? + The Quest for the Holy Grail (Monty Python) + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |