diff --git a/lua/SpecSwitcher/path.lua b/lua/SpecSwitcher/path.lua index 37c27ae..61c098a 100644 --- a/lua/SpecSwitcher/path.lua +++ b/lua/SpecSwitcher/path.lua @@ -1,149 +1,124 @@ -local path = {} +local PathObj = {} -function path.Common_Root( Left, Right, Separator ) - local Sep = Separator or "/" - local smallest_string = nil - local largest_string = nil - if string.len(Left) > string.len(Right) then - smallest_string = Right - largest_string = Left - else - smallest_string = Left - largest_string = Right +local posix_separator = '/' +local windows_separator = '\\' + +local function split( s, sep, include_sep ) + local include = include_sep or false + local fields, index = {}, 1 + repeat + local occurence = s:find(sep, index, true) + if include == true then + fields[#fields + 1] = s:sub(index - 1, occurence and occurence - 1) + else + fields[#fields + 1] = s:sub(index, occurence and occurence - 1) + end + index = occurence and occurence + #sep + until not index + return fields +end + +local function slice( t, first, last, step ) + local sliced = {} + + local first_index = first or 1 + local last_index = last or #t + local step_size = step or 1 + + for i = first_index, last_index, step_size do + sliced[#sliced + 1] = t[i] end - local last_sep_idx = 1 - local sep = string.byte(Sep) - for i = 1, #smallest_string do - if smallest_string:byte(i) == sep then - last_sep_idx = i - end + return sliced +end - if smallest_string:byte(i) ~= largest_string:byte(i) then +function PathObj:new( path ) + local obj = {} + local path_blocks = split(path, posix_separator) + + local slash_count = 0 + for i, part in ipairs(path_blocks) do + if part == '' then + slash_count = slash_count + 1 + else break end end - local match = string.sub(smallest_string, 1, last_sep_idx - 1) - - if match == '' then - return nil + if slash_count == 0 then + obj.root = '' + elseif slash_count == 2 then + obj.root = posix_separator .. posix_separator + path_blocks = slice(path_blocks, 3) else - return match - end -end - -function path.Get_Extension( P ) - if P == nil then - return nil + obj.root = posix_separator + path_blocks = slice(path_blocks, slash_count + 1) end - local rev_string = string.reverse(P) - local start_idx = 0 - local end_idx = 0 - start_idx, end_idx = string.find(rev_string, ".", 1, true) - - if start_idx == nil then - return nil + if obj.root ~= '' then + obj.parts = {obj.root, table.unpack(path_blocks)} else - return string.sub(P, #P - (start_idx -2)) + obj.parts = path_block end + + obj.drive = '' + obj.anchor = obj.drive .. obj.root + obj._segments = path_blocks + obj.name = path_blocks[#path_blocks] + + local suffices = slice(split(obj.name, ".", true), 2) + + obj.suffix = suffices[#suffices] + obj.suffices = suffices + + setmetatable(obj, self) + self.__index = self + + return obj end -function path.Get_Extension_From_List( P, Extension_List ) - if Extension_List == nil or P == nil then - return nil +function PathObj:to_string() + local out = self.drive .. self.root + + for i = 1, #self._segments - 1 do + out = out .. self._segments[i] .. '/' end - local ext_length = 0 - for _,item in ipairs(Extension_List) do - local current_ext_length = #item - if current_ext_length > ext_length then - ext_length = current_ext_length - end - end + out = out .. self._segments[#self._segments] - local rev_string = string.reverse(P) - local start_idx = 0 - local end_idx = 0 - local match = nil - while ( true ) do - start_idx, end_idx = string.find(rev_string, ".", start_idx+1, true) - if start_idx == nil or (start_idx-1) > ext_length then - break - end - - for _,exts in ipairs(Extension_List) do - if exts == string.sub(P, #P - (start_idx -2)) then - match = exts - end - end - end - - return match + return out end -function path.Get_Ext( P, Extension_List ) - if Extension_List == nil then - return path.Get_Extension(P) - else - return path.Get_Extension_From_List(P, Extension_List) +function PathObj:data_repr() + print("root = " .. self.root) + local segments = "segments = [" + for _, seg in ipairs(self.parts) do + segments = segments .. seg .. "," end -end + segments = segments .. "]" + print(segments) -function path.Walk_Up( P ) - if P == "/" then - return nil + print("name = " .. self.name) + print("suffix = " .. self.suffix) + + local suffices = "suffices = [" + for _, seg in ipairs(self.suffices) do + suffices = suffices .. seg .. "," end - local rev = string.reverse(P) - local start = 1 - if P:sub(-1) == "/" then - start = start + 1 - end - - local slash_first_idx, _ = string.find(rev, "/", start, true) - - return string.sub(P, 1, #P - slash_first_idx + 1) + suffices = suffices .. "]" + print(suffices) end -function path.Get_File( P ) - local rev = string.reverse(P) - local start = 1 - - local slash_first_idx, _ = string.find(rev, "/", start, true) - - return string.sub(P, #P - slash_first_idx + 2) +function PathObj:is_absolute() + return self.root ~= '' end -function path.Get_Filename( File ) - local dot_first_idx, _ = string.find(File, ".", 1, true) +print(PathObj:new( "home/folkert/test.ads" ):to_string()) +print(PathObj:new( "/home/folkert/test.ads" ):to_string()) +print(PathObj:new( "//home/folkert/test.ads" ):to_string()) +print(PathObj:new( "///home/folkert/test.ads" ):is_absolute()) - return string.sub(File, 1, dot_first_idx - 1) -end +local x = PathObj:new( "/home/foo/bar/baz.c" ) +print(x:to_string()) -function path.Generate_Dir_Walk( Base, Descend_List ) - Descend_List = Descend_List or {} - local Descend_Length = #Descend_List - - local i = -1 - local Base_Dir = Base - function Inner() - if i == Descend_Length then - local Temp_Dir = path.Walk_Up(Base_Dir) - if Temp_Dir ~= nil then - Base_Dir = Temp_Dir - i = -1 - end - end - i = i + 1 - if i == 0 then - return Base_Dir - elseif i <= Descend_Length then - return Base_Dir .. Descend_List[i] .. "/" - end - end - - return Inner -end - -return path +return PathObj