Locating the source of a function in zsh

First of all, a function can be defined without the function keyword so a better search would be

grep 'cp()' .*

That will search through files such as .zshrc and .profile and whatnot. If that finds nothing, you might also want to see the various files loaded by zsh. These are listed at the very end of man zsh:

FILES
       $ZDOTDIR/.zshenv
       $ZDOTDIR/.zprofile
       $ZDOTDIR/.zshrc
       $ZDOTDIR/.zlogin
       $ZDOTDIR/.zlogout
       ${TMPPREFIX}*   (default is /tmp/zsh*)
       /etc/zsh/zshenv
       /etc/zsh/zprofile
       /etc/zsh/zshrc
       /etc/zsh/zlogin
       /etc/zsh/zlogout    (installation-specific - /etc is the default)

By default $ZDOTDIR should be your $HOME. So, this command should find your offending file:

grep 'cp()\|cp ()' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin /etc/zsh/zshenv \
 /etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin 

I added the \| since you can also have spaces between the function name and the function itself. Finally, @Dennis points out that the parentheses can also be omitted if you use the function keyword. So, to be even more safe, do this:

grep -E 'function cp|cp *\(\)' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin \
  /etc/zsh/zshenv /etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin 

I needed to do this today and found that whence -v outputs the file containing the function definition.

$ whence -v function_name
function_name is a shell function from /path/to/file

Newer versions of zsh (since 5.4, added in commit 34f70c5) supports the $functions_source array as part of the zsh/parameter module (documentation: man zshmodules):

functions_source

This readonly associative array maps names of enabled functions to the name of the file containing the source of the function.

For an autoloaded function that has already been loaded, or marked for autoload with an absolute path, or that has had its path resolved with ‘functions -r’, this is the file found for autoloading, resolved to an absolute path.

For a function defined within the body of a script or sourced file, this is the name of that file. In this case, this is the exact path originally used to that file, which may be a relative path.

For any other function, including any defined at an interactive prompt or an autoload function whose path has not yet been resolved, this is the empty string. However, the hash element is reported as defined just so long as the function is present: the keys to this hash are the same as those to $funcions.

So, you can do

echo $functions_source[cp]

Terdon's answer already gave you the appropriate grep command to catch all possible variants of a function definition.

I want to add two more points.

  1. To get a list of files, which are actually read in (e.g. a non-standard file might be sourced by another file!), you can invoke zsh with the SOURCE_TRACE option enabled:

    $ zsh -o sourcetrace
    +/etc/zshenv:1> <sourcetrace>
    +/home/user/.zshrc:1> <sourcetrace>
    +/home/user/.zcompdump:1> <sourcetrace>
    +/home/user/.zshrc-last:1> <sourcetrace>
    
  2. With this ,,grep-approach'' you won't catch functions which are autoloaded via the autoload builtin. So, do a check of your fpath, too:

    $ for i ($fpath) { ls -l "$i"/cp }