Skip to content

Instantly share code, notes, and snippets.

@kylo252
Last active April 11, 2022 12:08
Show Gist options
  • Save kylo252/7b3edb23b55197316a33916fd79d942f to your computer and use it in GitHub Desktop.
Save kylo252/7b3edb23b55197316a33916fd79d942f to your computer and use it in GitHub Desktop.
-- 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