mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 15:14:44 +00:00
alias: Use read --tokenize
This did some weird unescaping to try to extract the first word. So we're now more likely to be *correct*, and the alias benchmark is about 20% *faster*. Call it a win-win.
This commit is contained in:
parent
86133b0a2b
commit
115892ccd2
3 changed files with 8 additions and 26 deletions
|
@ -44,22 +44,12 @@ function alias --description 'Creates a function wrapping a command'
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
# Extract the first command from the body. This is supposed to replace all non-escaped (i.e.
|
# Extract the first command from the body.
|
||||||
# preceded by an odd number of `\`) spaces with a newline so it splits on them. See issue #2220
|
printf '%s\n' $body | read -lt first_word body
|
||||||
# for why the following borderline incomprehensible code exists.
|
|
||||||
set -l tmp (string replace -ra -- "([^\\\ ])((\\\\\\\)*) " '$1\n' $body)
|
|
||||||
set first_word (string trim -- $tmp[1])
|
|
||||||
# If the user does something like `alias x 'foo; bar'` we need to strip the semicolon.
|
|
||||||
set base_command (string trim -c ';' -- $first_word)
|
|
||||||
if set -q tmp[2]
|
|
||||||
set body $tmp[2..-1]
|
|
||||||
else
|
|
||||||
set body
|
|
||||||
end
|
|
||||||
|
|
||||||
# Prevent the alias from immediately running into an infinite recursion if
|
# Prevent the alias from immediately running into an infinite recursion if
|
||||||
# $body starts with the same command as $name.
|
# $body starts with the same command as $name.
|
||||||
if test $base_command = $name
|
if test $first_word = $name
|
||||||
if contains $name (builtin --names)
|
if contains $name (builtin --names)
|
||||||
set prefix builtin
|
set prefix builtin
|
||||||
else
|
else
|
||||||
|
|
|
@ -44,22 +44,12 @@ function alias --description 'Creates a function wrapping a command'
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
# Extract the first command from the body. This is supposed to replace all non-escaped (i.e.
|
# Extract the first command from the body.
|
||||||
# preceded by an odd number of `\`) spaces with a newline so it splits on them. See issue #2220
|
printf '%s\n' $body | read -lt first_word body
|
||||||
# for why the following borderline incomprehensible code exists.
|
|
||||||
set -l tmp (string replace -ra -- "([^\\\ ])((\\\\\\\)*) " '$1\n' $body)
|
|
||||||
set first_word (string trim -- $tmp[1])
|
|
||||||
# If the user does something like `alias x 'foo; bar'` we need to strip the semicolon.
|
|
||||||
set base_command (string trim -c ';' -- $first_word)
|
|
||||||
if set -q tmp[2]
|
|
||||||
set body $tmp[2..-1]
|
|
||||||
else
|
|
||||||
set body
|
|
||||||
end
|
|
||||||
|
|
||||||
# Prevent the alias from immediately running into an infinite recursion if
|
# Prevent the alias from immediately running into an infinite recursion if
|
||||||
# $body starts with the same command as $name.
|
# $body starts with the same command as $name.
|
||||||
if test $base_command = $name
|
if test $first_word = $name
|
||||||
if contains $name (builtin --names)
|
if contains $name (builtin --names)
|
||||||
set prefix builtin
|
set prefix builtin
|
||||||
else
|
else
|
||||||
|
|
|
@ -10,9 +10,11 @@ my_alias
|
||||||
|
|
||||||
alias a-2='echo "hello there"'
|
alias a-2='echo "hello there"'
|
||||||
|
|
||||||
|
alias foo '"a b" c d e'
|
||||||
# Bare `alias` should list the aliases we have created and nothing else
|
# Bare `alias` should list the aliases we have created and nothing else
|
||||||
# We have to exclude two aliases because they're an artifact of the unit test
|
# We have to exclude two aliases because they're an artifact of the unit test
|
||||||
# framework and we can't predict the definition.
|
# framework and we can't predict the definition.
|
||||||
alias | grep -Ev '^alias (fish_indent|fish_key_reader) '
|
alias | grep -Ev '^alias (fish_indent|fish_key_reader) '
|
||||||
# CHECK: alias a-2 'echo "hello there"'
|
# CHECK: alias a-2 'echo "hello there"'
|
||||||
|
# CHECK: alias foo '"a b" c d e'
|
||||||
# CHECK: alias my_alias 'foo; and echo foo ran'
|
# CHECK: alias my_alias 'foo; and echo foo ran'
|
||||||
|
|
Loading…
Reference in a new issue