diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 938e2df3b0..d47d4f6ded 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1038,7 +1038,7 @@ enable({name}, {enable}) *vim.lsp.enable()* config to activate: >lua vim.lsp.config('lua_ls', { root_dir = function(bufnr, on_dir) - if not vim.fn.bufname(bufnr):match('%.txt$') then + if vim.fs.ext(vim.fn.bufname(bufnr)) ~= 'txt' then on_dir(vim.fn.getcwd()) end end diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index d5ce2c2209..5ae83df462 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -2537,6 +2537,28 @@ vim.fs.dirname({file}) *vim.fs.dirname()* Return: ~ (`string?`) Parent directory of {file} +vim.fs.ext({file}, {opts}) *vim.fs.ext()* + Return the file's last extension, if any. + + Similar to |fnamemodify()| with the |::e| modifier. The extension does not + include a leading period. + + Examples: >lua + vim.fs.ext('archive.tar.gz') -- 'gz' + vim.fs.ext('~/.git') -- '' + vim.fs.ext('plugin/myplug.lua') -- 'lua' +< + + Attributes: ~ + Since: 0.12.0 + + Parameters: ~ + • {file} (`string`) Path + • {opts} (`table?`) Reserved for future use + + Return: ~ + (`string`) Extension of {file} + vim.fs.find({names}, {opts}) *vim.fs.find()* Find files or directories (or other items as specified by `opts.type`) in the given path. @@ -2744,7 +2766,7 @@ vim.fs.root({source}, {marker}) *vim.fs.root()* -- Find the parent directory containing any file with a .csproj extension vim.fs.root(0, function(name, path) - return name:match('%.csproj$') ~= nil + return vim.fs.ext(name) == 'csproj' end) -- Find the first ancestor directory containing EITHER "stylua.toml" or ".luarc.json"; if diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index bf0363d4a4..1f8cd421d7 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -354,6 +354,7 @@ LUA • |vim.json.encode()| has an `sort_keys` option. • |Range:is_empty()| to check if a |vim.Range| is empty. • |vim.json.decode()| has an `skip_comments` option. +• |vim.fs.ext()| returns the last extension of a file. OPTIONS diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 7eadf8cb78..41e08eeeb2 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -409,7 +409,7 @@ end --- --- -- Find the parent directory containing any file with a .csproj extension --- vim.fs.root(0, function(name, path) ---- return name:match('%.csproj$') ~= nil +--- return vim.fs.ext(name) == 'csproj' --- end) --- --- -- Find the first ancestor directory containing EITHER "stylua.toml" or ".luarc.json"; if @@ -835,4 +835,27 @@ function M.relpath(base, target, opts) return vim.startswith(target, base) and target:sub(#base + 1) or nil end +--- Return the file's last extension, if any. +--- +--- Similar to |fnamemodify()| with the |::e| modifier. The extension does not include a leading +--- period. +--- +--- Examples: +--- +--- ```lua +--- vim.fs.ext('archive.tar.gz') -- 'gz' +--- vim.fs.ext('~/.git') -- '' +--- vim.fs.ext('plugin/myplug.lua') -- 'lua' +--- ``` +--- +---@since 14 +---@param file string Path +---@param opts table? Reserved for future use +---@return string Extension of {file} +function M.ext(file, opts) + vim.validate('file', file, 'string') + vim.validate('opts', opts, 'table', true) + return vim.fn.fnamemodify(file, ':e') +end + return M diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua index e22e72c589..d8f9eb156c 100644 --- a/runtime/lua/vim/health.lua +++ b/runtime/lua/vim/health.lua @@ -311,7 +311,7 @@ function M.error(msg, ...) end local path2name = function(path) - if path:match('%.lua$') then + if vim.fs.ext(path) == 'lua' then -- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp" -- Get full path, make sure all slashes are '/' diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 3b6f4b4ee2..30ce7eabd8 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -585,7 +585,7 @@ end --- ```lua --- vim.lsp.config('lua_ls', { --- root_dir = function(bufnr, on_dir) ---- if not vim.fn.bufname(bufnr):match('%.txt$') then +--- if vim.fs.ext(vim.fn.bufname(bufnr)) ~= 'txt' then --- on_dir(vim.fn.getcwd()) --- end --- end diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 4d93ce053b..de6e9f1350 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -753,4 +753,10 @@ describe('vim.fs', function() assert_rm_symlinked_dir({ recursive = true, force = true }) end) end) + + describe('ext()', function() + it('works', function() + -- See test/functional/vimscript/fnamemodify_spec.lua + end) + end) end)