aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Fabian Homborg <FHomborg@gmail.com>2015-09-23 13:28:32 +0200
committerGravatar Fabian Homborg <FHomborg@gmail.com>2015-09-23 13:28:32 +0200
commit54d1d98e3973a57f618e8c3f18ecb1b98f7f5368 (patch)
treed434fa7e837694af214031506f7ee4248cbbc145
parent6f92781992bc1419944ea8e40d63b9c2ab02fa9f (diff)
Fix aliases with whitespace
And document how that stuff works. Fixes #2220 Also, the string stuff is cool.
-rw-r--r--doc_src/alias.txt6
-rw-r--r--share/functions/alias.fish115
2 files changed, 61 insertions, 60 deletions
diff --git a/doc_src/alias.txt b/doc_src/alias.txt
index 028277a3..cbb9508e 100644
--- a/doc_src/alias.txt
+++ b/doc_src/alias.txt
@@ -18,6 +18,8 @@ alias NAME=DEFINITION
You cannot create an alias to a function with the same name.
+Note that spaces need to be escaped in the call to alias just like in the commandline _even inside the quotes_.
+
\subsection alias-example Example
@@ -31,4 +33,8 @@ alias rmi "rm -i"
function rmi
rm -i $argv
end
+
+# This needs to have the spaces escaped or "Chrome.app..." will be seen as an argument to "/Applications/Google":
+
+alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome banana'
\endfish
diff --git a/share/functions/alias.fish b/share/functions/alias.fish
index 2dc86b1b..11fdd164 100644
--- a/share/functions/alias.fish
+++ b/share/functions/alias.fish
@@ -1,70 +1,65 @@
+function alias --description 'Legacy function for creating shellscript functions using an alias-like syntax'
+ if count $argv > /dev/null
+ switch $argv[1]
+ case -h --h --he --hel --help
+ __fish_print_help alias
+ return 0
+ end
+ end
-function alias --description "Legacy function for creating shellscript functions using an alias-like syntax"
+ set -l name
+ set -l body
+ set -l prefix
+ set -l first_word
+ switch (count $argv)
- if count $argv >/dev/null
- switch $argv[1]
- case -h --h --he --hel --help
- __fish_print_help alias
- return 0
- end
- end
+ case 0
+ echo "Fish implements aliases using functions. Use 'functions' builtin to see list of functions and 'functions function_name' to see function definition, type 'help alias' for more information."
+ return 1
+ case 1
+ set -l tmp (string replace -r "=" '\n' -- $argv) ""
+ set name $tmp[1]
+ set body $tmp[2]
- set -l name
- set -l body
- set -l prefix
- set -l first_word
- switch (count $argv)
+ case 2
+ set name $argv[1]
+ set body $argv[2]
- case 0
- echo "Fish implements aliases using functions. Use 'functions' builtin to see list of functions and 'functions function_name' to see function definition, type 'help alias' for more information."
- return 1
- case 1
- # Some seds (e.g. on Mac OS X), don't support \n in the RHS
- # Use a literal newline instead
- # http://sed.sourceforge.net/sedfaq4.html#s4.1
- # The extra '' at the end is so $tmp[2] is guaranteed to work
- set -l tmp (echo $argv|sed -e 's/\([^=]\{0,1\}\)=/\1\
-/') ''
- set name $tmp[1]
- set body $tmp[2]
+ case \*
+ printf ( _ "%s: Expected one or two arguments, got %d\n") alias (count $argv)
+ return 1
+ end
- case 2
- set name $argv[1]
- set body $argv[2]
+ # 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
- case \*
- printf ( _ "%s: Expected one or two arguments, got %d\n") alias (count $argv)
- return 1
- end
+ # Extract the first command from the body
+ # This is supposed to replace all non-escaped (i.e. preceded by an odd number of `\`) spaces with a newline
+ # so it splits on them
+ set -l tmp (string replace -ra "([^\\\ ])((\\\\\\\)*) " '$1\n' $body)
+ set first_word (string trim $tmp[1])
+ if set -q tmp[2]
+ set body $tmp[2..-1]
+ else
+ set body
+ 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
+ # Prevent the alias from immediately running into an infinite recursion if
+ # $body starts with the same command as $name.
- # Extract the first command from the body
- switch $body
- case \*\ \* \*\t\*
- # note: strip leading spaces if present
- set first_word (echo $body|sed -e 's/^[[:space:]]\{1,\}//;s/[[:space:]].*//;q')
- case '*'
- set first_word $body
+ if test $first_word = $name
+ if contains $name (builtin --names)
+ set prefix builtin
+ else
+ set prefix command
end
-
- # 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
-
- eval "function $name --wraps $first_word; $prefix $body \$argv; end"
+ end
+ eval "function $name --wraps $first_word; $prefix $first_word $body \$argv; end"
end
+