
function type --description "Print the type of a command"

	# Initialize
	set -l res 1
	set -l mode normal
	set -l multi no
	set -l selection all
	set -l IFS \n\ \t

	# Parse options
	set -l names
	if test (count $argv) -gt 0
		for i in (seq (count $argv))
			set -l arg $argv[$i]
			set -l needbreak 0
			while test -n $arg
				set -l flag $arg
				set arg ''
				switch $flag
					case '--*'
						# do nothing; this just prevents it matching the next case
					case '-??*'
						# combined flags
						set -l IFS
						echo -n $flag | read __ flag arg
						set flag -$flag
						set arg -$arg
				end
				switch $flag
					case -t --type
						if test $mode != quiet
							set mode type
						end

					case -p --path
						if test $mode != quiet
							set mode path
						end

					case -P --force-path
						if test $mode != quiet
							set mode path
						end
						set selection files

					case -a --all
						set multi yes

					case -f --no-functions
						set selection files

					case -q --quiet
						set mode quiet

					case -h --help
						__fish_print_help type
						return 0

					case --
						set names $argv[$i..-1]
						set -e names[1]
						set needbreak 1
						break

					case '*'
						set names $argv[$i..-1]
						set needbreak 1
						break
				end
			end
			if test $needbreak -eq 1
				break
			end
		end
	end

	# Check all possible types for the remaining arguments
	for i in $names
		# Found will be set to 1 if a match is found
		set -l found 0

		if test $selection != files

			if functions -q -- $i
				set res 0
				set found 1
				switch $mode
					case normal
						printf (_ '%s is a function with definition\n') $i
						functions $i

					case type
						echo (_ 'function')
				end
				if test $multi != yes
					continue
				end
			end

			if contains -- $i (builtin -n)

				set res 0
				set found 1
				switch $mode
					case normal
						printf (_ '%s is a builtin\n') $i

					case type
						echo (_ 'builtin')
				end
				if test $multi != yes
					continue
				end
			end

		end

		set -l paths
		if test $multi != yes
			set paths (command -s -- $i)
		else
			set paths (which -a -- $i ^/dev/null)
		end
		for path in $paths
			set res 0
			set found 1
			switch $mode
				case normal
					printf (_ '%s is %s\n') $i $path

				case type
					echo (_ 'file')

				case path
					echo $path
			end
			if test $multi != yes
				continue
			end
		end

		if begin; test $found = 0; and test $mode != quiet; end
			printf (_ "%s: Could not find '%s'\n") type $i >&2
		end

	end

	return $res
end

