.. _intro_zsh_directories:

Directories
===========

One nice feature of :literal:`zsh` is the way it prints directories. For example, if we set the prompt like this:

.. code-block:: text
   :caption: Tilde in the prompt
   :name: directories_tilde_prompt

   phoenix% PROMPT='%~> '
   ~> cd src
   ~/src>

the shell will print the current directory in the prompt, using the :literal:`~` character. However, :literal:`zsh` is smarter than most other shells in this respect:

.. code-block:: text
   :caption: Named directory shortcuts
   :name: directories_named_dirs

   ~/src> cd ~subbarao
   ~subbarao> cd ~maruchck
   ~maruchck> cd lib
   ~maruchck/lib> cd fun
   ~maruchck/lib/fun> foo=/usr/princeton/common/src
   ~maruchck/lib/fun> cd ~foo
   ~foo> cd ..
   /usr/princeton/common> cd src
   ~foo> cd news/nntp
   ~foo/news/nntp> cd inews
   ~foo/news/nntp/inews>

Note that :literal:`zsh` prints :emphasis:`other` users' directories in the form :literal:`~user`.  Also note that you can set a parameter and use it as a directory name; :literal:`zsh` will act as if :literal:`foo` is a user with the login directory :literal:`/usr/princeton/common/src`. This is convenient, especially if you're sick of seeing prompts like this:

.. code-block:: text
   :caption: Long path in prompt
   :name: directories_long_prompt

   phoenix:/usr/princeton/common/src/X.V11R4/contrib/clients/xv/docs>

If you get stuck in this position, you can give the current directory a short name, like this:

.. code-block:: text
   :caption: Shorten path via parameter
   :name: directories_assign_namedir

   /usr/princeton/common/src/news/nntp/inews> inews=$PWD
   /usr/princeton/common/src/news/nntp/inews> echo ~inews
   /usr/princeton/common/src/news/nntp/inews
   ~inews>

When you reference a directory in the form :literal:`~inews`, the shell assumes that you want the directory displayed in this form; thus simply typing :literal:`echo ~inews` or :literal:`cd ~inews` causes the prompt to be shortened. You can define a shell function for this purpose:

.. code-block:: text
   :caption: namedir helper function
   :name: directories_namedir_function

   ~inews> namedir () { $1=$PWD ;  : ~$1 }
   ~inews> cd /usr/princeton/bin
   /usr/princeton/bin> namedir pbin
   ~pbin> cd /var/spool/mail
   /var/spool/mail> namedir spool
   ~spool> cd .msgs
   ~spool/.msgs>

You may want to add this one-line function to your :literal:`.zshrc`. :literal:`zsh` can also put the current directory in your title bar, if you are using a windowing system. One way to do this is with the :literal:`chpwd` function, which is automatically executed by the shell whenever you change directory.  If you are using xterm, this will work:

.. code-block:: text
   :caption: chpwd for xterm title
   :name: directories_chpwd_xterm

   chpwd () { print -Pn '^[]2;%~^G' }

The :literal:`-P` option tells :literal:`print` to treat its arguments like a prompt string; otherwise the :literal:`%~` would not be expanded. The :literal:`-n` option suppresses the terminating newline, as with :literal:`echo`.

If you are using an IRIS :literal:`wsh`, do this:

.. code-block:: text
   :caption: chpwd for IRIS wsh
   :name: directories_chpwd_iris

   chpwd () { print -Pn '\2201.y%~\234' }

The :literal:`print -D` command has other uses.  For example, to print the current directory to standard output in short form, you can do this:

.. code-block:: text
   :caption: print -D shortens PWD
   :name: directories_print_d_pwd

   % print -D $PWD
   ~subbarao/src

and to print each component of the path in short form:

.. code-block:: text
   :caption: print -D shortens path
   :name: directories_print_d_path

   % print -D $path
   /bin /usr/bin ~locbin ~locbin/X11 ~/bin
