Skip to content

Commit 434c787

Browse files
committed
feat(path): add commonprefix
1 parent c537b77 commit 434c787

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

spec/path_spec.lua

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@ local tests = {
5555
{{ [[C:\a\b]] }, { "C:/a/b" }},
5656
{{ [[\\srv\share\a]] }, { "//srv/share/a" }},
5757
},
58+
commonprefix = {
59+
"common",
60+
{{{ }}, { "" }},
61+
{{{ "" , "abc" }}, { "" }},
62+
{{{ "abc" , "abd" }}, { "ab" }},
63+
{{{ "Xbcd" , "Xb" }}, { "Xb" }},
64+
{{{ "abcX" , "abcd" }}, { "abc" }},
65+
{{{ "aXc" , "aX" }}, { "aX" }},
66+
{{{ "abc" , "abc" }}, { "abc" }},
67+
{{{ "abc" , "xbc" }}, { "" }},
68+
{{{ "/a/b" , "/a/c" }}, { "/a/" }},
69+
{{{ "/home/swenson/spam", "/home/swen/spam" }}, { "/home/swen" }},
70+
{{{ "/home/swen/spam" , "/home/swen/eggs" }}, { "/home/swen/" }},
71+
{{{ "/home/swen/spam" , "/home/swen/spam" }}, { "/home/swen/spam" }},
72+
{{{ "home:swenson:spam" , "home:swen:spam" }}, { "home:swen" }},
73+
{{{ ":home:swen:spam" , ":home:swen:eggs" }}, { ":home:swen:" }},
74+
{{{ ":home:swen:spam" , ":home:swen:spam" }}, { ":home:swen:spam" }},
75+
{{{ "/home/swen/spam" , "/home/swen/spam" }}, { "/home/swen/spam" }},
76+
"windows",
77+
{{{ [[\home\swen\spam]] , [[\home\swen\eggs]] }}, { [[\home\swen\]] }},
78+
},
5879
dirnames = {
5980
"posix",
6081
{{ "a/b/c" }, {{ "a/b" , "a" , "." }}},

src/mods/path.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,32 @@ function M.drive(p)
169169
return (splitroot(p))
170170
end
171171

172+
function M.commonprefix(paths)
173+
assert_arg(1, paths, "table")
174+
if #paths == 0 then
175+
return ""
176+
end
177+
178+
local min_path = paths[1]
179+
local max_path = paths[1]
180+
for i = 1, #paths do
181+
local path_ = paths[i]
182+
assert_arg(i, path_, "string")
183+
if path_ < min_path then
184+
min_path = path_
185+
elseif path_ > max_path then
186+
max_path = path_
187+
end
188+
end
189+
190+
local i = 1
191+
local n = #min_path
192+
while i <= n and sub(min_path, i, i) == sub(max_path, i, i) do
193+
i = i + 1
194+
end
195+
return sub(min_path, 1, i - 1)
196+
end
197+
172198
function M.expandvars(p)
173199
assert_arg(1, p, "string")
174200
local res = expandvars(getenv, p, "%${([^}]*)}", "${", "}")

types/path.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,20 @@ function M.relpath(path, start) end
272272
---@nodiscard
273273
function M.commonpath(paths) end
274274

275+
---
276+
---Return longest common leading string prefix.
277+
---
278+
---```lua
279+
---path.commonprefix({"abc", "abd"}) --> "ab"
280+
---path.commonprefix({"/home/swen/spam", "/home/swen/eggs"}) --> "/home/swen/"
281+
---path.commonprefix({"abc", "xyz"}) --> ""
282+
---```
283+
---
284+
---@param paths string[] List of paths.
285+
---@return string commonPrefix Longest common string prefix.
286+
---@nodiscard
287+
function M.commonprefix(paths) end
288+
275289
--------------------------------------------------------------------------------
276290
----------------------------------- Anchors ------------------------------------
277291
--------------------------------------------------------------------------------

0 commit comments

Comments
 (0)