aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <greg@gpanders.com>2022-05-15 14:38:19 -0600
committerGregory Anders <greg@gpanders.com>2022-05-31 13:04:40 -0600
commit67cbaf58c41a3db19c5014587e72d06be9e3d58e (patch)
tree49fa85e672d6637ef38a9e910a1323224ca653ab
parente6652821bd32e4ff8d62a0b67fc2041a5f41e252 (diff)
downloadrneovim-67cbaf58c41a3db19c5014587e72d06be9e3d58e.tar.gz
rneovim-67cbaf58c41a3db19c5014587e72d06be9e3d58e.tar.bz2
rneovim-67cbaf58c41a3db19c5014587e72d06be9e3d58e.zip
feat(fs): add vim.fs.parents()
vim.fs.parents() is a Lua iterator that returns the next parent directory of the given file or directory on each iteration.
-rw-r--r--runtime/doc/lua.txt28
-rw-r--r--runtime/lua/vim/_editor.lua1
-rw-r--r--runtime/lua/vim/fs.lua35
-rwxr-xr-xscripts/gen_vimdoc.py3
-rw-r--r--test/functional/lua/fs_spec.lua33
5 files changed, 100 insertions, 0 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index dd1843ade3..8f74dca418 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -2147,4 +2147,32 @@ set({mode}, {lhs}, {rhs}, {opts}) *vim.keymap.set()*
See also: ~
|nvim_set_keymap()|
+
+==============================================================================
+Lua module: fs *lua-fs*
+
+parents({start}) *vim.fs.parents()*
+ Iterate over all the parents of the given file or directory.
+
+ Example: >
+
+ local root_dir
+ for dir in vim.fs.parents(vim.api.nvim_buf_get_name(0)) do
+ if vim.fn.isdirectory(dir .. "/.git") == 1 then
+ root_dir = dir
+ break
+ end
+ end
+
+ if root_dir then
+ print("Found git repository at", root_dir)
+ end
+<
+
+ Parameters: ~
+ {start} (string) Initial file or directory.
+
+ Return: ~
+ (function) Iterator
+
vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index c8a0aa8260..453aa6ac81 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -50,6 +50,7 @@ for k, v in pairs({
keymap = true,
ui = true,
health = true,
+ fs = true,
}) do
vim._submodules[k] = v
end
diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua
new file mode 100644
index 0000000000..08d2e495d2
--- /dev/null
+++ b/runtime/lua/vim/fs.lua
@@ -0,0 +1,35 @@
+local M = {}
+
+--- Iterate over all the parents of the given file or directory.
+---
+--- Example:
+--- <pre>
+--- local root_dir
+--- for dir in vim.fs.parents(vim.api.nvim_buf_get_name(0)) do
+--- if vim.fn.isdirectory(dir .. "/.git") == 1 then
+--- root_dir = dir
+--- break
+--- end
+--- end
+---
+--- if root_dir then
+--- print("Found git repository at", root_dir)
+--- end
+--- </pre>
+---
+---@param start (string) Initial file or directory.
+---@return (function) Iterator
+function M.parents(start)
+ return function(_, dir)
+ local parent = vim.fn.fnamemodify(dir, ":h")
+ if parent == dir then
+ return nil
+ end
+
+ return parent
+ end,
+ nil,
+ start
+end
+
+return M
diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py
index 755749cef6..790c2ba52d 100755
--- a/scripts/gen_vimdoc.py
+++ b/scripts/gen_vimdoc.py
@@ -134,6 +134,7 @@ CONFIG = {
'ui.lua',
'filetype.lua',
'keymap.lua',
+ 'fs.lua',
],
'files': [
'runtime/lua/vim/_editor.lua',
@@ -142,6 +143,7 @@ CONFIG = {
'runtime/lua/vim/ui.lua',
'runtime/lua/vim/filetype.lua',
'runtime/lua/vim/keymap.lua',
+ 'runtime/lua/vim/fs.lua',
],
'file_patterns': '*.lua',
'fn_name_prefix': '',
@@ -167,6 +169,7 @@ CONFIG = {
'ui': 'vim.ui',
'filetype': 'vim.filetype',
'keymap': 'vim.keymap',
+ 'fs': 'vim.fs',
},
'append_only': [
'shared.lua',
diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua
new file mode 100644
index 0000000000..69eb8cd539
--- /dev/null
+++ b/test/functional/lua/fs_spec.lua
@@ -0,0 +1,33 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local exec_lua = helpers.exec_lua
+local eq = helpers.eq
+local mkdir_p = helpers.mkdir_p
+local rmdir = helpers.rmdir
+local nvim_dir = helpers.nvim_dir
+local test_build_dir = helpers.test_build_dir
+
+before_each(clear)
+
+describe('vim.fs', function()
+ describe('parents()', function()
+ it('works', function()
+ local test_dir = nvim_dir .. '/test'
+ mkdir_p(test_dir)
+ local dirs = exec_lua([[
+ local test_dir, test_build_dir = ...
+ local dirs = {}
+ for dir in vim.fs.parents(test_dir .. "/foo.txt") do
+ dirs[#dirs + 1] = dir
+ if dir == test_build_dir then
+ break
+ end
+ end
+ return dirs
+ ]], test_dir, test_build_dir)
+ eq({test_dir, nvim_dir, test_build_dir}, dirs)
+ rmdir(test_dir)
+ end)
+ end)
+end)