.. include:: ../global.rst

Changing Directory
^^^^^^^^^^^^^^^^^^

:lname:`Idio` supports a very simplistic set of directory changing
functions revolving around a *directory stack*.

The shell-like ``cd`` (with no arguments) cannot be directly
implemented in :lname:`Idio` (because it's a programming language and
``cd`` returns the value of the function :ref:`cd <cd>`) so you are
required to wrap it in parenthesis, which uses :envvar:`HOME`, or pass
``~`` which is a synonym for :envvar:`HOME`.

.. note::

   These functions work with respect to :ref:`PWD <PWD>` in the sense
   that *relative* directory movements modify `PWD` and then
   :ref:`libc/chdir <libc/chdir>` is called on `PWD`.

   For example, on this system :file:`/sbin` is a symlink to
   :file:`/usr/sbin`:

   .. code-block:: idio-console

      Idio> cd "/sbin"
      0
      Idio> (libc/getcwd)
      %P"/usr/sbin"
      Idio> cd ".."
      0
      Idio> (libc/getcwd)
      %P"/"

   Notice that the ``cd ".."`` returns us to :file:`/` and not
   :file:`/usr`, the parent of the directory we were actually in.

   An *absolute* directory movement simply sets `PWD` (and calls
   `libc/chdir`).

.. _`cd`:

.. idio:template:: cd [dir]


   change the current working directory to `dir`
   
   :param dir: the directory to change to, defaults to :envvar:`HOME`
   :type dir: string
   :return: current working directory or ``#f``
   
   If `dir` does not exist a message is displayed and ``#f`` is returned.
   
   If `dir` is not supplied or is the symbol ``~``, :envvar:`HOME` is
   used.
   
   This function modifies :ref:`PWD <PWD>`.
   
   .. seealso:: ``cd`` calls :ref:`setd <setd>`.
   

.. _`pushd`:

.. idio:function:: pushd d


   
   
   if `d` is a directory then change the working directory to it and push
   it onto the top of the directory stack.
   
   :param d: directory to change to
   :type d: string
   :return: current working directory or ``#f``
   
   This function modifies :ref:`PWD <PWD>`.
   


.. _`popd`:

.. idio:function:: popd 


   
   
   if the directory stack has more than one entry then pop an element off
   the directory stack and change the working directory to the top-most
   element
   
   :return: current working directory or ``#f``
   
   This function modifies :ref:`PWD <PWD>`.
   


.. _`dirs`:

.. idio:function:: dirs 


   
   print the directory stack


.. _`setd`:

.. idio:function:: setd d


   
   
   if `d` is a directory then change the working directory to it and set
   the top entry in the directory stack to it.
   
   :param d: directory to change to
   :type d: string
   :return: current working directory or ``#f``
   
   This function modifies :ref:`PWD <PWD>`.
   




.. include:: ../commit.rst