mirror of
https://github.com/neovim/neovim.git
synced 2026-08-25 08:31:51 +00:00
feat(vim.fs): slug() supports URI #41241
Problem: `vim.fs.slug()` does not handle URIs like `term://foo//123:bash`, so callers (e.g. terminal persistence) must strip the scheme before calling `slug()`. Solution: Detect `scheme://` from the raw input before `normalize()` and replace it with a `=uri-<scheme>-` prefix.
This commit is contained in:
@@ -2958,6 +2958,7 @@ vim.fs.slug({path}, {opts}) *vim.fs.slug()*
|
||||
• A hash of the normalized input is appended to prevent collisions.
|
||||
• Unsafe chars are replaced with "-".
|
||||
• `$HOME` is replaced with "~".
|
||||
• URIs (`scheme://...`) are prefixed with "=uri-{scheme}-".
|
||||
• UNC paths (Windows) are prefixed with "=unc-".
|
||||
• If `opts.maxlen` is exceeded, the result will be truncated to
|
||||
`{head}~~~{tail}-{hash8}`.
|
||||
@@ -2969,6 +2970,7 @@ vim.fs.slug({path}, {opts}) *vim.fs.slug()*
|
||||
vim.print(vim.fs.slug('C:/src/project/main.c')) --> "C--src-project-main.c-{hash}"
|
||||
vim.print(vim.fs.slug(vim.fn.expand('~/file.txt'))) --> "~-file.txt-{hash}"
|
||||
vim.print(vim.fs.slug('---')) --> "=special-{hash}"
|
||||
vim.print(vim.fs.slug('term://foo/bar//123:bash')) --> "=uri-term-foo-bar-123-bash-{hash}"
|
||||
vim.print(vim.fs.slug(('/a/very/long/path'):rep(10) .. '/file.txt', { maxlen = 60 }))
|
||||
--> "a-very-long-~~~-path-a-very-long-path-file.txt-{hash}"
|
||||
<
|
||||
|
||||
@@ -154,6 +154,7 @@ end
|
||||
--- - A hash of the normalized input is appended to prevent collisions.
|
||||
--- - Unsafe chars are replaced with "-".
|
||||
--- - `$HOME` is replaced with "~".
|
||||
--- - URIs (`scheme://...`) are prefixed with "=uri-{scheme}-".
|
||||
--- - UNC paths (Windows) are prefixed with "=unc-".
|
||||
--- - If `opts.maxlen` is exceeded, the result will be truncated to `{head}~~~{tail}-{hash8}`.
|
||||
--- - If the sanitized name is empty, the reserved label `=special` will be used.
|
||||
@@ -165,6 +166,7 @@ end
|
||||
--- vim.print(vim.fs.slug('C:/src/project/main.c')) --> "C--src-project-main.c-{hash}"
|
||||
--- vim.print(vim.fs.slug(vim.fn.expand('~/file.txt'))) --> "~-file.txt-{hash}"
|
||||
--- vim.print(vim.fs.slug('---')) --> "=special-{hash}"
|
||||
--- vim.print(vim.fs.slug('term://foo/bar//123:bash')) --> "=uri-term-foo-bar-123-bash-{hash}"
|
||||
--- vim.print(vim.fs.slug(('/a/very/long/path'):rep(10) .. '/file.txt', { maxlen = 60 }))
|
||||
--- --> "a-very-long-~~~-path-a-very-long-path-file.txt-{hash}"
|
||||
--- ```
|
||||
@@ -182,13 +184,19 @@ function M.slug(path, opts)
|
||||
end, true, '`opts.maxlen` must be >= 8')
|
||||
local maxlen = opts.maxlen or 180
|
||||
|
||||
-- Capture URI scheme before normalize() collapses "://" to ":/" (which looks like "C:/")
|
||||
local uri_scheme = path:match('^([a-zA-Z][a-zA-Z0-9.+-]*)://') ---@type string?
|
||||
|
||||
-- Normalize before computing the hash so equivalent paths produce the same result
|
||||
path = vim.fs.normalize(path, { plain = true })
|
||||
local s = path
|
||||
|
||||
-- Replace $HOME with `~`
|
||||
-- `fnamemodify` resolves relative paths against CWD, so only call it on absolute paths
|
||||
if vim.startswith(s, '/') or (iswin and s:match('^%w:/')) then
|
||||
if uri_scheme then
|
||||
-- Replace scheme prefix with "=uri-{scheme}-"
|
||||
s = '=uri-' .. uri_scheme .. '-' .. s:sub(#uri_scheme + 3) -- `+ 3` skips`:/`
|
||||
elseif vim.startswith(s, '/') or (iswin and s:match('^%w:/')) then
|
||||
-- Replace $HOME with `~`
|
||||
-- `fnamemodify` resolves relative paths against CWD, so only call it on absolute paths
|
||||
s = vim.fn.fnamemodify(s, ':~')
|
||||
end
|
||||
|
||||
|
||||
@@ -694,6 +694,10 @@ describe('vim.fs', function()
|
||||
eq('aux-321f6814', vim.fs.slug('aux'))
|
||||
eq('con.foo.bar-f386c405', vim.fs.slug('con.foo.bar'))
|
||||
eq('con-.-txt-48f98581', vim.fs.slug('con . txt'))
|
||||
-- URIs are prefixed with `=uri-<scheme>-`.
|
||||
eq('=uri-term-foo-bar-123-bash-7fd6bb99', vim.fs.slug('term://foo/bar//123:bash'))
|
||||
eq('=uri-http-example.com-2e152ec0', vim.fs.slug('http://example.com'))
|
||||
eq('=uri-scp-host-path-5188b9a2', vim.fs.slug('scp://host/path'))
|
||||
-- $HOME is replaced with `~`
|
||||
local p = vim.uv.os_homedir() .. '/my-project'
|
||||
local hash8_2 = vim.fn.sha256(vim.fs.normalize(p)):sub(1, 8)
|
||||
|
||||
Reference in New Issue
Block a user