7. PathlibPath#

class PathlibPath#
nuv: uv#
git_state: PathlibGitState#
error_msg: str or nil#
_raw_paths: PathlibStrList#
_drive_name: str#

# Drive name for Windows path. (“C:”, “D:”, “\127.0.0.1”)

_uri_protocol: str or nil#

# URI protocol (without :) when object is created with Path.from_uri such as file, sftp.

__windows_panic: boolean#

# Set to true when passed path might be a windows path. PathlibWindows ignores this.

__fs_event_callbacks: dict[str, PathlibWatcherCallback] or nil#

# List of functions called when a fs_event is triggered.

__string_cache: str or nil#

# Cache result of tostring(self).

__parent_cache: PathlibPath or nil#

# Cache reference to parent object.

static new(...)#

Create a new Path object

Parameters:

vararg (str or PathlibPath) – # List of string and Path objects

Return type:

PathlibPath

static cwd()#

Return vim.fn.getcwd in Path object

Return type:

PathlibPath

static home()#

Return vim.loop.os_homedir in Path object

Return type:

PathlibPath

static permission(mode_string)#

Calculate permission integer from “rwxrwxrwx” notation.

Parameters:

mode_string (str)

Return type:

integer

static stdpath(what, ...)#

Shorthand to vim.fn.stdpath and specify child path in later args.

Mason bin path: Path.stdpath(“data”, “mason”, “bin”) or Path.stdpath(“data”, “mason/bin”)

Parameters:
  • what (str) – # See :h stdpath for information

  • vararg (str or PathlibPath) – # child path after the result of stdpath

Return type:

PathlibPath

static from_uri(uri)#

Parse a uri and return its path. Protocol is saved at self._uri_protocol.

Parameters:

uri (str)

to_empty()#
copy_all_from(path)#

Copy all attributes from path to self

Parameters:

path (PathlibPath)

deep_copy()#

Copy all attributes from path to self

child(name)#

Create a new Path object as self’s child. name cannot be a grandchild.

Parameters:

name (str)

Return type:

PathlibPath

new_descendant(...)#

Create a new Path object as self’s descentant. Use self:child if new path is a direct child of the dir.

Parameters:

vararg (str)

Return type:

PathlibPath

descendant(...)#

Create a new Path object as self’s descentant. Use self:child if new path is a direct child of the dir.

Parameters:

vararg (str)

Return type:

PathlibPath

new_child_unpack(name)#

Unpack name and return a new self’s grandchild, where name contains more than one /.

Parameters:

name (str)

Return type:

PathlibPath

child_unpack(name)#

Unpack name and return a new self’s grandchild, where name contains more than one /.

Parameters:

name (str)

Return type:

PathlibPath

peek(index)#

Fetch one part of the path.

If index == 0: returns drive_name, elseif index > 0: gets the n-th element in the path starting from 1. When path is absolute, self:peek(1) is always an empty string (“”). elseif index < 0: gets the (-n)-th element counting from leaf. self:peek(-1) == self:basename().

>>> Path("folder/foo.txt"):peek(1)
"folder"
>>> Path("folder/foo.txt"):peek(2)
"foo.txt"
>>> Path("folder/foo.txt"):peek(-1)
"foo.txt"
>>> Path("/etc/passwd"):peek(0)
"" -- drive name is empty in posix paths
>>> Path("/etc/passwd"):peek(1)
"" -- first element of absolute path is always empty
>>> Path("/etc/passwd"):peek(2)
"etc"
Parameters:

index (integer)

Return type:

str or nil

basename()#

Return the basename of self.

Eg: foo/bar/baz.txt -> baz.txt

Return type:

str

with_basename(name)#

Return new object with new name. You can also use this to create siblings.

This does not check if name contains invalid path separators like “/” so be careful.

>>> Path("./folder/foo.txt"):with_basename("bar.png")
Path("./folder/bar.png")
Parameters:

name (str)

Return type:

PathlibPath

suffix()#

Return the group name of the file GID. Same as str(self) minus self:modify(“:r”).

>>> Path("folder/foo.txt"):suffix()
"foo"
>>> Path("folder/no-extension"):suffix()
""
>>> Path("folder/.bashrc"):suffix()
".bashrc"
>>> Path("folder/archive.tar.gz"):suffix()
"archive.tar"
Returns:

# extension of path including the dot (.): .py, .lua etc

Return type:

str

with_suffix(suffix)#

Return new object with new suffix.

>>> Path("./folder/foo.txt"):with_suffix(".png")
Path("./folder/foo.png")
Parameters:

