Skip to content

feature : #1869 add heading fold chevrons in editors#4331

Open
Tux69140 wants to merge 6 commits into
marktext:developfrom
Tux69140:feature/issue-1869-fold-collapse-text
Open

feature : #1869 add heading fold chevrons in editors#4331
Tux69140 wants to merge 6 commits into
marktext:developfrom
Tux69140:feature/issue-1869-fold-collapse-text

Conversation

@Tux69140
Copy link
Copy Markdown

@Tux69140 Tux69140 commented May 31, 2026

Closes #1869 Option to fold/collapse text
#1869

Summary

Adds heading section folding controls to both WYSIWYG and source-code editor modes.

In WYSIWYG mode, heading chevrons are shown when the heading is active or hovered, and remain visible when a section is folded.
In source-code mode, the fold gutter is moved to the left of the line numbers, uses matching chevron icons, follows the line-number color from the active theme, and applies the same active/hover/folded visibility behavior.

image image

Type of change

  • Bug fix (non-breaking, fixes an issue)
  • New feature (non-breaking, adds functionality)
  • Breaking change (causes existing functionality to change)
  • Documentation update

Test plan

  • New tests added
  • Manually tested on: Linux

Added a new Playwright e2e spec covering heading fold chevron visibility in both WYSIWYG and source mode, including focus, hover, and gutter-hover behavior.

Validated with:
pnpm -C packages/desktop run build
pnpm -C packages/desktop exec playwright test test/e2e/heading-fold-chevrons.spec.ts
pnpm -C packages/desktop exec playwright test test/e2e

Result: 75 passed, 2 skipped.

Notes for reviewers [optional]

The source editor uses CodeMirror 5 fold gutters. The chevron color is synchronized from the computed line-number color so it follows theme changes instead of duplicating theme color values.

Fold chevrons are intentionally hidden by default on unfolded headings, shown on active or hovered heading lines, and kept visible for folded headings to indicate hidden content.


By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

@Tux69140 Tux69140 force-pushed the feature/issue-1869-fold-collapse-text branch from 54158d2 to 622d71e Compare June 1, 2026 05:16
@Jocs Jocs requested a review from Copilot June 2, 2026 14:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds heading section folding controls (chevrons + fold/unfold actions) to both the Muya realtime (WYSIWYG) editor and the CodeMirror 5 source-code editor, addressing #1869 by making folds visible and directly actionable in the editor body/gutter.

Changes:

  • Introduces heading folding state and rendering in Muya (fold toggle icon, hide folded blocks, unfold-on-search/scroll integration).
  • Adds CodeMirror fold gutter styling/behavior (chevrons, hover/active visibility) plus fold/unfold-all commands and menu/keybindings.
  • Adds Playwright e2e coverage and updates end-user/dev documentation + localization strings for the new feature and commands.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/website/content/docs/end-user/PREFERENCES.md Documents new showHeadingFoldChevrons preference.
