mirror of
https://github.com/neovim/neovim.git
synced 2026-07-15 13:50:33 +00:00
Some servers register `workspace/didChangeWatchedFiles` watchers for URI schemes that cannot be watched locally. Skipping the unsupported glob and keep the rest of the registration batch active.
This commit is contained in:
@@ -1,11 +1,53 @@
|
||||
local bit = require('bit')
|
||||
local glob = vim.glob
|
||||
local watch = vim._watch
|
||||
local log = require('vim.lsp.log')
|
||||
local protocol = require('vim.lsp.protocol')
|
||||
local lpeg = vim.lpeg
|
||||
|
||||
local M = {}
|
||||
|
||||
-- Use a bounded set to suppress repeat warnings without unbounded growth.
|
||||
---@type table<string, true>
|
||||
local logged_invalid_patterns = {}
|
||||
---@type string[]
|
||||
local logged_invalid_pattern_keys = {}
|
||||
local logged_invalid_pattern_key_index = 1
|
||||
|
||||
---@param key string
|
||||
local function remember_invalid_pattern(key)
|
||||
local old_key = logged_invalid_pattern_keys[logged_invalid_pattern_key_index]
|
||||
if old_key then
|
||||
logged_invalid_patterns[old_key] = nil
|
||||
end
|
||||
logged_invalid_patterns[key] = true
|
||||
logged_invalid_pattern_keys[logged_invalid_pattern_key_index] = key
|
||||
logged_invalid_pattern_key_index = logged_invalid_pattern_key_index % 20 + 1
|
||||
end
|
||||
|
||||
--- Parses a glob pattern and logs invalid patterns once.
|
||||
---@param pattern string
|
||||
---@param client vim.lsp.Client
|
||||
---@return vim.lpeg.Pattern?
|
||||
local function glob_to_lpeg(pattern, client)
|
||||
local ok, pattern_or_err = pcall(glob.to_lpeg, pattern)
|
||||
if ok then
|
||||
return pattern_or_err
|
||||
end
|
||||
local key = string.format('%d:%s', client.id, pattern)
|
||||
if not logged_invalid_patterns[key] then
|
||||
log.error(
|
||||
string.format(
|
||||
'LSP[%s] skipping invalid workspace/didChangeWatchedFiles globPattern',
|
||||
client.name
|
||||
),
|
||||
pattern,
|
||||
pattern_or_err
|
||||
)
|
||||
remember_invalid_pattern(key)
|
||||
end
|
||||
end
|
||||
|
||||
if vim.fn.has('win32') == 1 or vim.fn.has('mac') == 1 then
|
||||
M._watchfunc = watch.watch
|
||||
elseif vim.fn.executable('inotifywait') == 1 then
|
||||
@@ -62,24 +104,22 @@ function M.register(reg, client_id)
|
||||
local glob_pattern = w.globPattern
|
||||
|
||||
if type(glob_pattern) == 'string' then
|
||||
local pattern = glob.to_lpeg(glob_pattern)
|
||||
if not pattern then
|
||||
error('Cannot parse pattern: ' .. glob_pattern)
|
||||
end
|
||||
for _, folder in ipairs(client.workspace_folders) do
|
||||
local base_dir = vim.uri_to_fname(folder.uri)
|
||||
table.insert(watch_regs[base_dir], { pattern = pattern, kind = kind })
|
||||
local pattern = glob_to_lpeg(glob_pattern, client)
|
||||
if pattern then
|
||||
for _, folder in ipairs(client.workspace_folders) do
|
||||
local base_dir = vim.uri_to_fname(folder.uri)
|
||||
table.insert(watch_regs[base_dir], { pattern = pattern, kind = kind })
|
||||
end
|
||||
end
|
||||
else
|
||||
local base_uri = glob_pattern.baseUri
|
||||
local uri = type(base_uri) == 'string' and base_uri or base_uri.uri
|
||||
local base_dir = vim.uri_to_fname(uri)
|
||||
local pattern = glob.to_lpeg(glob_pattern.pattern)
|
||||
if not pattern then
|
||||
error('Cannot parse pattern: ' .. glob_pattern.pattern)
|
||||
local pattern = glob_to_lpeg(glob_pattern.pattern, client)
|
||||
if pattern then
|
||||
local relative_pattern = lpeg.P(base_dir .. '/') * pattern --[[@as vim.lpeg.Pattern]]
|
||||
table.insert(watch_regs[base_dir], { pattern = relative_pattern, kind = kind })
|
||||
end
|
||||
pattern = lpeg.P(base_dir .. '/') * pattern
|
||||
table.insert(watch_regs[base_dir], { pattern = pattern, kind = kind })
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user