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.
This commit is contained in:
Gregory Anders 2022-05-15 14:38:19 -06:00
parent e6652821bd
commit 67cbaf58c4
5 changed files with 100 additions and 0 deletions

View File

@ -2147,4 +2147,32 @@ set({mode}, {lhs}, {rhs}, {opts}) *vim.keymap.set()*
See also: ~ See also: ~
|nvim_set_keymap()| |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: vim:tw=78:ts=8:ft=help:norl:

View File

@ -50,6 +50,7 @@ for k, v in pairs({
keymap = true, keymap = true,
ui = true, ui = true,
health = true, health = true,
fs = true,
}) do }) do
vim._submodules[k] = v vim._submodules[k] = v
end end

35
runtime/lua/vim/fs.lua Normal file
View File

@ -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

View File

@ -134,6 +134,7 @@ CONFIG = {
'ui.lua', 'ui.lua',
'filetype.lua', 'filetype.lua',
'keymap.lua', 'keymap.lua',
'fs.lua',
], ],
'files': [ 'files': [
'runtime/lua/vim/_editor.lua', 'runtime/lua/vim/_editor.lua',
@ -142,6 +143,7 @@ CONFIG = {
'runtime/lua/vim/ui.lua', 'runtime/lua/vim/ui.lua',
'runtime/lua/vim/filetype.lua', 'runtime/lua/vim/filetype.lua',
'runtime/lua/vim/keymap.lua', 'runtime/lua/vim/keymap.lua',
'runtime/lua/vim/fs.lua',
], ],
'file_patterns': '*.lua', 'file_patterns': '*.lua',
'fn_name_prefix': '', 'fn_name_prefix': '',
@ -167,6 +169,7 @@ CONFIG = {
'ui': 'vim.ui', 'ui': 'vim.ui',
'filetype': 'vim.filetype', 'filetype': 'vim.filetype',
'keymap': 'vim.keymap', 'keymap': 'vim.keymap',
'fs': 'vim.fs',
}, },
'append_only': [ 'append_only': [
'shared.lua', 'shared.lua',

View File

@ -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)