summaryrefslogtreecommitdiff
path: root/server-beta/src/file-uri.lua
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-09-23 18:44:37 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-09-23 18:44:37 +0800
commitf063428d49f7dffe68518b8418a5d36abb6a7fc1 (patch)
tree4b2eccf6e825d37e611223e535c42343156d7aa4 /server-beta/src/file-uri.lua
parent1dda93bba596496c1a427707fe97d92391129b8d (diff)
downloadlua-language-server-f063428d49f7dffe68518b8418a5d36abb6a7fc1.zip
file-uri
Diffstat (limited to 'server-beta/src/file-uri.lua')
-rw-r--r--server-beta/src/file-uri.lua102
1 files changed, 102 insertions, 0 deletions
diff --git a/server-beta/src/file-uri.lua b/server-beta/src/file-uri.lua
new file mode 100644
index 00000000..e58a86eb
--- /dev/null
+++ b/server-beta/src/file-uri.lua
@@ -0,0 +1,102 @@
+local platform = require 'bee.platform'
+
+local esc = {
+ [':'] = '%3A',
+ ['/'] = '%2F',
+ ['?'] = '%3F',
+ ['#'] = '%23',
+ ['['] = '%5B',
+ [']'] = '%5D',
+ ['@'] = '%40',
+
+ ['!'] = '%21', -- sub-delims
+ ['$'] = '%24',
+ ['&'] = '%26',
+ ["'"] = '%27',
+ ['('] = '%28',
+ [')'] = '%29',
+ ['*'] = '%2A',
+ ['+'] = '%2B',
+ [','] = '%2C',
+ [';'] = '%3B',
+ ['='] = '%3D',
+
+ [' '] = '%20',
+}
+
+local escPatt = '[^%w%-%.%_%~%/]'
+
+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
+
+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
+ if path:match '/%u:' then
+ path = path:lower()
+ 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
+
+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