Skip to content

Commit f67d771

Browse files
fix(capture): Correctly trim common root with multiple roots defined
Closes #984
1 parent d424ecc commit f67d771

File tree

2 files changed

+81
-6
lines changed

2 files changed

+81
-6
lines changed

lua/orgmode/utils/fs.lua

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,40 @@ end
4646
---@param paths string[]
4747
---@return string[]
4848
function M.trim_common_root(paths)
49-
local filepaths = vim.deepcopy(paths)
49+
local filepaths = vim.tbl_map(function(value)
50+
return vim.split(vim.fn.fnamemodify(value, ':h'), '/', { trimempty = true, plain = true })
51+
end, paths)
52+
5053
table.sort(filepaths, function(a, b)
51-
local _, count_a = a:gsub('/', '')
52-
local _, count_b = b:gsub('/', '')
53-
return count_a < count_b
54+
return #a < #b
5455
end)
5556

56-
local result = {}
57-
local root = vim.fn.fnamemodify(filepaths[1], ':h') .. '/'
57+
local get_common_root = function()
58+
local common_root = {}
59+
local counter = 1
60+
61+
while counter <= #filepaths[1] do
62+
local current = filepaths[1][counter]
63+
for _, filepath in ipairs(filepaths) do
64+
if filepath[counter] ~= current then
65+
return common_root
66+
end
67+
end
68+
table.insert(common_root, current)
69+
counter = counter + 1
70+
end
71+
72+
return common_root
73+
end
5874

75+
local common_root = get_common_root()
76+
77+
if #common_root == 0 then
78+
return paths
79+
end
80+
81+
local root = table.concat(common_root, '/') .. '/'
82+
local result = {}
5983
for _, path in ipairs(paths) do
6084
local relative_path = path:sub(#root + 1)
6185
table.insert(result, relative_path)

tests/plenary/utils/fs_spec.lua

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,54 @@ describe('get_real_path', function()
8686
assert.is.False(fs_utils.get_real_path('.'))
8787
end)
8888
end)
89+
90+
describe('trim_common_root', function()
91+
it('trims the common root when all files share the same root with the shortest one', function()
92+
local result = fs_utils.trim_common_root({
93+
'foo/bar/baz.org',
94+
'foo/bar/baz/bar.org',
95+
'foo/bar/baz3.org',
96+
})
97+
assert.are.same({
98+
'baz.org',
99+
'baz/bar.org',
100+
'baz3.org',
101+
}, result)
102+
end)
103+
104+
it('trims the common root when there are multiple different roots', function()
105+
local result = fs_utils.trim_common_root({
106+
'foo/bar/tea/notes.org',
107+
'foo/bar/tea/todos.org',
108+
'foo/bar/baz/work.org',
109+
'foo/bar/baz/personal.org',
110+
'foo/bar/baz/project.org',
111+
})
112+
113+
assert.are.same({
114+
'tea/notes.org',
115+
'tea/todos.org',
116+
'baz/work.org',
117+
'baz/personal.org',
118+
'baz/project.org',
119+
}, result)
120+
end)
121+
122+
it('returns paths as they are if they do not share the common root', function()
123+
local result = fs_utils.trim_common_root({
124+
'foo/bar/tea/notes.org',
125+
'foo/bar/tea/todos.org',
126+
'foo/bar/baz/work.org',
127+
'foo/bar/baz/personal.org',
128+
'other/bar/baz/project.org',
129+
})
130+
131+
assert.are.same({
132+
'foo/bar/tea/notes.org',
133+
'foo/bar/tea/todos.org',
134+
'foo/bar/baz/work.org',
135+
'foo/bar/baz/personal.org',
136+
'other/bar/baz/project.org',
137+
}, result)
138+
end)
139+
end)

0 commit comments

Comments
 (0)