Repository navigation
feat(project): markdown.outline 按标题输出 Markdown 的文档结构树 - #41
Merged
Merged
Conversation
用与 markdown.render 相同的 Comrak 方言解析,把标题按级别组织成与 LSP documentSymbol 归一化结果同形的符号树:selectionRange 是标题本身,range 是到下一个同级或更高级标题的整节;位置为零起始行和 UTF-16 列。宿主在没有语言服务器时也能为 Markdown 文件显示结构,且与预览页的目录一致。共享样例 rust/fixtures/editor/markdown-outline-v1.json。
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
关联
桌面端的“结构”工具窗口只显示语言服务器的文档符号。Markdown 没有语言服务器,所以打开
.md文件时结构窗口只显示“没有语言服务器为此文件提供结构”,而预览页的浮动目录能列出标题。这个 PR 让 Core 直接给出 Markdown 的标题结构,桌面端改动在配套 PR 1lck/Lithe-IDEA#1920(固定在本 PR 的 commitb0e19d5,本 PR 合入后改为 main 上的 commit)。改动
markdown.outline:请求{ "source": "<Markdown 文本>" },返回{ "symbols": [...] }。符号的形状与lsp.request对textDocument/documentSymbol归一化后的结果相同(name、detail、kind、tags、deprecated、range、selectionRange、containerName、children),宿主可以直接用显示语言服务器符号的同一套界面显示。markdown.render相同的 Comrak 方言解析,所以列出的标题和预览目录一致。为此把render里的 Comrak 选项抽成markdown.rs的dialect(),两条命令共用,渲染结果不变。<h2>这类原始 HTML 不算标题(预览目录也不列它们,因为它们没有data-sourcepos)。name取预览显示的文字:正文、行内代码、数学原文、短代码表情;去掉图片、脚注引用和 HTML 标签;空白折叠成一个空格并去掉首尾。文字为空的标题不列出,它那一节并入前一个标题。#后直接###)只缩进一层。这与预览目录的规则一致。kind固定为15(SymbolKind.String,编辑器标记 Markdown 标题的惯例);detail、containerName为null,tags为空,deprecated为false。\n、\r\n和单独的\r都算换行,与 Comrak 一致。selectionRange覆盖标题本身,setext 标题包括下划线那一行;range是整节,从标题所在行行首到下一个同级或更高级标题所在行行首,没有这样的标题就到文末。rust/crates/project/src/markdown_outline.rs。lithe-project新增对lithe-text的依赖,用来复用LspRangeResponse/LspPositionResponse;lithe-text只依赖lithe-protocol,不形成环。protocol/command.rs(枚举和命令名),runtime/dispatcher.rs(分发,坏请求返回invalid_request),runtime/request_trace.rs(与markdown.render一样列为高频命令,不逐次追踪)。rust/contracts/rust-core-api.md:命令表新增一行,“Markdown rendering”下新增“Markdown heading outline”一节,写明请求、返回和上述规则。rust/fixtures/editor/markdown-outline-v1.json,6 个用例:ATX 与 setext 混排、front matter 保持行号、引用块里的中文和表情标题(UTF-16 列)、CRLF、跳级与代码块/原始 HTML/空标题、空文档。桌面端测试读同一份样例。验证
cargo test -p lithe-project:81 个测试通过,其中markdown_outline有 7 个(样例、跳级与整节范围、容器里的标题、空标题、名称取字、空文档、单独\r)。cargo test -p lithe-core:820 个测试全部通过,含新增的markdown_outline_command_answers_the_shared_fixture和markdown_outline_command_rejects_a_payload_without_source。cargo fmt --all、cargo clippy -p lithe-project -p lithe-core --all-targets -- -D warnings、scripts/rust-core/verify-rust-core-comments.sh:通过。不涉及插件契约、能力版本或插件函数协议,所以不需要更新协议记录。