Allow overwriting argv with function -a and -V

Previously, if you called a function parameter 'argv', within the body
of the function, argv would be set to *all* the arguments to the
function, and not the one indicated by the parameter name.
The same behaviour happened if you inherited a variable named 'argv'.
Both behaviours were quite surprising, so this commit makes things more
obvious, although they could alternatively simply be made errors.

Part of #11780
This commit is contained in:
Isaac Oscar Gariano
2025-08-22 18:46:56 +10:00
committed by Johannes Altmanninger
parent 7a07c08860
commit 93c4d63295
3 changed files with 33 additions and 2 deletions

View File

@@ -21,7 +21,7 @@ A function is a list of commands that will be executed when the name of the func
The following options are available:
**-a** *NAMES* or **--argument-names** *NAMES*
Assigns the value of successive command-line arguments to the names given in *NAMES* (separated by space). These are the same arguments given in :envvar:`argv`, and are still available there. See also :ref:`Argument Handling <variables-argv>`.
Assigns the value of successive command-line arguments to the names given in *NAMES* (separated by spaces). These are the same arguments given in :envvar:`argv`, and are still available there (unless ``--inherit-variable argv`` was used or one of the given *NAMES* is ``argv``). See also :ref:`Argument Handling <variables-argv>`.
**-d** *DESCRIPTION* or **--description** *DESCRIPTION*
A description of what the function does, suitable as a completion description.

View File

@@ -948,7 +948,11 @@ fn function_prepare_environment(
// 2. inherited variables
// 3. argv
let mut overwrite_argv = false;
for (idx, named_arg) in props.named_arguments.iter().enumerate() {
if named_arg == L!("argv") {
overwrite_argv = true
};
if idx < argv.len() {
vars.set_one(named_arg, EnvMode::LOCAL | EnvMode::USER, argv[idx].clone());
} else {
@@ -957,10 +961,15 @@ fn function_prepare_environment(
}
for (key, value) in &*props.inherit_vars {
if key == L!("argv") {
overwrite_argv = true
};
vars.set(key, EnvMode::LOCAL | EnvMode::USER, value.clone());
}
vars.set_argv(argv);
if !overwrite_argv {
vars.set_argv(argv);
}
fb
}

View File

@@ -192,4 +192,26 @@ end
# CHECKERR: function ()
# CHECKERR: ^
# Tests the --argument-names and --inherit-variable can overwrite argv
function t --argument-names a argv c
echo $argv
end
t 1 2 3
#CHECK: 2
function t -a argv
echo $argv
end
t 1 2 3
#CHECK: 1
function outer
function inner -v argv -V argv
echo $argv
end
set -gx argv 4 5 6
end
outer 1 2 3
#CHECK: 1 2 3
exit 0