跪拜 Guibai
← Back to the summary

DSH gets a real markdown editor: QuireKit's multi-mode, lezer-optimized plugin goes open source

Declaration: This article was not optimized by any AI, line by line. Nor did it reference AI output. The full text was manually typed and edited.

I've been sick recently and not feeling well, so I haven't carefully polished articles. Since I have no backlog to publish, apart from seeing doctors and resting, I've been mostly refining the quirekit ecosystem, and incidentally made a small thing: dsh-quirekit-md-editor.

First, what it is

My daily main production tools are still codex and claude code, but dsh serves as a frequently used backup for simple tasks. While using dsh, I noticed a big difference from mainstream products like codex: the markdown and code it opens are only preview versions.

Against this backdrop, combined with the release of our md-editor product, I decided to adapt a super convenient built-in md editor for dsh: dsh-quirekit-md-editor. This also matches my long-standing thinking: the editor and note product track is highly competitive, and I don't want to make a homogenized product among the masses, nor fight against AI trends. What I want is to integrate into various products—other note products, Agent products, or customized editors for various companies. In short, integrate rather than confront.

See the integration effect:

Why dsh-quirekit-md-editor?

To be honest, I'm not the only one who noticed dsh can't edit markdown. I've seen community products like Marktext and Better Sidebar. But why do I still do it, and after finishing, why should people choose me over others? For quirekit's md-editor, this isn't really a problem, because we already have many things other solutions can't provide. These differentiators are the reasons people choose us.

1. Unique multi-mode editing

Most editors on the market either provide a semi-rich-text editor state like vscode's md-editor, or a left-input-right-preview form, or a heavy form where tiptap handles rich text and codemirror handles source mode (which involves pm json conversion, and md source will definitely be formatted).

But I've always wondered: why must the editor be left-right structured? Or why must rich-text mode be implemented with a rich-text editor like tiptap? So we designed an msfe (markdown source-first editor framework) with a tiptap API style based on codemirror. In this mode, we implemented pure source editing, half-source half-rich-text editing (selected targets display as md source format), and full rich-text mode (hiding md fences and markers, with an experience similar to Feishu Docs or Notion, but actual modifications are always md strings).

In this system, menus and operations across all modes are shared. For example, comments:

Formatting and other operations also have a complete experience in source mode:

I've barely experienced this in other editors on the market.

2. Impressive performance

quirekit's codemirror pulls the source code and uses a vendor version, which gives us many opportunities to modify the source.

The biggest modification is to lezer's algorithm. Lezer itself is incremental—when you change one character, it only re-parses a few blocks around the change, and the rest are taken directly from the previous syntax tree. But the problem is it takes them block by block. If there are a thousand paragraphs after the change point, it checks and reattaches each one to the new tree. The longer the document, the more work each keystroke does.

Lezer has its own optimization: to make finding nodes by position faster, when building the object tree, it automatically packs adjacent blocks into groups, and groups into larger groups. But when reusing the old tree, this structure isn't leveraged.

Our optimization strategy: if an entire group is unchanged, reattach the whole group at once, not block by block. Only when the group is a complex structure—like code or lists—do we judge block by block as before, because in markdown such content is inherently a whole, and incorrect splitting could cause structural changes. After the change, a 3-million-character document and a 100-thousand-character document have essentially the same parsing cost per keystroke.

Here's a comparison from a previous optimization:

Workload Before optimization After optimization
Syntax tree visits 107,760 1,380 (98.7% less)
Syntax tree comparisons 153,940 660 (99.6% less)

However, to ensure correctness, for very large lists, modifications in that list part may still fall back to the original lezer logic, but only for that small block. I also extracted this optimization into a new version of incremark. Previously, I open-sourced an immature solution based on line breaks, increamrk, which hit many pitfalls caused by splitting.

During the dsh plugin implementation, I also optimized the performance overhead from UI layer updates. I compared with existing Marktext and Better Sidebar products, and also had Claude run a performance comparison:

So our editing experience has a big advantage with large documents—performance doesn't degrade as files get bigger, and editing stays very responsive.

https://markdown.quirekit.com/#algorithms I've put an animation there that visually demonstrates our update strategy

3. Rich interaction features

Our md-editor natively designs various complex blocks, a self-developed formula editor, and built-in multiple diagram editing solutions, including:

  1. Three text-drawing solutions: mermaid, plantUML, Graphviz
  2. Self-developed flowchart component with textual storage
  3. Self-developed mind map component with textual storage
  4. Excalidraw whiteboard component with textual storage

To let dsh natively generate illustrated, beautiful documents, we included relevant skill descriptions, so dsh can natively generate documents with both text and images.

4. Innovation in deep interaction integration

For md-editor, we provide the ability to select text and send it to dsh, which other products also have:

Meanwhile, our md-editor natively has a comment feature. Based on this, the above swipe-to-send seems linear and single-item. With comments, we can implement batch operations: select something we're unsatisfied with, comment on it, refine the overall plan, then send the comments as a batch to dsh for direct batch processing.

Of course, comments also support sending one by one:

Here's a demonstration of the actual effect: Write two comments, hand them to the Agent together, and after fixing, both comments automatically mark as resolved

Installation

Requires DSH 0.2.2-rc.1 or higher (lower versions untested). For Web version, run:

dsh plugin --profile web add dsh-quirekit-md-editor

Restart dsh web, then open Markdown files from the "File" tab. Desktop version: go to the "Plugins" page, click "Add Plugin", enter dsh-quirekit-md-editor to install and enable. The full demo video is in the GitHub repo's README.


The editor in this plugin is the MD Editor from the QuireKit ecosystem. To embed it in your own product, you can directly npm install @quirekit/md-editor. The DSH plugin is an external integration I made with it. If you run into problems, feel free to open an issue on GitHub or leave a comment below.


This article was first published and is continuously updated at yishuai.wang.

Comments

Top 1 of 2 from juejin.cn, machine-translated. The original thread is authoritative.

Byper

Interesting.

king王一帅

It's just a small application in the QuireKit branch series.