diff --git a/src/lib/editorFile.js b/src/lib/editorFile.js index 7a452d4c9..bf1f21cb7 100644 --- a/src/lib/editorFile.js +++ b/src/lib/editorFile.js @@ -1285,8 +1285,9 @@ export default class EditorFile { /** * Sets syntax highlighting of the file. * @param {string} [mode] + * @param {{ recommend?: boolean }} [options] */ - setMode(mode) { + setMode(mode, options = {}) { if (this.type !== "editor") return; const event = createFileEvent(this); this.#emit("changemode", event); @@ -1309,7 +1310,9 @@ export default class EditorFile { // Store mode info for later use when creating editor view this.currentMode = mode; this.currentLanguageExtension = modeInfo?.getExtension() || null; - maybeRecommendLanguageModeExtension(this, modeInfo); + if (options.recommend !== false) { + maybeRecommendLanguageModeExtension(this, modeInfo); + } // sets file icon this.#tab.lead( diff --git a/src/lib/editorManager.js b/src/lib/editorManager.js index bc11557cc..6b7c07dd0 100644 --- a/src/lib/editorManager.js +++ b/src/lib/editorManager.js @@ -1746,6 +1746,7 @@ async function EditorManager($header, $body) { editor, readOnlyCompartment, getFile, + reapplyActiveFile, switchFile, moveFileByPinnedState, normalizePinnedTabOrder, @@ -2944,6 +2945,12 @@ async function EditorManager($header, $body) { toggleProblemButton(); } + function reapplyActiveFile() { + const file = manager.activeFile; + if (!file || file.type !== "editor" || !file.loaded || file.loading) return; + applyFileToEditor(file, { forceRecreate: true }); + } + /** * Initializes the file tab container. */ diff --git a/src/lib/languageModeRecommendations.js b/src/lib/languageModeRecommendations.js index 68cdd9e18..48143e177 100644 --- a/src/lib/languageModeRecommendations.js +++ b/src/lib/languageModeRecommendations.js @@ -1,3 +1,4 @@ +import { getModeForPath } from "cm/modelist"; import notificationManager from "lib/notificationManager"; import Path from "utils/Path"; import Url from "utils/Url"; @@ -98,9 +99,9 @@ class LanguageModeRecommendations { } this.pendingKeywords.add(keyword); - void this.showRecommendation(keyword) - .then(() => { - this.notifiedKeywords.add(keyword); + void this.showRecommendation(keyword, filename) + .then((shown) => { + if (shown) this.notifiedKeywords.add(keyword); }) .catch((error) => { console.warn("Failed to show extension recommendation.", error); @@ -110,8 +111,12 @@ class LanguageModeRecommendations { }); } - async showRecommendation(keyword) { + async showRecommendation(keyword, filename) { const hasPlugins = await this.getPluginAvailability(keyword); + // If a plugin registered the mode while the lookup was pending, suppress + // this stale recommendation and leave the keyword eligible for future checks. + if (!hasPlainTextFallback(getModeForPath(filename), filename)) return false; + const displayExt = `.${keyword}`; if (hasPlugins) { @@ -135,7 +140,7 @@ class LanguageModeRecommendations { }, ], }); - return; + return true; } const issueUrl = getIssueUrl(keyword); @@ -159,6 +164,7 @@ class LanguageModeRecommendations { }, ], }); + return true; } } diff --git a/src/main.js b/src/main.js index 05ef4c067..1d35cc823 100644 --- a/src/main.js +++ b/src/main.js @@ -295,6 +295,12 @@ async function onDeviceReady() { // Re-emit events for active file after plugins are loaded const { activeFile } = editorManager; + for (const file of editorManager.files) { + if (file?.type === "editor") { + file.setMode(undefined, { recommend: false }); + } + } + editorManager.reapplyActiveFile(); if (activeFile?.uri) { // Re-emit file-loaded event editorManager.emit("file-loaded", activeFile);