Skip to content

fix(editor): preserve restored tab editability while loading#2431

Merged
bajrangCoder merged 2 commits into
mainfrom
fix/editor-restore-readonly-regression
Jul 1, 2026
Merged

fix(editor): preserve restored tab editability while loading#2431
bajrangCoder merged 2 commits into
mainfrom
fix/editor-restore-readonly-regression

Conversation

@bajrangCoder

@bajrangCoder bajrangCoder commented Jul 1, 2026

Copy link
Copy Markdown
Member

Closes: #2418

@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a tab-restore editability flicker (issue #2418) where editable files would briefly become read-only at the start of #loadText() because setReadOnly(true) was unconditionally called for all files entering the loading phase. The fix also widens the editable computation to respect both options.editable and options.readOnly.

  • Root cause fixed: The unconditional setReadOnly(true) in #loadText() is replaced with a guard that only applies it when !editable, so editable files no longer flicker to read-only state during loading.
  • Early state assignment: this.readOnly and this.#editable are now set eagerly in the constructor before any load/loaded branch, superseding the removed else { this.editable = editable } and the removed else if (editable !== undefined) cleanup branches.
  • editable computation widened: options?.editable ?? true is replaced with options?.editable !== undefined ? !!options.editable : !options?.readOnly, so passing readOnly: true without an explicit editable key now correctly marks the file as non-editable.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to removing an unconditional read-only guard that was causing the flicker, replacing it with a properly gated one, and consolidating the editable-state assignment.

The three touch-points are self-consistent: early this.readOnly/this.#editable assignment in the constructor means all downstream consumers (applyCurrentEditorOptions in editorManager reads file.editable, #loadText reads from #loadOptions.editable) see correct state. The only behavioral change for editable files is that setReadOnly(true) is no longer dispatched at load start, which was precisely the flicker bug. For non-editable files the guard still fires, preserving the protection window. No new code paths are introduced and no data is mutated in unexpected ways.

No files require special attention.

Important Files Changed

Filename Overview
src/lib/editorFile.js Fixes editability flicker by guarding setReadOnly(true) at load start; early this.readOnly/this.#editable assignment replaces redundant setter-based branches; editable now correctly derives from both options.editable and options.readOnly.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant R as restore() / constructor
    participant LT as #loadText()
    participant EM as editorManager<br/>(applyCurrentEditorOptions)

    Note over R: options.editable / options.readOnly resolved
    R->>R: "editable = options.editable !== undefined<br/>? !!options.editable : !options.readOnly"
    R->>R: "this.readOnly = !editable (early assignment)"
    R->>R: "this.#editable = editable (early assignment)"

    alt file not yet loaded
        R->>R: "store #loadOptions { editable }"
        Note over R,EM: user switches to tab → makeActive()
        R->>LT: "#loadText() triggered"
        alt !editable (read-only file)
            LT->>EM: "setReadOnly(true) → compartment = read-only"
        else editable file (FIX: no longer flickers)
            Note over LT: setReadOnly(true) NOT called
        end
        LT->>LT: "loading = true … async file read …"
        LT->>LT: "session set, loading = false"
        alt this is the active file
            LT->>EM: "setReadOnly(editable === false)"
            LT->>EM: emit(file-loaded)
        end
    else file already loaded (options.text provided)
        Note over R,EM: this.readOnly / #editable already set above
        Note over EM: on tab switch → applyCurrentEditorOptions()<br/>ro = !file.editable ∥ !!file.loading → compartment correct
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant R as restore() / constructor
    participant LT as #loadText()
    participant EM as editorManager<br/>(applyCurrentEditorOptions)

    Note over R: options.editable / options.readOnly resolved
    R->>R: "editable = options.editable !== undefined<br/>? !!options.editable : !options.readOnly"
    R->>R: "this.readOnly = !editable (early assignment)"
    R->>R: "this.#editable = editable (early assignment)"

    alt file not yet loaded
        R->>R: "store #loadOptions { editable }"
        Note over R,EM: user switches to tab → makeActive()
        R->>LT: "#loadText() triggered"
        alt !editable (read-only file)
            LT->>EM: "setReadOnly(true) → compartment = read-only"
        else editable file (FIX: no longer flickers)
            Note over LT: setReadOnly(true) NOT called
        end
        LT->>LT: "loading = true … async file read …"
        LT->>LT: "session set, loading = false"
        alt this is the active file
            LT->>EM: "setReadOnly(editable === false)"
            LT->>EM: emit(file-loaded)
        end
    else file already loaded (options.text provided)
        Note over R,EM: this.readOnly / #editable already set above
        Note over EM: on tab switch → applyCurrentEditorOptions()<br/>ro = !file.editable ∥ !!file.loading → compartment correct
    end
Loading

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

Comment thread src/lib/editorFile.js
@bajrangCoder

This comment was marked as outdated.

@bajrangCoder bajrangCoder merged commit 9a550bb into main Jul 1, 2026
10 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in The Code Board - Acode Jul 1, 2026
@bajrangCoder bajrangCoder deleted the fix/editor-restore-readonly-regression branch July 1, 2026 13:59
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.

Typing Blocked

1 participant