Lsp_symbols for latex

This commit is contained in:
flin16 2025-05-26 15:00:43 -05:00
parent 22f40b3d40
commit 5d3f173b42
6 changed files with 809 additions and 1 deletions

View file

@ -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",

View file

@ -52,3 +52,90 @@ vim.keymap.set("v", "<D-c>", '"+y', { desc = "Copy to clipboard in visual mode"
vim.keymap.set("v", "<D-x>", '"+d', { desc = "Cut to clipboard" })
map_nv("<D-a>", "gg<S-v>G", { 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 <leader>fg to trigger the picker
vim.keymap.set("n", "<leader>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

377
lua/output.txt Normal file
View file

@ -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
}
}
} }

View file

@ -115,6 +115,23 @@ return {
config = function()
vim.keymap.set("n", "<leader>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

328
lua/test.txt Normal file
View file

@ -0,0 +1,328 @@
{
_log_prefix = "LSP[texlab]",
_on_attach_cbs = { <function 55> },
_on_exit_cbs = { <function 56>, <function 2> },
_on_init_cbs = { <function 57> },
_trace = "off",
attached_buffers = {
[7] = true
},
cancel_request = <function 58>,
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 = <table 6>,
cmd = { "texlab" },
cmd_cwd = "/Users/fengyuanlin/test",
filetypes = { "tex", "plaintex", "bib" },
handlers = <7>{},
init_options = vim.empty_dict(),
keys = { { "<Leader>K", "<plug>(vimtex-doc-package)",
desc = "Vimtex Docs",
mode = "n",
silent = true
} },
log_level = 2,
message_level = 2,
name = "texlab",
on_attach = <function 55>,
on_exit = <function 56>,
on_init = <function 57>,
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"
} },
<metatable> = <10>{
__tostring = <function 59>
}
},
dynamic_capabilities = {
capabilities = {},
client_id = 2,
<metatable> = {
__index = <table 3>
}
},
flags = {},
get_language_id = <function 17>,
handlers = <table 7>,
id = 2,
initialized = true,
is_stopped = <function 60>,
messages = {
messages = {},
name = "texlab",
progress = {},
status = {}
},
name = "texlab",
notify = <function 61>,
offset_encoding = "utf-16",
on_attach = <function 62>,
progress = {
_idx_read = 0,
_idx_write = 0,
_items = {},
_size = 51,
pending = {},
<metatable> = {
__call = <function 63>,
__index = <table 4>
}
},
request = <function 64>,
request_sync = <function 65>,
requests = {},
root_dir = "/Users/fengyuanlin/test",
rpc = {
is_closing = <function 66>,
notify = <function 67>,
request = <function 68>,
terminate = <function 69>
},
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 = <table 8>,
stop = <function 70>,
supports_method = <function 71>,
workspace_did_change_configuration = <function 72>,
workspace_folders = <table 9>,
<metatable> = <table 5>
}