Last active
April 11, 2022 12:08
-
-
Save kylo252/7b3edb23b55197316a33916fd79d942f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- creates documentation for all functions in a buffer | |
local function log(...) | |
local objects = vim.tbl_map(vim.inspect, { ... }) | |
local plenary_log = require("plenary.log").new { level = "debug", plugin = "lsp_scratch", info_level = 3 } | |
plenary_log.info(unpack(objects)) | |
return ... | |
end | |
local function write_file(path, txt, flag) | |
local data = type(txt) == "string" and txt or vim.inspect(txt) | |
local uv = vim.loop | |
uv.fs_open(path, flag, 438, function(open_err, fd) | |
assert(not open_err, open_err) | |
uv.fs_write(fd, data, -1, function(write_err) | |
assert(not write_err, write_err) | |
uv.fs_close(fd, function(close_err) | |
assert(not close_err, close_err) | |
end) | |
end) | |
end) | |
end | |
local function write_file_json(path, txt, flag) | |
local cjson = vim.json.new() | |
cjson.encode_escape_forward_slash(false) | |
local cjson_tbl = cjson.encode(txt) | |
-- we need to restore the global status | |
cjson.encode_escape_forward_slash(true) | |
write_file(path, cjson_tbl, flag) | |
end | |
local fmt = string.format | |
---create positional params | |
---@param opts table contains bufnr, pos and so on and on | |
---@return table | |
local function create_give_position_params(opts) | |
local pos = opts.pos | |
local bufnr = opts.bufnr | |
local params = { | |
textDocument = vim.lsp.util.make_text_document_params(bufnr), | |
position = { line = pos[1], character = pos[2] }, | |
} | |
log("got: " .. vim.inspect(params)) | |
return params | |
end | |
---request_doc_symbols | |
---@param opts any | |
local function request_doc_symbols(opts) | |
local params = create_give_position_params(opts) | |
vim.lsp.buf_request(opts.bufnr, "textDocument/documentSymbol", params, function(err, result, _, _) | |
if err then | |
error("Error during textDocument/documentSymbol request: " .. err.message) | |
return | |
end | |
if not result or vim.tbl_isempty(result) then | |
vim.notify "No results from textDocument/documentSymbol" | |
return | |
end | |
local locations = vim.lsp.util.symbols_to_items(result or {}, opts.bufnr) or {} | |
local filtered_symbols = vim.tbl_filter(function(item) | |
return (not opts.kind and true) or (opts.kind == item.kind) | |
end, locations) | |
if vim.tbl_isempty(filtered_symbols) then | |
vim.notify "No document_symbol locations found" | |
return | |
end | |
opts.cb(filtered_symbols, opts) | |
end) | |
end | |
---request hover | |
---@param opts any | |
local function request_hover(opts) | |
local params = create_give_position_params(opts) | |
vim.lsp.buf_request(opts.bufnr, "textDocument/hover", params, function(err, result, _, _) | |
if err then | |
error("Error during textDocument/hover request: " .. err.message) | |
return | |
end | |
if not (result and result.contents) then | |
vim.notify "No results from textDocument/hover" | |
return | |
end | |
opts.cb(result, opts) | |
end) | |
end | |
local save_symbols_doc = function(results, opts) | |
local bufname = vim.api.nvim_buf_get_name(opts.bufnr) | |
local fname = vim.fn.fnamemodify(bufname, ":t:r") | |
local outfile = fmt("docs/%s_docstring", fname) | |
write_file(outfile .. ".lua", vim.inspect(results.contents), "a") | |
--[[ json output might be desirable ]] | |
write_file_json(outfile .. ".json", results, "a") | |
local outdoc = fmt("docs/%s.md", fname) | |
local markdown_lines = vim.lsp.util.convert_input_to_markdown_lines(results.contents) | |
markdown_lines = vim.lsp.util.trim_empty_lines(markdown_lines) | |
local markdown_block = fmt("\n-\n%s\n", table.concat(markdown_lines, "\n")) | |
write_file(outdoc, markdown_block, "a") | |
end | |
local save_symbols = function(results, opts) | |
local bufname = vim.api.nvim_buf_get_name(opts.bufnr) | |
local fname = vim.fn.fnamemodify(bufname, ":t:r") | |
results = vim.tbl_filter(function(v) | |
return not v.text:match "<Anonymous>" | |
end, results) | |
local symbols_raw = fmt("docs/%s_symbols", fname) | |
write_file(symbols_raw .. ".lua", "return " .. vim.inspect(results), "w") | |
--[[ json output might be desirable ]] | |
write_file_json(symbols_raw .. ".json", results, "w") | |
end | |
local function collect_info(opts) | |
opts = opts or {} | |
vim.fn.mkdir("docs", "p") | |
opts.bufnr = opts.bufnr or vim.api.nvim_get_current_buf() | |
opts.winnr = opts.winnr or vim.api.nvim_get_current_win() | |
opts.kind = opts.kind or "Function" | |
opts.cb = opts.cb or save_symbols | |
opts.pos = { 0, 0 } -- only meaningful for the first lookup | |
request_doc_symbols(opts) | |
local bufname = vim.api.nvim_buf_get_name(opts.bufnr) | |
local fname = vim.fn.fnamemodify(bufname, ":t:r") | |
vim.defer_fn(function() | |
local symbols = dofile(fmt("docs/%s_symbols.lua", fname)) | |
for _, v in pairs(symbols) do | |
local s_pos = { v.lnum - 1, v.col } | |
log(fmt("requesting hover info for %s,%s", v.lnum, v.col)) | |
opts.pos = s_pos | |
opts.cb = save_symbols_doc | |
request_hover(opts) | |
end | |
end, 1000) -- we need to wait for the server to resolve the info | |
end | |
local M = { | |
collect_info = collect_info, | |
request_doc_symbols = request_doc_symbols, | |
request_hover = request_hover, | |
} | |
-- M.collect_info { bufnr = 1 } | |
return M |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment