aboutsummaryrefslogtreecommitdiffhomepage
path: root/share/functions/type.fish
diff options
context:
space:
mode:
authorGravatar Kevin Ballard <kevin@sb.org>2014-07-09 23:38:33 -0700
committerGravatar Kevin Ballard <kevin@sb.org>2014-07-13 19:11:29 -0700
commitbfd3a47380f65e24ff568efd1570338298d56200 (patch)
tree6b9aab751d324512314e07067e7fd20817c7f4e8 /share/functions/type.fish
parent0933e5cab470125fc3757dc146173551a4cad177 (diff)
Fix `type` function to work better
Stop using getopt to parse flags. It's far more expensive than necessary, and results in long flags not being parsed on OS X. This also allows args starting with - after the options list to be properly interpreted as a value to test. Print the error message to stderr as is appropriate. Use the new `command -p` functionality when the -a flag has not been provided (`command` does not have any equivalent to the -a flag), instead of using `which`. This is faster and also avoids any possible disagreement between `which` and what fish thinks is valid. Stop testing every path to see if it's executable, that test has already been done by `which` or `command -p`. The end result is `type -P ls` is roughly 250% faster, according to profiling, on my OS X machine.
Diffstat (limited to 'share/functions/type.fish')
-rw-r--r--share/functions/type.fish114
1 files changed, 43 insertions, 71 deletions
diff --git a/share/functions/type.fish b/share/functions/type.fish
index 4a4c7703..2ddcc622 100644
--- a/share/functions/type.fish
+++ b/share/functions/type.fish
@@ -5,74 +5,48 @@ function type --description "Print the type of a command"
set -l res 1
set -l mode normal
set -l selection all
-
- #
- # Get options
- #
- set -l options
- set -l shortopt tpPafh
- if not getopt -T > /dev/null
- # GNU getopt
- set -l longopt type,path,force-path,all,no-functions,help
- set options -o $shortopt -l $longopt --
- # Verify options
- if not getopt -n type $options $argv >/dev/null
- return 1
- end
- else
- # Old getopt, used on OS X
- set options $shortopt
- # Verify options
- if not getopt $options $argv >/dev/null
- return 1
- end
- end
- # Do the real getopt invocation
- set -l tmp (getopt $options $argv)
+ # Parse options
+ set -l names
+ if test (count $argv) -gt 0
+ for i in (seq (count $argv))
+ switch $argv[$i]
+ case -t --type
+ set mode type
- # Break tmp up into an array
- set -l opt
- eval set opt $tmp
-
- for i in $opt
- switch $i
- case -t --type
- set mode type
+ case -p --path
+ set mode path
- case -p --path
- set mode path
+ case -P --force-path
+ set mode path
+ set selection files
- case -P --force-path
- set mode path
- set selection files
+ case -a --all
+ set selection multi
- case -a --all
- set selection multi
+ case -f --no-functions
+ set selection files
- case -f --no-functions
- set selection files
+ case -h --help
+ __fish_print_help type
+ return 0
- case -h --help
- __fish_print_help type
- return 0
-
- case --
- break
+ case --
+ set names $argv[$i..-1]
+ set -e names[1]
+ break
+ case '*'
+ set names $argv[$i..-1]
+ break
+ end
end
end
# Check all possible types for the remaining arguments
- for i in $argv
-
- switch $i
- case '-*'
- continue
- end
-
+ for i in $names
# Found will be set to 1 if a match is found
- set found 0
+ set -l found 0
if test $selection != files
@@ -119,32 +93,30 @@ function type --description "Print the type of a command"
set -l paths
if test $selection != multi
- set paths (which $i ^/dev/null)
+ set paths (command -p $i)
else
set paths (which -a $i ^/dev/null)
end
for path in $paths
- if test -x (echo $path)
- set res 0
- set found 1
- switch $mode
- case normal
- printf (_ '%s is %s\n') $i $path
+ set res 0
+ set found 1
+ switch $mode
+ case normal
+ printf (_ '%s is %s\n') $i $path
- case type
- echo (_ 'file')
+ case type
+ echo (_ 'file')
- case path
- echo $path
- end
- if test $selection != multi
- continue
- end
+ case path
+ echo $path
+ end
+ if test $selection != multi
+ continue
end
end
if test $found = 0
- printf (_ "%s: Could not find '%s'\n") type $i
+ printf (_ "%s: Could not find '%s'\n") type $i >&2
end
end