☰

# std/paths

Theme:

- Manual
- Standard library
- Index
- Compiler docs
- Fusion docs
- devel, stable

Search:
Source Edit

This module implements path handling.

See also:

- files module for file access

# Imports

osseps, envvars, osappdirs, pathnorm, hashes, sugar, strutils, ospaths2

# Types

    Path = distinct string

  Source Edit

# Procs

    func `/`(head, tail: Path): Path {.inline, ...raises: [], tags: [], forbids: [].}

  Joins two directory names to one.

  returns normalized path concatenation of `head` and `tail`, preserving whether or not `tail` has a trailing slash (or, if tail if empty, whether head has one).

  See also:

  - splitPath proc
  - uri.combine proc
  - uri./ proc
  Source Edit

    func `/../`(head, tail: Path): Path {.inline, ...raises: [], tags: [], forbids: [].}

  The same as `parentDir(head) / tail`, unless there is no parent directory. Then `head / tail` is performed instead.

  See also:

  - / proc
  - parentDir proc
  Source Edit

    func `==`(x, y: Path): bool {.inline, ...raises: [], tags: [], forbids: [].}

  Compares two paths.

  On a case-sensitive filesystem this is done case-sensitively otherwise case-insensitively.

  Source Edit

    proc absolutePath(path: Path; root = getCurrentDir()): Path {.
        ...raises: [ValueError], tags: [], forbids: [].}

  Returns the absolute path of `path`, rooted at `root` (which must be absolute; default: current directory). If `path` is absolute, return it, ignoring `root`.

  See also:

  - normalizePath proc
  Source Edit

    func add(x: var Path; y: Path) {.borrow, ...raises: [], tags: [], forbids: [].}

  Source Edit

    func addFileExt(filename: Path; ext: string): Path {.inline, ...raises: [],
        tags: [], forbids: [].}

  Adds the file extension `ext` to `filename`, unless `filename` already has an extension.

  `Ext` should be given without the leading `'.'`, because some filesystems may use a different character. (Although I know of none such beast.)

  See also:

  - splitFile proc
  - extractFilename proc
  - lastPathPart proc
  - changeFileExt proc
  Source Edit

    func changeFileExt(filename: Path; ext: string): Path {.inline, ...raises: [],
        tags: [], forbids: [].}

  Changes the file extension to `ext`.

  If the `filename` has no extension, `ext` will be added. If `ext` == "" then any extension is removed.

  `Ext` should be given without the leading `'.'`, because some filesystems may use a different character. (Although I know of none such beast.)

  See also:

  - splitFile proc
  - extractFilename proc
  - lastPathPart proc
  - addFileExt proc
  Source Edit

    proc expandTilde(path: Path): Path {.inline,
                                         ...tags: [ReadEnvEffect, ReadIOEffect],
                                         raises: [], forbids: [].}

  Expands `~` or a path starting with `~/` to a full path, replacing `~` with getHomeDir() (otherwise returns `path` unmodified).

  Windows: this is still supported despite the Windows platform not having this convention; also, both `~/` and `~\` are handled.

  Example:

      import std/appdirs
      assert expandTilde(Path("~") / Path("appname.cfg")) == getHomeDir() / Path("appname.cfg")
      assert expandTilde(Path("~/foo/bar")) == getHomeDir() / Path("foo/bar")
      assert expandTilde(Path("/foo/bar")) == Path("/foo/bar")

  Source Edit

    func extractFilename(path: Path): Path {.inline, ...raises: [], tags: [],
        forbids: [].}

  Extracts the filename of a given `path`.

  This is the same as `name & ext` from splitFile(path) proc.

  See also:

  - splitFile proc
  - lastPathPart proc
  - changeFileExt proc
  - addFileExt proc
  Source Edit

    proc getCurrentDir(): Path {.inline, ...tags: [], raises: [OSError], forbids: [].}

  Returns the current working directory i.e. where the built binary is run.

  So the path returned by this proc is determined at run time.

  See also:

  - getHomeDir proc
  - getConfigDir proc
  - getTempDir proc
  - setCurrentDir proc
  - currentSourcePath template
  - getProjectPath proc
  Source Edit

    func hash(x: Path): Hash {....raises: [], tags: [], forbids: [].}

  Source Edit

    func isAbsolute(path: Path): bool {.inline, ...raises: [], tags: [], forbids: [].}

  Checks whether a given `path` is absolute.

  On Windows, network paths are considered absolute too.

  Source Edit

    proc isRelativeTo(path: Path; base: Path): bool {.inline,
        ...raises: [ValueError, OSError], tags: [RootEffect], forbids: [].}

  Returns true if `path` is relative to `base`. Source Edit

    func isRootDir(path: Path): bool {.inline, ...raises: [], tags: [], forbids: [].}

  Checks whether a given `path` is a root directory. Source Edit

    func lastPathPart(path: Path): Path {.inline, ...raises: [], tags: [], forbids: [].}

  Like extractFilename proc, but ignores trailing dir separator; aka: baseName in some other languages.

  See also:

  - splitFile proc
  - extractFilename proc
  - changeFileExt proc
  - addFileExt proc
  Source Edit

    proc normalizeExe(file: var Path) {.borrow, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc normalizePath(path: var Path) {.borrow, ...raises: [], tags: [], forbids: [].}

  Source Edit

    proc normalizePathEnd(path: var Path; trailingSep = false) {.borrow, ...raises: [],
        tags: [], forbids: [].}

  Source Edit

    func parentDir(path: Path): Path {.inline, ...raises: [], tags: [], forbids: [].}

  Returns the parent directory of `path`.

  This is similar to `splitPath(path).head` when `path` doesn't end in a dir separator, but also takes care of path normalizations. The remainder can be obtained with lastPathPart(path) proc.

  See also:

  - relativePath proc
  - splitPath proc
  - tailDir proc
  - parentDirs iterator
  Source Edit

    proc relativePath(path, base: Path; sep = DirSep): Path {.inline,
        ...raises: [ValueError, OSError], tags: [RootEffect], forbids: [].}

  Converts `path` to a path relative to `base`.

  The `sep` (default: DirSep) is used for the path normalizations, this can be useful to ensure the relative path only contains `'/'` so that it can be used for URL constructions.

  On Windows, if a root of `path` and a root of `base` are different, returns `path` as is because it is impossible to make a relative path. That means an absolute path can be returned.

  See also:

  - splitPath proc
  - parentDir proc
  - tailDir proc
  Source Edit

    func splitFile(path: Path): tuple[dir, name: Path, ext: string] {.inline,
        ...raises: [], tags: [], forbids: [].}

  Splits a filename into `(dir, name, extension)` tuple.

  `dir` does not end in DirSep unless it's `/`. `extension` includes the leading dot.

  If `path` has no extension, `ext` is the empty string. If `path` has no directory component, `dir` is the empty string. If `path` has no filename component, `name` and `ext` are empty strings.

  See also:

  - extractFilename proc
  - lastPathPart proc
  - changeFileExt proc
  - addFileExt proc
  Source Edit

    func splitPath(path: Path): tuple[head, tail: Path] {.inline, ...raises: [],
        tags: [], forbids: [].}

  Splits a directory into `(head, tail)` tuple, so that `head / tail == path` (except for edge cases like "/usr").

  See also:

  - add proc
  - / proc
  - /../ proc
  - relativePath proc
  Source Edit

    func tailDir(path: Path): Path {.inline, ...raises: [], tags: [], forbids: [].}

  Returns the tail part of `path`.

  See also:

  - relativePath proc
  - splitPath proc
  - parentDir proc
  Source Edit

    func unixToNativePath(path: Path; drive = Path("")): Path {.inline, ...raises: [],
        tags: [], forbids: [].}

  Converts an UNIX-like path to a native one.

  On an UNIX system this does nothing. Else it converts `'/'`, `'.'`, `'..'` to the appropriate things.

  On systems with a concept of "drives", `drive` is used to determine which drive label to use during absolute path conversion. `drive` defaults to the drive of the current working directory, and is ignored on systems that do not have a concept of "drives".

  Source Edit

# Iterators

    iterator parentDirs(path: Path; fromRoot = false; inclusive = true): Path {.
        ...raises: [], tags: [], forbids: [].}

  Walks over all parent directories of a given `path`.

  If `fromRoot` is true (default: false), the traversal will start from the file system root directory. If `inclusive` is true (default), the original argument will be included in the traversal.

  Relative paths won't be expanded by this iterator. Instead, it will traverse only the directories appearing in the relative path.

  See also:

  - parentDir proc
  Source Edit

# Templates

    template `$`(x: Path): string

  Source Edit

# Exports

ExtSep, FileSystemCaseSensitive, DynlibFormat, DirSep, AltSep, PathSep, ScriptExt, doslikeFileSystem, ExeExt, CurDir, ParDir, ReadDirEffect, WriteDirEffect