Skip to content

fix(editor): stabilize restored selection and loading state which was causing two edge cases#2168

Merged
bajrangCoder merged 2 commits into
Acode-Foundation:mainfrom
bajrangCoder:fix/editor-restore-loading-edge-cases
Jun 9, 2026
Merged

fix(editor): stabilize restored selection and loading state which was causing two edge cases#2168
bajrangCoder merged 2 commits into
Acode-Foundation:mainfrom
bajrangCoder:fix/editor-restore-loading-edge-cases

Conversation

@bajrangCoder

Copy link
Copy Markdown
Member

No description provided.

@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes two editor state restoration edge cases: it eliminates the "loading..." placeholder that was polluting undo history and causing visible flicker, and it ensures persisted selections are always collapsed to single cursor positions to prevent out-of-bounds errors on restore.

  • Loading state overhaul: replaces session.setValue(\"loading...\") with a two-phase emit approach — the first emit(\"file-loaded\") (before I/O) shows the existing content in read-only mode, and the second (after loading) triggers a full CodeMirror state recreation with the new document and all extensions.
  • savedDoc tracking fix: when both a cache and a disk copy exist, the old code used cache content as #savedDoc, silently hiding unsaved changes; the new code always reads the disk separately to get an accurate reference point for hasUnsavedChanges().
  • Selection collapse in saveState: collapseSelectionForRestore ensures only a collapsed cursor is ever persisted, preventing a restored multi-character selection from extending beyond a newly-loaded (possibly shorter) document.

Confidence Score: 4/5

The core loading-state and savedDoc fixes are sound, but the setTimeout cursor/scroll restoration path still applies to the global editor regardless of which tab is active, meaning a background file finishing its load can silently move the cursor or scroll position of the tab the user is currently looking at.

The two-phase emit pattern, the direct field assignment for background-tab editable state, and the savedDoc disk-read fix are all correct. The one concern is that restoreSelection and setScrollPosition inside the setTimeout callback use the global editor reference with no active-tab guard — so when a background file finishes loading, its saved cursor and scroll are applied to whatever file the user is currently viewing.

src/lib/editorFile.js — the setTimeout block at the end of #loadText needs a guard to skip cursor and scroll restoration when the loaded file is not the active tab.

Important Files Changed

Filename Overview
src/lib/editorFile.js Loading flow restructured: removes "loading..." placeholder, introduces two-phase file-loaded emit, reads disk for savedDoc even when cache exists, and correctly sets editable state for background tabs via direct field assignment.
src/lib/saveState.js Adds collapseSelectionForRestore to always persist a collapsed cursor instead of a selection range, preventing out-of-bounds restore errors when document length changes between sessions.

Sequence Diagram

sequenceDiagram
    participant LT as #loadText()
    participant EM as editorManager
    participant AFE as applyFileToEditor()

    LT->>LT: "setReadOnly(true), loading=true"
    LT->>EM: emit("file-loaded") [interim, active tab only]
    EM->>AFE: applyFileToEditor(file)
    AFE->>AFE: isReusableEditorState? → fast-path: old doc, read-only

    LT->>LT: read cache (if exists)
    LT->>LT: "read disk → savedDoc = EditorState.create({doc: diskValue}).doc"
    LT->>LT: "session = EditorState.create({doc: value})"
    LT->>LT: "__cmSessionReady = false"
    LT->>LT: "markLoaded({savedDoc})"

    LT->>EM: emit("file-loaded") [final, active tab only]
    EM->>AFE: applyFileToEditor(file)
    AFE->>AFE: "isReusableEditorState? → false (__cmSessionReady=false)"
    AFE->>AFE: create full state with doc + all extensions
    AFE->>AFE: "__cmSessionReady = true"

    LT->>LT: setTimeout: restoreSelection + restoreFolds
Loading

Reviews (2): Last reviewed commit: "fix" | Re-trigger Greptile

Comment thread src/lib/editorFile.js
Comment thread src/lib/editorFile.js Outdated
@bajrangCoder

This comment was marked as outdated.

@bajrangCoder bajrangCoder merged commit a77773d into Acode-Foundation:main Jun 9, 2026
7 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in The Code Board - Acode Jun 9, 2026
@bajrangCoder bajrangCoder deleted the fix/editor-restore-loading-edge-cases branch June 9, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant