Here is the answer to a similar question, which advises not to use which for reasons not related to the point in question.
However, your assumption that which can only see executable files is incorrect.
However, it does not see the default functions and aliases.
This is why the manpage says:
The recommended way to use this utility is to add an alias function (C shell) or a shell (Bourne shell), for which, as shown below:
[ba]sh: which () { (alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot $@ } export -f which
If you define this function in your .bashrc and reuse it, you should be able to do
which -a
and it should also give you functions and aliases.
However, note: if some profile or bashrc has already defined something for which , this takes precedence (you can find it with type -a which btw).
If I define a script, a function, and an alias called something , I get with type -a :
type -a something something is aliased to `echo "something"' something is a function something () { echo "function something" } something is /home/myself/bin/something
So far, which -a after creating the function gives me:
which -a something alias something='echo "something"' /usr/bin/echo /bin/echo something () { echo "function something" } ~/bin/something