.. include:: ../global.rst .. _`path manipulation`: Path Manipulation ^^^^^^^^^^^^^^^^^ The following are simple functions to manipulate common PATH-like strings. .. warning:: Throughout these examples, `var` is a *symbol* and so, in all probability, you will need to quote the name: .. code-block:: idio path-append 'PATH "/usr/local/bin" .. _`path-append`: .. idio:function:: path-append var val [keyword arguments] A wrapper to :ref:`path-modify `'s ``append`` function. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param val: the path element(s) to be added, `sep` separated :type val: string See :ref:`path-modify ` for the keyword arguments `:sep`, `:once` and `:test`. :Example: Append ``"/usr/local/bin"`` to :envvar:`PATH` if it is a directory: .. code-block:: idio path-append 'PATH "/usr/local/bin" :test d? .. _`path-append-unique`: .. idio:function:: path-append-unique var val [keyword arguments] A wrapper to :ref:`path-modify `'s ``append`` function with `:once` set to `true`. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param val: the path element(s) to be added, `sep` separated :type val: string See :ref:`path-modify ` for the keyword arguments `:sep` and `:test`. .. _`path-prepend`: .. idio:function:: path-prepend var val [keyword arguments] A wrapper to :ref:`path-modify `'s ``prepend`` function. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param val: the path element(s) to be added, `sep` separated :type val: string See :ref:`path-modify ` for the keyword arguments `:sep`, `:once` and `:test`. :Example: Prepend ``"/usr/local/bin"`` to :envvar:`PATH` if it is a directory: .. code-block:: idio path-prepend 'PATH "/usr/local/bin" :test d? .. _`path-prepend-unique`: .. idio:function:: path-prepend-unique var val [keyword arguments] A wrapper to :ref:`path-modify `'s ``prepend`` function with `:once` set to true. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param val: the path element(s) to be added, `sep` separated :type val: string See :ref:`path-modify ` for the keyword arguments `:sep` and `:test`. .. _`path-remove`: .. idio:function:: path-remove var old [keyword arguments] A wrapper to :ref:`path-modify `'s ``remove`` function. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param old: the path element to be removed :type old: string See :ref:`path-modify ` for the keyword arguments `:sep` and `:once`. :Example: Remove ``"/usr/local/bin"`` from :envvar:`PATH`: .. code-block:: idio path-remove 'PATH "/usr/local/bin" .. _`path-remove-first`: .. idio:function:: path-remove-first var old [keyword arguments] A wrapper to :ref:`path-modify `'s ``remove`` function with `:once` set to `true`. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param old: the path element to be removed :type old: string See :ref:`path-modify ` for the keyword argument `:sep`. .. _`path-replace`: .. idio:function:: path-replace var old new [keyword arguments] A wrapper to :ref:`path-modify `'s ``replace`` function. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param old: the path element to be replaced :type old: string :param new: the path element(s) to be substituted, `sep` separated :type new: string See :ref:`path-modify ` for the keyword arguments `:sep`, `:once` and `:test`. :Example: Append ``"/usr/local/bin"`` to :envvar:`PATH` if it is a directory: .. code-block:: idio path-append 'PATH "/usr/local/bin" :test d? .. _`path-replace-first`: .. idio:function:: path-replace-first var old new [keyword arguments] A wrapper to :ref:`path-modify `'s ``replace`` function with `:once` set to `true`. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param old: the path element to be replaced :type old: string :param new: the path element(s) to be substituted, `sep` separated :type new: string See :ref:`path-modify ` for the keyword arguments `:sep` and `:test`. .. _`trim-path`: .. idio:function:: trim-path val (:sep ":") Returns a path value with duplicate elements removed after the first. :param val: the value of the path to be manipulated, eg. PATH, CLASSPATH :type val: string :keyword :sep: the element separator, defaults to ``:`` :type :sep: string, optional .. _`path-verify`: .. idio:function:: path-verify val (:sep ":") (:test #f) A wrapper to :ref:`path-modify `'s ``verify`` function. :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :keyword :sep: the element separator, defaults to ``:`` :type :sep: string, optional :keyword :test: apply the predicate on the path segment :type :test: predicate (function), **required** .. note:: The `:test` keyword argument is required. It uses the `:test` style for consistency. :Example: Reduce :envvar:`PATH` to those elements that are directories: .. code-block:: idio path-verify 'PATH :test d? .. _`std-paths`: .. idio:function:: std-paths act val [keyword arguments] Call :samp:`path-{act}` for * :envvar:`PATH` with :file:`{val}/bin` * :envvar:`MANPATH` with :file:`{val}/share/man` or :file:`{val}/man` if either exists :param act: an `act` for :ref:`path-modify ` :type act: symbol :param val: the top of the standard hierarchy tree :type val: string See :ref:`path-modify ` for the keyword arguments `:sep`, `:once` and `:test`. :Example: Append ``"/usr/local/bin"`` to :envvar:`PATH` and one of ``"/usr/local/share/bin"`` or ``"/usr/local/man"`` (if they exist) to :envvar:`MANPATH`: .. code-block:: idio std-paths 'append "/usr/local" .. _`std-paths-unique`: .. idio:function:: std-paths-unique act val [keyword arguments] Call :samp:`path-{act}` with `:once` set to `true` for * :envvar:`PATH` with :file:`{val}/bin` * :envvar:`MANPATH` with :file:`{val}/share/man` or :file:`{val}/man` if either exists :param act: an `act` for :ref:`path-modify ` :type act: symbol :param val: the top of the standard hierarchy tree :type val: string See :ref:`path-modify ` for the keyword arguments `:sep` and `:test`. :Example: Append ``"/usr/local/bin"`` to :envvar:`PATH` and one of ``"/usr/local/share/bin"`` or ``"/usr/local/man"`` (if they exist) to :envvar:`MANPATH`: .. code-block:: idio std-paths 'append "/usr/local" .. _`all-paths`: .. idio:function:: all-paths act val [keyword arguments] Call :samp:`path-{act}` for * :envvar:`PATH` with :file:`{val}/bin` * :envvar:`LD_LIBRARY_PATH` with :file:`{val}/lib` * :envvar:`MANPATH` with :file:`{val}/share/man` or :file:`{val}/man` if either exists :param act: an `act` for :ref:`path-modify ` :type act: symbol :param val: the top of the standard hierarchy tree :type val: string See :ref:`path-modify ` for the keyword arguments `:sep`, `:once` and `:test`. :Example: Append ``"/usr/local/bin"`` to :envvar:`PATH`, ``"/usr/local/lib"`` to :envvar:`LI_LIBRARY_PATH` and one of ``"/usr/local/share/bin"`` or ``"/usr/local/man"`` (if they exist) to :envvar:`MANPATH`: .. code-block:: idio all-paths 'append "/usr/local" .. _`all-paths-unique`: .. idio:function:: all-paths-unique act val [keyword arguments] Call :samp:`path-{act}` with `:once` set to `true` for * :envvar:`PATH` with :file:`{val}/bin` * :envvar:`LD_LIBRARY_PATH` with :file:`{val}/lib` * :envvar:`MANPATH` with :file:`{val}/share/man` or :file:`{val}/man` if either exists :param act: an `act` for :ref:`path-modify ` :type act: symbol :param val: the top of the standard hierarchy tree :type val: string See :ref:`path-modify ` for the keyword arguments `:sep` and `:test`. :Example: Append ``"/usr/local/bin"`` to :envvar:`PATH`, ``"/usr/local/lib"`` to :envvar:`LI_LIBRARY_PATH` and one of ``"/usr/local/share/bin"`` or ``"/usr/local/man"`` (if they exist) to :envvar:`MANPATH`: .. code-block:: idio all-paths 'append "/usr/local" .. _`reduce-pathname`: .. idio:function:: reduce-pathname val (:sep "/") Reduce pathname `val` by: * removing ``.`` and ``..`` elements as appropriate :param val: the pathname to be normalized :type val: string :keyword :sep: the element separator, defaults to ``#\/`` :type :sep: unicode, optional .. _`normalize-pathname`: .. idio:function:: normalize-pathname val (:sep "/") Normalize pathname `val` by: * prefixing with PWD, if not an absolute pathname * calling :ref:`reduce-pathname ` :param val: the pathname to be normalized :type val: string :keyword :sep: the element separator, defaults to ``#\/`` :type :sep: unicode, optional .. _`dirname-pathname`: .. idio:function:: dirname-pathname val (:sep "/") Return the dirname of pathname `val` :param val: the pathname to be examined :type val: string :keyword :sep: the element separator, defaults to ``#\/`` :type :sep: unicode, optional .. _`basename-pathname`: .. idio:function:: basename-pathname val (:sep "/") Return the basename of pathname `val` :param val: the pathname to be examined :type val: string :keyword :sep: the element separator, defaults to ``#\/`` :type :sep: unicode, optional .. _`path-modify`: .. idio:function:: path-modify var val act wrt (:sep ":") (:once #f) (:test #f) Modify path `var` in various ways (*append*, *prepend*, *remove*, *replace*, etc.). It handles paths with whitespace and various kinds of separators (Unix's ``:``, Windows' ``;``, Tcl's :literal:`\ ` -- see note). :param var: the name of the path to be manipulated, eg. PATH, CLASSPATH :type var: symbol :param val: the path element(s) to be added, `sep` separated :type val: string :param act: the action to be performed :param wrt: the element in the path to be operated on :type wrt: string :keyword :sep: the element separator, defaults to ``:`` :type :sep: string, optional :keyword :once: do the operation once (see below), defaults to ``#f`` :type :once: boolean, optional :keyword :test: apply the predicate on the path segment :type :test: predicate (function), optional `act` can be: .. csv-table:: :widths: auto :align: left ``first`` ``start``, prepend `val` ``last`` ``end``, append `val` ``verify``, apply the conditional operator ``after`` ``before``, insert `val` after/before `wrt` ``replace``, replace `wrt` with `val` ``remove``, remove `wrt` If `:once` is `true` then * if `act` is ``replace`` or ``remove`` perform the action once * if `act` is one of ``first``, ``last``, ``before``, ``after`` ensure that `val` appears once in the result In particular, subsequent instances of `val` may be removed or `val` may not be appended depending on the current elements of `var`. The `:test` flag might be one of the standard predicates, :ref:`d? `, :ref:`e? ` or :ref:`f? `, or something bespoke. .. note:: Technically, :envvar:`TCLLIBPATH` is a Tcl `list` which can, presumably, be whitespace separated. ``path-modify`` uses :ref:`split-string-exactly ` to retain adjacent separators which will do the wrong thing here with adjacent whitespace code points. You may want to construct a normalized value with something like: .. code-block:: idio TCLLIBPATH = join-string " " (split-string TCLLIBPATH " \t") .. include:: ../commit.rst