Skip to content

Commit 8a65a49

Browse files
kuuotechrisbra
authored andcommitted
patch 9.1.1605: cannot specify scope for chdir()
Problem: Cannot specify scope for chdir() Solution: Add optional scope argument (kuuote) closes: #17888 Signed-off-by: kuuote <znmxodq1@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent d82c918 commit 8a65a49

7 files changed

Lines changed: 50 additions & 13 deletions

File tree

runtime/doc/builtin.txt

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,16 +1783,23 @@ charidx({string}, {idx} [, {countcc} [, {utf16}]])
17831783
Return type: |Number|
17841784

17851785

1786-
chdir({dir}) *chdir()*
1787-
Change the current working directory to {dir}. The scope of
1788-
the directory change depends on the directory of the current
1789-
window:
1790-
- If the current window has a window-local directory
1791-
(|:lcd|), then changes the window local directory.
1792-
- Otherwise, if the current tabpage has a local
1793-
directory (|:tcd|) then changes the tabpage local
1794-
directory.
1795-
- Otherwise, changes the global directory.
1786+
chdir({dir} [, {scope}]) *chdir()*
1787+
Changes the current working directory to {dir}. The scope of
1788+
the change is determined as follows:
1789+
If {scope} is not present, the current working directory is
1790+
changed to the scope of the current directory:
1791+
- If the window local directory (|:lcd|) is set, it
1792+
changes the current working directory for that scope.
1793+
- Otherwise, if the tab page local directory (|:tcd|) is
1794+
set, it changes the current directory for that scope.
1795+
- Otherwise, changes the global directory for that scope.
1796+
1797+
If {scope} is present, changes the current working directory
1798+
for the specified scope:
1799+
"window" Changes the window local directory. |:lcd|
1800+
"tabpage" Changes the tab page local directory. |:tcd|
1801+
"global" Changes the global directory. |:cd|
1802+
17961803
{dir} must be a String.
17971804
If successful, returns the previous working directory. Pass
17981805
this to another chdir() to restore the directory.

runtime/doc/version9.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*version9.txt* For Vim version 9.1. Last change: 2025 Jul 25
1+
*version9.txt* For Vim version 9.1. Last change: 2025 Aug 08
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -41722,6 +41722,7 @@ Functions: ~
4172241722
not finished
4172341723
- Add the optional {opts} |Dict| argument to |getchar()| to control: cursor
4172441724
behaviour, return type and whether or not to simplify the returned key
41725+
- |chdir()| allows to optionally specify a scope argument
4172541726

4172641727
Others: ~
4172741728
- the regex engines match correctly case-insensitive multi-byte characters

src/evalfunc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2086,7 +2086,7 @@ static funcentry_T global_functions[] =
20862086
ret_number, f_charcol},
20872087
{"charidx", 2, 4, FEARG_1, arg4_string_number_bool_bool,
20882088
ret_number, f_charidx},
2089-
{"chdir", 1, 1, FEARG_1, arg1_string,
2089+
{"chdir", 1, 2, FEARG_1, arg2_string,
20902090
ret_string, f_chdir},
20912091
{"cindent", 1, 1, FEARG_1, arg1_lnum,
20922092
ret_number, f_cindent},

src/filepath.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,22 @@ f_chdir(typval_T *argvars, typval_T *rettv)
842842
vim_free(cwd);
843843
}
844844

845-
if (curwin->w_localdir != NULL)
845+
if (argvars[1].v_type != VAR_UNKNOWN)
846+
{
847+
char_u *s = tv_get_string(&argvars[1]);
848+
if (STRCMP(s, "global") == 0)
849+
scope = CDSCOPE_GLOBAL;
850+
else if (STRCMP(s, "tabpage") == 0)
851+
scope = CDSCOPE_TABPAGE;
852+
else if (STRCMP(s, "window") == 0)
853+
scope = CDSCOPE_WINDOW;
854+
else
855+
{
856+
semsg(_(e_invalid_value_for_argument_str_str), "scope", s);
857+
return;
858+
}
859+
}
860+
else if (curwin->w_localdir != NULL)
846861
scope = CDSCOPE_WINDOW;
847862
else if (curtab->tp_localdir != NULL)
848863
scope = CDSCOPE_TABPAGE;

src/testdir/test_cd.vim

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,20 @@ func Test_chdir_func()
9696
call assert_equal('y', fnamemodify(getcwd(3, 2), ':t'))
9797
call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t'))
9898

99+
" Forcing scope
100+
call chdir('.', 'global')
101+
call assert_match('^\[global\]', trim(execute('verbose pwd')))
102+
call chdir('.', 'tabpage')
103+
call assert_match('^\[tabpage\]', trim(execute('verbose pwd')))
104+
call chdir('.', 'window')
105+
call assert_match('^\[window\]', trim(execute('verbose pwd')))
106+
99107
" Error case
100108
call assert_fails("call chdir('dir-abcd')", 'E344:')
101109
silent! let d = chdir("dir_abcd")
102110
call assert_equal("", d)
111+
call assert_fails("call chdir('.', test_null_string())", 'E475:')
112+
call assert_fails("call chdir('.', [])", 'E730:')
103113
" Should not crash
104114
call chdir(d)
105115
call assert_equal('', chdir([]))

src/testdir/test_vim9_builtin.vim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,8 @@ enddef
770770

771771
def Test_chdir()
772772
assert_fails('chdir(true)', 'E1174:')
773+
assert_fails('chdir(".", test_null_string())', 'E475:')
774+
assert_fails('chdir(".", [])', 'E730:')
773775
enddef
774776

775777
def Test_cindent()

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,8 @@ static char *(features[]) =
719719

720720
static int included_patches[] =
721721
{ /* Add new patch number below this line */
722+
/**/
723+
1605,
722724
/**/
723725
1604,
724726
/**/

0 commit comments

Comments
 (0)