suffix (str) – # New suffix

add_suffix(suffix, force)#

Append given suffix to path, if suffix is not as same as given.

>>> Path("./folder/foo.tar"):add_suffix(".gz")
Path("./folder/foo.tar.gz")
>>> Path("./folder/foo.txt.bak"):add_suffix(".bak")
Path("./folder/foo.txt.bak") -- is already ".bak", so no change applied
Parameters:
  • suffix (str) – # Append this suffix to path, if suffix is not already equal.

  • force (boolean or nil) – # If true, always append given suffix. Result will be foo.txt.bak.bak in above expample.

remove_suffix(suffix)#

Remove suffix if and only if path ends with the given suffix.

>>> Path("./folder/foo.tar.gz"):remove_suffix(".tar.gz")
Path("./folder/foo")
>>> Path("./folder/foo.txt"):remove_suffix(".bak")
Path("./folder/foo.txt") -- is already not ".bak", so no change applied
Parameters:

suffix (str) – # Remove this suffix from path.

stem()#

Return the group name of the file GID. Same as self:modify(“:t:r”).

Returns:

# stem of path. (src/version.c -> “version”)

Return type:

str

with_stem(stem)#

Return new object with new stem.

>>> Path("./folder/foo.txt"):with_stem("bar")
Path("./folder/bar.txt")
Parameters:

stem (str)

parent()#

Return parent directory of itself. If parent does not exist, returns nil.

If you never want a nil, use self:parent_assert(). This will raise an error if parent not found. This could be used to chain methods: (self:parent_assert():tostring(), self:parent_assert():fs_iterdir()).

Return type:

PathlibPath or nil

parent_assert()#

Return parent directory of itself. This will raise an error when parent is not found.

Return type:

PathlibPath

parents()#

Return iterator of parents.

as_uri()#

Returns a URI representation of self.

This may not align with results from LSP, so convert LSP data with Path.from_uri and compare the path objects to get a consistent result.

Objects are comparable with == and ~=.

Returns:

encoded # URI representation of file path.

Return type:

str

is_absolute()#

Returns whether registered path is absolute

Return type:

boolean

is_hidden()#

Return whether the file is treated as a _hidden_ file.

Posix: basename starts with ., Windows: calls GetFileAttributesA.

Return type:

boolean

is_relative()#

Returns whether registered path is relative

Return type:

boolean

relative_to(other, walk_up)#

Compute a version of this path relative to the path represented by other.

If it’s impossible, nil is returned and self.error_msg is modified.

When walk_up == false (the default), the path MUST start with other. When the argument is true, ‘../’ entries may be added to form a relative path but this function DOES NOT check the actual filesystem for file existence whatsoever.

If the paths referencing different drives or if only one of self or other is relative, nil is returned and self.error_msg is modified.

>>> p = Path("/etc/passwd")
>>> p:relative_to(Path("/"))
Path.new("etc/passwd")
>>> p:relative_to(Path("/usr"))
nil; p.error_msg = "'%s' is not in the subpath of '%s'."
>>> p:relative_to(Path("C:/foo"))
nil; p.error_msg = "'%s' is not on the same disk as '%s'."
>>> p:relative_to(Path("./foo"))
nil; p.error_msg = "Only one path is relative: '%s', '%s'."
Parameters:
  • other (PathlibPath)

  • walk_up (boolean or nil) – # If true, uses ../ to make relative path.

is_relative_to(other)#

Return whether or not this path is relative to the other path.

This is a wrapper of vim.startswith(tostring(self), tostring(other)) and nothing else. It neither accesses the filesystem nor treats “..” segments specially.

Use self:absolute() or self:to_absolute() beforehand if needed.

other may be a string, but MUST use the same path separators.

>>> p = Path("/etc/passwd")
>>> p:is_relative_to("/etc") -- Must be [[\etc]] on Windows.
true
>>> p:is_relative_to(Path("/usr"))
false
Parameters:

other (PathlibPath or PathlibString)

as_posix()#
absolute(cwd)#

Returns a new path object with absolute path.

Use self:to_absolute() instead to modify the object itself which does not need a deepcopy.

If self is already an absolute path, returns itself.

Parameters:

cwd (PathlibPath or nil) – # If passed, this is used instead of vim.fn.getcwd().

Return type:

PathlibPath

to_absolute(cwd)#

Modifies itself to point to an absolute path.

Use self:absolute() instead to return a new path object without modifying self.

If self is already an absolute path, does nothing.

Parameters:

