mirror of
https://github.com/neovim/neovim.git
synced 2026-09-08 23:18:59 +00:00
Problem: LuaLS struggles with the generics used in Nvim's runtime, requiring broad diagnostic suppressions. Indexing is also slow. Solution: Use EmmyLua for type checks in the build and CI. It offers more sophisticated type checking, substantially better support for generics, and much better flow analysis. Correct the affected annotations. Use `@internal`, supported directly by EmmyLua, instead of `@nodoc` for shared internal declarations, and support it in the help parser. AI-assisted
82 lines
2.5 KiB
Lua
82 lines
2.5 KiB
Lua
if vim.g.loaded_shada_plugin then
|
|
return
|
|
end
|
|
vim.g.loaded_shada_plugin = 1
|
|
|
|
local augroup = vim.api.nvim_create_augroup('nvim.shada', {})
|
|
|
|
---@type fun(binstrings: string[]): string[]
|
|
local shada_get_strings = vim.fn['shada#get_strings']
|
|
|
|
---@type fun(strings: string[]): string[]
|
|
local shada_get_binstrings = vim.fn['shada#get_binstrings']
|
|
|
|
---Ensures that pattern and augroup are set correctly.
|
|
---@param event string|string[]
|
|
---@param opts vim.api.keyset.create_autocmd
|
|
---@param fn fun(args: vim.api.keyset.create_autocmd.callback_args): boolean?
|
|
local function def_autocmd(event, opts, fn)
|
|
opts = opts or {}
|
|
opts.group = augroup
|
|
opts.pattern = { '*.shada', '*.shada.tmp.[a-z]' }
|
|
opts.callback = function(ev)
|
|
if vim.v.cmdarg ~= '' then
|
|
error('++opt not supported')
|
|
end
|
|
fn(ev)
|
|
end
|
|
vim.api.nvim_create_autocmd(event, opts)
|
|
end
|
|
|
|
---Read shada strings from file.
|
|
---@param file string Filename
|
|
---@return string[] # lines from shada file
|
|
local function read_strings(file)
|
|
local f = assert(io.open(file, 'rb'))
|
|
local strings = f:read('*a')
|
|
f:close()
|
|
return shada_get_strings(strings)
|
|
end
|
|
|
|
def_autocmd('BufReadCmd', {}, function(ev)
|
|
local lines = read_strings(ev.file)
|
|
vim.api.nvim_buf_set_lines(ev.buf, 0, -1, false, lines)
|
|
vim.bo[ev.buf].filetype = 'shada'
|
|
end)
|
|
|
|
def_autocmd('FileReadCmd', {}, function(ev)
|
|
local lines = read_strings(ev.file)
|
|
local lnum = vim.fn.line("'[")
|
|
vim.api.nvim_buf_set_lines(ev.buf, lnum, lnum, true, lines)
|
|
end)
|
|
|
|
def_autocmd('BufWriteCmd', {}, function(ev)
|
|
local buflines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
|
local ret = vim.fn.writefile(shada_get_binstrings(buflines), ev.file, 'b')
|
|
if ret == 0 then
|
|
-- To check that we are not saving into a different file, we must compare ev.match (always an
|
|
-- absolute path), and not ev.file (can be relative), against nvim_buf_get_name() (always
|
|
-- returns an absolute path).
|
|
if ev.match == vim.api.nvim_buf_get_name(ev.buf) or vim.o.cpoptions:find('%+') then
|
|
vim.bo[ev.buf].modified = false
|
|
end
|
|
end
|
|
end)
|
|
|
|
def_autocmd({ 'FileWriteCmd', 'FileAppendCmd' }, {}, function(ev)
|
|
vim.fn.writefile(
|
|
shada_get_binstrings(
|
|
vim.fn.getline(
|
|
math.min(vim.fn.line("'["), vim.fn.line("']")),
|
|
math.max(vim.fn.line("'["), vim.fn.line("']"))
|
|
) --[=[@as string[] ]=]
|
|
),
|
|
ev.file,
|
|
ev.event == 'FileAppendCmd' and 'ab' or 'b'
|
|
)
|
|
end)
|
|
|
|
def_autocmd('SourceCmd', {}, function(ev)
|
|
vim.cmd.rshada(vim.fn.fnameescape(ev.file))
|
|
end)
|