local Meta = require "cave.meta" local PosixPath = require "pathlib.posix" --[[@as PathlibPosixPath]] local List = Meta.List local Str = Meta.String local validate = Meta.validate ---@alias cave.PathLikeItem string|cave.Path ---@alias cave.PathLike cave.PathLikeItem|cave.PathLikeItem[] ---@class cave.Path : PathlibPosixPath ---@operator div(cave.PathLikeItem): cave.Path ---@operator concat(cave.PathLikeItem): string local Path = Meta.derive("Path", PosixPath) require("pathlib.utils.paths").link_dunders(Path, PosixPath) Path.LikeItem = { Str, Path } Path.LikeItemList = List { Str, Path } Path.Like = { Str, Path, Path.LikeItemList } ---@param path_like cave.PathLike ---@return cave.Path function Path.like(path_like) validate { path_like = { path_like, Path.Like } } local self = Path.new_empty() local path_like_type = type(path_like) if path_like_type == "string" or not vim.tbl_islist(path_like) then self:_init(path_like) else self:_init(unpack(path_like)) end return self end ---@param path cave.Path ---@return cave.Path function Path:copy_all_from(path) ---@type cave.Path return PosixPath.copy_all_from(self, path) end ---@return cave.Path function Path:copy() return Path.new_empty():copy_all_from(self) end ---@param ... cave.PathLikeItem ---@return cave.Path function Path.new(...) validate { ["..."] = { { ... }, Path.LikeItemList } } local self = Path.new_empty() self:_init(...) return self end ---@return cave.Path function Path.new_empty() local self = setmetatable({}, Path) self:to_empty() return self end ---@return cave.Path function Path.cwd() return Path.new(vim.fn.getcwd()) end ---@return cave.Path function Path.home() return Path.new(vim.loop.os_homedir()) end ---@param what string ---@param ... cave.PathLikeItem ---@return cave.Path function Path.stdpath(what, ...) validate { what = { what, Str }, ["..."] = { { ... }, Path.LikeItemList } } return Path.new(vim.fn.stdpath(what), ...) end -- ---@return cave.Path -- function Path:to_absolute(cwd) return PosixPath.to_absolute(self, cwd) end ---@param name cave.PathLikeItem ---@return cave.Path function Path.executable(name) validate { name = { name, { Str, Path } } } if type(name) ~= "string" then name = tostring(name) end local s = vim.fn.exepath(name) assert(#s > 0, ("'%s' is not executable"):format(name)) return Path.new(s) end ---@return boolean function Path:is_executable() return vim.fn.executable(self:tostring()) == 1 end return Path