diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 22:40:31 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 22:40:31 +0000 |
commit | 339e2d15cc26fe86988ea06468d912a46c8d6f29 (patch) | |
tree | a6167fc8fcfc6ae2dc102f57b2473858eac34063 /runtime/lua/vim/uri.lua | |
parent | 067dc73729267c0262438a6fdd66e586f8496946 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.gz rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.bz2 rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.zip |
Merge remote-tracking branch 'upstream/master' into fix_repeatcmdline
Diffstat (limited to 'runtime/lua/vim/uri.lua')
-rw-r--r-- | runtime/lua/vim/uri.lua | 145 |
1 files changed, 67 insertions, 78 deletions
diff --git a/runtime/lua/vim/uri.lua b/runtime/lua/vim/uri.lua index d6b0b7410e..2dc817c5c1 100644 --- a/runtime/lua/vim/uri.lua +++ b/runtime/lua/vim/uri.lua @@ -1,72 +1,71 @@ ---- TODO: This is implemented only for files now. +---TODO: This is implemented only for files currently. -- 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 M = {} +local sbyte = string.byte +local schar = string.char +local tohex = require('bit').tohex +local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9.+-]*):.*' +local WINDOWS_URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9.+-]*):[a-zA-Z]:.*' +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%-._~!$&'()*+,;=:@/", +} - --- Convert hex to char - ---@private - 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 +---Converts hex to char +---@param hex string +---@return string +local function hex_to_char(hex) + return schar(tonumber(hex, 16)) 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 - - ---@private - 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 +---@param char string +---@return string +local function percent_encode_char(char) + return '%' .. tohex(sbyte(char), 2) end ----@private +---@param uri string +---@return boolean local function is_windows_file_uri(uri) return uri:match('^file:/+[a-zA-Z]:') ~= nil end ---- Get a URI from a file path. +---URI-encodes a string using percent escapes. +---@param str string string to encode +---@param rfc "rfc2396" | "rfc2732" | "rfc3986" | nil +---@return string encoded string +function M.uri_encode(str, rfc) + local pattern = PATTERNS[rfc] or PATTERNS.rfc3986 + return (str:gsub('([' .. pattern .. '])', percent_encode_char)) -- clamped to 1 retval with () +end + +---URI-decodes a string containing percent escapes. +---@param str string string to decode +---@return string decoded string +function M.uri_decode(str) + return (str:gsub('%%([a-fA-F0-9][a-fA-F0-9])', hex_to_char)) -- clamped to 1 retval with () +end + +---Gets a URI from a file path. ---@param path string Path to file ---@return string URI -local function uri_from_fname(path) - local volume_path, fname = path:match('^([a-zA-Z]:)(.*)') +function M.uri_from_fname(path) + local volume_path, fname = path:match('^([a-zA-Z]:)(.*)') ---@type string? local is_windows = volume_path ~= nil if is_windows then - path = volume_path .. uri_encode(fname:gsub('\\', '/')) + path = volume_path .. M.uri_encode(fname:gsub('\\', '/')) else - path = uri_encode(path) + path = M.uri_encode(path) end local uri_parts = { 'file://' } if is_windows then @@ -76,17 +75,14 @@ local function uri_from_fname(path) return table.concat(uri_parts) end -local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9.+-]*):.*' -local WINDOWS_URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9.+-]*):[a-zA-Z]:.*' - ---- Get a URI from a bufnr ----@param bufnr number +---Gets a URI from a bufnr. +---@param bufnr integer ---@return string URI -local function uri_from_bufnr(bufnr) +function M.uri_from_bufnr(bufnr) local fname = vim.api.nvim_buf_get_name(bufnr) local volume_path = fname:match('^([a-zA-Z]:).*') local is_windows = volume_path ~= nil - local scheme + local scheme ---@type string? if is_windows then fname = fname:gsub('\\', '/') scheme = fname:match(WINDOWS_URI_SCHEME_PATTERN) @@ -96,42 +92,35 @@ local function uri_from_bufnr(bufnr) if scheme then return fname else - return uri_from_fname(fname) + return M.uri_from_fname(fname) end end ---- Get a filename from a URI +---Gets a filename from a URI. ---@param uri string ---@return string filename or unchanged URI for non-file URIs -local function uri_to_fname(uri) +function M.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. + uri = M.uri_decode(uri) + --TODO improve this. if is_windows_file_uri(uri) then - uri = uri:gsub('^file:/+', '') - uri = uri:gsub('/', '\\') + uri = uri:gsub('^file:/+', ''):gsub('/', '\\') else - uri = uri:gsub('^file:/+', '/') + uri = uri:gsub('^file:/+', '/') ---@type string end return uri end ---- Get the buffer for a uri. ---- Creates a new unloaded buffer if no buffer for the uri already exists. +---Gets the buffer for a uri. +---Creates a new unloaded buffer if no buffer for the uri already exists. -- ---@param uri string ----@return number bufnr -local function uri_to_bufnr(uri) - return vim.fn.bufadd(uri_to_fname(uri)) +---@return integer bufnr +function M.uri_to_bufnr(uri) + return vim.fn.bufadd(M.uri_to_fname(uri)) 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 +return M |