aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/doc/lua.txt17
-rw-r--r--runtime/doc/news.txt1
-rw-r--r--runtime/lua/vim/fs.lua33
3 files changed, 51 insertions, 0 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index a84a364847..44cbf238cf 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -3148,6 +3148,23 @@ vim.fs.parents({start}) *vim.fs.parents()*
(`nil`)
(`string?`)
+vim.fs.relpath({base}, {target}, {opts}) *vim.fs.relpath()*
+ Gets `target` path relative to `base`, or `nil` if `base` is not an
+ ancestor.
+
+ Example: >lua
+ vim.fs.relpath('/var', '/var/lib') -- 'lib'
+ vim.fs.relpath('/var', '/usr/bin') -- nil
+<
+
+ Parameters: ~
+ • {base} (`string`)
+ • {target} (`string`)
+ • {opts} (`table?`) Reserved for future use
+
+ Return: ~
+ (`string?`)
+
vim.fs.rm({path}, {opts}) *vim.fs.rm()*
WARNING: This feature is experimental/unstable.
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 3b1c38b8d9..a1868e97d0 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -284,6 +284,7 @@ LUA
supporting two new parameters, `encoding` and `strict_indexing`.
• |vim.json.encode()| has an option to enable forward slash escaping
• |vim.fs.abspath()| converts paths to absolute paths.
+• |vim.fs.relpath()| gets relative path compared to base path.
OPTIONS
diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua
index 04a6e43db1..91e06688b3 100644
--- a/runtime/lua/vim/fs.lua
+++ b/runtime/lua/vim/fs.lua
@@ -741,4 +741,37 @@ function M.abspath(path)
return M.joinpath(cwd, path)
end
+--- Gets `target` path relative to `base`, or `nil` if `base` is not an ancestor.
+---
+--- Example:
+---
+--- ```lua
+--- vim.fs.relpath('/var', '/var/lib') -- 'lib'
+--- vim.fs.relpath('/var', '/usr/bin') -- nil
+--- ```
+---
+--- @param base string
+--- @param target string
+--- @param opts table? Reserved for future use
+--- @return string|nil
+function M.relpath(base, target, opts)
+ vim.validate('base', base, 'string')
+ vim.validate('target', target, 'string')
+ vim.validate('opts', opts, 'table', true)
+
+ base = vim.fs.normalize(vim.fs.abspath(base))
+ target = vim.fs.normalize(vim.fs.abspath(target))
+ if base == target then
+ return '.'
+ end
+
+ local prefix = ''
+ if iswin then
+ prefix, base = split_windows_path(base)
+ end
+ base = prefix .. base .. (base ~= '/' and '/' or '')
+
+ return vim.startswith(target, base) and target:sub(#base + 1) or nil
+end
+
return M