Skip to content

Commit 1c31adb

Browse files
authored
feat: exclude positions in Path:shorten (#268)
1 parent b42e0cf commit 1c31adb

File tree

3 files changed

+76
-14
lines changed

3 files changed

+76
-14
lines changed

lua/plenary/path.lua

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -345,23 +345,49 @@ function Path:normalize(cwd)
345345
return _normalize_path(self.filename, self._cwd)
346346
end
347347

348-
local function shorten_len(filename, len)
349-
local final_match
348+
local function shorten_len(filename, len, exclude)
349+
len = len or 1
350+
exclude = exclude or { -1 }
351+
local exc = {}
352+
353+
-- get parts in a table
354+
local parts = {}
355+
local empty_pos = {}
356+
for m in (filename .. path.sep):gmatch("(.-)" .. path.sep) do
357+
if m ~= "" then
358+
parts[#parts + 1] = m
359+
else
360+
table.insert(empty_pos, #parts + 1)
361+
end
362+
end
363+
364+
for _, v in pairs(exclude) do
365+
if v < 0 then
366+
exc[v + #parts + 1] = true
367+
else
368+
exc[v] = true
369+
end
370+
end
371+
350372
local final_path_components = {}
351-
for match in (filename .. path.sep):gmatch("(.-)" .. path.sep) do
352-
if #match > len then
373+
local count = 1
374+
for _, match in ipairs(parts) do
375+
if not exc[count] and #match > len then
353376
table.insert(final_path_components, string.sub(match, 1, len))
354377
else
355378
table.insert(final_path_components, match)
356379
end
357380
table.insert(final_path_components, path.sep)
358-
final_match = match
381+
count = count + 1
359382
end
360383

361384
local l = #final_path_components -- so that we don't need to keep calculating length
362385
table.remove(final_path_components, l) -- remove final slash
363-
table.remove(final_path_components, l - 1) -- remvove shortened final component
364-
table.insert(final_path_components, final_match) -- insert full final component
386+
387+
-- add back empty positions
388+
for i = #empty_pos, 1, -1 do
389+
table.insert(final_path_components, empty_pos[i], path.sep)
390+
end
365391

366392
return table.concat(final_path_components)
367393
end
@@ -388,10 +414,10 @@ local shorten = (function()
388414
end
389415
end)()
390416

391-
function Path:shorten(len)
417+
function Path:shorten(len, exclude)
392418
assert(len ~= 0, "len must be at least 1")
393-
if len and len > 1 then
394-
return shorten_len(self.filename, len)
419+
if (len and len > 1) or exclude ~= nil then
420+
return shorten_len(self.filename, len, exclude)
395421
end
396422
return shorten(self.filename)
397423
end

tests/plenary/path_spec.lua

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,8 @@ describe("Path", function()
213213
local short_path = Path:new(long_path):shorten()
214214
assert.are.same(short_path, "/t/i/a/l/path")
215215
end)
216-
end)
217216

218-
describe(":shorten", function()
219-
it("can shorten a path components to a given length", function()
217+
it("can shorten a path's components to a given length", function()
220218
local long_path = "/this/is/a/long/path"
221219
local short_path = Path:new(long_path):shorten(2)
222220
assert.are.same(short_path, "/th/is/a/lo/path")
@@ -231,6 +229,41 @@ describe("Path", function()
231229
short_path = Path:new(long_path):shorten(5)
232230
assert.are.same(short_path, "this/is/an/extre/long/path")
233231
end)
232+
233+
it("can shorten a path's components when excluding parts", function()
234+
local long_path = "/this/is/a/long/path"
235+
local short_path = Path:new(long_path):shorten(nil, { 1, -1 })
236+
assert.are.same(short_path, "/this/i/a/l/path")
237+
238+
-- without the leading /
239+
long_path = "this/is/a/long/path"
240+
short_path = Path:new(long_path):shorten(nil, { 1, -1 })
241+
assert.are.same(short_path, "this/i/a/l/path")
242+
243+
-- where excluding positions greater than the number of parts
244+
long_path = "this/is/an/extremely/long/path"
245+
short_path = Path:new(long_path):shorten(nil, { 2, 4, 6, 8 })
246+
assert.are.same(short_path, "t/is/a/extremely/l/path")
247+
248+
-- where excluding positions less than the negation of the number of parts
249+
long_path = "this/is/an/extremely/long/path"
250+
short_path = Path:new(long_path):shorten(nil, { -2, -4, -6, -8 })
251+
assert.are.same(short_path, "this/i/an/e/long/p")
252+
end)
253+
254+
it("can shorten a path's components to a given length and exclude positions", function()
255+
local long_path = "/this/is/a/long/path"
256+
local short_path = Path:new(long_path):shorten(2, { 1, -1 })
257+
assert.are.same(short_path, "/this/is/a/lo/path")
258+
259+
long_path = "this/is/a/long/path"
260+
short_path = Path:new(long_path):shorten(3, { 2, -2 })
261+
assert.are.same(short_path, "thi/is/a/long/pat")
262+
263+
long_path = "this/is/an/extremely/long/path"
264+
short_path = Path:new(long_path):shorten(5, { 3, -3 })
265+
assert.are.same(short_path, "this/is/an/extremely/long/path")
266+
end)
234267
end)
235268

236269
describe("mkdir / rmdir", function()

tests/plenary/strings_spec.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ describe("strings", function()
7878
args = { "アイウエオ", 10, nil, 1 },
7979
expected = { single = "アイウエオ", double = "アイウエオ" },
8080
},
81-
{ args = { "アイウエオ", 9, nil, -1 }, expected = { single = "…イウエオ", double = "…ウエオ" } },
81+
{
82+
args = { "アイウエオ", 9, nil, -1 },
83+
expected = { single = "…イウエオ", double = "…ウエオ" },
84+
},
8285
{ args = { "アイウエオ", 8, nil, -1 }, expected = { single = "…ウエオ", double = "…ウエオ" } },
8386
{ args = { "├─┤", 7, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } },
8487
{ args = { "├─┤", 6, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } },

0 commit comments

Comments
 (0)