mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
Merge 0129148b9c
into 15bfdf73ea
This commit is contained in:
commit
5840d7cb39
@ -38,7 +38,7 @@ local M = {}
|
||||
--- @field refs integer how many clients are using this group
|
||||
---
|
||||
--- @class vim.lsp.CTGroupState
|
||||
--- @field buffers table<integer,vim.lsp.CTBufferState>
|
||||
--- @field buffers vim.Buflocal
|
||||
--- @field debounce integer debounce duration in ms
|
||||
--- @field clients table<integer, table> clients using this state. {client_id, client}
|
||||
|
||||
@ -138,7 +138,20 @@ function M.init(client, bufnr)
|
||||
state.clients[client.id] = client
|
||||
else
|
||||
state = {
|
||||
buffers = {},
|
||||
buffers = vim.buflocal(function(b)
|
||||
local bufstate = {
|
||||
name = api.nvim_buf_get_name(b),
|
||||
lines = {},
|
||||
lines_tmp = {},
|
||||
pending_changes = {},
|
||||
needs_flush = false,
|
||||
refs = 0,
|
||||
}
|
||||
if group.sync_kind == protocol.TextDocumentSyncKind.Incremental then
|
||||
bufstate.lines = api.nvim_buf_get_lines(b, 0, -1, true)
|
||||
end
|
||||
return bufstate
|
||||
end),
|
||||
debounce = client.flags.debounce_text_changes or 150,
|
||||
clients = {
|
||||
[client.id] = client,
|
||||
@ -146,23 +159,8 @@ function M.init(client, bufnr)
|
||||
}
|
||||
state_by_group[group] = state
|
||||
end
|
||||
local buf_state = state.buffers[bufnr]
|
||||
if buf_state then
|
||||
buf_state.refs = buf_state.refs + 1
|
||||
else
|
||||
buf_state = {
|
||||
name = api.nvim_buf_get_name(bufnr),
|
||||
lines = {},
|
||||
lines_tmp = {},
|
||||
pending_changes = {},
|
||||
needs_flush = false,
|
||||
refs = 1,
|
||||
}
|
||||
state.buffers[bufnr] = buf_state
|
||||
if group.sync_kind == protocol.TextDocumentSyncKind.Incremental then
|
||||
buf_state.lines = api.nvim_buf_get_lines(bufnr, 0, -1, true)
|
||||
end
|
||||
end
|
||||
local buf_state = state.buffers:get(bufnr)
|
||||
buf_state.refs = buf_state.refs + 1
|
||||
end
|
||||
|
||||
--- @param client vim.lsp.Client
|
||||
@ -171,7 +169,7 @@ end
|
||||
--- @return string
|
||||
function M._get_and_set_name(client, bufnr, name)
|
||||
local state = state_by_group[get_group(client)] or {}
|
||||
local buf_state = (state.buffers or {})[bufnr]
|
||||
local buf_state = state.buffers:get(bufnr)
|
||||
local old_name = buf_state.name
|
||||
buf_state.name = name
|
||||
return old_name
|
||||
@ -198,11 +196,11 @@ function M.reset_buf(client, bufnr)
|
||||
return
|
||||
end
|
||||
assert(state.buffers, 'CTGroupState must have buffers')
|
||||
local buf_state = state.buffers[bufnr]
|
||||
local buf_state = state.buffers:get(bufnr)
|
||||
buf_state.refs = buf_state.refs - 1
|
||||
assert(buf_state.refs >= 0, 'refcount on buffer state must not get negative')
|
||||
if buf_state.refs == 0 then
|
||||
state.buffers[bufnr] = nil
|
||||
state.buffers:clear(bufnr)
|
||||
reset_timer(buf_state)
|
||||
end
|
||||
end
|
||||
@ -215,10 +213,10 @@ function M.reset(client)
|
||||
end
|
||||
state.clients[client.id] = nil
|
||||
if vim.tbl_count(state.clients) == 0 then
|
||||
for _, buf_state in pairs(state.buffers) do
|
||||
for _, buf_state in state.buffers:pairs() do
|
||||
reset_timer(buf_state)
|
||||
end
|
||||
state.buffers = {}
|
||||
state.buffers:clear()
|
||||
end
|
||||
end
|
||||
|
||||
@ -301,7 +299,7 @@ local function send_changes_for_group(bufnr, firstline, lastline, new_lastline,
|
||||
)
|
||||
)
|
||||
end
|
||||
local buf_state = state.buffers[bufnr]
|
||||
local buf_state = state.buffers:get(bufnr)
|
||||
buf_state.needs_flush = true
|
||||
reset_timer(buf_state)
|
||||
local debounce = next_debounce(state.debounce, buf_state)
|
||||
@ -359,11 +357,11 @@ function M.flush(client, bufnr)
|
||||
return
|
||||
end
|
||||
if bufnr then
|
||||
local buf_state = state.buffers[bufnr] or {}
|
||||
local buf_state = state.buffers:get(bufnr)
|
||||
reset_timer(buf_state)
|
||||
send_changes(bufnr, group.sync_kind, state, buf_state)
|
||||
else
|
||||
for buf, buf_state in pairs(state.buffers) do
|
||||
for buf, buf_state in state.buffers:pairs() do
|
||||
reset_timer(buf_state)
|
||||
send_changes(buf, group.sync_kind, state, buf_state)
|
||||
end
|
||||
|
@ -1137,6 +1137,73 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
---@class vim.Buflocal<T>
|
||||
---@field private _values table<integer, any>
|
||||
---@field private _default any|fun(b: integer):any
|
||||
|
||||
---@class vim.Buflocal<T>
|
||||
local Buflocal = {}
|
||||
|
||||
local buflocal_mt = {
|
||||
__index = Buflocal,
|
||||
}
|
||||
|
||||
---@generic T : any
|
||||
---@param bufnr integer
|
||||
---@return T
|
||||
function Buflocal:get(bufnr)
|
||||
bufnr = assert(bufnr) == 0 and vim.api.nvim_get_current_buf() or bufnr
|
||||
local value = self._values[bufnr]
|
||||
if not value then
|
||||
if type(self._default) == "function" then
|
||||
value = self._default(bufnr)
|
||||
else
|
||||
value = self._default or {}
|
||||
end
|
||||
self._values[bufnr] = value
|
||||
vim.api.nvim_buf_attach(bufnr, false, {
|
||||
on_detach = function(_, b)
|
||||
self._values[b] = nil
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd("BufWipeout", {
|
||||
buffer = bufnr,
|
||||
callback = function(args)
|
||||
self._values[args.buf] = nil
|
||||
end
|
||||
})
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function Buflocal:pairs()
|
||||
return pairs(self._values)
|
||||
end
|
||||
|
||||
---@param bufnr integer?
|
||||
function Buflocal:clear(bufnr)
|
||||
if bufnr == nil then
|
||||
self._values = {}
|
||||
else
|
||||
self._values[bufnr == 0 and vim.api.nvim_get_current_buf() or bufnr] = nil
|
||||
end
|
||||
end
|
||||
|
||||
---@generic T
|
||||
---@param default? T|fun(b: integer):T
|
||||
---@return vim.Buflocal
|
||||
function vim.buflocal(default)
|
||||
local state = {
|
||||
_values = {},
|
||||
_default = default,
|
||||
}
|
||||
return setmetatable(state, buflocal_mt)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- @private
|
||||
--- @generic T
|
||||
--- @param root string
|
||||
|
@ -3977,6 +3977,38 @@ describe('lua stdlib', function()
|
||||
}
|
||||
eq(expected, results)
|
||||
end)
|
||||
|
||||
it("vim.buflocal", function()
|
||||
local result = exec_lua([[
|
||||
local buflocal = vim.buflocal()
|
||||
local buf1 = vim.api.nvim_create_buf(true, true)
|
||||
local buf2 = vim.api.nvim_create_buf(true, true)
|
||||
|
||||
local state1 = buflocal:get(buf1)
|
||||
state1.x = 10
|
||||
|
||||
local state2 = buflocal:get(buf2)
|
||||
state2.x = 20
|
||||
|
||||
local results = {}
|
||||
results.values = {}
|
||||
results.x1 = buflocal:get(buf1).x
|
||||
results.x2 = buflocal:get(buf2).x
|
||||
|
||||
for _, value in buflocal:pairs() do
|
||||
table.insert(results.values, value)
|
||||
end
|
||||
|
||||
vim.api.nvim_buf_delete(buf1, { force = true })
|
||||
local ok, err = pcall(buflocal.get, buflocal, buf1)
|
||||
results.deleted_buf = {ok, err}
|
||||
return results
|
||||
]])
|
||||
eq(10, result.x1)
|
||||
eq(20, result.x2)
|
||||
eq(false, result.deleted_buf[1])
|
||||
eq(true, vim.startswith(result.deleted_buf[2], "vim/shared.lua:0: Invalid buffer id: "))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('lua: builtin modules', function()
|
||||
|
Loading…
Reference in New Issue
Block a user