Skip to content

fix(undo): keep undo history when toggling markdown write/preview and request-script tabs - #10351

Open
jackkav wants to merge 1 commit into
developfrom
claude/undo-codeeditor-remount
Open

fix(undo): keep undo history when toggling markdown write/preview and request-script tabs#10351
jackkav wants to merge 1 commit into
developfrom
claude/undo-codeeditor-remount

Conversation

@jackkav

@jackkav jackkav commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What

Undo history (and, for the markdown editor, the content) was clobbered when you toggle markdown Write↔Preview or the Pre-request↔After-response script tabs. This fixes both.

Why

Each of those toggles unmounts and remounts a CodeEditor while it's hidden. The editor-state cache (historyKey) is supposed to carry undo across that remount, but three things broke it:

  1. persistState bailed out on hidden editors. It early-returned when the editor reported a zero-size viewport (a hidden/unmounting editor always does), so it never saved the undo history. The URL bar (OneLineEditor) has no such guard, which is why it survived and these didn't.
  2. The cache didn't persist the editor value. The markdown editor feeds CodeEditor an internal defaultValue that lags behind (it's updated via a debounced onChange), so on remount the editor re-seeded from stale/empty content and the restored history no longer matched.
  3. Volatile React keys. The request-pane description and script editors were keyed on a volatile uniqueKey, so any revalidation remounted them and reset their state.

How

  • persistState (code-editor.tsx) now always persists history/cursor/selections/marks; only the layout-dependent scroll position is skipped when invalid.
  • The editor-state cache (editor-state-cache.ts) now persists/restores the value, so content stays consistent with the restored undo stack regardless of defaultValue lag. Restored before setHistory, whose replacement discards the throwaway history the re-seed creates.
  • The request-pane description and pre/after-response script editors (request-pane.tsx) use stable per-request keys (their content doesn't depend on env/response), matching the earlier URL-bar fix.
  • Corrected the markdown editor's TabList aria-label (was a copy-pasted Request scripts tabs).

Test

New e2e smoke test editor-toggle-undo.test.ts: editing then toggling write↔preview (markdown) and pre↔after-response (scripts) keeps the value + undo stack, and Cmd/Ctrl+Z still undoes after switching back. Both pass locally; tsc + ESLint clean.

…preview and request-script tabs

Toggling markdown write<->preview or the pre/after-response script tabs unmounts
and remounts a CodeEditor while it is hidden. Undo (and, for markdown, the
content) was clobbered:

- persistState bailed out early when the hidden editor reported a zero-size
  viewport, so it never saved the undo history. Now it always persists history
  (and cursor/selections/marks); only the layout-dependent scroll position is
  skipped when invalid.
- The editor-state cache now also persists/restores the editor VALUE, so content
  stays consistent with the restored undo stack even when defaultValue lags (the
  markdown editor feeds CodeEditor a debounced-onChange-backed internal value).
- The request-pane description and pre/after-response script editors used a
  volatile React key that remounted them on every revalidation, resetting state
  and clobbering undo. They now use stable per-request keys (their content does
  not depend on env/response).

Also corrects the markdown editor's TabList aria-label (was 'Request scripts tabs').

Covered by an e2e smoke test: both markdown write/preview and pre/after-response
script toggles keep undo working after switching back.
Copilot AI lite review requested due to automatic review settings August 7, 2026 15:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes CodeMirror undo/content state being lost when toggling UI tabs that hide/unmount editors (Markdown Write↔Preview and Pre-request↔After-response scripts) by making the editor-state cache resilient to hidden editors and by eliminating volatile React keys that caused unnecessary remounts.

Changes:

  • Persist editor history/cursor/selection/marks even when the editor is hidden (only skip invalid scroll state), and persist/restore the editor value to keep it consistent with the restored undo stack.
  • Replace volatile uniqueKey-based keys with stable per-request/per-script keys for request description and request scripts editors to prevent state clobbering on revalidation.
  • Add a Playwright smoke test to verify value + undo history survive these toggles; also correct the Markdown editor TabList aria-label.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/insomnia/src/ui/components/panes/request-pane.tsx Uses stable per-request/per-script keys to avoid remounts that reset editor state.
packages/insomnia/src/ui/components/markdown-editor.tsx Fixes TabList aria-label for correct accessibility naming and test targeting.
packages/insomnia/src/ui/components/.client/codemirror/editor-state-cache.ts Extends cached editor state to include persisted editor value.
packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx Persists state on hidden/unmounting editors and restores cached value before history.
packages/insomnia-smoke-test/tests/smoke/editor-toggle-undo.test.ts Adds E2E coverage ensuring toggling editors preserves value and undo stack.

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

@jackkav
jackkav requested a review from ryan-willis August 7, 2026 16:00
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

✅ Circular References Report

Generated at: 2026-08-07T16:00:39.783Z
Status: ✅ NO CHANGE

Summary

Metric Base (develop) PR Change
Total Circular References 9 9 0 (0.00%)
Click to view all circular references in PR (9)
insomnia-inso/src/db/models/types.ts -> insomnia-inso/src/db/types.ts
insomnia/src/main/prompt-bridge.ts -> insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/network/network.ts -> insomnia-scripting-environment/src/objects/index.ts -> insomnia-scripting-environment/src/objects/collection.ts -> insomnia-scripting-environment/src/objects/response.ts
insomnia/src/network/network.ts -> insomnia/src/common/render.ts
insomnia/src/ui/components/settings/import-export.tsx -> insomnia/src/ui/components/modals/export-requests-modal.tsx
insomnia/src/ui/components/tabs/tab-list.tsx -> insomnia/src/ui/components/tabs/tab.tsx
insomnia/src/ui/components/templating/tag-editor-arg-sub-form.tsx -> insomnia/src/ui/components/templating/external-vault/external-vault-form.tsx
insomnia/src/ui/components/viewers/response-viewer.tsx -> insomnia/src/ui/components/viewers/response-multipart-viewer.tsx
Click to view all circular references in base branch (9)
insomnia-inso/src/db/models/types.ts -> insomnia-inso/src/db/types.ts
insomnia/src/main/prompt-bridge.ts -> insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/main/window-utils.ts -> insomnia/src/main/plugin-window.ts
insomnia/src/network/network.ts -> insomnia-scripting-environment/src/objects/index.ts -> insomnia-scripting-environment/src/objects/collection.ts -> insomnia-scripting-environment/src/objects/response.ts
insomnia/src/network/network.ts -> insomnia/src/common/render.ts
insomnia/src/ui/components/settings/import-export.tsx -> insomnia/src/ui/components/modals/export-requests-modal.tsx
insomnia/src/ui/components/tabs/tab-list.tsx -> insomnia/src/ui/components/tabs/tab.tsx
insomnia/src/ui/components/templating/tag-editor-arg-sub-form.tsx -> insomnia/src/ui/components/templating/external-vault/external-vault-form.tsx
insomnia/src/ui/components/viewers/response-viewer.tsx -> insomnia/src/ui/components/viewers/response-multipart-viewer.tsx

Analysis

No Change: This PR does not introduce or remove any circular references.


This report was generated automatically by comparing against the develop branch.

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.

2 participants