mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-03 00:16:20 +08:00
84b25855b0
See https://stackoverflow.com/questions/63115744/alias-with-spaces-and-arguments-in-fish-3
This was broken in 115892ccd2
73 lines
2.4 KiB
Fish
73 lines
2.4 KiB
Fish
function alias --description 'Creates a function wrapping a command'
|
|
set -l options h/help s/save
|
|
argparse -n alias --max-args=2 $options -- $argv
|
|
or return
|
|
|
|
if set -q _flag_help
|
|
__fish_print_help alias
|
|
return 0
|
|
end
|
|
|
|
set -l name
|
|
set -l body
|
|
set -l prefix
|
|
set -l first_word
|
|
set -l wrapped_cmd
|
|
|
|
if not set -q argv[1]
|
|
# Print the known aliases.
|
|
for func in (functions -n)
|
|
set -l output (functions $func | string match -r -- "^function .* --description (?:'alias (.*)'|alias\\\\ (.*))\$")
|
|
if set -q output[2]
|
|
set output (string replace -r -- '^'$func'[= ]' '' $output[2])
|
|
echo alias $func (string escape -- $output[1])
|
|
end
|
|
end
|
|
return 0
|
|
else if not set -q argv[2]
|
|
# Alias definition of the form "name=value".
|
|
set -l tmp (string split -m 1 "=" -- $argv) ""
|
|
set name $tmp[1]
|
|
set body $tmp[2]
|
|
else
|
|
# Alias definition of the form "name value".
|
|
set name $argv[1]
|
|
set body $argv[2]
|
|
end
|
|
|
|
# sanity check
|
|
if test -z "$name"
|
|
printf ( _ "%s: Name cannot be empty\n") alias
|
|
return 1
|
|
else if test -z "$body"
|
|
printf ( _ "%s: Body cannot be empty\n") alias
|
|
return 1
|
|
end
|
|
|
|
# Extract the first command from the body.
|
|
printf '%s\n' $body | read -lt first_word body
|
|
|
|
# Prevent the alias from immediately running into an infinite recursion if
|
|
# $body starts with the same command as $name.
|
|
if test $first_word = $name
|
|
if contains $name (builtin --names)
|
|
set prefix builtin
|
|
else
|
|
set prefix command
|
|
end
|
|
end
|
|
set -l cmd_string (string escape -- "alias $argv")
|
|
|
|
# We've tokenized the first word, but we need to reescape them so they won't be split apart by `source`.
|
|
# E.g. if the first_word is "some command with spaces", that needs to be understood as one argument.
|
|
# As $body is the rest of the tokenized read, it doesn't need to be escaped.
|
|
set first_word (string escape -- $first_word)
|
|
|
|
set wrapped_cmd (string join ' ' -- $first_word $body | string escape)
|
|
echo "function $name --wraps $wrapped_cmd --description $cmd_string; $prefix $first_word $body \$argv; end" | source
|
|
if set -q _flag_save
|
|
funcsave $name
|
|
end
|
|
#echo "function $name --wraps $wrapped_cmd --description $cmd_string; $prefix $first_word $body \$argv; end"
|
|
end
|