feature : #1869 add heading fold chevrons in editors#4331
Open
Tux69140 wants to merge 6 commits into
Open
Conversation
54158d2 to
622d71e
Compare
Contributor
There was a problem hiding this comment.
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}`) | ||
| } |
Author
|
thanks, and sorry, I'm new in code process. |
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.
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.
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.
Type of change
Test plan
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 buildpnpm -C packages/desktop exec playwright test test/e2e/heading-fold-chevrons.spec.tspnpm -C packages/desktop exec playwright test test/e2eResult: 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.