Merge #24504 feat(lsp): protocol.Methods

This commit is contained in:
Justin M. Keyes
2023-08-01 07:36:57 -07:00
committed by GitHub
6 changed files with 419 additions and 75 deletions

View File

@@ -1,9 +1,10 @@
--[[
Generates lua-ls annotations for lsp
USAGE:
nvim -l scripts/lsp_types.lua gen # this will overwrite runtime/lua/vim/lsp/types/protocol.lua
nvim -l scripts/lsp_types.lua gen --build/new_lsp_types.lua
nvim -l scripts/lsp_types.lua gen --out runtime/lua/vim/lsp/types/protocol.lua --ref 2023.0.0a2 # specify a git reference from microsoft/lsprotocol
nvim -l scripts/gen_lsp.lua gen # this will overwrite runtime/lua/vim/lsp/types/protocol.lua
nvim -l scripts/gen_lsp.lua gen --version 3.18 --build/new_lsp_types.lua
nvim -l scripts/gen_lsp.lua gen --version 3.18 --out runtime/lua/vim/lsp/types/protocol.lua
nvim -l scripts/gen_lsp.lua gen --version 3.18 --methods
--]]
local M = {}
@@ -18,24 +19,96 @@ local function tofile(fname, text)
end
end
function M.gen(opt)
if vim.uv.fs_stat('./lsp.json') then
vim.fn.delete('./lsp.json')
local function read_json(opt)
local uri = 'https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/lsp/'
.. opt.version
.. '/metaModel/metaModel.json'
local res = vim.system({ 'curl', '--no-progress-meter', uri, '-o', '-' }):wait()
if res.code ~= 0 or (res.stdout or ''):len() < 999 then
print(('URL failed: %s'):format(uri))
vim.print(res)
error(res.stdout)
end
vim.fn.system({
'curl',
'https://raw.githubusercontent.com/microsoft/lsprotocol/' .. opt.ref .. '/generator/lsp.json',
'-o',
'./lsp.json',
return vim.json.decode(res.stdout)
end
-- Gets the Lua symbol for a given fully-qualified LSP method name.
local function name(s)
return s:gsub('/', '_', 3)
end
local function gen_methods(protocol)
local output = {
'-- Generated by gen_lsp.lua, keep at end of file.',
'--- LSP method names.',
'---',
'---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#metaModel',
'protocol.Methods = {',
}
local indent = (' '):rep(2)
table.sort(protocol.requests, function(a, b)
return name(a.method) < name(b.method)
end)
for _, item in ipairs(protocol.requests) do
if item.method then
if item.documentation then
local document = vim.split(item.documentation, '\n?\n', { trimempty = true })
for _, docstring in ipairs(document) do
output[#output + 1] = indent .. '--- ' .. docstring
end
end
output[#output + 1] = ("%s%s = '%s',"):format(indent, name(item.method), item.method)
end
end
output[#output + 1] = '}'
output = vim.list_extend(
output,
vim.split(
[[
local function freeze(t)
return setmetatable({}, {
__index = t,
__newindex = function()
error('cannot modify immutable table')
end,
})
local protocol = vim.fn.json_decode(vim.fn.readfile('./lsp.json'))
vim.fn.delete('./lsp.json')
protocol = protocol or {}
end
protocol.Methods = freeze(protocol.Methods)
return protocol
]],
'\n',
{ trimempty = true }
)
)
local fname = './runtime/lua/vim/lsp/protocol.lua'
local bufnr = vim.fn.bufadd(fname)
vim.fn.bufload(bufnr)
vim.api.nvim_set_current_buf(bufnr)
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
local index = vim.iter(ipairs(lines)):find(function(key, item)
return vim.startswith(item, '-- Generated by') and key or nil
end)
index = index and index - 1 or vim.api.nvim_buf_line_count(bufnr) - 1
vim.api.nvim_buf_set_lines(bufnr, index, -1, true, output)
vim.cmd.write()
end
function M.gen(opt)
local protocol = read_json(opt)
if opt.methods then
gen_methods(protocol)
end
local output = {
'--[[',
'This file is autogenerated from scripts/lsp_types.lua',
'This file is autogenerated from scripts/gen_lsp.lua',
'Regenerate:',
[=[nvim -l scripts/lsp_types.lua gen --runtime/lua/vim/lsp/types/protocol.lua]=],
[=[nvim -l scripts/gen_lsp.lua gen --version 3.18 --runtime/lua/vim/lsp/types/protocol.lua]=],
'--]]',
'',
'---@alias lsp.null nil',
@@ -190,14 +263,17 @@ end
local opt = {
output_file = 'runtime/lua/vim/lsp/types/protocol.lua',
ref = 'main',
version = nil,
methods = nil,
}
for i = 1, #_G.arg do
if _G.arg[i] == '--out' then
opt.output_file = _G.arg[i+1]
elseif _G.arg[i] == '--ref' then
opt.ref = _G.arg[i+1]
opt.output_file = _G.arg[i + 1]
elseif _G.arg[i] == '--version' then
opt.version = _G.arg[i + 1]
elseif _G.arg[i] == '--methods' then
opt.methods = true
elseif vim.startswith(_G.arg[i], '--') then
opt.output_file = _G.arg[i]:sub(3)
end