Support FOO=bar syntax for passing variables to individual commands
This adds initial support for statements with prefixed variable assignments.
Statments like this are supported:
a=1 b=$a echo $b # outputs 1
Just like in other shells, the left-hand side of each assignment must
be a valid variable identifier (no quoting/escaping). Array indexing
(PATH[1]=/bin ls $PATH) is *not* yet supported, but can be added fairly
easily.
The right hand side may be any valid string token, like a command
substitution, or a brace expansion.
Since `a=* foo` is equivalent to `begin set -lx a *; foo; end`,
the assignment, like `set`, uses nullglob behavior, e.g. below command
can safely be used to check if a directory is empty.
x=/nothing/{,.}* test (count $x) -eq 0
Generic file completion is done after the equal sign, so for example
pressing tab after something like `HOME=/` completes files in the
root directory
Subcommand completion works, so something like
`GIT_DIR=repo.git and command git ` correctly calls git completions
(but the git completion does not use the variable as of now).
The variable assignment is highlighted like an argument.
Closes #6048
2019-10-23 09:13:29 +08:00
|
|
|
# RUN: %fish %s
|
|
|
|
|
|
|
|
# erase all lowercase variables to make sure they don't break our tests
|
|
|
|
for varname in (set -xn | string match -r '^[a-z].*')
|
|
|
|
while set -q $varname
|
|
|
|
set -e $varname
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# CHECK: bar
|
|
|
|
foo=bar echo $foo
|
|
|
|
|
|
|
|
# CHECK: nil
|
|
|
|
set -q foo; or echo nil
|
|
|
|
|
|
|
|
# CHECK: lx
|
|
|
|
foo=bar set -qlx foo; and echo lx
|
|
|
|
|
|
|
|
# CHECK: 3
|
|
|
|
a={1, 2, 3} count $a
|
|
|
|
|
|
|
|
# CHECK: 1+2+3
|
|
|
|
a={1, 2, 3} string join + $a
|
|
|
|
|
|
|
|
# CHECK: 1 2 3
|
|
|
|
a=(echo 1 2 3) echo $a
|
|
|
|
|
|
|
|
# CHECK: a a2
|
|
|
|
a=a b={$a}2 echo $a $b
|
|
|
|
|
|
|
|
# CHECK: a
|
|
|
|
a=a builtin echo $a
|
|
|
|
|
|
|
|
# CHECK: 0
|
|
|
|
a=failing-glob-* count $a
|
|
|
|
|
|
|
|
# CHECK: ''
|
|
|
|
a=b true | echo "'$a'"
|
|
|
|
|
|
|
|
if a=b true
|
|
|
|
# CHECK: ''
|
|
|
|
echo "'$a'"
|
|
|
|
end
|
|
|
|
|
|
|
|
# CHECK: b
|
|
|
|
not a=b echo $a
|
|
|
|
|
|
|
|
# CHECK: b
|
|
|
|
a=b not echo $a
|
|
|
|
|
|
|
|
# CHECK: b
|
|
|
|
a=b not builtin echo $a
|
|
|
|
|
|
|
|
# CHECK: /usr/bin:/bin
|
|
|
|
xPATH={/usr,}/bin sh -c 'echo $xPATH'
|
|
|
|
|
|
|
|
# CHECK: 2
|
|
|
|
yPATH=/usr/bin:/bin count $yPATH
|
|
|
|
|
|
|
|
# CHECK: b
|
|
|
|
a=b begin; true | echo $a; end
|
|
|
|
|
|
|
|
# CHECK: b
|
|
|
|
a=b if true; echo $a; end
|
|
|
|
|
|
|
|
# CHECK: b
|
|
|
|
a=b switch x; case x; echo $a; end
|
|
|
|
|
|
|
|
complete -c x --erase
|
|
|
|
complete -c x -xa arg
|
|
|
|
complete -C' a=b x ' # Mind the leading space.
|
|
|
|
# CHECK: arg
|
|
|
|
alias xalias=x
|
|
|
|
complete -C'a=b xalias '
|
|
|
|
# CHECK: arg
|
|
|
|
alias envxalias='a=b x'
|
|
|
|
complete -C'a=b envxalias '
|
|
|
|
# CHECK: arg
|
2019-11-25 16:19:53 +08:00
|
|
|
|
|
|
|
# Eval invalid grammar to allow fish to parse this file
|
|
|
|
eval 'a=(echo b)'
|
|
|
|
# CHECKERR: {{.*}}: Unsupported use of '='. In fish, please use 'set a (echo b)'.
|
|
|
|
eval ': | a=b'
|
|
|
|
# CHECKERR: {{.*}}: Unsupported use of '='. In fish, please use 'set a b'.
|
|
|
|
eval 'not a=b'
|
|
|
|
# CHECKERR: {{.*}}: Unsupported use of '='. In fish, please use 'set a b'.
|