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>
This commit is contained in:
kuuote
2025-08-08 13:09:25 +02:00
committed by Christian Brabandt
parent d82c918e2f
commit 8a65a49d50
7 changed files with 50 additions and 13 deletions

View File

@ -1783,16 +1783,23 @@ charidx({string}, {idx} [, {countcc} [, {utf16}]])
Return type: |Number| Return type: |Number|
chdir({dir}) *chdir()* chdir({dir} [, {scope}]) *chdir()*
Change the current working directory to {dir}. The scope of Changes the current working directory to {dir}. The scope of
the directory change depends on the directory of the current the change is determined as follows:
window: If {scope} is not present, the current working directory is
- If the current window has a window-local directory changed to the scope of the current directory:
(|:lcd|), then changes the window local directory. - If the window local directory (|:lcd|) is set, it
- Otherwise, if the current tabpage has a local changes the current working directory for that scope.
directory (|:tcd|) then changes the tabpage local - Otherwise, if the tab page local directory (|:tcd|) is
directory. set, it changes the current directory for that scope.
- Otherwise, changes the global directory. - Otherwise, changes the global directory for that scope.
If {scope} is present, changes the current working directory
for the specified scope:
"window" Changes the window local directory. |:lcd|
"tabpage" Changes the tab page local directory. |:tcd|
"global" Changes the global directory. |:cd|
{dir} must be a String. {dir} must be a String.
If successful, returns the previous working directory. Pass If successful, returns the previous working directory. Pass
this to another chdir() to restore the directory. this to another chdir() to restore the directory.

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2025 Jul 25 *version9.txt* For Vim version 9.1. Last change: 2025 Aug 08
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -41722,6 +41722,7 @@ Functions: ~
not finished not finished
- Add the optional {opts} |Dict| argument to |getchar()| to control: cursor - Add the optional {opts} |Dict| argument to |getchar()| to control: cursor
behaviour, return type and whether or not to simplify the returned key behaviour, return type and whether or not to simplify the returned key
- |chdir()| allows to optionally specify a scope argument
Others: ~ Others: ~
- the regex engines match correctly case-insensitive multi-byte characters - the regex engines match correctly case-insensitive multi-byte characters

View File

@ -2086,7 +2086,7 @@ static funcentry_T global_functions[] =
ret_number, f_charcol}, ret_number, f_charcol},
{"charidx", 2, 4, FEARG_1, arg4_string_number_bool_bool, {"charidx", 2, 4, FEARG_1, arg4_string_number_bool_bool,
ret_number, f_charidx}, ret_number, f_charidx},
{"chdir", 1, 1, FEARG_1, arg1_string, {"chdir", 1, 2, FEARG_1, arg2_string,
ret_string, f_chdir}, ret_string, f_chdir},
{"cindent", 1, 1, FEARG_1, arg1_lnum, {"cindent", 1, 1, FEARG_1, arg1_lnum,
ret_number, f_cindent}, ret_number, f_cindent},

View File

@ -842,7 +842,22 @@ f_chdir(typval_T *argvars, typval_T *rettv)
vim_free(cwd); vim_free(cwd);
} }
if (curwin->w_localdir != NULL) if (argvars[1].v_type != VAR_UNKNOWN)
{
char_u *s = tv_get_string(&argvars[1]);
if (STRCMP(s, "global") == 0)
scope = CDSCOPE_GLOBAL;
else if (STRCMP(s, "tabpage") == 0)
scope = CDSCOPE_TABPAGE;
else if (STRCMP(s, "window") == 0)
scope = CDSCOPE_WINDOW;
else
{
semsg(_(e_invalid_value_for_argument_str_str), "scope", s);
return;
}
}
else if (curwin->w_localdir != NULL)
scope = CDSCOPE_WINDOW; scope = CDSCOPE_WINDOW;
else if (curtab->tp_localdir != NULL) else if (curtab->tp_localdir != NULL)
scope = CDSCOPE_TABPAGE; scope = CDSCOPE_TABPAGE;

View File

@ -96,10 +96,20 @@ func Test_chdir_func()
call assert_equal('y', fnamemodify(getcwd(3, 2), ':t')) call assert_equal('y', fnamemodify(getcwd(3, 2), ':t'))
call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t')) call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t'))
" Forcing scope
call chdir('.', 'global')
call assert_match('^\[global\]', trim(execute('verbose pwd')))
call chdir('.', 'tabpage')
call assert_match('^\[tabpage\]', trim(execute('verbose pwd')))
call chdir('.', 'window')
call assert_match('^\[window\]', trim(execute('verbose pwd')))
" Error case " Error case
call assert_fails("call chdir('dir-abcd')", 'E344:') call assert_fails("call chdir('dir-abcd')", 'E344:')
silent! let d = chdir("dir_abcd") silent! let d = chdir("dir_abcd")
call assert_equal("", d) call assert_equal("", d)
call assert_fails("call chdir('.', test_null_string())", 'E475:')
call assert_fails("call chdir('.', [])", 'E730:')
" Should not crash " Should not crash
call chdir(d) call chdir(d)
call assert_equal('', chdir([])) call assert_equal('', chdir([]))

View File

@ -770,6 +770,8 @@ enddef
def Test_chdir() def Test_chdir()
assert_fails('chdir(true)', 'E1174:') assert_fails('chdir(true)', 'E1174:')
assert_fails('chdir(".", test_null_string())', 'E475:')
assert_fails('chdir(".", [])', 'E730:')
enddef enddef
def Test_cindent() def Test_cindent()

View File

@ -719,6 +719,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1605,
/**/ /**/
1604, 1604,
/**/ /**/