cwd (PathlibPath or nil) – # If passed, this is used instead of vim.fn.getcwd().

modify(mods)#

Get the path being modified with filename-modifiers

Parameters:

mods (str) – # filename-modifiers passed to vim.fn.fnamemodify

Returns:

# result of vim.fn.fnamemodify(tostring(self), mods)

Return type:

str

resolve(allow_abs2rel)#

Resolves path. Eliminates ../ representation.

Changes internal. (See Path:resolve_copy to create new object)

Parameters:

allow_abs2rel (boolean or nil) – # Allow absolute path to be converted to relative path when there are too many ‘../’

resolve_copy(allow_abs2rel)#

Resolves path. Eliminates ../ representation and returns a new object. self is not changed.

Parameters:

allow_abs2rel (boolean or nil) – # Allow absolute path to be converted to relative path when there are too many ‘../’

Return type:

PathlibPath

glob(pattern)#

Run vim.fn.globpath on this path.

Parameters:

pattern (str) – # glob pattern expression

Returns:

# iterator of results.

Return type:

fun():PathlibPath or nil

byte(...)#
Parameters:

vararg (any)

find(...)#
Parameters:

vararg (any)

gmatch(...)#
Parameters:

vararg (any)

gsub(...)#
Parameters:

vararg (any)

len()#

Return the length of the string representation. >>> Path(“foo/bar.txt”):len() == string.len(“foo/bar.txt”) true

lower()#
match(...)#
Parameters:

vararg (any)

rep(...)#
Parameters:

vararg (any)

reverse()#
sub(...)#
Parameters:

vararg (any)

upper()#
fs_stat(follow_symlinks)#

Return result of luv.fs_stat.

Parameters:

follow_symlinks (boolean or nil) – # Whether to resolve symlinks

Returns:

stat # nil if fs_stat failed

Return type:

uv.aliases.fs_stat_table or nil

stat(follow_symlinks)#

Return result of luv.fs_stat. Use self:stat_async to use with callback.

Parameters:

follow_symlinks (boolean or nil) – # Whether to resolve symlinks

Returns:

stat # nil if fs_stat failed

Return type:

uv.aliases.fs_stat_table or nil

lstat()#
exists(follow_symlinks)#
Parameters:

follow_symlinks (any)

size()#
is_dir(follow_symlinks)#
Parameters:

follow_symlinks (any)

is_file(follow_symlinks)#
Parameters:

follow_symlinks (any)

realpath()#

Return result of luv.fs_realpath in PathlibPath.

Returns:

# Resolves symlinks if exists. Returns nil if link does not exist.

Return type:

PathlibPath or nil

get_mode(follow_symlinks)#

Get mode of path object. Use self:get_type to get type description in string instead.

Parameters:

follow_symlinks (boolean) – # Whether to resolve symlinks

Return type:

PathlibModeEnum or nil

get_type(follow_symlinks)#

Get type description of path object. Use self:get_mode to get mode instead.

Parameters:

follow_symlinks (boolean) – # Whether to resolve symlinks

samefile(other)#

Return whether other is the same file or not.

Parameters:

other (PathlibPath)

Return type:

boolean

is_mount()#
mkdir(mode, recursive)#

Make directory. When recursive is true, will create parent dirs like shell command mkdir -p

Parameters:
  • mode (integer) – # permission. You may use Path.permission() to convert from “rwxrwxrwx”

  • recursive (boolean) – # if true, creates parent directories as well

Returns:

success

Return type:

boolean or nil

touch(mode, recursive)#

Make file. When recursive is true, will create parent dirs like shell command mkdir -p

Parameters:
  • mode (integer) – # permission. You may use Path.permission() to convert from “rwxrwxrwx”

  • recursive (boolean) – # if true, creates parent directories as well

Returns:

success

Return type:

boolean or nil

copy(target)#

Copy file to target

Parameters:

target (PathlibPath) – # self will be copied to target

Returns:

success # whether operation succeeded

Return type:

boolean or nil

Create a simlink named self pointing to target

Parameters:

target (PathlibPath)

Returns:

success # whether operation succeeded

Return type:

boolean or nil

Create a hardlink named self pointing to target

Parameters:

target (PathlibPath)

Returns:

success # whether operation succeeded

Return type:

boolean or nil

rename(target)#

Rename self to target. If target exists, fails with false. Ref: Path:move

Parameters:

target (PathlibPath)

Returns:

success # whether operation succeeded

Return type:

boolean or nil

move(target)#

Move self to target. Overwrites target if exists. Ref: Path:rename

Parameters:

