feat(vim.fs): abspath({cwd, plain}) #40597

Adds optional parameters to `vim.fs.abspath`:
1. `cwd` to specify directory akin to `--relative-from` in `realpath(1)`.
2. `plain` disables expansion of tilde (~) in paths.
This commit is contained in:
AlexCodesApps
2026-08-01 14:09:21 +01:00
committed by GitHub
parent 9fbcb28ea6
commit b11f1b1f76
4 changed files with 48 additions and 12 deletions

View File

@@ -865,21 +865,37 @@ function M.rm(path, opts)
end
end
--- Converts `path` to an absolute path. Expands tilde (~) at the beginning of the path
--- to the user's home directory. Does not check if the path exists, normalize the path, resolve
--- symlinks or hardlinks (including `.` and `..`), or expand environment variables. If the path is
--- already absolute, it is returned unchanged. Also converts `\` path separators to `/`.
--- @class vim.fs.abspath.Opts
--- @inlinedoc
---
--- Resolve the path relative to this directory.
--- @field cwd? string
---
--- Do not expand tilde (~).
--- @field plain? boolean
--- Converts `path` to an absolute path. Expands tilde (~) at the beginning of the path (unless
--- plain=true). Does not check if the path exists, normalize the path, resolve symlinks or
--- hardlinks (including "." and ".."), or expand environment variables. If the path is already
--- absolute, it is returned unchanged. Converts `\` path separators to `/`.
---
--- @since 13
--- @param path string Path
--- @param opts? vim.fs.abspath.Opts
--- @return string Absolute path
function M.abspath(path)
function M.abspath(path, opts)
-- TODO(justinmk): mark f_fnamemodify as API_FAST and use it, ":p:h" should be safe...
--
opts = opts or {}
vim.validate('path', path, 'string')
vim.validate('cwd', opts.cwd, 'string', true)
vim.validate('plain', opts.plain, 'boolean', true)
-- Expand ~ to user's home directory
path = expand_home(path)
if not opts.plain then
path = expand_home(path)
end
-- Convert path separator to `/`
path = path:gsub(os_sep, '/')
@@ -897,7 +913,8 @@ function M.abspath(path)
-- Windows allows paths like C:foo/bar, these paths are relative to the current working directory
-- of the drive specified in the path
local cwd = assert((iswin and prefix:match('^%w:$')) and uv.fs_realpath(prefix) or uv.cwd())
local cwd =
assert((iswin and prefix:match('^%w:$')) and uv.fs_realpath(prefix) or opts.cwd or uv.cwd())
-- Convert cwd path separator to `/`
cwd = cwd:gsub(os_sep, '/')