mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	 04a0486c66
			
		
	
	04a0486c66
	
	
	
		
			
			* Change uri_to_fname to not convert non-file URIs A URI with a scheme other than file doesn't have a local file path. * fixup! Change uri_to_fname to not convert non-file URIs * fixup! fixup! Change uri_to_fname to not convert non-file URIs
		
			
				
	
	
		
			113 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| --- TODO: This is implemented only for files now.
 | |
| -- https://tools.ietf.org/html/rfc3986
 | |
| -- https://tools.ietf.org/html/rfc2732
 | |
| -- https://tools.ietf.org/html/rfc2396
 | |
| 
 | |
| 
 | |
| local uri_decode
 | |
| do
 | |
|   local schar = string.char
 | |
|   local function hex_to_char(hex)
 | |
|     return schar(tonumber(hex, 16))
 | |
|   end
 | |
|   uri_decode = function(str)
 | |
|     return str:gsub("%%([a-fA-F0-9][a-fA-F0-9])", hex_to_char)
 | |
|   end
 | |
| end
 | |
| 
 | |
| local uri_encode
 | |
| do
 | |
|   local PATTERNS = {
 | |
|     --- RFC 2396
 | |
|     -- https://tools.ietf.org/html/rfc2396#section-2.2
 | |
|     rfc2396 = "^A-Za-z0-9%-_.!~*'()";
 | |
|     --- RFC 2732
 | |
|     -- https://tools.ietf.org/html/rfc2732
 | |
|     rfc2732 = "^A-Za-z0-9%-_.!~*'()[]";
 | |
|     --- RFC 3986
 | |
|     -- https://tools.ietf.org/html/rfc3986#section-2.2
 | |
|     rfc3986 = "^A-Za-z0-9%-._~!$&'()*+,;=:@/";
 | |
|   }
 | |
|   local sbyte, tohex = string.byte
 | |
|   if jit then
 | |
|     tohex = require'bit'.tohex
 | |
|   else
 | |
|     tohex = function(b) return string.format("%02x", b) end
 | |
|   end
 | |
|   local function percent_encode_char(char)
 | |
|     return "%"..tohex(sbyte(char), 2)
 | |
|   end
 | |
|   uri_encode = function(text, rfc)
 | |
|     if not text then return end
 | |
|     local pattern = PATTERNS[rfc] or PATTERNS.rfc3986
 | |
|     return text:gsub("(["..pattern.."])", percent_encode_char)
 | |
|   end
 | |
| end
 | |
| 
 | |
| 
 | |
| local function is_windows_file_uri(uri)
 | |
|   return uri:match('^file:///[a-zA-Z]:') ~= nil
 | |
| end
 | |
| 
 | |
| local function uri_from_fname(path)
 | |
|   local volume_path, fname = path:match("^([a-zA-Z]:)(.*)")
 | |
|   local is_windows = volume_path ~= nil
 | |
|   if is_windows then
 | |
|     path = volume_path..uri_encode(fname:gsub("\\", "/"))
 | |
|   else
 | |
|     path = uri_encode(path)
 | |
|   end
 | |
|   local uri_parts = {"file://"}
 | |
|   if is_windows then
 | |
|     table.insert(uri_parts, "/")
 | |
|   end
 | |
|   table.insert(uri_parts, path)
 | |
|   return table.concat(uri_parts)
 | |
| end
 | |
| 
 | |
| local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*)://.*'
 | |
| 
 | |
| local function uri_from_bufnr(bufnr)
 | |
|   local fname = vim.api.nvim_buf_get_name(bufnr)
 | |
|   local scheme = fname:match(URI_SCHEME_PATTERN)
 | |
|   if scheme then
 | |
|     return fname
 | |
|   else
 | |
|     return uri_from_fname(fname)
 | |
|   end
 | |
| end
 | |
| 
 | |
| local function uri_to_fname(uri)
 | |
|   local scheme = assert(uri:match(URI_SCHEME_PATTERN), 'URI must contain a scheme: ' .. uri)
 | |
|   if scheme ~= 'file' then
 | |
|     return uri
 | |
|   end
 | |
|   uri = uri_decode(uri)
 | |
|   -- TODO improve this.
 | |
|   if is_windows_file_uri(uri) then
 | |
|     uri = uri:gsub('^file:///', '')
 | |
|     uri = uri:gsub('/', '\\')
 | |
|   else
 | |
|     uri = uri:gsub('^file://', '')
 | |
|   end
 | |
|   return uri
 | |
| end
 | |
| 
 | |
| -- Return or create a buffer for a uri.
 | |
| local function uri_to_bufnr(uri)
 | |
|   local scheme = assert(uri:match(URI_SCHEME_PATTERN), 'URI must contain a scheme: ' .. uri)
 | |
|   if scheme == 'file' then
 | |
|     return vim.fn.bufadd(uri_to_fname(uri))
 | |
|   else
 | |
|     return vim.fn.bufadd(uri)
 | |
|   end
 | |
| end
 | |
| 
 | |
| return {
 | |
|   uri_from_fname = uri_from_fname,
 | |
|   uri_from_bufnr = uri_from_bufnr,
 | |
|   uri_to_fname = uri_to_fname,
 | |
|   uri_to_bufnr = uri_to_bufnr,
 | |
| }
 | |
| -- vim:sw=2 ts=2 et
 |