target (PathlibPath)

Returns:

success # whether operation succeeded

Return type:

boolean or nil

replace(target)#
Parameters:

target (PathlibPath)

chmod(mode, follow_symlinks)#

Change the permission of the path to mode.

Parameters:
  • mode (integer) – # permission. You may use Path.permission() to convert from “rwxrwxrwx”

  • follow_symlinks (boolean) – # Whether to resolve symlinks

Returns:

success # whether operation succeeded

Return type:

boolean or nil

Remove this file or link. If the path is a directory, use Path:rmdir() instead.

Returns:

success # whether operation succeeded

Return type:

boolean or nil

rmdir()#

Remove this directory. The directory must be empty.

Returns:

success # whether operation succeeded

Return type:

boolean or nil

fs_open(flags, mode, ensure_dir)#

Call luv.fs_open.

true will default to 0o755.

Parameters:
  • flags (uv.aliases.fs_access_flags or integer)

  • mode (integer or nil) – # permission. You may use Path.permission() to convert from “rwxrwxrwx”. Default to 0o644.

  • ensure_dir (integer or boolean or nil) – # if not nil, runs mkdir -p self:parent() with permission to ensure parent exists.

Returns:

fd

Return type:

integer or nil

fs_read(size, offset)#

Call luv.fs_open(“r”) -> luv.fs_read.

Parameters:
  • size (integer or nil) – # if nil, uses self:stat().size

  • offset (integer or nil)

Returns:

content # content of the file

Return type:

str or nil

fs_write(data, offset)#

Call luv.fs_open(“w”) -> luv.fs_write.

Parameters:
  • data (uv.aliases.buffer)

  • offset (integer or nil)

Returns:

bytes # number of bytes written

Return type:

integer or nil

fs_append(data, offset)#

Call luv.fs_open(“a”) -> luv.fs_write.

Parameters:
  • data (uv.aliases.buffer)

  • offset (integer or nil)

Returns:

bytes # number of bytes written

Return type:

integer or nil

io_read()#

Call io.read. Use self:fs_read to use with nio.run instead.

Returns:

data # whole file content

Return type:

str or nil

io_read_bytes()#

Call io.read with byte read mode.

Returns:

bytes # whole file content

Return type:

str or nil

io_write(data)#

Call io.write. Use self:fs_write to use with nio.run instead. If failed, returns error message

Parameters:

data (str) – # content

Returns:

# success

Return type:

boolean

io_write_bytes(data)#

Call io.write with byte write mode.

Parameters:

data (str) – # content

fs_iterdir(follow_symlinks, depth, skip_dir)#

Iterate dir with luv.fs_scandir.

Parameters:
  • follow_symlinks (boolean or nil) – # If true, resolves hyperlinks and go into the linked directory.

  • depth (integer or nil) – # How deep the traverse. If nil or <1, scans everything.

  • skip_dir (nil or fun(PathlibPath):boolean) – # Function to decide whether to dig in a directory.

depth()#

Get length of self._raw_paths. /foo/bar.txt ==> 3: { “”, “foo”, “bar.txt” } (root dir counts as 1!!)

Return type:

integer

tostring(sep)#

Alias to tostring(self). Returns the string representation of self.

If you pass string to vim.cmd, use self:cmd_string() instead to avoid weird results.

If you pass string to vim.system and other shell commands, use self:shell_string() instead.

If you compare against LSP filepath, convert the LSP result with Path.from_uri compare path objects to avoid mismatch with escape sequence (eg ‘%3A’).

Parameters:

sep (str or nil) – # If not nil, this is used as a path separator.

Return type:

str

cmd_string()#

Returns a string representation that is safe to pass to vim.cmd.

Return type:

PathlibString

shell_string(special)#

Returns a string representation that is safe to shell.

Use this for vim.fn.system, :! etc. However, use self:cmd_string() for vim.system.

If result is passed to the :! command, set special to true.

Parameters:

special (boolean or nil) – # If true, special items such as “!”, “%”, “#” and “<cword>” will be preceded by a backslash. The backslash will be removed again by the :! command. See :h shellescape for more details. The <NL> character is escaped.

Return type:

PathlibString

regex_string(sep, charset, escape_with)#

Return a string representation that is safe to pass to regex search.

Use this when passing path to shell commands with regex search. >>> local path = Path(“./⦋evil⦌/$folder$/”) >>> local find = nio.process.run({ cmd = “find”, args = { “.”, “-type”, “f” } }) >>> local grep = nio.process.run({ >>> cmd = “grep”, >>> args = { “-V”, path:regex_string(“/”, Path.const.regex_charset.bre) }, >>> stdin = find.stdout, >>> }) grep.stdout.read() => _files that are not under_ ./[evil]/$folder$/

