Skip to content

Commit a76ee04

Browse files
committed
add find_upwards
1 parent 1d9bafc commit a76ee04

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

lua/plenary/path2.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@
6464
--- seems unnecessary... just do `Path:new("some/file/path"):read()`
6565
---
6666
--- - renamed `iter` into `iter_lines` for more clarity
67+
---
68+
--- - `find_upwards` returns `nil` if file not found rather than an empty string
6769

6870
local bit = require "plenary.bit"
6971
local uv = vim.loop
@@ -1421,4 +1423,28 @@ function Path:walk(top_down)
14211423
end
14221424
end
14231425

1426+
--- Search for a filename up from the current path, including the current
1427+
--- directory, searching up to the root directory.
1428+
--- Returns the `Path` of the first item found.
1429+
--- Returns `nil` if filename is not found.
1430+
---@param filename string
1431+
---@return plenary.Path2?
1432+
function Path:find_upwards(filename)
1433+
vim.validate { filename = { filename, "s" } }
1434+
1435+
if self:is_dir() then
1436+
local target = self / filename
1437+
if target:exists() then
1438+
return target
1439+
end
1440+
end
1441+
1442+
for parent in self:iter_parents() do
1443+
local target = Path:new { parent, filename }
1444+
if target:exists() then
1445+
return target
1446+
end
1447+
end
1448+
end
1449+
14241450
return Path

tests/plenary/path2_spec.lua

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,4 +1101,26 @@ SOFTWARE.]]
11011101
assert.are.same(should, data)
11021102
end)
11031103
end)
1104+
1105+
describe("find_upwards", function()
1106+
it_cross_plat("finds file in current dir", function()
1107+
local p = Path:new "lua/plenary"
1108+
local res = assert(p:find_upwards "busted.lua")
1109+
local expect = Path:new "lua/plenary/busted.lua"
1110+
assert.are.same(expect, res)
1111+
end)
1112+
1113+
it_cross_plat("finds file in parent dir", function()
1114+
local p = Path:new "lua/plenary"
1115+
local res = assert(p:find_upwards "say.lua")
1116+
local expect = Path:new "lua/say.lua"
1117+
assert.are.same(expect, res)
1118+
end)
1119+
1120+
it_cross_plat("doesn't find file", function()
1121+
local p = Path:new "."
1122+
local res = p:find_upwards "aisohtenaishoetnaishoetnasihoetnashitoen"
1123+
assert.is_nil(res)
1124+
end)
1125+
end)
11041126
end)

0 commit comments

Comments
 (0)