diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
commit | 4ca61ec457822dd14966afa0752340ae8ce180a1 (patch) | |
tree | ae8adb1ad82c717868e551e699fd3cf3bb290089 /script/file-uri.lua | |
parent | c63b2e404d8d2bb984afe3678a5ba2b2836380cc (diff) | |
download | lua-language-server-4ca61ec457822dd14966afa0752340ae8ce180a1.zip |
no longer beta
Diffstat (limited to 'script/file-uri.lua')
-rw-r--r-- | script/file-uri.lua | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/script/file-uri.lua b/script/file-uri.lua new file mode 100644 index 00000000..ba44f2e7 --- /dev/null +++ b/script/file-uri.lua @@ -0,0 +1,89 @@ +local platform = require 'bee.platform' + +local escPatt = '[^%w%-%.%_%~%/]' + +local function esc(c) + return ('%%%02X'):format(c:byte()) +end + +local function normalize(str) + return str:gsub('%%(%x%x)', function (n) + return string.char(tonumber(n, 16)) + end) +end + +local m = {} + +-- c:\my\files --> file:///c%3A/my/files +-- /usr/home --> file:///usr/home +-- \\server\share\some\path --> file://server/share/some/path + +--- path -> uri +---@param path string +---@return string uri +function m.encode(path) + local authority = '' + if platform.OS == 'Windows' then + path = path:gsub('\\', '/') + end + + if path:sub(1, 2) == '//' then + local idx = path:find('/', 3) + if idx then + authority = path:sub(3, idx) + path = path:sub(idx + 1) + if path == '' then + path = '/' + end + else + authority = path:sub(3) + path = '/' + end + end + + if path:sub(1, 1) ~= '/' then + path = '/' .. path + end + + -- lower-case windows drive letters in /C:/fff or C:/fff + local start, finish, drive = path:find '/(%u):' + if drive then + path = path:sub(1, start) .. drive:lower() .. path:sub(finish, -1) + end + + local uri = 'file://' + .. authority:gsub(escPatt, esc) + .. path:gsub(escPatt, esc) + return uri +end + +-- file:///c%3A/my/files --> c:\my\files +-- file:///usr/home --> /usr/home +-- file://server/share/some/path --> \\server\share\some\path + +--- uri -> path +---@param uri string +---@return string path +function m.decode(uri) + local scheme, authority, path = uri:match('([^:]*):?/?/?([^/]*)(.*)') + if not scheme then + return '' + end + scheme = normalize(scheme) + authority = normalize(authority) + path = normalize(path) + local value + if scheme == 'file' and #authority > 0 and #path > 1 then + value = '//' .. authority .. path + elseif path:match '/%a:' then + value = path:sub(2, 2):lower() .. path:sub(3) + else + value = path + end + if platform.OS == 'Windows' then + value = value:gsub('/', '\\') + end + return value +end + +return m |