There are presets you can use for well known languages. They are defined at Path.const.regex_charset.*. “bre” = .⦋⦌⧵*^$ : basic regex (sed, grep) “ere” = .⦋⦌()⧵*^$+?{}| : extended regex (grep -E) “rust” = ⧵.+*?()|⦋⦌{}^$#&-~ “lua” = ^$()%.⦋⦌*+-? “vimscript” = ^$.*?/⧵⦋⦌~

>>> Path("⦋a-z⦌.txt"):regex_string(nil, Path.const.regex_charset.rust)
`⧵⦋a-z⧵⦌⧵.txt`
>>> Path("⦋a-z⦌.txt"):regex_string(nil, Path.const.regex_charset.lua, "%")
`%⦋a-z%⦌%.txt`

Windows users should pass an escaped separator when needed. >>> Windows(⦋⦋C:⧵folder⧵foo.txt⦌⦌):regex_string(”⧵⧵⧵⧵”, Path.const.regex_charset.rust) C:⧵⧵folder⧵⧵foo⧵.txt >>> Windows(⦋⦋C:⧵folder⧵foo.txt⦌⦌):regex_string(nil, Path.const.regex_charset.lua, “%”) – no need to escape \ in lua C:⧵folder⧵foo%.txt

If you want search multiple path separators (e.g. search for both “/” and “\”), pass a regex that matches both separators to sep. >>> local separators = “⦋/⧵⧵⦌” >>> Path(“folder/foo.txt”):regex_string(separators, Path.const.regex_charset.lua, “%”) folder⦋/⧵⦌foo%.txt – matches both folder/foo.txt and folder⧵foo.txt

You may also provide your own set of chars. >>> Path(“abc.txt”):regex_string(nil, “abc”) ⧵a⧵b⧵c.txt

Parameters:
  • sep (str or nil) – # If not nil, this is used as a path separator.

  • charset (PathlibRegexEscape or str) – # Charset that must be escaped.

  • escape_with (str or nil) – # Escaped with. Defaults to “\” (backslash)

escaped_string(sep, charset, escape_with)#

Return a string representation where charset in each path segment is escaped using escape_with.

Path separator is not escaped.

Parameters:
  • sep (str or nil) – # If not nil, this is used as a path separator.

  • charset (PathlibRegexEscape or str) – # Charset that must be escaped.

  • escape_with (str or nil) – # Escaped with. Defaults to “\” (backslash)

has_watcher(func_name)#

Register fs_event watcher for self.

Parameters:

func_name (str or nil) – # Name of the callback to check existence. If nil, returns whether any callback exists.

Returns:

exists

Return type:

boolean

register_watcher(func_name, callback)#

Register fs_event watcher for self.

Parameters:
  • func_name (str) – # Name of the callback to prevent register same callback multiple time

  • callback (PathlibWatcherCallback) – # Callback passed to luv.fs_event_start

Returns:

succeess

Return type:

boolean

unregister_watcher(func_name)#

Unregister fs_event watcher for self.

Parameters:

func_name (str or nil) – # Name of the callback registered with self:register(func_name, …). If nil removes all.

Returns:

succeess

Return type:

boolean

execute_watchers(func_name, args)#

Register fs_event watcher for self.

Parameters:
  • func_name (str or nil) – # Name of the callback to check existence. If nil, calls all watchers.

  • args (PathlibWatcherArgs)

iterdir(opts)#

Alias to vim.fs.dir but returns PathlibPath objects.

depth: integer|nil How deep the traverse (default 1) skip: (fun(dir_name: string): boolean)|nil Predicate to control traversal. Return false to stop searching the current directory. Only useful when depth > 1

“path” is the PathlibPath object. “type” is one of the following: “file”, “directory”, “link”, “fifo”, “socket”, “char”, “block”, “unknown”.

Parameters:

opts (table or nil) – Optional keyword arguments:

Returns:

# items in {self}. Each iteration yields two values: “path” and “type”.

Return type:

fun():PathlibPath or nil or str or nil

fs_opendir(follow_symlinks, depth)#

Iterate dir with luv.fs_opendir.

Parameters:
  • follow_symlinks (boolean or nil) – # If true, resolves hyperlinks and go into the linked directory.

  • depth (integer or nil) – # How deep the traverse. If nil or <1, scans everything.

Return type:

function