`Completion' is where you hit a particular command key (TAB is the standard one) and the shell tries to guess the word you are typing and finish it for you --- a godsend for long file names, in particular, but in zsh there are many, many more possibilities than that.
There is also a related process, `expansion', where the shell sees
  you have typed something which would be turned by the shell into
  something else, such as a variable turning into its value ($PWD
  becomes /home/users/mydir) or a history reference (!! becomes
  everything on the last command line).  In zsh, when you hit TAB it
  will look to see if there is an expansion to be done; if there is,
  it does that, otherwise it tries to perform completion.  (You can
  see if the word would be expanded --- not completed --- by TAB by
  typing \C-x g, which lists expansions.)  Expansion is generally
  fairly intuitive and not under user control; for the rest of the
  chapter I will discuss completion only.
An elegant completion system appeared in version 4, replacing the old
  compctl command.  This is based on functions called automatically for
  completion in particular contexts (for example, there is a function
  called _cd to handle completion for the cd command) and is
  installed automatically with the shell, so all you need to do, in
  principal, is to arrange for this to be loaded.  Putting `autoload -U
  compinit; compinit' in your .zshrc should be enough if the system is
  installed properly.
The simplest sort is filename completion, mentioned above. Unless you have made special arrangements, as described below, then after you type a command name, anything else you type is assumed by the completion system to be a filename. If you type part of a word and hit TAB, zsh will see if it matches the first part a filename and if it does it will automatically insert the rest.
The other simple type is command completion, which applies (naturally) to the first word on the line. In this case, zsh assumes the word is some command to be executed lying in your $PATH (or something else you can execute, like a builtin command, a function or an alias) and tries to complete that.
However, the new completion system is highly sensitive to context
  and comes with completions for many UNIX commands.  These are
  automatically loaded when you run compinit as described above.
  So the real answer to the question `what can be completed?' is
  `anything where an automated guess is possible'.  Just hit TAB
  and see if the shell manages to guess correctly.
Often there will be more than one possible completion: two files
  start with the same characters, for example.  Zsh has a lot of
  flexibility for what it does here via its options.  The default is
  for it to beep and completion to stop until you type another
  character.  You can type \C-D to see all the possible completions.
  (That's assuming you're at the end of the line, otherwise \C-D will
  delete the next character and you have to use ESC-\C-D.)  This can be
  changed by the following options, among others:
  
NO_BEEP set, that annoying beep goes away
   NO_LIST_BEEP, beeping is only turned off for ambiguous
      completions
   AUTO_LIST set, when the completion is ambiguous you get a
      list without having to type \C-D
   BASH_AUTO_LIST set, the list only happens the second
      time you hit tab on an ambiguous completion
   LIST_AMBIGUOUS, this is modified so that nothing is listed if
      there is an unambiguous prefix or suffix to be inserted --- this
      can be combined with BASH_AUTO_LIST, so that where both are
      applicable you need to hit tab three times for a listing.
   MENU_COMPLETE set, one completion is always inserted
      completely, then when you hit TAB it changes to the next, and so
      on until you get back to where you started
   AUTO_MENU, you only get the menu behaviour when you hit TAB
      again on the ambiguous completion.
   ALWAYS_LAST_PROMPT, which
      causes the cursor to return to the line you were editing after
      printing the list, provided that is short enough.
  AUTO_LIST and
  AUTO_MENU together give an intuitive combination.  Note that
  from version 3.1 LIST_AMBIGUOUS is set by default; if you use
  autolist, you may well want to `unsetopt listambiguous'.
Sometimes you have a word on the command-line which is incomplete in the middle. Normally if you hit tab in zsh, it will simply go to the end of the word and try to complete there. However, there are two ways of changing this.
First, there is the option COMPLETE_IN_WORD.  This tries to fill in
  the word at the point of the cursor.  For example, if the current
  directory contains foobar, then with the option set, you can
  complete fbar to foobar by moving the cursor to the
  b and hitting tab.
To complete just what's before the cursor, ignoring anything after, you
  need the function expand-or-complete-prefix: it works mostly like the
  usual function bound to tab, but it ignores anything on the right of the
  cursor.  If you always want this behaviour (some other shells do this),
  bind it to tab; otherwise put another binding, e.g. ^X TAB in
  ~/.zshrc:
  
    bindkey "^X^I" expand-or-complete-prefix
  
The completion system's handling of filenames allows you to complete
  multiple segments of a path in one go, so for example /u/l/b
  can expand to /usr/local/bin or anything else that matches.  This
  saves you having to expand the middle part of the path separately.
The main resource is the zshcompsys manual page.  It's complicated,
  I'm afraid, far too much to go into here.  See also the user guide
  referred to above, or copy one of the very many existing functions.  For
  a professionally produced guide, see the book `From Bash to Z Shell:
  Conquering the Command Line' by Oliver Kiddle, Jerry Peek and Peter
  Stephenson (me), published by Apress, ISBN 1-59059-376-6.  Chapter 10
  tells you how to configure the completion system and chapter 15 how
  to write your own completion functions.
If you're using the completion system the shell will decide what to complete when you hit TAB. That's usually the right thing for the context, but sometimes you just want to complete files, like TAB used to do in the old days. You can set up this up as follows:
    zle -C complete-file complete-word _generic
    zstyle ':completion:complete-file::::' completer _files
    bindkey '^xF' complete-file
  
  This turns the key \C-x F into a command complete-file which
  goes straight to the completion system's file completion command,
  ignoring the normal context.  Change the binding how you like.
Note the way the form of completion to use is specified by picking a
  `completer' called `_files'.  You can define any completion
  to be bound to a keystroke by putting the appropriate completion
  function at that point.  Then change all occurrences of
  `complete-file' to a name of your own.
If you simply want to try filename completion as a default when other
  completions fail, add it to the `completer' style for normal
  completion, for example:
  
    zstyle ':completion:*' completer _complete _ignored _files
  
  This adds filename completion to the end of the default types of
  completion.  Your actual completer style may include other actions,
  such as expansion or approximate completion.