From 90bae01db930f11951f75cb28f2da54c2b8b4b9b Mon Sep 17 00:00:00 2001 From: Ana Date: Sun, 27 Sep 2026 09:10:40 +0200 Subject: [PATCH] fix(editor): highlight Solidity files (#20928) Map .sol to Monaco's built-in 'sol' language id. The grammar already ships with monaco-editor; only the extension lookup was missing, so .sol fell through to plaintext. Closes #13835 Co-authored-by: Neil --- src/renderer/src/lib/language-detect.test.ts | 5 +++++ src/renderer/src/lib/language-detect.ts | 2 ++ .../solidity-language-id-registration.test.ts | 20 +++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 src/renderer/src/lib/solidity-language-id-registration.test.ts diff --git a/src/renderer/src/lib/language-detect.test.ts b/src/renderer/src/lib/language-detect.test.ts index ad973ccf848..9493bae9485 100644 --- a/src/renderer/src/lib/language-detect.test.ts +++ b/src/renderer/src/lib/language-detect.test.ts @@ -112,6 +112,11 @@ describe('detectLanguage', () => { expect(detectLanguage('C:\\theme\\snippets\\CART.LIQUID')).toBe('liquid') }) + it('maps .sol files to the Monaco built-in sol language id, not the solidity alias', () => { + expect(detectLanguage('contracts/Vault.sol')).toBe('sol') + expect(detectLanguage('C:\\repo\\contracts\\TOKEN.SOL')).toBe('sol') + }) + it('maps Salesforce Apex sources to the apex language id (case-insensitive)', () => { expect(detectLanguage('force-app/main/default/classes/AccountService.cls')).toBe('apex') expect(detectLanguage('force-app/main/default/triggers/AccountTrigger.trigger')).toBe('apex') diff --git a/src/renderer/src/lib/language-detect.ts b/src/renderer/src/lib/language-detect.ts index 1090906a6bd..da92de9464d 100644 --- a/src/renderer/src/lib/language-detect.ts +++ b/src/renderer/src/lib/language-detect.ts @@ -93,6 +93,8 @@ const EXT_TO_LANGUAGE: Record = { '.hrl': 'erlang', '.hs': 'haskell', '.clj': 'clojure', + // Why: Monaco registers Solidity under the id 'sol'; 'solidity' is only an alias. + '.sol': 'sol', '.vue': 'vue', '.svelte': 'svelte', '.astro': 'astro', diff --git a/src/renderer/src/lib/solidity-language-id-registration.test.ts b/src/renderer/src/lib/solidity-language-id-registration.test.ts new file mode 100644 index 00000000000..5cfe2598837 --- /dev/null +++ b/src/renderer/src/lib/solidity-language-id-registration.test.ts @@ -0,0 +1,20 @@ +import { readFileSync } from 'node:fs' +import { createRequire } from 'node:module' +import { describe, expect, it } from 'vitest' +import { detectLanguage } from './language-detect' + +// Why: Monaco registers Solidity as id 'sol' with 'solidity' only an alias, and +// mapping an alias silently renders plaintext. Pin against the installed package +// so an upstream id change fails here instead of in the editor. +describe('solidity language id', () => { + it('matches the id monaco-editor registers for .sol', () => { + const require = createRequire(import.meta.url) + const source = readFileSync( + require.resolve('monaco-editor/esm/vs/basic-languages/solidity/solidity.contribution.js'), + 'utf8' + ) + const registeredId = /id:\s*["']([^"']+)["']/.exec(source)?.[1] + expect(registeredId).toBeDefined() + expect(detectLanguage('contracts/Vault.sol')).toBe(registeredId) + }) +})