This plugin aims to decrease the difficulties of path management across mutliple OSs in neovim. The plugin API is heavily inspired by Python's pathlib.Path with tweaks to fit neovim usage.
- Documentation
- Module References
PathlibPath: base class with operations.PathlibPosixPath: posix system specific.PathlibWindowsPath: posix system specific.
- 🔎 Search for Keyword
localPath=require("pathlib")
localdir=Path("~/Documents") -- Same as `Path.home() / "Documents"`localfoo=dir/"foo.txt"print(foo:basename(), foo:stem(), foo:suffix()) -- foo.txt, foo, .txtprint(foo:parent()) -- "/home/user/Documents"localgit_root=Path("/path/to/git/workdir")
assert(git_root:child(".git"):exists(), string.format("%s is not a git repo.", git_root))
require("pathlib.git").fill_git_state({ file_a, file_b, ... })
file_a.git_state.ignored-- is git ignoredfile_a.git_state.status-- git status (modified, added, staged, ...)file_a.git_state.git_root-- root directory of the repoThe API is designed so it is very easy to switch between sync and async operations. Call them inside a nvim-nio async context without any change, and the operations are converted to be async (does not block the main thread).
localfoo=Path("~/Documents/foo.txt")
localcontent="File Content\n"-- # synclocalsync_bytes=foo:fs_write(content)
assert(sync_bytes==content:len(), foo.error_msg)
-- # asyncrequire("nio").run(function()
localasync_bytes=foo:fs_write(content)
assert(async_bytes==content:len(), foo.error_msg)
end)localPath=require("pathlib")
localcwd=Path.cwd()
vim.print(string.format([[cwd: %s]], cwd))
-- Use __div to chain file tree!localfolder=Path(".") /"folder"localfoo=folder/"foo.txt"assert(tostring(foo) =="folder/foo.txt") -- $PWD/folder/foo.txtassert(tostring(foo:parent()) =="folder")
-- Path object is comparableassert(foo==Path("./folder/foo.txt")) -- Path object can be created with argumentsassert(foo==Path(folder, "foo.txt")) -- Unpack any of them if you want!-- Calculate relativilyassert(foo:is_relative_to(Path("folder")))
assert(notfoo:is_relative_to(Path("./different folder")))
assert(foo:relative_to(folder) ==Path("foo.txt"))- Very fast operations to work with parents / children / siblings.
- No need to worry about path separator => OS Independent.
/: Unix,\: Windows
There are wrappers around vim functions such as fnamemodify, stdpath and getcwd.
path:modify(":p:t:r") -- vim.fn.fnamemodify-- Define child directory of stdpathsPath.stdpath("data", "mason", "bin") -- vim.fn.stdpath("data") .. "/mason/bin"localluv=vim.looplocalPath=require("pathlib")
-- Create new folderlocalnew_file=Path.new("./new/folder/foo.txt")
new_file:parent_assert():mkdir(Path.permission("rwxr-xr-x"), true) -- (permission, recursive)-- Create new file and write to itlocalfd=new_file:fs_open("w", Path.permission("rw-r--r--"), true)
assert(fd~=nil, "File creation failed. " ..new_file.error_msg)
luv.fs_write(fd, "File Content\n")
luv.fs_close(fd)
-- HINT: new_file:fs_write(...) does this all at once.-- SHORTHAND: read file content with `io.read`localcontent=new_file:io_read()
assert(content=="File Content\n")
-- SHORTHAND: write to filenew_file:io_write("File Content\n")
new_file:copy(new_file:with_basename("bar.txt")) -- copy `foo.txt` to `bar.txt`new_file:symlink_to(new_file:with_basename("baz.txt")) -- create symlink of `foo.txt` named `baz.txt`-- Continue from aboveforpathinnew_file:parent_assert():fs_iterdir() do-- loop: [Path("./new/folder/foo.txt"), Path("./new/folder/bar.txt"), Path("./new/folder/baz.txt")]endThis library uses nvim-nio under the hood to run async calls. Supported methods will turn into async calls inside a nio.run async context and has the EXACT SAME INTERFACE.
localnio=require("nio")
localpath=Path("foo.txt")
nio.run(function() -- async run (does not block the main thread)vim.print(path:fs_stat()) -- coroutine (async)path:fs_write("File Content\n") -- coroutine (async)vim.print(path:fs_read()) -- coroutine (async)vim.print("async done") -- prints lastend)
vim.print("sync here") -- prints first (maybe not if above functions end very fast)When execution fails, function will return nil and the error message is captured into self.error_msg. This property holds the error message of the latest async function call.
nio.run(function ()
localpath=Path("./does/not/exist.txt")
localfd=path:fs_open("r")
assert(fd, "ERROR: " ..path.error_msg)
-- fd will be nil when `:fs_open` fails. Check `self.error_msg` for the error message.end)- API documentation.
- PathlibPath
- PathlibPosixPath
- PathlibWindowsPath
- Git
- Git operation integration.
- Git test suite.
- List out every possible git state: ignored, staged etc.
- Create file for each state.
- Add docs for each state:
man git-diff -> RAW OUTPUT FORMAT
- Windows implementation, test environment.
- Create a CI/CD action to run on windows.
- Prepare windows specific test suite.
I'll happily accept any feature request Feel free to ask for any functionality :)
- Python
pathlib