@@ -69,4 +69,37 @@ function M.trim_common_root(paths)
6969 return result
7070end
7171
72+ --- @param filepath string an absolute path
73+ --- @param base string an absolute path to an ancestor of filepath ;
74+ --- here, `'.'` represents the current working directory, and
75+ --- *not* the current file's directory.
76+ --- @return string filepath_relative_to_base
77+ function M .make_relative (filepath , base )
78+ vim .validate ({
79+ filepath = { filepath , ' string' , false },
80+ base = { base , ' string' , false },
81+ })
82+ filepath = vim .fn .fnamemodify (filepath , ' :p' )
83+ base = vim .fn .fnamemodify (base , ' :p' )
84+ if base :sub (- 1 ) ~= ' /' then
85+ base = base .. ' /'
86+ end
87+ local levels_up = 0
88+ for parent in vim .fs .parents (base ) do
89+ if parent :sub (- 1 ) ~= ' /' then
90+ parent = parent .. ' /'
91+ end
92+ if vim .startswith (filepath , parent ) then
93+ filepath = filepath :sub (parent :len () + 1 )
94+ if levels_up > 0 then
95+ return vim .fs .joinpath (string.rep (' ..' , levels_up , ' /' ), filepath )
96+ end
97+ return vim .fs .joinpath (' .' , filepath )
98+ end
99+ levels_up = levels_up + 1
100+ end
101+ -- No common root, just return the absolute path.
102+ return filepath
103+ end
104+
72105return M
0 commit comments