Skip to content

mini.files: Windows C:// internal paths break LSP file operation filters #2472

Description

@so1ve

Module

mini.files

Description

On Windows, mini.files appears to use C://... as an internal normalized path form. That can be useful internally, but the same path currently reaches the LSP file-operation flow and breaks per-client file-operation filtering.

In the current implementation, rename actions eventually call vim.uri_from_fname(d.from) / vim.uri_from_fname(d.to) inside the LSP hook. If d.from / d.to are Windows paths in mini.files' internal C://Users/... form, Neovim produces URIs like file:///C://Users/....

Later, mini.files applies each client's workspace.fileOperations.*.filters by converting the URI back with vim.uri_to_fname(...):gsub('\\', '/'). On Windows this remains C://Users/..., which does not match lua_ls' normal filter glob such as C:/Users/Miku/AppData/Local/nvim/**.

As a result, mini.files sends workspace/didRenameFiles with files = {}. lua_ls receives an empty rename list, so its require-path update logic exits early and the expected "Do you want to modify the require path?" prompt never appears.

Minimal reproduction / evidence

Environment:

  • Windows
  • Neovim 0.12.3
  • mini.nvim main at 1345d191bb3da9c7b0e977f4387c5761f9bff68d
  • lua-language-server attached to a Lua project rooted at C:/Users/Miku/AppData/Local/nvim

Observed from MiniFilesActionRename event data:

from = "C://Users/Miku/AppData/Local/nvim/lua/ray/utils/windows.lua"
to = "C://Users/Miku/AppData/Local/nvim/lua/ray/utils/jindows.lua"

Local checks inside Neovim:

local p = "C://Users/Miku/AppData/Local/nvim/lua/ray/utils/windows.lua"
print(vim.fs.normalize(p))
-- C:/Users/Miku/AppData/Local/nvim/lua/ray/utils/windows.lua

print(vim.uri_from_fname(p))
-- file:///C://Users/Miku/AppData/Local/nvim/lua/ray/utils/windows.lua

print((vim.uri_to_fname(vim.uri_from_fname(p)):gsub('\\', '/')))
-- C://Users/Miku/AppData/Local/nvim/lua/ray/utils/windows.lua

Filter match check:

local glob = "C:/Users/Miku/AppData/Local/nvim/**"
local lp = vim.glob.to_lpeg(glob)

print(lp:match("C:/Users/Miku/AppData/Local/nvim/lua/ray/utils/windows.lua") ~= nil)
-- true

print(lp:match("C://Users/Miku/AppData/Local/nvim/lua/ray/utils/windows.lua") ~= nil)
-- false

A control workaround using normalized paths triggers lua_ls correctly:

Snacks.rename.on_rename_file(vim.fs.normalize(event.data.from), vim.fs.normalize(event.data.to))

That causes lua_ls to show the expected Modify Require Path prompt.

Expected behavior

mini.files may keep C://... internally if needed, but paths should be normalized/canonicalized before crossing the LSP boundary. In particular, LSP URI construction and file-operation filter matching should use canonical Windows paths like C:/Users/..., not mini.files' internal C://Users/... representation.

Related context

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions