From c7f5f44b6091f99ad85db039653b84fb096bc879 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 14 May 2026 13:02:36 -0400 Subject: [PATCH] refactor(vim.fs): deduplicate by using vim.fn #39782 Problem: 61e99217e684 replaced usages of `vim.fn`. This duplicates non-trivial logic and may have introduced bugs like 38e38d1b401e. Later on, b02eeb6a7281 graduated `fnamemodify` to `fast`, so avoiding it in `vim.fs` is no longer necessary. Solution: Use `vim.fn` to deduplicate `vim.fs.dirname()` and `vim.fs.basename()`. Note: the "nvim -l" test-runner switch from the original PR (#30483) is already done by 9432e6c1e2e9 (#39676). --- runtime/doc/lua.txt | 4 ++-- runtime/lua/vim/fs.lua | 32 ++++++++------------------------ 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 41397a9525..f8f0eef74d 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -2604,7 +2604,7 @@ vim.fs.basename({file}) *vim.fs.basename()* • {file} (`string?`) Path Return: ~ - (`string?`) Basename of {file} + (`string?`) Basename of `file` vim.fs.dir({path}, {opts}) *vim.fs.dir()* Gets an iterator over items found in `path` (normalized via @@ -2642,7 +2642,7 @@ vim.fs.dirname({file}) *vim.fs.dirname()* • {file} (`string?`) Path Return: ~ - (`string?`) Parent directory of {file} + (`string?`) Parent directory of `file` vim.fs.ext({file}, {opts}) *vim.fs.ext()* Return the file's last extension, if any. diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index bfb767f9c2..127025ef72 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -44,9 +44,7 @@ local uv = vim.uv local M = {} --- Can't use `has('win32')` because the `nvim -ll` test runner doesn't support `vim.fn` yet. -local sysname = uv.os_uname().sysname:lower() -local iswin = not not (sysname:find('windows') or sysname:find('mingw')) +local iswin = vim.fn.has('win32') == 1 local os_sep = iswin and '\\' or '/' --- Iterate over all the parents of the given path (not expanded/resolved, the caller must do that). @@ -90,27 +88,15 @@ end ---@since 10 ---@generic T : string|nil ---@param file T Path ----@return T Parent directory of {file} +---@return T # Parent directory of `file` function M.dirname(file) if file == nil then return nil end vim.validate('file', file, 'string') + local dir = vim.fn.fnamemodify(file, ':h') if iswin then - file = file:gsub(os_sep, '/') --[[@as string]] - if file:match('^%w:/?$') then - return file - end - end - if not file:match('/') then - return '.' - elseif file == '/' or file:match('^/[^/]+$') then - return '/' - end - ---@type string - local dir = file:match('/$') and file:sub(1, #file - 1) or file:match('^(/?.+)/') - if iswin and dir:match('^%w:$') then - return dir .. '/' + return (dir:gsub(os_sep, '/')) end return dir end @@ -120,19 +106,17 @@ end ---@since 10 ---@generic T : string|nil ---@param file T Path ----@return T Basename of {file} +---@return T # Basename of `file` function M.basename(file) if file == nil then return nil end vim.validate('file', file, 'string') + local name = vim.fn.fnamemodify(file, ':t') if iswin then - file = file:gsub(os_sep, '/') --[[@as string]] - if file:match('^%w:/?$') then - return '' - end + return (name:gsub(os_sep, '/')) end - return file:match('/$') and '' or (file:match('[^/]*$')) + return name end --- Concatenates partial paths (one absolute or relative path followed by zero or more relative