Repository navigation
fix(frontend): preserve literal lists inside Markdown code fences - #4323
Jarvis636431 wants to merge 3 commits into
Conversation
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf2a03b344
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| function isInsideCodeFence(value: string, lineStart: number): boolean { | ||
| let fence = '' | ||
| for (const line of value.slice(0, lineStart).split(/\r?\n/)) { | ||
| const match = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line) |
There was a problem hiding this comment.
Handle fences that start on list-marker lines
When a fenced block begins as the first block of a Markdown list item, the opening delimiter is on the same physical line as the list marker and this regexp ignores it, while the indented closing delimiter still matches and is recorded as a new opener. The scanner then remains "inside" a fence, so Enter stops continuing every real list that follows that valid nested code block until another matching delimiter appears; fence tracking needs to account for list-container prefixes instead of treating that closer as an opener.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fe645997e0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| listIndents.push(offset) | ||
| content = line.slice(offset) | ||
| } | ||
| const match = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(content) |
There was a problem hiding this comment.
Ignore fence-like lines inside raw HTML blocks
For Markdown such as <pre>\n~~~\n</pre>\n\n- next, ~~~ is literal HTML-block content, not a fenced-code opener. This match nevertheless opens a fence that </pre> cannot close, so continueListOnEnter returns null on the real list below and Enter stops continuing subsequent lists until another matching delimiter appears. Skip raw HTML blocks, including HTML comments, when tracking fences so keyboard behavior agrees with the editor's marked preview.
Useful? React with 👍 / 👎.
| while ((prefix = /^ {0,3}(?:[-*+]|\d{1,9}[.)]) {1,4}(?=\S|$)/.exec(content))) { | ||
| offset += prefix[0].length | ||
| listIndents.push(offset) |
There was a problem hiding this comment.
Exclude thematic breaks from list-container tracking
For a valid document such as - - -\n ~~~\ncode\n ~~~\n- next, this loop consumes the thematic break as nested list prefixes. The top-level fence is consequently assigned fenceIndent = 2; its unindented code line incorrectly ends it, and its actual closing delimiter becomes a fresh opener. Enter on - next and subsequent lists then returns null instead of continuing the list. Recognize thematic breaks before updating list-container indentation.
Useful? React with 👍 / 👎.
| let offset = listIndents.at(-1)! | ||
| let content = line.slice(offset) | ||
| let prefix: RegExpExecArray | null | ||
| while ((prefix = /^ {0,3}(?:[-*+]|\d{1,9}[.)]) {1,4}(?=\S|$)/.exec(content))) { |
There was a problem hiding this comment.
Recognize list containers opened by bare markers
With -\n ~~~\n code\n- next, the first line is a valid Markdown list-item opener, but the mandatory space after the marker makes this regex ignore it. The following fence is therefore recorded at root indentation zero rather than inside the item. Although the sibling - next ends that unclosed contained fence in Markdown, the scanner still considers it code and suppresses list continuation there. Accept an end-of-line immediately after a list marker and retain the item's normal content indentation.
Useful? React with 👍 / 👎.
Description
Pressing Enter after
- literalinside a fenced code block currently inserts another-; an empty literal task/list marker can also be removed. Check the preceding fence state before applying list continuation, so the textarea inserts an ordinary newline inside code.Recognize backtick and tilde fences, up to three leading spaces, matching closing delimiter types/lengths, and CRLF input. Keep list continuation after closed fences and existing Tab behavior unchanged.
Type of Change
Related Issue
Fixes #4321
Testing
cd frontend && node --import tsx --test src/utils/markdownEditing.test.ts— 49 passed.cd frontend && npm run type-check— passed.c40b33ecproduction module in a temporary directory: 9 regression cases fail before the fix; all pass afterward.git diff --check c40b33ec...fix/markdown-fenced-list-enter— passed.Checklist
Before / After
Within a fenced code block,
- literal|+ Enter previously produced- literal\n- |; it now produces- literal\n|through the textarea's normal Enter behavior (|denotes the caret). This is a keyboard behavior fix with no layout changes; validation uses deterministic source-level tests, not a full browser session.