packages/website/content/docs/end-user/KEYBINDINGS_WINDOWS.md Documents fold/unfold-all section shortcuts (Windows).
packages/website/content/docs/end-user/KEYBINDINGS_OSX.md Documents fold/unfold-all section shortcuts (macOS).
packages/website/content/docs/end-user/KEYBINDINGS_LINUX.md Documents fold/unfold-all section shortcuts (Linux).
packages/website/content/docs/end-user/EDITING.md Adds end-user guidance for heading folding behavior and commands.
packages/website/content/docs/dev/INTERFACE.md Adds developer-facing overview of folding UI in both editors.
packages/muyajs/lib/parser/render/renderBlock/renderIcon.js Renders a heading fold-toggle icon alongside heading front icons.
packages/muyajs/lib/parser/render/index.js Adds CSS classes for folded headings/hidden blocks during render.
packages/muyajs/lib/index.js Exposes fold/unfold APIs and wires showHeadingFoldChevrons container class + clears folds on content/undo/redo.
packages/muyajs/lib/contentState/searchCtrl.js Unfolds folded content when navigating to a search match.
packages/muyajs/lib/contentState/paragraphCtrl.js Clears folded heading state when selecting all content.
packages/muyajs/lib/contentState/index.js Registers fold controller, stores fold state, and ensures cursor isn’t left in hidden content on render.
packages/muyajs/lib/contentState/foldCtrl.js Implements heading fold state, hide/unhide logic, and fold/unfold-all operations.
packages/muyajs/lib/contentState/clickCtrl.js Handles click on fold toggle icon to fold/unfold a heading section.
packages/muyajs/lib/config/index.js Adds showHeadingFoldChevrons to Muya default options.
packages/muyajs/lib/assets/styles/index.css Styles WYSIWYG fold chevrons and hides folded blocks.
packages/desktop/test/e2e/heading-fold-chevrons.spec.ts New Playwright e2e spec covering chevron visibility behaviors in both modes.
packages/desktop/static/locales/zh-TW.json Adds strings for fold/unfold-all commands + preference label (zh-TW).
packages/desktop/static/locales/zh-CN.json Adds strings for fold/unfold-all commands + preference label (zh-CN).
packages/desktop/static/locales/pt.json Adds strings for fold/unfold-all commands + preference label (pt).
packages/desktop/static/locales/ko.json Adds strings for fold/unfold-all commands + preference label (ko).
packages/desktop/static/locales/ja.json Adds strings for fold/unfold-all commands + preference label (ja).
packages/desktop/static/locales/fr.json Adds strings for fold/unfold-all commands + preference label (fr).
packages/desktop/static/locales/es.json Adds strings for fold/unfold-all commands + preference label (es).
packages/desktop/static/locales/en.json Adds strings for fold/unfold-all commands + preference label (en).
packages/desktop/static/locales/de.json Adds strings for fold/unfold-all commands + preference label (de).
packages/desktop/src/shared/types/preferences.ts Types the new showHeadingFoldChevrons preference.
packages/desktop/src/renderer/src/store/preferences.ts Adds showHeadingFoldChevrons to preferences store state/defaults.
packages/desktop/src/renderer/src/prefComponents/editor/index.vue Adds UI toggle for showHeadingFoldChevrons in preferences.
packages/desktop/src/renderer/src/components/editorWithTabs/sourceCode.vue Implements source-mode fold gutter behavior, hover tracking, fold/unfold-all, and TOC scroll integration.
packages/desktop/src/renderer/src/components/editorWithTabs/editor.vue Wires preference to Muya options, adds fold/unfold-all handling for WYSIWYG, and unfolds-on-scroll-to-header.
packages/desktop/src/renderer/src/commands/index.ts Adds command descriptors for fold/unfold-all sections.
packages/desktop/src/renderer/src/commands/descriptions.ts Maps new command IDs to i18n description keys.
packages/desktop/src/renderer/src/codeMirror/index.ts Imports CodeMirror fold addons + fold gutter CSS.
packages/desktop/src/main/preferences/schema.json Adds showHeadingFoldChevrons to main-process preference schema.
packages/desktop/src/main/menu/templates/view.ts Adds View menu items for fold/unfold-all sections.
packages/desktop/src/main/menu/index.ts Ensures new View menu items update properly.
packages/desktop/src/main/menu/actions/view.ts Implements main-process menu actions to dispatch fold/unfold-all commands.
packages/desktop/src/main/keyboard/keybindingsWindows.ts Adds default keybindings for fold/unfold-all (Windows).
packages/desktop/src/main/keyboard/keybindingsLinux.ts Adds default keybindings for fold/unfold-all (Linux).
packages/desktop/src/main/keyboard/keybindingsDarwin.ts Adds default keybindings for fold/unfold-all (macOS).
packages/desktop/src/common/commands/constants.ts Adds constants for the new fold/unfold-all commands.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +46 to +61
ContentState.prototype.getFoldHeadingForBlock = function(block) {
if (!block) return null

const outmostBlock = block.parent ? this.findOutMostBlock(block) : block
let heading = this.getBlock(outmostBlock.preSibling)

while (heading) {
if (this.isHeadingFolded(heading) && this.getSectionBlocks(heading).includes(outmostBlock)) {
return heading
}

heading = this.getBlock(heading.preSibling)
}

return null
}
Comment on lines +1220 to +1228
h1.ag-paragraph:hover .ag-front-icon,
h2.ag-paragraph:hover .ag-front-icon,
h3.ag-paragraph:hover .ag-front-icon,
h4.ag-paragraph:hover .ag-front-icon,
h5.ag-paragraph:hover .ag-front-icon,
h6.ag-paragraph:hover .ag-front-icon,
.ag-paragraph.ag-heading-folded-block:not(.ag-active) .ag-front-icon {
display: block;
}
Comment on lines 882 to 892
const scrollToHeader = (slug: unknown) => {
if (typeof slug !== 'string') return

const didUnfold = editor.value.unfoldBlockByKey(slug)
if (didUnfold) {
requestAnimationFrame(() => scrollToElement(`#${slug}`))
return
}

return scrollToElement(`#${slug}`)
}
@Tux69140
Copy link
Copy Markdown
Author

Tux69140 commented Jun 3, 2026

thanks, and sorry, I'm new in code process.
I have solve this points.

Respond to Copilot review comments for the heading folding PR by optimizing Muya fold lookup during render, wiring the showHeadingFoldChevrons preference into WYSIWYG CSS, and preventing source-mode TOC navigation from mutating hidden Muya fold state.

Also harden the dev-session restore path discovered while validating the review fixes: skip unreadable buffer files without deleting them, merge only duplicate dev buffer stores, preserve restore warning mappings after tab id remapping, and fall back to normal restore if compaction fails.

Validation: pnpm -C packages/desktop run typecheck; pnpm -C packages/desktop exec eslint src/main/app/index.ts src/main/editorBufferStore/index.ts ../../packages/muyajs/lib/contentState/foldCtrl.js ../../packages/muyajs/lib/contentState/index.js.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option to fold/collapse text

2 participants