Skip to content

fix(editor): apply plugin language modes after restore (for plugin modes)#2375

Merged
bajrangCoder merged 2 commits into
mainfrom
fix/plugin-mode-restore
Jun 24, 2026
Merged

fix(editor): apply plugin language modes after restore (for plugin modes)#2375
bajrangCoder merged 2 commits into
mainfrom
fix/plugin-mode-restore

Conversation

@bajrangCoder

Copy link
Copy Markdown
Member

No description provided.

@bajrangCoder bajrangCoder marked this pull request as ready for review June 24, 2026 08:24
@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes plugin-provided language modes not being applied to editor files that were restored before the plugins finished loading. After plugins load, the code now refreshes mode metadata for all open editor files and force-recreates the active file's editor state to pick up the newly registered language extensions.

  • src/main.js: After loadPlugins(), iterates all editor files calling setMode(undefined, { recommend: false }) to refresh currentMode/currentLanguageExtension metadata, then calls reapplyActiveFile() to force-recreate the active file's CodeMirror state with the correct plugin language extension.
  • src/lib/editorFile.js: Adds an options.recommend parameter to setMode() so callers can refresh mode metadata without triggering extension recommendation notifications.
  • src/lib/languageModeRecommendations.js: After the async plugin-availability API call resolves, re-checks whether the file's mode is still the text fallback; if a plugin registered the mode during the fetch, suppresses the now-stale recommendation and leaves the keyword eligible for future evaluation.

Confidence Score: 5/5

Safe to merge — the changes are well-scoped, additive, and don't alter existing code paths for users without plugins.

The mode-refresh loop and active-file reapply only run once after plugin load, use correct guards (file.type === "editor", file.loaded, !file.loading), and default behavior of all modified APIs is unchanged. The stale-recommendation suppression in showRecommendation is logically sound: the post-fetch re-check correctly detects whether a plugin registered a mode during the async window, and the notifiedKeywords update is now correctly gated on the actual return value.

No files require special attention.

Important Files Changed

Filename Overview
src/main.js Adds a post-plugin-load mode refresh loop and active-file reapply; logic is correct and ordering is safe.
src/lib/editorFile.js Adds optional recommend flag to setMode(); default behavior is unchanged, new option is correctly guarded.
src/lib/languageModeRecommendations.js Adds stale-recommendation suppression: after async fetch, re-checks whether a plugin registered the mode; return value semantics are correct throughout.
src/lib/editorManager.js Adds reapplyActiveFile() helper that force-recreates the active file's editor state; guard conditions are appropriate.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant App as main.js
    participant PM as Plugin Loader
    participant EM as EditorManager
    participant EF as EditorFile (each)
    participant LMR as LanguageModeRecommendations
    participant CM as CodeMirror Editor

    App->>PM: loadPlugins()
    PM-->>App: plugins loaded (modes registered)

    App->>EF: "file.setMode(undefined, { recommend: false })"
    Note over EF: Resolves currentMode via getModeForPath()<br/>(now picks up plugin-registered mode)
    EF-->>App: currentMode / currentLanguageExtension updated

    App->>EM: reapplyActiveFile()
    EM->>CM: "applyFileToEditor(activeFile, { forceRecreate: true })"
    Note over CM: Recreates EditorState with<br/>plugin language extension

    App->>EM: emit(file-loaded, activeFile)
    App->>EM: emit(switch-file, activeFile)

    Note over LMR: On initial restore (before plugins loaded)
    LMR->>LMR: showRecommendation(keyword, filename)
    LMR->>LMR: await getPluginAvailability(keyword)
    LMR->>LMR: re-check hasPlainTextFallback(getModeForPath(filename))
    alt Plugin registered mode during fetch
        LMR-->>LMR: return false (suppress stale recommendation)
        Note over LMR: notifiedKeywords NOT updated
    else Still plain-text fallback
        LMR->>LMR: pushNotification()
        LMR-->>LMR: return true
        Note over LMR: notifiedKeywords.add(keyword)
    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 App as main.js
    participant PM as Plugin Loader
    participant EM as EditorManager
    participant EF as EditorFile (each)
    participant LMR as LanguageModeRecommendations
    participant CM as CodeMirror Editor

    App->>PM: loadPlugins()
    PM-->>App: plugins loaded (modes registered)

    App->>EF: "file.setMode(undefined, { recommend: false })"
    Note over EF: Resolves currentMode via getModeForPath()<br/>(now picks up plugin-registered mode)
    EF-->>App: currentMode / currentLanguageExtension updated

    App->>EM: reapplyActiveFile()
    EM->>CM: "applyFileToEditor(activeFile, { forceRecreate: true })"
    Note over CM: Recreates EditorState with<br/>plugin language extension

    App->>EM: emit(file-loaded, activeFile)
    App->>EM: emit(switch-file, activeFile)

    Note over LMR: On initial restore (before plugins loaded)
    LMR->>LMR: showRecommendation(keyword, filename)
    LMR->>LMR: await getPluginAvailability(keyword)
    LMR->>LMR: re-check hasPlainTextFallback(getModeForPath(filename))
    alt Plugin registered mode during fetch
        LMR-->>LMR: return false (suppress stale recommendation)
        Note over LMR: notifiedKeywords NOT updated
    else Still plain-text fallback
        LMR->>LMR: pushNotification()
        LMR-->>LMR: return true
        Note over LMR: notifiedKeywords.add(keyword)
    end
Loading

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

Comment thread src/main.js
@bajrangCoder

This comment was marked as outdated.

@bajrangCoder bajrangCoder merged commit 77b3982 into main Jun 24, 2026
10 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in The Code Board - Acode Jun 24, 2026
@bajrangCoder bajrangCoder deleted the fix/plugin-mode-restore branch June 24, 2026 10:46
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