From 5d3f173b42ec8c810debfcfbc7df535938c7c986 Mon Sep 17 00:00:00 2001 From: flin16 Date: Mon, 26 May 2025 15:00:43 -0500 Subject: [PATCH] Lsp_symbols for latex --- lazyvim.json | 1 - lua/config/keymaps.lua | 87 ++++++ lua/output.txt | 377 ++++++++++++++++++++++++++ lua/plugins/example.lua | 17 ++ lua/telescope/_extensions/tex_toc.lua | 0 lua/test.txt | 328 ++++++++++++++++++++++ 6 files changed, 809 insertions(+), 1 deletion(-) create mode 100644 lua/output.txt delete mode 100644 lua/telescope/_extensions/tex_toc.lua create mode 100644 lua/test.txt diff --git a/lazyvim.json b/lazyvim.json index 2f6f577..9bda2ca 100644 --- a/lazyvim.json +++ b/lazyvim.json @@ -1,6 +1,5 @@ { "extras": [ - "lazyvim.plugins.extras.ai.copilot", "lazyvim.plugins.extras.coding.mini-surround", "lazyvim.plugins.extras.coding.yanky", "lazyvim.plugins.extras.editor.refactoring", diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index dfcaf79..03fb796 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -52,3 +52,90 @@ vim.keymap.set("v", "", '"+y', { desc = "Copy to clipboard in visual mode" vim.keymap.set("v", "", '"+d', { desc = "Cut to clipboard" }) map_nv("", "ggG", { desc = "Select all" }) -- end +local function get_environments_from_lsp_symbols(symbols) + local blocks = {} + local lsp_symbol_kind = vim.lsp.protocol.SymbolKind -- Access the SymbolKind enum + + local function traverse(nodes) + for _, symbol in ipairs(nodes) do + -- We check for 'Struct' which texlab uses for most \begin{}...\end{} blocks. + -- You could add other kinds here if your LSP server uses them. + if symbol.kind == lsp_symbol_kind.Struct then + table.insert(blocks, { + -- lnum is 0-indexed from LSP, so we add 1 for vim + lnum = symbol.range.start.line + 1, + -- 'text' is the name of the environment (e.g., "figure", "itemize") + text = "\\begin{" .. symbol.name .. "}", + }) + end + -- Recursively search in child symbols + if symbol.children and #symbol.children > 0 then + traverse(symbol.children) + end + end + end + + traverse(symbols) + return blocks +end + +-- Set the keymap fg to trigger the picker +vim.keymap.set("n", "fg", function() + local Snacks = require("snacks") + return Snacks.picker({ + finder = "lsp_symbols", -- Use the LSP symbols as the source + layout = { + layout = { + box = "horizontal", + width = 0.5, + height = 0.5, + { + box = "vertical", + border = "rounded", + title = "Find directory", + { win = "input", height = 1, border = "bottom" }, + { win = "list", border = "none" }, + }, + }, + }, + format = 'lsp_symbol', + confirm = function(picker, item) + picker:close() + Snacks.picker.pick("files", { + dirs = { item.file }, + }) + end, + filter = { + tex = true, + } + }) +end +, { desc = "Find LaTeX environments using LSP" }) -- Updated description +local function get_symbols() + -- 1. 检查texlab是否已附加到当前缓冲区 + local clients = vim.lsp.get_clients({ bufnr = 0 }) + local texlab_found = false + local bufnr = vim.api.nvim_get_current_buf() + for _, client in ipairs(clients) do + if client.name == "texlab" then + texlab_found = true + client.request("textDocument/documentSymbol", { + textDocument = vim.lsp.util.make_text_document_params(bufnr), + }, function(err, result, ctx, config) + if err then + print("Error:", vim.inspect(err)) + return + end + print("texlab symbols:", vim.inspect(result)) + end, bufnr) + break + end + end + + if not texlab_found then + vim.notify("Texlab LSP 未附加到当前缓冲区。", vim.log.levels.WARN) + return + end + + vim.notify("正在向 texlab 请求文档结构...", vim.log.levels.INFO) +end diff --git a/lua/output.txt b/lua/output.txt new file mode 100644 index 0000000..5be1945 --- /dev/null +++ b/lua/output.txt @@ -0,0 +1,377 @@ + +{ { + children = { { + children = {}, + deprecated = false, + kind = 13, + name = "Definition", + range = { + ["end"] = { + character = 16, + line = 18 + }, + start = { + character = 0, + line = 15 + } + }, + selectionRange = { + ["end"] = { + character = 16, + line = 18 + }, + start = { + character = 0, + line = 15 + } + } + }, { + children = { { + children = { { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 176, + line = 23 + }, + start = { + character = 2, + line = 23 + } + }, + selectionRange = { + ["end"] = { + character = 176, + line = 23 + }, + start = { + character = 2, + line = 23 + } + } + }, { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 107, + line = 24 + }, + start = { + character = 2, + line = 24 + } + }, + selectionRange = { + ["end"] = { + character = 107, + line = 24 + }, + start = { + character = 2, + line = 24 + } + } + }, { + children = { { + children = { { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 40, + line = 28 + }, + start = { + character = 9, + line = 28 + } + }, + selectionRange = { + ["end"] = { + character = 40, + line = 28 + }, + start = { + character = 9, + line = 28 + } + } + }, { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 53, + line = 29 + }, + start = { + character = 9, + line = 29 + } + }, + selectionRange = { + ["end"] = { + character = 53, + line = 29 + }, + start = { + character = 9, + line = 29 + } + } + }, { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 45, + line = 30 + }, + start = { + character = 9, + line = 30 + } + }, + selectionRange = { + ["end"] = { + character = 45, + line = 30 + }, + start = { + character = 9, + line = 30 + } + } + } }, + deprecated = false, + kind = 10, + name = "Enumerate", + range = { + ["end"] = { + character = 23, + line = 31 + }, + start = { + character = 8, + line = 27 + } + }, + selectionRange = { + ["end"] = { + character = 23, + line = 31 + }, + start = { + character = 8, + line = 27 + } + } + } }, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 23, + line = 31 + }, + start = { + character = 2, + line = 25 + } + }, + selectionRange = { + ["end"] = { + character = 23, + line = 31 + }, + start = { + character = 2, + line = 25 + } + } + }, { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 45, + line = 32 + }, + start = { + character = 2, + line = 32 + } + }, + selectionRange = { + ["end"] = { + character = 45, + line = 32 + }, + start = { + character = 2, + line = 32 + } + } + }, { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 42, + line = 33 + }, + start = { + character = 2, + line = 33 + } + }, + selectionRange = { + ["end"] = { + character = 42, + line = 33 + }, + start = { + character = 2, + line = 33 + } + } + }, { + children = {}, + deprecated = false, + kind = 22, + name = "Item", + range = { + ["end"] = { + character = 75, + line = 34 + }, + start = { + character = 2, + line = 34 + } + }, + selectionRange = { + ["end"] = { + character = 75, + line = 34 + }, + start = { + character = 2, + line = 34 + } + } + } }, + deprecated = false, + kind = 10, + name = "Enumerate", + range = { + ["end"] = { + character = 16, + line = 35 + }, + start = { + character = 1, + line = 22 + } + }, + selectionRange = { + ["end"] = { + character = 16, + line = 35 + }, + start = { + character = 1, + line = 22 + } + } + } }, + deprecated = false, + kind = 13, + name = "Theorem", + range = { + ["end"] = { + character = 13, + line = 36 + }, + start = { + character = 0, + line = 20 + } + }, + selectionRange = { + ["end"] = { + character = 13, + line = 36 + }, + start = { + character = 0, + line = 20 + } + } + }, { + children = {}, + deprecated = false, + kind = 10, + name = "Enumerate", + range = { + ["end"] = { + character = 15, + line = 39 + }, + start = { + character = 0, + line = 37 + } + }, + selectionRange = { + ["end"] = { + character = 15, + line = 39 + }, + start = { + character = 0, + line = 37 + } + } + } }, + deprecated = false, + kind = 2, + name = "1 Main result", + range = { + ["end"] = { + character = 15, + line = 39 + }, + start = { + character = 0, + line = 13 + } + }, + selectionRange = { + ["end"] = { + character = 15, + line = 39 + }, + start = { + character = 0, + line = 13 + } + } + } } diff --git a/lua/plugins/example.lua b/lua/plugins/example.lua index ad0daa9..44473f6 100644 --- a/lua/plugins/example.lua +++ b/lua/plugins/example.lua @@ -115,6 +115,23 @@ return { config = function() vim.keymap.set("n", "U", vim.cmd.UndotreeToggle, { desc = "Toggle Undotree" }) end, + }, + { + "hrsh7th/nvim-cmp", + requires = { + { "kdheepak/cmp-latex-symbols" }, + }, + sources = { + { + name = "latex_symbols", + option = { + strategy = 0, -- mixed + }, + }, + }, + }, + { + "latex-lsp/texlab", } } -- every spec file under the "plugins" directory will be loaded automatically by lazy.nvim diff --git a/lua/telescope/_extensions/tex_toc.lua b/lua/telescope/_extensions/tex_toc.lua deleted file mode 100644 index e69de29..0000000 diff --git a/lua/test.txt b/lua/test.txt new file mode 100644 index 0000000..b404de2 --- /dev/null +++ b/lua/test.txt @@ -0,0 +1,328 @@ +{ + _log_prefix = "LSP[texlab]", + _on_attach_cbs = { }, + _on_exit_cbs = { , }, + _on_init_cbs = { }, + _trace = "off", + attached_buffers = { + [7] = true + }, + cancel_request = , + capabilities = <6>{ + general = { + positionEncodings = { "utf-16" } + }, + textDocument = { + callHierarchy = { + dynamicRegistration = false + }, + codeAction = { + codeActionLiteralSupport = { + codeActionKind = { + valueSet = { "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" } + } + }, + dataSupport = true, + dynamicRegistration = true, + isPreferredSupport = true, + resolveSupport = { + properties = { "edit" } + } + }, + completion = { + completionItem = { + commitCharactersSupport = false, + deprecatedSupport = true, + documentationFormat = { "markdown", "plaintext" }, + insertReplaceSupport = true, + insertTextModeSupport = { + valueSet = { 1 } + }, + labelDetailsSupport = true, + preselectSupport = false, + resolveSupport = { + properties = { "documentation", "detail", "additionalTextEdits", "command", "data" } + }, + snippetSupport = true, + tagSupport = { + valueSet = { 1 } + } + }, + completionItemKind = { + valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 } + }, + completionList = { + itemDefaults = { "commitCharacters", "editRange", "insertTextFormat", "insertTextMode", "data" } + }, + contextSupport = true, + dynamicRegistration = false, + insertTextMode = 1 + }, + declaration = { + linkSupport = true + }, + definition = { + dynamicRegistration = true, + linkSupport = true + }, + diagnostic = { + dynamicRegistration = false + }, + documentHighlight = { + dynamicRegistration = false + }, + documentSymbol = { + dynamicRegistration = false, + hierarchicalDocumentSymbolSupport = true, + symbolKind = { + valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } + } + }, + formatting = { + dynamicRegistration = true + }, + hover = { + contentFormat = { "markdown", "plaintext" }, + dynamicRegistration = true + }, + implementation = { + linkSupport = true + }, + inlayHint = { + dynamicRegistration = true, + resolveSupport = { + properties = { "textEdits", "tooltip", "location", "command" } + } + }, + publishDiagnostics = { + dataSupport = true, + relatedInformation = true, + tagSupport = { + valueSet = { 1, 2 } + } + }, + rangeFormatting = { + dynamicRegistration = true + }, + references = { + dynamicRegistration = false + }, + rename = { + dynamicRegistration = true, + prepareSupport = true + }, + semanticTokens = { + augmentsSyntaxTokens = true, + dynamicRegistration = false, + formats = { "relative" }, + multilineTokenSupport = false, + overlappingTokenSupport = true, + requests = { + full = { + delta = true + }, + range = false + }, + serverCancelSupport = false, + tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" }, + tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" } + }, + signatureHelp = { + dynamicRegistration = false, + signatureInformation = { + activeParameterSupport = true, + documentationFormat = { "markdown", "plaintext" }, + parameterInformation = { + labelOffsetSupport = true + } + } + }, + synchronization = { + didSave = true, + dynamicRegistration = false, + willSave = true, + willSaveWaitUntil = true + }, + typeDefinition = { + linkSupport = true + } + }, + window = { + showDocument = { + support = true + }, + showMessage = { + messageActionItem = { + additionalPropertiesSupport = false + } + }, + workDoneProgress = true + }, + workspace = { + applyEdit = true, + configuration = true, + didChangeConfiguration = { + dynamicRegistration = false + }, + didChangeWatchedFiles = { + dynamicRegistration = true, + relativePatternSupport = true + }, + fileOperations = { + didRename = true, + willRename = true + }, + inlayHint = { + refreshSupport = true + }, + semanticTokens = { + refreshSupport = true + }, + symbol = { + dynamicRegistration = false, + symbolKind = { + valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } + } + }, + workspaceEdit = { + resourceOperations = { "rename", "create", "delete" } + }, + workspaceFolders = true + } + }, + commands = {}, + config = { + autostart = true, + capabilities = , + cmd = { "texlab" }, + cmd_cwd = "/Users/fengyuanlin/test", + filetypes = { "tex", "plaintex", "bib" }, + handlers = <7>{}, + init_options = vim.empty_dict(), + keys = { { "K", "(vimtex-doc-package)", + desc = "Vimtex Docs", + mode = "n", + silent = true + } }, + log_level = 2, + message_level = 2, + name = "texlab", + on_attach = , + on_exit = , + on_init = , + root_dir = "/Users/fengyuanlin/test", + settings = <8>{ + texlab = { + bibtexFormatter = "texlab", + build = { + args = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "%f" }, + executable = "latexmk", + forwardSearchAfter = false, + onSave = false + }, + chktex = { + onEdit = false, + onOpenAndSave = false + }, + diagnosticsDelay = 300, + formatterLineLength = 80, + forwardSearch = { + args = {} + }, + latexFormatter = "latexindent", + latexindent = { + modifyLineBreaks = false + } + } + }, + single_file_support = true, + workspace_folders = <9>{ { + name = "/Users/fengyuanlin/test", + uri = "file:///Users/fengyuanlin/test" + } }, + = <10>{ + __tostring = + } + }, + dynamic_capabilities = { + capabilities = {}, + client_id = 2, + = { + __index =
+ } + }, + flags = {}, + get_language_id = , + handlers =
, + id = 2, + initialized = true, + is_stopped = , + messages = { + messages = {}, + name = "texlab", + progress = {}, + status = {} + }, + name = "texlab", + notify = , + offset_encoding = "utf-16", + on_attach = , + progress = { + _idx_read = 0, + _idx_write = 0, + _items = {}, + _size = 51, + pending = {}, + = { + __call = , + __index =
+ } + }, + request = , + request_sync = , + requests = {}, + root_dir = "/Users/fengyuanlin/test", + rpc = { + is_closing = , + notify = , + request = , + terminate = + }, + server_capabilities = { + completionProvider = { + resolveProvider = true, + triggerCharacters = { "\\", "{", "}", "@", "/", " " } + }, + definitionProvider = true, + documentFormattingProvider = true, + documentHighlightProvider = true, + documentLinkProvider = { + resolveProvider = false + }, + documentSymbolProvider = true, + executeCommandProvider = { + commands = { "texlab.cleanAuxiliary", "texlab.cleanArtifacts", "texlab.changeEnvironment", "texlab.findEnvironments", "texlab.showDependencyGraph", "texlab.cancelBuild" } + }, + foldingRangeProvider = true, + hoverProvider = true, + inlayHintProvider = true, + referencesProvider = true, + renameProvider = { + prepareProvider = true + }, + textDocumentSync = { + change = 2, + openClose = true, + save = { + includeText = false + } + }, + workspaceSymbolProvider = true + }, + settings =
, + stop = , + supports_method = , + workspace_did_change_configuration = , + workspace_folders =
, + =
+ }