2024-04-12 18:19:32 +08:00
|
|
|
# RUN: %fish -C 'set -g fish %fish' %s
|
2019-10-05 02:28:47 +08:00
|
|
|
|
|
|
|
# caret position (#5812)
|
|
|
|
printf '<%s>\n' ($fish -c ' $f[a]' 2>&1)
|
|
|
|
|
|
|
|
# CHECK: <fish: Invalid index value>
|
|
|
|
# CHECK: < $f[a]>
|
|
|
|
# CHECK: < ^>
|
|
|
|
|
|
|
|
printf '<%s>\n' ($fish -c 'if $f[a]; end' 2>&1)
|
|
|
|
# CHECK: <fish: Invalid index value>
|
|
|
|
# CHECK: <if $f[a]; end>
|
|
|
|
# CHECK: < ^>
|
2020-02-08 17:38:11 +08:00
|
|
|
|
|
|
|
set a A
|
|
|
|
set aa AA
|
|
|
|
set aaa AAA
|
|
|
|
echo {$aa}a{1,2,3}(for a in 1 2 3; echo $a; end)
|
|
|
|
#CHECK: AAa11 AAa21 AAa31 AAa12 AAa22 AAa32 AAa13 AAa23 AAa33
|
2020-02-08 18:16:53 +08:00
|
|
|
|
|
|
|
# basic expansion test
|
|
|
|
echo {}
|
|
|
|
echo {apple}
|
|
|
|
echo {apple,orange}
|
|
|
|
#CHECK: {}
|
|
|
|
#CHECK: {apple}
|
|
|
|
#CHECK: apple orange
|
|
|
|
|
|
|
|
# expansion tests with spaces
|
|
|
|
echo {apple, orange}
|
|
|
|
echo { apple, orange, banana }
|
|
|
|
#CHECK: apple orange
|
|
|
|
#CHECK: apple orange banana
|
|
|
|
|
|
|
|
# expansion with spaces and cartesian products
|
|
|
|
echo \'{ hello , world }\'
|
|
|
|
#CHECK: 'hello' 'world'
|
|
|
|
|
|
|
|
# expansion with escapes
|
2020-03-10 02:36:12 +08:00
|
|
|
for phrase in {good\,, beautiful ,morning}
|
|
|
|
echo -n "$phrase "
|
|
|
|
end | string trim
|
2021-11-23 04:08:56 +08:00
|
|
|
echo
|
2020-03-10 02:36:12 +08:00
|
|
|
for phrase in {goodbye\,,\ cruel\ ,world\n}
|
|
|
|
echo -n $phrase
|
|
|
|
end
|
2020-02-08 18:16:53 +08:00
|
|
|
#CHECK: good, beautiful morning
|
|
|
|
#CHECK: goodbye, cruel world
|
|
|
|
|
|
|
|
# dual expansion cartesian product
|
2020-03-10 02:36:12 +08:00
|
|
|
echo { alpha, beta }\ {lambda, gamma }, | string replace -r ',$' ''
|
2020-02-08 18:16:53 +08:00
|
|
|
#CHECK: alpha lambda, beta lambda, alpha gamma, beta gamma
|
|
|
|
|
|
|
|
# expansion with subshells
|
|
|
|
for name in { (echo Meg), (echo Jo) }
|
2020-03-10 02:36:12 +08:00
|
|
|
echo $name
|
2020-02-08 18:16:53 +08:00
|
|
|
end
|
|
|
|
#CHECK: Meg
|
|
|
|
#CHECK: Jo
|
|
|
|
|
|
|
|
# subshells with expansion
|
2020-03-10 02:36:12 +08:00
|
|
|
for name in (for name in {Beth, Amy}; printf "$name\n"; end)
|
|
|
|
printf "$name\n"
|
|
|
|
end
|
2020-02-08 18:16:53 +08:00
|
|
|
#CHECK: Beth
|
|
|
|
#CHECK: Amy
|
|
|
|
|
|
|
|
echo {{a,b}}
|
|
|
|
#CHECK: {a} {b}
|
2020-03-17 02:44:19 +08:00
|
|
|
|
|
|
|
# Test expansion of variables
|
|
|
|
|
|
|
|
# We don't use the test utility function of the same name because we want
|
|
|
|
# different behavior. Specifically, that the expansion of any variables or
|
|
|
|
# other strings before we are invoked produce the expected expansion.
|
|
|
|
function expansion --description 'Prints argument count followed by arguments'
|
|
|
|
echo (count $argv) $argv
|
|
|
|
end
|
|
|
|
|
|
|
|
set -l foo
|
|
|
|
expansion "$foo"
|
|
|
|
expansion $foo
|
|
|
|
expansion "prefix$foo"
|
|
|
|
expansion prefix$foo
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1 prefix
|
|
|
|
#CHECK: 0
|
|
|
|
|
|
|
|
expansion "$$foo"
|
|
|
|
expansion $$foo
|
|
|
|
expansion "prefix$$foo"
|
|
|
|
expansion prefix$$foo
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1 prefix
|
|
|
|
#CHECK: 0
|
|
|
|
|
|
|
|
set -l foo ''
|
|
|
|
expansion "$foo"
|
|
|
|
expansion $foo
|
|
|
|
expansion "prefix$foo"
|
|
|
|
expansion prefix$foo
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 1 prefix
|
|
|
|
#CHECK: 1 prefix
|
|
|
|
|
|
|
|
expansion "$$foo"
|
|
|
|
expansion $$foo
|
|
|
|
expansion "prefix$$foo"
|
|
|
|
expansion prefix$$foo
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1 prefix
|
|
|
|
#CHECK: 0
|
|
|
|
|
|
|
|
set -l foo bar
|
|
|
|
set -l bar
|
|
|
|
expansion "$$foo"
|
|
|
|
expansion $$foo
|
|
|
|
expansion "prefix$$foo"
|
|
|
|
expansion prefix$$foo
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1 prefix
|
|
|
|
#CHECK: 0
|
|
|
|
|
|
|
|
set -l bar baz
|
|
|
|
expansion "$$foo"
|
|
|
|
expansion $$foo
|
|
|
|
expansion "prefix$$foo"
|
|
|
|
expansion prefix$$foo
|
|
|
|
#CHECK: 1 baz
|
|
|
|
#CHECK: 1 baz
|
|
|
|
#CHECK: 1 prefixbaz
|
|
|
|
#CHECK: 1 prefixbaz
|
|
|
|
|
|
|
|
set -l bar baz quux
|
|
|
|
expansion "$$foo"
|
|
|
|
expansion $$foo
|
|
|
|
expansion "prefix$$foo"
|
|
|
|
expansion prefix$$foo
|
|
|
|
#CHECK: 1 baz quux
|
|
|
|
#CHECK: 2 baz quux
|
|
|
|
#CHECK: 1 prefixbaz quux
|
|
|
|
#CHECK: 2 prefixbaz prefixquux
|
|
|
|
|
|
|
|
set -l foo bar fooer fooest
|
|
|
|
set -l fooer
|
|
|
|
set -l fooest
|
|
|
|
expansion "$$foo"
|
|
|
|
expansion $$foo
|
|
|
|
expansion "prefix$$foo"
|
|
|
|
expansion prefix$$foo
|
|
|
|
#CHECK: 1 baz quux fooer fooest
|
|
|
|
#CHECK: 2 baz quux
|
|
|
|
#CHECK: 1 prefixbaz quux fooer fooest
|
|
|
|
#CHECK: 2 prefixbaz prefixquux
|
|
|
|
|
|
|
|
set -l fooer ''
|
|
|
|
expansion $$foo
|
|
|
|
expansion prefix$$foo
|
|
|
|
#CHECK: 3 baz quux
|
|
|
|
#CHECK: 3 prefixbaz prefixquux prefix
|
|
|
|
|
|
|
|
# Slices
|
|
|
|
|
|
|
|
set -l foo bar '' fooest
|
|
|
|
expansion "$$foo"
|
|
|
|
expansion $$foo
|
|
|
|
expansion "prefix$$foo"
|
|
|
|
expansion prefix$$foo
|
|
|
|
expansion $foo[-5..2] # No result, because the starting index is invalid and we force-reverse.
|
|
|
|
expansion $foo[-2..-1]
|
|
|
|
expansion $foo[-10..-5]
|
|
|
|
expansion (printf '%s\n' $foo)[-5..2]
|
|
|
|
expansion (printf '%s\n' $foo)[-2..-1]
|
|
|
|
expansion (printf '%s\n' $foo)[-10..-5]
|
|
|
|
expansion (echo one)[2..-1]
|
|
|
|
#CHECK: 1 baz quux fooest
|
|
|
|
#CHECK: 2 baz quux
|
|
|
|
#CHECK: 1 prefixbaz quux fooest
|
|
|
|
#CHECK: 2 prefixbaz prefixquux
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 2 fooest
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 2 fooest
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 0
|
|
|
|
|
|
|
|
set -l foo
|
|
|
|
expansion "$foo[1]"
|
|
|
|
expansion $foo[1]
|
|
|
|
expansion "$foo[-1]"
|
|
|
|
expansion $foo[-1]
|
|
|
|
expansion "$foo[2]"
|
|
|
|
expansion $foo[2]
|
|
|
|
expansion "$foo[1 2]"
|
|
|
|
expansion $foo[1 2]
|
|
|
|
expansion "$foo[2 1]"
|
|
|
|
expansion $foo[2 1]
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 1
|
|
|
|
#CHECK: 0
|
|
|
|
set -l foo a b c
|
|
|
|
expansion $foo[17]
|
|
|
|
expansion $foo[-17]
|
|
|
|
expansion $foo[17..18]
|
|
|
|
expansion $foo[4..-2]
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 0
|
|
|
|
#CHECK: 0
|
|
|
|
set -l foo a
|
|
|
|
expansion $foo[2..-1]
|
|
|
|
#CHECK: 0
|
2021-08-17 12:08:08 +08:00
|
|
|
expansion $foo[0]
|
|
|
|
#CHECKERR: {{.*}}expansion.fish (line {{\d+}}): array indices start at 1, not 0.
|
|
|
|
#CHECKERR: expansion $foo[0]
|
|
|
|
#CHECKERR: ^
|
|
|
|
# see https://github.com/fish-shell/fish-shell/issues/8213
|
|
|
|
expansion $foo[1..0]
|
|
|
|
#CHECKERR: {{.*}}expansion.fish (line {{\d+}}): array indices start at 1, not 0.
|
|
|
|
#CHECKERR: expansion $foo[1..0]
|
|
|
|
#CHECKERR: ^
|
|
|
|
expansion $foo[-0]
|
|
|
|
#CHECKERR: {{.*}}expansion.fish (line {{\d+}}): array indices start at 1, not 0.
|
|
|
|
#CHECKERR: expansion $foo[-0]
|
|
|
|
#CHECKERR: ^
|
2020-03-17 02:44:19 +08:00
|
|
|
|
|
|
|
echo "$foo[d]"
|
|
|
|
#CHECKERR: {{.*}}expansion.fish (line {{\d+}}): Invalid index value
|
|
|
|
#CHECKERR: echo "$foo[d]"
|
|
|
|
#CHECKERR: ^
|
|
|
|
echo $foo[d]
|
|
|
|
#CHECKERR: {{.*}}expansion.fish (line {{\d+}}): Invalid index value
|
|
|
|
#CHECKERR: echo $foo[d]
|
|
|
|
#CHECKERR: ^
|
|
|
|
|
|
|
|
echo ()[1]
|
|
|
|
# No output
|
|
|
|
echo ()[d]
|
|
|
|
#CHECKERR: {{.*}}expansion.fish (line {{\d+}}): Invalid index value
|
|
|
|
#CHECKERR: echo ()[d]
|
|
|
|
#CHECKERR: ^
|
|
|
|
|
|
|
|
set -l outer out1 out2
|
|
|
|
set -l inner 1 2
|
|
|
|
echo $outer[$inner[2]]
|
|
|
|
#CHECK: out2
|
|
|
|
echo $outer[$inner[2..1]]
|
|
|
|
#CHECK: out2 out1
|
|
|
|
|
|
|
|
# Percent self
|
|
|
|
echo %selfNOT NOT%self \%self "%self" '%self'
|
|
|
|
echo %self | string match -qr '^\\d+$'
|
|
|
|
#CHECK: %selfNOT NOT%self %self %self %self
|
|
|
|
echo "All digits: $status"
|
|
|
|
#CHECK: All digits: 0
|
|
|
|
|
|
|
|
set paren ')'
|
|
|
|
echo $$paren
|
|
|
|
#CHECKERR: {{.*}}expansion.fish (line {{\d+}}): $) is not a valid variable in fish.
|
|
|
|
#CHECKERR: echo $$paren
|
|
|
|
#CHECKERR: ^
|
|
|
|
|
|
|
|
# Test tilde expansion
|
|
|
|
# On OS X, /tmp is symlinked to /private/tmp
|
|
|
|
# $PWD is our best bet for resolving it
|
|
|
|
set -l saved $PWD
|
|
|
|
cd (mktemp -d)
|
|
|
|
set tmpdir $PWD
|
|
|
|
cd $saved
|
|
|
|
mkdir $tmpdir/realhome
|
|
|
|
ln -s $tmpdir/realhome $tmpdir/linkhome
|
2020-03-28 22:46:47 +08:00
|
|
|
set expandedtilde (env HOME=$tmpdir/linkhome $fish -c 'echo ~')
|
2020-03-17 02:44:19 +08:00
|
|
|
if test $expandedtilde != $tmpdir/linkhome
|
|
|
|
echo '~ expands to' $expandedtilde ' - expected ' $tmpdir/linkhome
|
|
|
|
end
|
|
|
|
rm $tmpdir/linkhome
|
|
|
|
rmdir $tmpdir/realhome
|
|
|
|
rmdir $tmpdir
|
|
|
|
|
|
|
|
# Test path variables
|
|
|
|
set TEST_DELIMITER one two three
|
|
|
|
set TEST_DELIMITER_PATH one two three
|
|
|
|
echo TEST_DELIMITER: $TEST_DELIMITER "$TEST_DELIMITER"
|
|
|
|
echo TEST_DELIMITER_PATH: $TEST_DELIMITER_PATH "$TEST_DELIMITER_PATH"
|
|
|
|
#CHECK: TEST_DELIMITER: one two three one two three
|
|
|
|
#CHECK: TEST_DELIMITER_PATH: one two three one:two:three
|
|
|
|
|
|
|
|
set testvar ONE:TWO:THREE
|
|
|
|
echo "Not a path: $testvar" (count $testvar)
|
|
|
|
#CHECK: Not a path: ONE:TWO:THREE 1
|
|
|
|
set --path testvar $testvar
|
|
|
|
echo "As a path: $testvar" (count $testvar)
|
|
|
|
#CHECK: As a path: ONE:TWO:THREE 3
|
|
|
|
set testvar "$testvar:FOUR"
|
|
|
|
echo "Appended path: $testvar" (count $testvar)
|
|
|
|
#CHECK: Appended path: ONE:TWO:THREE:FOUR 4
|
|
|
|
set --unpath testvar $testvar
|
|
|
|
echo "Back to normal variable: $testvar" (count $testvar)
|
|
|
|
#CHECK: Back to normal variable: ONE TWO THREE FOUR 4
|
|
|
|
|
|
|
|
# Test fatal syntax errors
|
|
|
|
$fish -c 'echo $,foo'
|
2022-11-16 02:05:18 +08:00
|
|
|
#CHECKERR: fish: Expected a variable name after this $.
|
2020-03-17 02:44:19 +08:00
|
|
|
#CHECKERR: echo $,foo
|
|
|
|
#CHECKERR: ^
|
|
|
|
$fish -c 'echo {'
|
|
|
|
#CHECKERR: fish: Unexpected end of string, incomplete parameter expansion
|
|
|
|
#CHECKERR: echo {
|
|
|
|
#CHECKERR: ^
|
|
|
|
$fish -c 'echo {}}'
|
|
|
|
#CHECKERR: fish: Unexpected '}' for unopened brace expansion
|
|
|
|
#CHECKERR: echo {}}
|
|
|
|
#CHECKERR: ^
|
2022-08-12 00:06:05 +08:00
|
|
|
printf '<%s>\n' ($fish -c 'command (asd)' 2>&1)
|
2023-11-18 19:24:58 +08:00
|
|
|
#CHECK: <fish: command substitutions not allowed in command position. Try var=(your-cmd) $var ...>
|
2022-08-12 00:06:05 +08:00
|
|
|
#CHECK: <command (asd)>
|
|
|
|
#CHECK: < ^~~~^>
|
2020-03-17 02:44:19 +08:00
|
|
|
true
|
2022-08-12 01:24:41 +08:00
|
|
|
|
|
|
|
printf '<%s>\n' ($fish -c 'echo "$abc["' 2>&1)
|
|
|
|
#CHECK: <fish: Invalid index value>
|
|
|
|
#CHECK: <echo "$abc[">
|
|
|
|
#CHECK: < ^>
|
2024-02-07 05:12:55 +08:00
|
|
|
|
|
|
|
set -l pager command less
|
|
|
|
echo foo | $pager
|
|
|
|
#CHECKERR: checks/expansion.fish (line 339): The expanded command is a keyword.
|
|
|
|
#CHECKERR: echo foo | $pager
|
|
|
|
#CHECKERR: ^~~~~^
|