Skip to content

fix(desktop): persist sidebar folder collapse state across view switches (#5631) - #5632

Merged
Jocs merged 1 commit into
marktext:developfrom
VictorVow:fix/persist-files-tree
Oct 8, 2026
Merged

Jocs merged 1 commit into
marktext:developfrom
VictorVow:fix/persist-files-tree

Conversation

@VictorVow

@VictorVow VictorVow commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Closes #5631

Summary

If you expand some folders in the Files sidebar, flip over to the TOC (or Search) and then come back, all of them have collapsed again. It used to remember them, so this is a regression.

The cause is that the Files tree is behind a v-if in sideBar/index.vue, so switching views throws away every treeFolder and builds new ones on the way back. Each treeFolder kept its open/closed state in a local ref that was copied from folder.isCollapsed when the component was created and never written back. So the new components just started from the original value again. It looks like this came in with the electron-vite rewrite (#4001).

The fix keeps the state on the folder node itself. isCollapsed in treeFolder.vue is now a computed with a getter and setter, and the setter goes through a small new SET_FOLDER_COLLAPSED action in the project store. Because treeCtrl updates folder nodes in place when files are added, removed or resorted, the state also survives file-watcher updates. Opening a different folder still starts with everything collapsed, same as before.

Before / after:

Before:
before

After:
after

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: test/e2e/issue-5631-folder-collapse.spec.ts (fails on develop, passes with the fix)
  • Manually tested on: Linux

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

Jocs added a commit that referenced this pull request Oct 8, 2026
Expanded folders reset whenever the side bar switched to the table of
contents or search, because a component-local collapse ref is thrown away
with the `v-if`ed tree. The state lives on the tree node now, so this locks
the behaviour down: expand two nested folders, switch views, come back, and
both are still expanded.

Ported from the regression spec contributed in #5632, which is the same fix
this branch needed as a prerequisite for #528. It drives the app the same way
as the reveal spec instead of passing the fixture as a launch argument — the
launcher always passes the app path first, so a second directory would open a
second window — and both specs now share an `openProjectFolder` helper.

Co-authored-by: A. S. <[email protected]>
…switches

The Files tree is rendered under v-if, so switching the sidebar to Table
of Contents or Search destroys every treeFolder and recreates it on the
way back. Each treeFolder kept isCollapsed in a local ref seeded from the
tree node and never wrote it back, so every folder reset to collapsed.
This regressed in the electron-vite rewrite (marktext#4001).

Make isCollapsed a writable computed over the tree node, writing through
a new SET_FOLDER_COLLAPSED project store action, so the state lives on
the tree data and survives the remount. treeCtrl mutates folder nodes in
place, so file-watcher updates keep it too; opening a new project root
still starts fully collapsed.

Add an Electron e2e regression test that expands nested folders, switches
to TOC and back, and asserts they are still expanded.
@Jocs
Jocs force-pushed the fix/persist-files-tree branch from ce1bc55 to b0d8a23 Compare October 8, 2026 07:14
@Jocs Jocs changed the title fix: #5631 persist sidebar folder collapse state across view switches fix(desktop): persist sidebar folder collapse state across view switches (#5631) Oct 8, 2026

@Jocs Jocs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Verified on the rebased head b0d8a235:

  • rebased onto the current develop; the only conflict was the project store's returned-symbol list, which now lists both COMMIT_NAME_INPUT (added on develop meanwhile) and SET_FOLDER_COLLAPSED;
  • pnpm typecheck, pnpm lint, pnpm build:unpack and the new test/e2e/issue-5631-folder-collapse.spec.ts all pass locally;
  • CI (lint, unit tests, e2e, packaging) is green.

Nice diagnosis — the local ref being thrown away with the v-ifed tree is exactly the root cause, and keeping the state on the node through a small store action is the right minimal fix. Thanks @VictorVow!

@Jocs
Jocs merged commit 65bcec6 into marktext:develop Oct 8, 2026
10 checks passed
Jocs added a commit that referenced this pull request Oct 8, 2026
Open a document in a deep folder, collapse that folder, switch to another file
and back: there was no way to find it again. The title bar shows the path but is
not navigable, while Atom, IntelliJ and VS Code all reveal the active file in
their project tree.

Reveal it the way VS Code's Explorer does for `explorer.autoReveal`:

- expand only the folders leading to the file, never collapsing anything;
- scroll only when the row is not already fully visible, then centre it, using
  the same formula as `ListWidget.reveal(index, 0.5)`;
- leave the caret, the tree selection and `activeItem` alone, so F2 and Delete
  keep acting on what the user picked;
- do nothing while the file list is off screen, and reveal again as soon as it
  is visible.

A single watcher on `currentFile` drives it, so every existing way of switching
files — tab click, cycle, quick open, sidebar click, startup restore — gets the
behaviour without touching those call sites. Moving the folder collapse state
onto the tree node (#5632) is what lets the store expand ancestors before the
render instead of racing freshly mounted folder components.

Also adds `autoRevealInSidebar` (on by default), a "Show in Side Bar" tab
context-menu entry and a `file.reveal-in-sidebar` command for the manual case,
with unit tests for the expansion and scroll maths and an e2e spec that drives
the real app against a generated project.
Jocs added a commit that referenced this pull request Oct 8, 2026
Open a document in a deep folder, collapse that folder, switch to another file
and back: there was no way to find it again. The title bar shows the path but is
not navigable, while Atom, IntelliJ and VS Code all reveal the active file in
their project tree.

Reveal it the way VS Code's Explorer does for `explorer.autoReveal`:

- expand only the folders leading to the file, never collapsing anything;
- scroll only when the row is not already fully visible, then centre it, using
  the same formula as `ListWidget.reveal(index, 0.5)`;
- leave the caret, the tree selection and `activeItem` alone, so F2 and Delete
  keep acting on what the user picked;
- do nothing while the file list is off screen, and reveal again as soon as it
  is visible.

A single watcher on `currentFile` drives it, so every existing way of switching
files — tab click, cycle, quick open, sidebar click, startup restore — gets the
behaviour without touching those call sites. Moving the folder collapse state
onto the tree node (#5632) is what lets the store expand ancestors before the
render instead of racing freshly mounted folder components.

Also adds `autoRevealInSidebar` (on by default), a "Show in Side Bar" tab
context-menu entry and a `file.reveal-in-sidebar` command for the manual case,
with unit tests for the expansion and scroll maths and an e2e spec that drives
the real app against a generated project.
Jocs added a commit that referenced this pull request Oct 8, 2026
Open a document in a deep folder, collapse that folder, switch to another file
and back: there was no way to find it again. The title bar shows the path but is
not navigable, while Atom, IntelliJ and VS Code all reveal the active file in
their project tree.

Reveal it the way VS Code's Explorer does for `explorer.autoReveal`:

- expand only the folders leading to the file, never collapsing anything, and
  only once the file is known to be in the tree;
- scroll only when the row is not already fully visible, then centre it, using
  the same formula as `ListWidget.reveal(index, 0.5)`;
- leave the caret, the tree selection and `activeItem` alone, so F2 and Delete
  keep acting on what the user picked;
- do nothing while the file list is off screen, and retry as the tree fills in,
  so a project opened or restored after that file is revealed as well.

A single watcher on `currentFile` plus the tree's change counter drives it, so
every existing way of switching files — tab click, cycle, quick open, sidebar
click, startup restore — gets the behaviour without touching those call sites.
Moving the folder collapse state onto the tree node (#5632) is what lets the
store expand ancestors before the render instead of racing freshly mounted
folder components.

Also adds `autoRevealInSidebar` (on by default), a "Show in Side Bar" tab
context-menu entry and a `file.reveal-in-sidebar` command for the manual case,
with unit tests for the expansion and scroll maths and an e2e spec that drives
the real app against a generated project.
Jocs added a commit that referenced this pull request Oct 8, 2026
…#5654)

Open a document in a deep folder, collapse that folder, switch to another file
and back: there was no way to find it again. The title bar shows the path but is
not navigable, while Atom, IntelliJ and VS Code all reveal the active file in
their project tree.

Reveal it the way VS Code's Explorer does for `explorer.autoReveal`:

- expand only the folders leading to the file, never collapsing anything, and
  only once the file is known to be in the tree;
- scroll only when the row is not already fully visible, then centre it, using
  the same formula as `ListWidget.reveal(index, 0.5)`;
- leave the caret, the tree selection and `activeItem` alone, so F2 and Delete
  keep acting on what the user picked;
- do nothing while the file list is off screen, and retry as the tree fills in,
  so a project opened or restored after that file is revealed as well.

A single watcher on `currentFile` plus the tree's change counter drives it, so
every existing way of switching files — tab click, cycle, quick open, sidebar
click, startup restore — gets the behaviour without touching those call sites.
Moving the folder collapse state onto the tree node (#5632) is what lets the
store expand ancestors before the render instead of racing freshly mounted
folder components.

Also adds `autoRevealInSidebar` (on by default), a "Show in Side Bar" tab
context-menu entry and a `file.reveal-in-sidebar` command for the manual case,
with unit tests for the expansion and scroll maths and an e2e spec that drives
the real app against a generated project.
@VictorVow
VictorVow deleted the fix/persist-files-tree branch October 8, 2026 13:36
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.

[Bug] Expanded folders in the Files sidebar collapse after switching to TOC or Search

2 participants