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