From 7fe2e0a6d63fe68e686632f0922e2d4db7e77578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 12:04:36 +0200 Subject: [PATCH 01/28] refactor: compute location sooner --- src/extensions.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/extensions.ts b/src/extensions.ts index 76853ab8..d756ff86 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -100,7 +100,12 @@ export function registerExtension (manifest: IExtensionManifest, extHostKind?: E const location = URI.from({ scheme: 'extension', authority: id, path }) const addExtensionPromise = (async () => { - const logger = await getService(ILogService) + const remoteAuthority = (await getService(IWorkbenchEnvironmentService)).remoteAuthority + let realLocation = location + if (extHostKind === ExtensionHostKind.Remote) { + realLocation = URI.from({ scheme: Schemas.vscodeRemote, authority: remoteAuthority, path }) + } + const localizedManifest = defaultNLS != null ? localizeManifest(logger, manifest, defaultNLS) : manifest let extension: IExtensionWithExtHostKind = { @@ -108,21 +113,13 @@ export function registerExtension (manifest: IExtensionManifest, extHostKind?: E type: builtin ? ExtensionType.System : ExtensionType.User, isBuiltin: builtin, identifier: { id }, - location, + location: realLocation, targetPlatform: TargetPlatform.WEB, isValid: true, validations: [], extHostKind } - if (extHostKind === ExtensionHostKind.Remote) { - const remoteAuthority = (await getService(IWorkbenchEnvironmentService)).remoteAuthority - extension = { - ...extension, - location: URI.from({ scheme: Schemas.vscodeRemote, authority: remoteAuthority, path }) - } - } - await deltaExtensions([extension], []) return extension From 41da985068c72638d1e0f04ad1f58f5c99ecb93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:37:38 +0200 Subject: [PATCH 02/28] fix: properly use variable --- src/service-override/layout.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/service-override/layout.ts b/src/service-override/layout.ts index 2cc92cd9..551ee776 100644 --- a/src/service-override/layout.ts +++ b/src/service-override/layout.ts @@ -218,12 +218,12 @@ export class LayoutService implements ILayoutService, IWorkbenchLayoutService { // otherwise fall back to any view that has views still refs #111463 if (panelToOpen == null || !this.hasViews(panelToOpen)) { panelToOpen = this.viewDescriptorService - .getViewContainersByLocation(ViewContainerLocation.Panel) + .getViewContainersByLocation(location) .find(viewContainer => this.hasViews(viewContainer.id))?.id } if (panelToOpen != null) { - void this.paneCompositeService.openPaneComposite(panelToOpen, ViewContainerLocation.Panel, true) + void this.paneCompositeService.openPaneComposite(panelToOpen, location, true) } } From fc2cbcc26ccc6d2f08571aecc1bb500032c45b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:38:51 +0200 Subject: [PATCH 03/28] fix: make sure to not keep monaco deleted files --- scripts/install-vscode | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/install-vscode b/scripts/install-vscode index 9673306c..538fed6e 100755 --- a/scripts/install-vscode +++ b/scripts/install-vscode @@ -46,6 +46,9 @@ cd .. mkdir -p editor-patch cp -R $monaco_esm_directory editor-patch/a cp -R $monaco_esm_directory editor-patch/b +find editor-patch/b/vs/editor -name "*.js" -type f -delete +find editor-patch/b/vs/base -name "*.js" -type f -delete +find editor-patch/b/vs/platform -name "*.js" -type f -delete ## Change shake level from ClassMembers to Files sed -i'' -e 's/shakeLevel: 2/shakeLevel: 0/g' build/gulpfile.editor.js yarn gulp editor-distro From 4037bf4bb8cc4b62813b4e788b2deb435e1beff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:39:23 +0200 Subject: [PATCH 04/28] fix: handle deleted files in treemending script --- src/monaco-treemending.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/monaco-treemending.ts b/src/monaco-treemending.ts index 5c9ba741..ea6f1f35 100644 --- a/src/monaco-treemending.ts +++ b/src/monaco-treemending.ts @@ -62,8 +62,13 @@ async function run () { return } try { - await fs.mkdir(path.dirname(file), { recursive: true }) - await fs.writeFile(file, content) + if (index.newHeader === '1970-01-01 01:00:00.000000000 +0100') { + // timestamp 0 means the fiel was removed + await fs.unlink(file) + } else { + await fs.mkdir(path.dirname(file), { recursive: true }) + await fs.writeFile(file, content) + } callback(null) } catch (err) { callback(err) From d5185128af4fe30100ad9ddfed2f90ed740fc417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:40:14 +0200 Subject: [PATCH 05/28] feat: download vscode-loc as well --- .gitignore | 1 + scripts/install-vscode | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 77f605c5..2658bd96 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules/ vscode/ +vscode-loc/ vscode-default-extensions/ dist/ monaco-editor-treemending.patch \ No newline at end of file diff --git a/scripts/install-vscode b/scripts/install-vscode index 538fed6e..ebca1872 100755 --- a/scripts/install-vscode +++ b/scripts/install-vscode @@ -6,6 +6,7 @@ cat <<< "$(jq ".config.vscode.ref = \"$vscodeRef\"" package.json)" > package.jso monaco_esm_directory="`pwd`/node_modules/monaco-editor/esm" output_directory="`pwd`/vscode" +loc_output_directory="`pwd`/vscode-loc" extension_output_directory="`pwd`/vscode-default-extensions" patch_file="`pwd`/scripts/vscode.patch" editor_patch_file="`pwd`/monaco-editor-treemending.patch" @@ -99,5 +100,11 @@ NODE_OPTIONS=--max-old-space-size=8192 npx tsc --declaration --importHelpers --m # Copy files that are already built find ./ \( -name '*.js' -o -name '*.d.ts' -o -name '*.css' -o -name '*.mp3' -o -name '*.svg' -o -name '*.html' \) -exec rsync -R \{\} "$output_directory/src" \; +echo "Downloading vscode-loc" +rm -rf $loc_output_directory +mkdir -p $loc_output_directory +curl -L --max-redirs 5 https://github.com/microsoft/vscode-loc/archive/refs/heads/main.tar.gz | tar -xz -C $loc_output_directory --strip-components=2 vscode-loc-main/i18n + + echo "Cleaning..." rm -rf $build_directory From d225608bf374126c6a0679b3ce66ad208208ffb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:41:03 +0200 Subject: [PATCH 06/28] feat: add setLocale method in monaco nls --- scripts/vscode.patch | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/scripts/vscode.patch b/scripts/vscode.patch index e28f5450..0594da76 100644 --- a/scripts/vscode.patch +++ b/scripts/vscode.patch @@ -296,6 +296,44 @@ index 01f2c6987ac..5d6abf9d561 100644 this._cachedResolver = new KeybindingResolver(defaults, overrides, (str) => this._log(str)); } return this._cachedResolver; +diff --git a/src/vs/nls.ts b/src/vs/nls.ts +index db57b98d67b..defd683e0b0 100644 +--- a/src/vs/nls.ts ++++ b/src/vs/nls.ts +@@ -130,6 +130,24 @@ export function localize(data: ILocalizeInfo | string, message: string, ...args: + return _format(message, args); + } + ++ ++let locale: string | undefined = undefined; ++let translations: Record> = {}; ++ ++export function setLocale(_locale: string, _translations: Record>) { ++ locale = _locale; ++ translations = _translations; ++} ++ ++/** ++ * @skipMangle ++ */ ++export function localizeWithPath(path: string, data: ILocalizeInfo | string, defaultMessage: string, ...args: (string | number | boolean | undefined | null)[]): string { ++ const key = typeof data === 'object' ? data.key : data; ++ const message = (translations[path] ?? {})[key] ?? defaultMessage; ++ return _format(message, args); ++} ++ + /** + * + * @param stringFromLocalizeCall You must pass in a string that was returned from a `nls.localize()` call +@@ -142,7 +160,7 @@ export function getConfiguredDefaultLocale(stringFromLocalizeCall: string): stri + export function getConfiguredDefaultLocale(_: string): string | undefined { + // This returns undefined because this implementation isn't used and is overwritten by the loader + // when loaded. +- return undefined; ++ return locale; + } + + /** diff --git a/src/vs/platform/assignment/common/assignmentService.ts b/src/vs/platform/assignment/common/assignmentService.ts index 67e34826627..7c5287d6a32 100644 --- a/src/vs/platform/assignment/common/assignmentService.ts From 4c117a0918e75a4e386efb932beeacc3b213eef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:42:15 +0200 Subject: [PATCH 07/28] feat: replace localize calls to localizeWithPath to be able to translate them using vscode-loc. In VSCode this is handled by the build process --- scripts/vscode.patch | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/scripts/vscode.patch b/scripts/vscode.patch index 0594da76..067265d0 100644 --- a/scripts/vscode.patch +++ b/scripts/vscode.patch @@ -11,7 +11,7 @@ index f44673cd1cd..cdb439f7dd1 100644 "xterm", "xterm-addon-canvas", diff --git a/build/lib/standalone.js b/build/lib/standalone.js -index 38be1131300..52c3b2b0a82 100644 +index 38be1131300..f958d658cb2 100644 --- a/build/lib/standalone.js +++ b/build/lib/standalone.js @@ -150,6 +150,9 @@ function createESMSourcesAndResources2(options) { @@ -35,16 +35,29 @@ index 38be1131300..52c3b2b0a82 100644 relativePath = relativePath.replace(/\\/g, '/'); if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { relativePath = './' + relativePath; -@@ -318,4 +325,4 @@ function transportCSS(module, enqueue, write) { +@@ -183,6 +190,13 @@ function createESMSourcesAndResources2(options) { + fileContents = fileContents.replace(/import ([a-zA-Z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) { + return `import * as ${m1} from ${m2};`; + }); ++ fileContents = fileContents.replace(/(\bfunction\s+localize\()|(\blocalize\()/g, function (text) { ++ if (/function\s+localize/.test(text)) { ++ return text; ++ } ++ return `localizeWithPath('${file.slice(0, -3)}', `; ++ }); ++ fileContents = fileContents.replace(/import { localize }/g, 'import { localizeWithPath }'); + write(getDestAbsoluteFilePath(file), fileContents); + continue; + } +@@ -318,4 +332,4 @@ function transportCSS(module, enqueue, write) { return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; } } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhbG9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInN0YW5kYWxvbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QixxQ0FBcUM7QUFFckMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDakQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFFNUMsTUFBTSxRQUFRLEdBQStCLEVBQUUsQ0FBQztBQUVoRCxTQUFTLFNBQVMsQ0FBQyxRQUFnQixFQUFFLFFBQXlCO0lBQzdELFNBQVMsVUFBVSxDQUFDLE9BQWU7UUFDbEMsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDdEIsT0FBTztTQUNQO1FBQ0QsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUV6QixVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUMzQixPQUFPO1NBQ1A7UUFDRCxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7SUFDRCxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ25DLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxTQUFnQixhQUFhLENBQUMsT0FBdUQ7SUFDcEYsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBZ0MsQ0FBQztJQUVoRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMs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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhbG9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInN0YW5kYWxvbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QixxQ0FBcUM7QUFFckMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDakQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFFNUMsTUFBTSxRQUFRLEdBQStCLEVBQUUsQ0FBQztBQUVoRCxTQUFTLFNBQVMsQ0FBQyxRQUFnQixFQUFFLFFBQXlCO0lBQzdELFNBQVMsVUFBVSxDQUFDLE9BQWU7UUFDbEMsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDdEIsT0FBTztTQUNQO1FBQ0QsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUV6QixVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUMzQixPQUFPO1NBQ1A7UUFDRCxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7SUFDRCxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ25DLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxTQUFnQixhQUFhLENBQUMsT0FBdUQ7SUFDcEYsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBZ0MsQ0FBQztJQUVoRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMs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 -\ No newline at end of file diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts -index 775a1be5996..ce8435bd920 100644 +index 775a1be5996..9a6d37f2765 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -180,6 +180,9 @@ export function createESMSourcesAndResources2(options: IOptions2): void { @@ -68,6 +81,22 @@ index 775a1be5996..ce8435bd920 100644 relativePath = relativePath.replace(/\\/g, '/'); if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { relativePath = './' + relativePath; +@@ -216,6 +223,15 @@ export function createESMSourcesAndResources2(options: IOptions2): void { + return `import * as ${m1} from ${m2};`; + }); + ++ fileContents = fileContents.replace(/(\bfunction\s+localize\()|(\blocalize\()/g, function (text) { ++ if (/function\s+localize/.test(text)) { ++ return text; ++ } ++ return `localizeWithPath('${file.slice(0, -3)}', `; ++ }); ++ ++ fileContents = fileContents.replace(/import { localize }/g, 'import { localizeWithPath }'); ++ + write(getDestAbsoluteFilePath(file), fileContents); + continue; + } diff --git a/extensions/typescript-language-features/web/typingsInstaller.ts b/extensions/typescript-language-features/web/typingsInstaller.ts index 7b9b164c40c..a961bb7267a 100644 --- a/extensions/typescript-language-features/web/typingsInstaller.ts From 9455c5f218dc63652a3bc56350bb87a1c1f55cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:42:52 +0200 Subject: [PATCH 08/28] fix: do not encode URL --- scripts/vscode.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/vscode.patch b/scripts/vscode.patch index 067265d0..6ef2c123 100644 --- a/scripts/vscode.patch +++ b/scripts/vscode.patch @@ -97,6 +97,19 @@ index 775a1be5996..9a6d37f2765 100644 write(getDestAbsoluteFilePath(file), fileContents); continue; } +diff --git a/extensions/markdown-language-features/src/extension.browser.ts b/extensions/markdown-language-features/src/extension.browser.ts +index 30639672490..2095905a4d8 100644 +--- a/extensions/markdown-language-features/src/extension.browser.ts ++++ b/extensions/markdown-language-features/src/extension.browser.ts +@@ -30,7 +30,7 @@ function startServer(context: vscode.ExtensionContext, parser: IMdParser): Promi + const serverMain = vscode.Uri.joinPath(context.extensionUri, 'server/dist/browser/workerMain.js'); + + const worker = new Worker(serverMain.toString()); +- worker.postMessage({ i10lLocation: vscode.l10n.uri?.toString() ?? '' }); ++ worker.postMessage({ i10lLocation: vscode.l10n.uri?.toString(true) ?? '' }); + + return startClient((id: string, name: string, clientOptions: LanguageClientOptions) => { + return new LanguageClient(id, name, clientOptions, worker); diff --git a/extensions/typescript-language-features/web/typingsInstaller.ts b/extensions/typescript-language-features/web/typingsInstaller.ts index 7b9b164c40c..a961bb7267a 100644 --- a/extensions/typescript-language-features/web/typingsInstaller.ts From 2ee7b08eefbdb41b3fda3bdc38330b483dcaacd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:47:57 +0200 Subject: [PATCH 09/28] feat: stop removing some stuff from vscode --- rollup/rollup.config.ts | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/rollup/rollup.config.ts b/rollup/rollup.config.ts index 5e3a2c69..6d1b385a 100644 --- a/rollup/rollup.config.ts +++ b/rollup/rollup.config.ts @@ -98,10 +98,8 @@ const KEEP_COLORS = new Set([ ]) const REMOVE_WORKBENCH_CONTRIBUTIONS = new Set([ - 'DebugTitleContribution', 'ResetConfigurationDefaultsOverridesCache', 'ConfigurationMigrationWorkbenchContribution', - 'RegisterSearchViewContribution', 'ExtensionPoints' ]) @@ -198,13 +196,12 @@ function isCallPure (file: string, functionName: string, node: recast.types.name } } - if (file.includes('layoutActions') || file.includes('fileActions.contribution') || file.includes('windowActions') || file.includes('workspaceActions')) { + if (file.includes('windowActions') || file.includes('workspaceActions')) { return true } const firstParamCode = recast.print(firstParam).code if (firstParamCode.includes('DEBUG_CONFIGURE_COMMAND_ID') || - firstParamCode.includes('workbench.action.toggleMaximizedPanel') || firstParamCode.includes('OpenEditorsView')) { return true } @@ -273,13 +270,6 @@ function isCallPure (file: string, functionName: string, node: recast.types.name return false } - if (functionName === 'viewDescriptorsToRegister.push') { - const firstParamName = args[0]!.type === 'Identifier' ? getMemberExpressionPath(args[0]) : null - if (firstParamName === 'openEditorsViewDescriptor') { - return true - } - } - if (functionName === 'registerSingleton') { if (file.includes('vs/workbench/api/')) { return false From ad53b8248de0d7dfe247fc3082bc8ea1e7f403ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:49:19 +0200 Subject: [PATCH 10/28] feat: add l20n entrypoint to register a localization --- rollup/rollup.config.ts | 8 ++++++++ rollup/rollup.types.config.ts | 1 + src/l10n.ts | 18 ++++++++++++++++++ src/missing-services.ts | 6 ++++-- tsconfig.types.json | 1 + 5 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/l10n.ts diff --git a/rollup/rollup.config.ts b/rollup/rollup.config.ts index 6d1b385a..8c61d3c9 100644 --- a/rollup/rollup.config.ts +++ b/rollup/rollup.config.ts @@ -464,6 +464,7 @@ const input = { api: './src/api.ts', extensions: './src/extensions.ts', services: './src/services.ts', + l10n: './src/l10n.ts', monaco: './src/monaco.ts', ...Object.fromEntries( fs.readdirSync(path.resolve(SRC_DIR, 'service-override'), { withFileTypes: true }) @@ -871,6 +872,10 @@ export default (args: Record): rollup.RollupOptions[] => { types: './monaco.d.ts', default: './monaco.js' }, + './l10n': { + types: './l10n.d.ts', + default: './l10n.js' + }, './vscode/*': { default: './vscode/src/*.js' } @@ -895,6 +900,9 @@ export default (args: Record): rollup.RollupOptions[] => { lifecycle: [ './lifecycle.d.ts' ], + l10n: [ + './l10n.d.ts' + ], 'vscode/*': [ './vscode/src/*.d.ts' ] diff --git a/rollup/rollup.types.config.ts b/rollup/rollup.types.config.ts index fa956b2c..7566302c 100644 --- a/rollup/rollup.types.config.ts +++ b/rollup/rollup.types.config.ts @@ -101,6 +101,7 @@ export default rollup.defineConfig((<{input: Record, output: str 'services.d': './dist/types/src/services.d.ts', 'extensions.d': './dist/types/src/extensions.d.ts', 'monaco.d': './dist/types/src/monaco.d.ts', + 'l10n.d': './dist/types/src/l10n.d.ts', ...Object.fromEntries(fs.readdirSync(path.resolve(DIST_DIR, 'types/src/service-override'), { withFileTypes: true }) .filter(f => f.isFile()) .map(f => f.name) diff --git a/src/l10n.ts b/src/l10n.ts new file mode 100644 index 00000000..83d4499a --- /dev/null +++ b/src/l10n.ts @@ -0,0 +1,18 @@ +import { setLocale } from 'vs/nls' + +const extensionTranslationsUri: Record> = {} + +function registerLocalization (language: string, main: Record>, extensionTranslationsUris: Record): void { + setLocale(language, main) + + extensionTranslationsUri[language] = extensionTranslationsUris +} + +function getBuiltInExtensionTranslationsUris (language: string): Record | undefined { + return extensionTranslationsUri[language] +} + +export { + registerLocalization, + getBuiltInExtensionTranslationsUris +} diff --git a/src/missing-services.ts b/src/missing-services.ts index 61aef179..5d7f80fb 100644 --- a/src/missing-services.ts +++ b/src/missing-services.ts @@ -173,6 +173,7 @@ import { IBannerService } from 'vs/workbench/services/banner/browser/bannerServi import { ITitleService } from 'vs/workbench/services/title/common/titleService' import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents' import { unsupported } from './tools' +import { getBuiltInExtensionTranslationsUris } from './l10n' class NullLoggerService extends AbstractLoggerService { constructor () { @@ -1106,8 +1107,9 @@ registerSingleton(ILanguagePackService, class LanguagePackService implements ILa return [] } - async getBuiltInExtensionTranslationsUri (): Promise { - return undefined + async getBuiltInExtensionTranslationsUri (id: string, language: string): Promise { + const uri = getBuiltInExtensionTranslationsUris(language)?.[id] + return uri != null ? URI.parse(uri) : undefined } }, InstantiationType.Delayed) diff --git a/tsconfig.types.json b/tsconfig.types.json index 925e667b..a1b9ed85 100644 --- a/tsconfig.types.json +++ b/tsconfig.types.json @@ -63,6 +63,7 @@ "src/extensions.ts", "src/service-override/*.ts", "src/monaco.ts", + "src/l10n.ts", "src/rollup-vsix-plugin.ts", "src/rollup-extension-directory-plugin.ts" ] From 422317f16bfef84256a3207fad5dfb5483913544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:49:56 +0200 Subject: [PATCH 11/28] feat: add some tools --- src/tools.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/tools.ts b/src/tools.ts index 96357a7d..77acef97 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -21,3 +21,26 @@ export function memoizedConstructor (ctor: new (...args: any[]) => T): new (. }) }) } + +export async function sleep (duration: number): Promise { + await new Promise(resolve => setTimeout(resolve, duration)) +} + +export function throttle (fct: (param: T) => Promise, merge: (a: T, b: T) => T, delay: number): (param: T) => Promise { + let lastPromise: Promise = Promise.resolve() + let toConsume: T | null = null + + return async (param: T) => { + if (toConsume == null) { + toConsume = param + lastPromise = lastPromise.then(async () => sleep(delay)).then(async () => { + const _toConsume = toConsume! + toConsume = null + await fct(_toConsume) + }) + } else { + toConsume = merge(toConsume, param) + } + await lastPromise + } +} From e4f38c3e84a8bd72416a6d963a304cc436f06d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:51:55 +0200 Subject: [PATCH 12/28] feat: update rollup plugin to stop translating manifest at build time and bundling nls files --- package-lock.json | 115 +++++++++++++++++++++++ package.json | 1 + src/extension-tools.ts | 8 +- src/rollup-extension-directory-plugin.ts | 23 ++--- src/rollup-vsix-plugin.ts | 42 ++++----- 5 files changed, 151 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5925d580..92ee8216 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "cookie": "^0.5.0", "kerberos": "^2.0.1", "keytar": "^7.9.0", + "memfs": "^4.6.0", "mime-types": "^2.1.35", "monaco-editor": "0.44.0", "node-pty": "1.1.0-beta1", @@ -5129,6 +5130,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "peer": true + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -5763,6 +5770,14 @@ "node": ">= 14" } }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "engines": { + "node": ">=10.18" + } + }, "node_modules/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", @@ -6293,6 +6308,41 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-joy": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/json-joy/-/json-joy-9.6.0.tgz", + "integrity": "sha512-vJtJD89T0OOZFMaENe95xKCOdibMev/lELkclTdhZxLplwbBPxneWNuctUPizk2nLqtGfBxwCXVO42G9LBoFBA==", + "dependencies": { + "arg": "^5.0.2", + "hyperdyperid": "^1.2.0" + }, + "bin": { + "jj": "bin/jj.js", + "json-pack": "bin/json-pack.js", + "json-pack-test": "bin/json-pack-test.js", + "json-patch": "bin/json-patch.js", + "json-patch-test": "bin/json-patch-test.js", + "json-pointer": "bin/json-pointer.js", + "json-pointer-test": "bin/json-pointer-test.js", + "json-unpack": "bin/json-unpack.js" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "quill-delta": "^5", + "rxjs": "7", + "tslib": "2" + } + }, + "node_modules/json-joy/node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -6451,12 +6501,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "peer": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "peer": true + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -6535,6 +6597,25 @@ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, + "node_modules/memfs": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.6.0.tgz", + "integrity": "sha512-I6mhA1//KEZfKRQT9LujyW6lRbX7RkC24xKododIDO3AGShcaFAMKElv1yFGWX8fD4UaSiwasr3NeQ5TdtHY1A==", + "dependencies": { + "json-joy": "^9.2.0", + "thingies": "^1.11.1" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -7965,6 +8046,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/quill-delta": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz", + "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==", + "peer": true, + "dependencies": { + "fast-diff": "^1.3.0", + "lodash.clonedeep": "^4.5.0", + "lodash.isequal": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -8441,6 +8536,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "peer": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8894,6 +8998,17 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thingies": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.12.0.tgz", + "integrity": "sha512-AiGqfYC1jLmJagbzQGuoZRM48JPsr9yB734a7K6wzr34NMhjUPrWSQrkF7ZBybf3yCerCL2Gcr02kMv4NmaZfA==", + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", diff --git a/package.json b/package.json index a8cf11c2..0d8d5b0d 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "cookie": "^0.5.0", "kerberos": "^2.0.1", "keytar": "^7.9.0", + "memfs": "^4.6.0", "mime-types": "^2.1.35", "monaco-editor": "0.44.0", "node-pty": "1.1.0-beta1", diff --git a/src/extension-tools.ts b/src/extension-tools.ts index 043e6b1d..280522bf 100644 --- a/src/extension-tools.ts +++ b/src/extension-tools.ts @@ -171,7 +171,7 @@ async function extractResourcesFromExtensionManifestContribute (contribute: Real return resources.filter((resource, index, list) => !resource.path.startsWith('$(') && !list.slice(0, index).some(o => o === resource)) } -export async function extractResourcesFromExtensionManifest (manifest: IExtensionManifest, getFileContent: (path: string) => Promise): Promise { +export async function extractResourcesFromExtensionManifest (manifest: IExtensionManifest, getFileContent: (path: string) => Promise, listFiles: (path: string) => Promise): Promise { let resources: ExtensionResource[] = [] if (manifest.contributes != null) { @@ -188,6 +188,12 @@ export async function extractResourcesFromExtensionManifest (manifest: IExtensio resources.push(...(await extractResources(jsPath, getFileContent))) } + const nlsFiles = (await listFiles('/')).filter(file => /^package\.nls(?:\..*)?\.json$/.exec(file) != null) + resources.push(...nlsFiles.map(path => ({ + path, + mimeType: 'application/json' + }))) + resources = resources.map(r => { if (r.mimeType == null) { const detectedType = mime.lookup(r.path) diff --git a/src/rollup-extension-directory-plugin.ts b/src/rollup-extension-directory-plugin.ts index 19695504..5ad5fab5 100644 --- a/src/rollup-extension-directory-plugin.ts +++ b/src/rollup-extension-directory-plugin.ts @@ -1,12 +1,9 @@ import { createFilter, FilterPattern, dataToEsm } from '@rollup/pluginutils' import { Plugin } from 'rollup' -import { IExtensionManifest } from 'vs/platform/extensions/common/extensions' -import { localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls.js' -import { ConsoleLogger } from 'vs/platform/log/common/log' +import type { IExtensionManifest } from 'vs/platform/extensions/common/extensions' import * as path from 'path' import * as fsPromise from 'fs/promises' -import * as fs from 'fs' -import { ExtensionResource, extractResourcesFromExtensionManifest, parseJson } from './extension-tools' +import { ExtensionResource, extractResourcesFromExtensionManifest, parseJson } from './extension-tools.js' interface Options { include?: FilterPattern @@ -15,8 +12,6 @@ interface Options { getAdditionalResources?: (manifest: IExtensionManifest, directory: string) => Promise } -const logger = new ConsoleLogger() - export default function plugin ({ include, exclude, @@ -43,11 +38,7 @@ export default function plugin ({ const basename = path.basename(id) if (basename === 'package.json') { const content = await fsPromise.readFile(id) - let parsed = parseJson(id, content.toString('utf-8')) - const nlsFile = path.resolve(path.dirname(id), 'package.nls.json') - if (fs.existsSync(nlsFile)) { - parsed = localizeManifest(logger, parsed, parseJson(id, (await fsPromise.readFile(nlsFile)).toString())) - } + const parsed = parseJson(id, content.toString('utf-8')) return { code: dataToEsm(transformManifest(parsed), { compact: true, @@ -64,9 +55,13 @@ export default function plugin ({ const manifestPath = path.resolve(id, 'package.json') const manifest = transformManifest(parseJson(id, (await fsPromise.readFile(manifestPath)).toString('utf8'))) try { - const extensionResources = await extractResourcesFromExtensionManifest(manifest, async (resourcePath) => { + const getFileContent = async (resourcePath: string) => { return (await fsPromise.readFile(path.join(id, resourcePath))) - }) + } + const listFiles = async (dirPath: string) => { + return (await fsPromise.readdir(path.join(id, dirPath))) + } + const extensionResources = await extractResourcesFromExtensionManifest(manifest, getFileContent, listFiles) const resources = Array.from(new Set([ ...extensionResources, ...await getAdditionalResources(manifest, id) diff --git a/src/rollup-vsix-plugin.ts b/src/rollup-vsix-plugin.ts index de3fb9e2..262514c7 100644 --- a/src/rollup-vsix-plugin.ts +++ b/src/rollup-vsix-plugin.ts @@ -1,12 +1,11 @@ import { createFilter, FilterPattern } from '@rollup/pluginutils' import { InputPluginOption, Plugin } from 'rollup' import * as yauzl from 'yauzl' -import { IExtensionManifest } from 'vs/platform/extensions/common/extensions' -import { localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls.js' -import { ConsoleLogger } from 'vs/platform/log/common/log' +import type { IExtensionManifest } from 'vs/platform/extensions/common/extensions' +import { IFs, createFsFromVolume, Volume } from 'memfs' import { Readable } from 'stream' import * as path from 'path' -import { ExtensionResource, extractResourcesFromExtensionManifest, parseJson } from './extension-tools' +import { ExtensionResource, extractResourcesFromExtensionManifest, parseJson } from './extension-tools.js' interface Options { include?: FilterPattern @@ -16,8 +15,6 @@ interface Options { getAdditionalResources?: (manifest: IExtensionManifest) => Promise } -const logger = new ConsoleLogger() - function read (stream: Readable): Promise { const bufs: Buffer[] = [] return new Promise((resolve) => { @@ -30,7 +27,7 @@ function read (stream: Readable): Promise { }) } -async function readVsix (file: string): Promise> { +async function readVsix (file: string): Promise { return new Promise((resolve) => { const files: Record = {} yauzl.open(file, { lazyEntries: true }, (err, zipfile) => { @@ -50,7 +47,7 @@ async function readVsix (file: string): Promise> { } }) zipfile.on('end', function () { - resolve(files) + resolve(createFsFromVolume(Volume.fromJSON(files, '/'))) }) }) }) @@ -82,14 +79,18 @@ export default function plugin ({ async load (id) { if (!filter(id)) return null - const files = await readVsix(id) - const manifest = transformManifest(parseJson(id, files['package.json']!.toString('utf8'))) - - const extensionResources = (await extractResourcesFromExtensionManifest(manifest, async path => { - return files[getVsixPath(path)]! - })).filter(resource => getVsixPath(resource.realPath ?? resource.path) in files) + const vsixFS = await readVsix(id) + const readFileSync = (filePath: string) => vsixFS.readFileSync(path.join('/', filePath)) as Buffer + const manifest = transformManifest(parseJson(id, readFileSync('package.json').toString('utf8'))) - const vsixFile = Object.fromEntries(Object.entries(files).map(([key, value]) => [getVsixPath(key), value])) + const getFileContent = async (filePath: string): Promise => { + return readFileSync(filePath) + } + const listFiles = async (path: string) => { + return (vsixFS.readdirSync(path) as string[]) + } + const extensionResources = (await extractResourcesFromExtensionManifest(manifest, getFileContent, listFiles)) + .filter(resource => vsixFS.existsSync(path.join('/', resource.realPath ?? resource.path))) const resources = [ ...extensionResources, @@ -100,12 +101,12 @@ export default function plugin ({ const assetPath = getVsixPath(resource.realPath ?? resource.path) let url: string if (process.env.NODE_ENV === 'development') { - url = `'data:text/javascript;base64,${vsixFile[assetPath]!.toString('base64')}'` + url = `'data:text/javascript;base64,${readFileSync(assetPath).toString('base64')}'` } else { url = 'import.meta.ROLLUP_FILE_URL_' + this.emitFile({ type: 'asset', name: `${path.basename(id)}/${path.basename(assetPath)}`, - source: vsixFile[assetPath] + source: readFileSync(assetPath) }) } @@ -122,15 +123,10 @@ export default function plugin ({ : [])] }))).flat() - let packageJson = parseJson(id, vsixFile['package.json']!.toString('utf8')) - if ('package.nls.json' in vsixFile) { - packageJson = localizeManifest(logger, packageJson, parseJson(id, vsixFile['package.nls.json']!.toString())) - } - return ` import { registerExtension } from 'vscode/extensions' -const manifest = ${JSON.stringify(transformManifest(packageJson))} +const manifest = ${JSON.stringify(manifest)} const { registerFileUrl, whenReady } = registerExtension(manifest) From 755321ffa5f93742814c2c9242f0b905c05e4033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:53:51 +0200 Subject: [PATCH 13/28] fix: fix extension sometime not registered when we're already registering another one --- src/extensions.ts | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/extensions.ts b/src/extensions.ts index d756ff86..2c2a62fe 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -15,6 +15,7 @@ import { IExtensionWithExtHostKind, SimpleExtensionService, getLocalExtHostExten import { registerExtensionFile } from './service-override/files' import { setDefaultApi } from './api' import { getService } from './services' +import { throttle } from './tools' const defaultApiInitializeBarrier = new Barrier() export async function initialize (): Promise { @@ -71,24 +72,14 @@ function registerExtensionFileUrl (extensionLocation: URI, filePath: string, url return fileDisposable } -let _toAdd: IExtension[] = [] -let _toRemove: IExtension[] = [] -let lastPromise: Promise | undefined -async function deltaExtensions (toAdd: IExtensionWithExtHostKind[], toRemove: IExtension[]) { - _toAdd.push(...toAdd) - _toRemove.push(...toRemove) - - if (lastPromise == null) { - lastPromise = new Promise(resolve => setTimeout(resolve)).then(async () => { - const extensionService = await getService(IExtensionService) as SimpleExtensionService - await extensionService.deltaExtensions(_toAdd, _toRemove) - _toAdd = [] - _toRemove = [] - lastPromise = undefined - }) - } - await lastPromise +interface ExtensionDelta { + toAdd: IExtensionWithExtHostKind[] + toRemove: IExtension[] } +const deltaExtensions = throttle(async ({ toAdd, toRemove }: ExtensionDelta) => { + const extensionService = await getService(IExtensionService) as SimpleExtensionService + await extensionService.deltaExtensions(toAdd, toRemove) +}, (a, b) => ({ toAdd: [...a.toAdd, ...b.toAdd], toRemove: [...a.toRemove, ...b.toRemove] }), 0) export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalProcess, params?: RegisterExtensionParams): RegisterLocalProcessExtensionResult export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalWebWorker, params?: RegisterExtensionParams): RegisterLocalExtensionResult @@ -120,7 +111,7 @@ export function registerExtension (manifest: IExtensionManifest, extHostKind?: E extHostKind } - await deltaExtensions([extension], []) + await deltaExtensions({ toAdd: [extension], toRemove: [] }) return extension })() @@ -132,7 +123,7 @@ export function registerExtension (manifest: IExtensionManifest, extHostKind?: E }, async dispose () { const extension = await addExtensionPromise - await deltaExtensions([], [extension]) + await deltaExtensions({ toAdd: [], toRemove: [extension] }) disposableStore.dispose() } } From 11794fafb630902c4e57035a58fb095686ff8f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:54:32 +0200 Subject: [PATCH 14/28] feat: translate extension manifests as in vscode --- src/extensions.ts | 16 ++-- src/tools/l10n.ts | 185 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 src/tools/l10n.ts diff --git a/src/extensions.ts b/src/extensions.ts index 2c2a62fe..6799daf6 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -4,17 +4,17 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { URI } from 'vs/base/common/uri' import { getExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil' import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle' -import { ITranslations, localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls' +import { ITranslations } from 'vs/platform/extensionManagement/common/extensionNls' import { joinPath } from 'vs/base/common/resources' import { FileAccess, Schemas } from 'vs/base/common/network' import { Barrier } from 'vs/base/common/async' import { ExtensionHostKind } from 'vs/workbench/services/extensions/common/extensionHostKind' import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService' -import { ILogService } from 'vs/platform/log/common/log' import { IExtensionWithExtHostKind, SimpleExtensionService, getLocalExtHostExtensionService } from './service-override/extensions' import { registerExtensionFile } from './service-override/files' import { setDefaultApi } from './api' -import { getService } from './services' +import { IInstantiationService, getService } from './services' +import { ExtensionManifestTranslator } from './tools/l10n' import { throttle } from './tools' const defaultApiInitializeBarrier = new Barrier() @@ -26,7 +26,6 @@ export async function initialize (): Promise { } interface RegisterExtensionParams { - defaultNLS?: ITranslations builtin?: boolean path?: string } @@ -85,7 +84,7 @@ export function registerExtension (manifest: IExtensionManifest, extHostKind: Ex export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalWebWorker, params?: RegisterExtensionParams): RegisterLocalExtensionResult export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.Remote, params?: RegisterRemoteExtensionParams): RegisterRemoteExtensionResult export function registerExtension (manifest: IExtensionManifest, extHostKind?: ExtensionHostKind, params?: RegisterExtensionParams): RegisterExtensionResult -export function registerExtension (manifest: IExtensionManifest, extHostKind?: ExtensionHostKind, { defaultNLS, builtin = manifest.publisher === 'vscode', path = '/' }: RegisterExtensionParams = {}): RegisterExtensionResult { +export function registerExtension (manifest: IExtensionManifest, extHostKind?: ExtensionHostKind, { builtin = manifest.publisher === 'vscode', path = '/' }: RegisterExtensionParams = {}): RegisterExtensionResult { const disposableStore = new DisposableStore() const id = getExtensionId(manifest.publisher, manifest.name) const location = URI.from({ scheme: 'extension', authority: id, path }) @@ -97,9 +96,12 @@ export function registerExtension (manifest: IExtensionManifest, extHostKind?: E realLocation = URI.from({ scheme: Schemas.vscodeRemote, authority: remoteAuthority, path }) } - const localizedManifest = defaultNLS != null ? localizeManifest(logger, manifest, defaultNLS) : manifest + const instantiationService = await getService(IInstantiationService) + const translator = instantiationService.createInstance(ExtensionManifestTranslator) - let extension: IExtensionWithExtHostKind = { + const localizedManifest = await translator.translateManifest(realLocation, manifest) + + const extension: IExtensionWithExtHostKind = { manifest: localizedManifest, type: builtin ? ExtensionType.System : ExtensionType.User, isBuiltin: builtin, diff --git a/src/tools/l10n.ts b/src/tools/l10n.ts new file mode 100644 index 00000000..3a4e300e --- /dev/null +++ b/src/tools/l10n.ts @@ -0,0 +1,185 @@ +import { localize } from 'vs/nls' +import { ParseError, getNodeType, parse } from 'vs/base/common/json' +import { joinPath } from 'vs/base/common/resources' +import { URI } from 'vs/base/common/uri' +import { IExtensionManifest } from 'vs/platform/extensions/common/extensions' +import { IFileService } from 'vs/platform/files/common/files' +import { ILogService } from 'vs/platform/log/common/log' +import { localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls' +import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages' +import * as platform from 'vs/base/common/platform' +import { getBuiltInExtensionTranslationsUris } from '../l10n' + +/** + * The code below is extracted from vs/platform/extensionManagement/common/extensionsScannerService.ts + */ +interface Translations { + [id: string]: string +} +type NlsConfiguration = { + language: string | undefined + pseudo: boolean + devMode: boolean + translations: Translations +} +interface MessageBag { + [key: string]: string | { message: string, comment: string[] } +} +interface TranslationBundle { + contents?: { + package: MessageBag + } +} +interface LocalizedMessages { + values: MessageBag | undefined + default: URI | null +} + +export class ExtensionManifestTranslator { + constructor ( + @IFileService protected readonly fileService: IFileService, + @ILogService protected readonly logService: ILogService + ) { + } + + /** + * Parses original message bundle, returns null if the original message bundle is null. + */ + private async resolveOriginalMessageBundle (originalMessageBundle: URI | null, errors: ParseError[]): Promise<{ [key: string]: string } | undefined> { + if (originalMessageBundle != null) { + try { + const originalBundleContent = (await this.fileService.readFile(originalMessageBundle)).value.toString() + return parse(originalBundleContent, errors) + } catch (error) { + /* Ignore Error */ + } + } + return undefined + } + + private findMessageBundles (extensionLocation: URI, nlsConfiguration: NlsConfiguration): Promise<{ localized: URI, original: URI | null }> { + return new Promise<{ localized: URI, original: URI | null }>((resolve) => { + const loop = (locale: string): void => { + const toCheck = joinPath(extensionLocation, `package.nls.${locale}.json`) + void this.fileService.exists(toCheck).then(exists => { + if (exists) { + resolve({ localized: toCheck, original: joinPath(extensionLocation, 'package.nls.json') }) + } + const index = locale.lastIndexOf('-') + if (index === -1) { + resolve({ localized: joinPath(extensionLocation, 'package.nls.json'), original: null }) + } else { + locale = locale.substring(0, index) + loop(locale) + } + }) + } + if (nlsConfiguration.devMode || nlsConfiguration.pseudo || nlsConfiguration.language == null) { + return resolve({ localized: joinPath(extensionLocation, 'package.nls.json'), original: null }) + } + loop(nlsConfiguration.language) + }) + } + + private formatMessage (extensionLocation: URI, message: string): string { + return `[${extensionLocation.path}]: ${message}` + } + + public async translateManifest (extensionLocation: URI, extensionManifest: IExtensionManifest): Promise { + const nlsConfiguration: NlsConfiguration = { + devMode: false, + language: platform.language, + pseudo: platform.language === 'pseudo', + translations: getBuiltInExtensionTranslationsUris(platform.language) ?? {} + } + + const localizedMessages = await this.getLocalizedMessages(extensionLocation, extensionManifest, nlsConfiguration) + if (localizedMessages != null) { + try { + const errors: ParseError[] = [] + // resolveOriginalMessageBundle returns null if localizedMessages.default === undefined; + const defaults = await this.resolveOriginalMessageBundle(localizedMessages.default, errors) + if (errors.length > 0) { + errors.forEach((error) => { + this.logService.error(this.formatMessage(extensionLocation, localize('jsonsParseReportErrors', 'Failed to parse {0}: {1}.', localizedMessages.default?.path, getParseErrorMessage(error.error)))) + }) + return extensionManifest + } else if (getNodeType(localizedMessages) !== 'object') { + this.logService.error(this.formatMessage(extensionLocation, localize('jsonInvalidFormat', 'Invalid format {0}: JSON object expected.', localizedMessages.default?.path))) + return extensionManifest + } + const localized = localizedMessages.values ?? Object.create(null) + return localizeManifest(this.logService, extensionManifest, localized, defaults) + } catch (error) { + /* Ignore Error */ + } + } + return extensionManifest + } + + private async getLocalizedMessages (extensionLocation: URI, extensionManifest: IExtensionManifest, nlsConfiguration: NlsConfiguration): Promise { + const defaultPackageNLS = joinPath(extensionLocation, 'package.nls.json') + const reportErrors = (localized: URI | null, errors: ParseError[]): void => { + errors.forEach((error) => { + this.logService.error(this.formatMessage(extensionLocation, localize('jsonsParseReportErrors', 'Failed to parse {0}: {1}.', localized?.path, getParseErrorMessage(error.error)))) + }) + } + const reportInvalidFormat = (localized: URI | null): void => { + this.logService.error(this.formatMessage(extensionLocation, localize('jsonInvalidFormat', 'Invalid format {0}: JSON object expected.', localized?.path))) + } + + const translationId = `${extensionManifest.publisher}.${extensionManifest.name}` + const translationUri = nlsConfiguration.translations[translationId] + + if (translationUri != null) { + try { + const translationResource = URI.parse(translationUri) + const content = (await this.fileService.readFile(translationResource)).value.toString() + const errors: ParseError[] = [] + const translationBundle: TranslationBundle = parse(content, errors) + if (errors.length > 0) { + reportErrors(translationResource, errors) + return { values: undefined, default: defaultPackageNLS } + } else if (getNodeType(translationBundle) !== 'object') { + reportInvalidFormat(translationResource) + return { values: undefined, default: defaultPackageNLS } + } else { + const values = translationBundle.contents?.package + return { values, default: defaultPackageNLS } + } + } catch (error) { + return { values: undefined, default: defaultPackageNLS } + } + } else { + const exists = await this.fileService.exists(defaultPackageNLS) + if (!exists) { + return undefined + } + let messageBundle + try { + messageBundle = await this.findMessageBundles(extensionLocation, nlsConfiguration) + } catch (error) { + return undefined + } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (messageBundle.localized == null) { + return { values: undefined, default: messageBundle.original } + } + try { + const messageBundleContent = (await this.fileService.readFile(messageBundle.localized)).value.toString() + const errors: ParseError[] = [] + const messages: MessageBag = parse(messageBundleContent, errors) + if (errors.length > 0) { + reportErrors(messageBundle.localized, errors) + return { values: undefined, default: messageBundle.original } + } else if (getNodeType(messages) !== 'object') { + reportInvalidFormat(messageBundle.localized) + return { values: undefined, default: messageBundle.original } + } + return { values: messages, default: messageBundle.original } + } catch (error) { + return { values: undefined, default: messageBundle.original } + } + } + } +} From 36797b5e5e308c159c3bd36c8ad2b114e4d8435a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:55:24 +0200 Subject: [PATCH 15/28] feat: build language packs --- package.json | 3 +- rollup/rollup.language-packs.ts | 127 +++++++++++++++++++++ tsconfig.rollup-config-language-packs.json | 6 + 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 rollup/rollup.language-packs.ts create mode 100644 tsconfig.rollup-config-language-packs.json diff --git a/package.json b/package.json index 0d8d5b0d..a707da7a 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,10 @@ }, "type": "module", "scripts": { - "build": "npm run clean && npm run lint && npm run compile && npm run compile-rollup-plugins && npm run generate-types && npm run compile-treemending-script && npm run compile-server && npm run compile-default-extensions && npm run copy-monaco-editor", + "build": "npm run clean && npm run lint && npm run compile && npm run compile-rollup-plugins && npm run generate-types && npm run compile-treemending-script && npm run compile-server && npm run compile-default-extensions && npm run compile-language-packs && npm run copy-monaco-editor", "compile": "NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.config.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config.json`}' --vscode-version ${npm_package_config_vscode_version} --vscode-ref ${npm_package_config_vscode_ref}", "compile-default-extensions": "NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.default-extensions.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-default-extensions.json`}'", + "compile-language-packs": "NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.language-packs.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-language-packs.json`}'", "clean": "rm -rf dist/", "compile-server": "rollup --config rollup/rollup.server.config.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-server.json`, include: [`./rollup/rollup.server.config.ts`, `./rollup/rollup-metadata-plugin.ts`]}'", "compile-treemending-script": "rollup --config rollup/rollup.treemending-script.config.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-treemending-script.json`, include: [`./rollup/rollup.treemending-script.config.ts`, `./rollup/rollup-metadata-plugin.ts`]}'", diff --git a/rollup/rollup.language-packs.ts b/rollup/rollup.language-packs.ts new file mode 100644 index 00000000..1194a223 --- /dev/null +++ b/rollup/rollup.language-packs.ts @@ -0,0 +1,127 @@ +import nodeResolve from '@rollup/plugin-node-resolve' +import * as rollup from 'rollup' +import { IExtensionManifest } from 'vs/platform/extensions/common/extensions' +import { dataToEsm } from '@rollup/pluginutils' +import { PackageJson } from 'type-fest' +import * as fs from 'fs' +import * as path from 'path' +import { fileURLToPath } from 'url' +import * as fsPromise from 'fs/promises' +import pkg from '../package.json' assert { type: 'json' } + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) + +const EXTENSIONS = ['', '.ts', '.js'] + +const BASE_DIR = path.resolve(__dirname, '..') +const LOC_PATH = path.resolve(BASE_DIR, 'vscode-loc') + +const locExtensions = fs.readdirSync(LOC_PATH, { withFileTypes: true }) + .filter(f => f.isDirectory() && fs.existsSync(path.resolve(LOC_PATH, f.name, 'package.json'))) + .map(f => f.name) + +export default rollup.defineConfig([ + ...locExtensions.map(name => ({ + input: { + index: path.resolve(LOC_PATH, name) + }, + output: [{ + minifyInternalExports: false, + preserveModules: true, + assetFileNames: '[name][extname]', + format: 'esm', + dir: `dist/${name}`, + entryFileNames: '[name].js', + hoistTransitiveImports: false + }], + external (source) { + return source === 'vscode/l10n' + }, + plugins: [ + { + name: 'resolve-asset-url', + resolveFileUrl (options) { + let relativePath = options.relativePath + if (!relativePath.startsWith('.')) { + relativePath = `./${options.relativePath}` + } + return `'${relativePath}'` + } + }, + { + name: 'loader', + resolveId (source) { + return source + }, + async load (id) { + if (path.dirname(id) === LOC_PATH) { + const packageJson: IExtensionManifest = JSON.parse((await fsPromise.readFile(path.resolve(id, 'package.json'))).toString()) + const mainLocalization = packageJson.contributes!.localizations![0]! + + const mainTranslation = mainLocalization.translations.find(t => t.id === 'vscode')! + const otherTranslations = mainLocalization.translations.filter(t => t.id !== 'vscode')! + + const translationAssets: Record = Object.fromEntries(await Promise.all(otherTranslations.map(async t => { + const assetRef = this.emitFile({ + type: 'asset', + name: path.relative('.', t.path), + source: await fsPromise.readFile(path.resolve(id, t.path)) + }) + return [t.id, assetRef] + }))) + + return ` +import { registerLocalization } from 'vscode/l10n' +import content from '${path.resolve(id, mainTranslation.path)}' +registerLocalization('${mainLocalization.languageId}', content, { +${Object.entries(translationAssets).map(([id, assetRef]) => ` '${id}': new URL(import.meta.ROLLUP_FILE_URL_${assetRef}, import.meta.url).href`).join(',\n')} +}) + ` + } + return undefined + }, + transform (code, id) { + if (!id.endsWith('.json')) return null + + const parsed = JSON.parse(code) + return { + code: dataToEsm(parsed.contents, { + preferConst: true + }), + map: { mappings: '' } + } + }, + generateBundle () { + const packageJson: PackageJson = { + name: `@codingame/monaco-${name.toLowerCase()}`, + ...Object.fromEntries(Object.entries(pkg).filter(([key]) => ['version', 'keywords', 'author', 'license', 'repository', 'type'].includes(key))), + private: false, + description: `Language pack designed to be used with ${pkg.name}`, + main: 'index.js', + module: 'index.js', + types: 'index.d.ts', + dependencies: { + vscode: `npm:${pkg.name}@^${pkg.version}` + } + } + this.emitFile({ + fileName: 'package.json', + needsCodeReference: false, + source: JSON.stringify(packageJson, null, 2), + type: 'asset' + }) + + this.emitFile({ + fileName: 'index.d.ts', + needsCodeReference: false, + source: 'export {}', + type: 'asset' + }) + } + }, + nodeResolve({ + extensions: EXTENSIONS + }) + ] + })) +]) diff --git a/tsconfig.rollup-config-language-packs.json b/tsconfig.rollup-config-language-packs.json new file mode 100644 index 00000000..3e9deb86 --- /dev/null +++ b/tsconfig.rollup-config-language-packs.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "./rollup/rollup.language-packs.ts" + ] +} \ No newline at end of file From 9a68c404d3256cca244a4999c75bd92a770d67d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:56:55 +0200 Subject: [PATCH 16/28] fix(demo): prevent webview background from being white on system dark mode please don't ask me why --- demo/src/style.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/demo/src/style.css b/demo/src/style.css index f4889862..643bea62 100644 --- a/demo/src/style.css +++ b/demo/src/style.css @@ -4,8 +4,6 @@ line-height: 24px; font-weight: 400; - color-scheme: light dark; - font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; From 3c85754ffcf90c5da3e4d269d2fc2594111b9d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:57:33 +0200 Subject: [PATCH 17/28] fix(demo): disable remote extension if there is no remote authority --- demo/src/main.ts | 8 +++++--- demo/src/setup.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/demo/src/main.ts b/demo/src/main.ts index 39febbe4..24cefde5 100644 --- a/demo/src/main.ts +++ b/demo/src/main.ts @@ -5,7 +5,7 @@ import { registerFileSystemOverlay, HTMLFileSystemProvider } from '@codingame/mo import * as vscode from 'vscode' import { ILogService, StandaloneServices, IPreferencesService, IEditorService, IDialogService, getService } from 'vscode/services' import { ConfirmResult, Parts, isPartVisibile, setPartVisibility } from '@codingame/monaco-vscode-views-service-override' -import { clearStorage } from './setup' +import { clearStorage, remoteAuthority } from './setup' import { CustomEditorInput } from './features/customView' import './features/debugger' import './features/search' @@ -14,8 +14,6 @@ import './features/filesystem' import './features/intellisense' import './features/notifications' import './features/terminal' -import './features/remoteExtension' - import '@codingame/monaco-vscode-clojure-default-extension' import '@codingame/monaco-vscode-coffeescript-default-extension' import '@codingame/monaco-vscode-cpp-default-extension' @@ -58,6 +56,10 @@ import '@codingame/monaco-vscode-markdown-math-default-extension' import '@codingame/monaco-vscode-npm-default-extension' import '@codingame/monaco-vscode-media-preview-default-extension' +if (remoteAuthority != null) { + import('./features/remoteExtension') +} + const modelRef = await createModelReference(monaco.Uri.file('/tmp/test.js'), `// import anotherfile let variable = 1 function inc () { diff --git a/demo/src/setup.ts b/demo/src/setup.ts index 2a21c79d..ae88362f 100644 --- a/demo/src/setup.ts +++ b/demo/src/setup.ts @@ -64,7 +64,7 @@ window.MonacoEnvironment = { } const params = new URL(document.location.href).searchParams -const remoteAuthority = params.get('remoteAuthority') ?? undefined +export const remoteAuthority = params.get('remoteAuthority') ?? undefined const connectionToken = params.get('connectionToken') ?? undefined const remotePath = remoteAuthority != null ? params.get('remotePath') ?? undefined : undefined From 0d1f9b0f4a13cdcc4b8f3c900ef48170f02c31b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:58:41 +0200 Subject: [PATCH 18/28] feat(demo): install language packs --- demo/package-lock.json | 175 ++++++++++++++++++++++++++++++++++++++++- demo/package.json | 16 +++- demo/vite.config.ts | 6 +- 3 files changed, 193 insertions(+), 4 deletions(-) diff --git a/demo/package-lock.json b/demo/package-lock.json index 1f342f86..20ae2018 100644 --- a/demo/package-lock.json +++ b/demo/package-lock.json @@ -57,6 +57,20 @@ "@codingame/monaco-vscode-julia-default-extension": "file:../dist/default-extension-julia", "@codingame/monaco-vscode-keybindings-service-override": "file:../dist/service-override-keybindings", "@codingame/monaco-vscode-language-detection-worker-service-override": "file:../dist/service-override-language-detection-worker", + "@codingame/monaco-vscode-language-pack-cs": "file:../dist/vscode-language-pack-cs", + "@codingame/monaco-vscode-language-pack-de": "file:../dist/vscode-language-pack-de", + "@codingame/monaco-vscode-language-pack-es": "file:../dist/vscode-language-pack-es", + "@codingame/monaco-vscode-language-pack-fr": "file:../dist/vscode-language-pack-fr", + "@codingame/monaco-vscode-language-pack-it": "file:../dist/vscode-language-pack-it", + "@codingame/monaco-vscode-language-pack-ja": "file:../dist/vscode-language-pack-ja", + "@codingame/monaco-vscode-language-pack-ko": "file:../dist/vscode-language-pack-ko", + "@codingame/monaco-vscode-language-pack-pl": "file:../dist/vscode-language-pack-pl", + "@codingame/monaco-vscode-language-pack-pt-br": "file:../dist/vscode-language-pack-pt-BR", + "@codingame/monaco-vscode-language-pack-qps-ploc": "file:../dist/vscode-language-pack-qps-ploc", + "@codingame/monaco-vscode-language-pack-ru": "file:../dist/vscode-language-pack-ru", + "@codingame/monaco-vscode-language-pack-tr": "file:../dist/vscode-language-pack-tr", + "@codingame/monaco-vscode-language-pack-zh-hans": "file:../dist/vscode-language-pack-zh-hans", + "@codingame/monaco-vscode-language-pack-zh-hant": "file:../dist/vscode-language-pack-zh-hant", "@codingame/monaco-vscode-languages-service-override": "file:../dist/service-override-languages", "@codingame/monaco-vscode-latex-default-extension": "file:../dist/default-extension-latex", "@codingame/monaco-vscode-layout-service-override": "file:../dist/service-override-layout", @@ -870,9 +884,10 @@ "dev": true, "license": "MIT", "dependencies": { + "memfs": "^4.6.0", "mime-types": "^2.1.35", "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release", - "yauzl": "^2.9.2" + "yauzl": "^2.10.0" } }, "../dist/server": { @@ -894,7 +909,7 @@ "vscode-regexpp": "^3.1.0", "xterm-addon-serialize": "0.12.0-beta.26", "xterm-addon-unicode11": "0.7.0-beta.26", - "yauzl": "^2.9.2", + "yauzl": "^2.10.0", "yazl": "^2.4.3" }, "bin": { @@ -1208,6 +1223,106 @@ "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" } }, + "../dist/vscode-language-pack-cs": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-de": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-es": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-fr": { + "name": "@codingame/monaco-vscode-language-pack-fr", + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-it": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-ja": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-ko": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-pl": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-pt-BR": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-qps-ploc": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-ru": { + "name": "@codingame/monaco-vscode-language-pack-ru", + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-tr": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-zh-hans": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, + "../dist/vscode-language-pack-zh-hant": { + "version": "0.0.0-semantic-release", + "license": "MIT", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@^0.0.0-semantic-release" + } + }, "node_modules/@balena/dockerignore": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", @@ -1405,6 +1520,62 @@ "resolved": "../dist/service-override-language-detection-worker", "link": true }, + "node_modules/@codingame/monaco-vscode-language-pack-cs": { + "resolved": "../dist/vscode-language-pack-cs", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-de": { + "resolved": "../dist/vscode-language-pack-de", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-es": { + "resolved": "../dist/vscode-language-pack-es", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-fr": { + "resolved": "../dist/vscode-language-pack-fr", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-it": { + "resolved": "../dist/vscode-language-pack-it", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-ja": { + "resolved": "../dist/vscode-language-pack-ja", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-ko": { + "resolved": "../dist/vscode-language-pack-ko", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-pl": { + "resolved": "../dist/vscode-language-pack-pl", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-pt-br": { + "resolved": "../dist/vscode-language-pack-pt-BR", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-qps-ploc": { + "resolved": "../dist/vscode-language-pack-qps-ploc", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-ru": { + "resolved": "../dist/vscode-language-pack-ru", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-tr": { + "resolved": "../dist/vscode-language-pack-tr", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-zh-hans": { + "resolved": "../dist/vscode-language-pack-zh-hans", + "link": true + }, + "node_modules/@codingame/monaco-vscode-language-pack-zh-hant": { + "resolved": "../dist/vscode-language-pack-zh-hant", + "link": true + }, "node_modules/@codingame/monaco-vscode-languages-service-override": { "resolved": "../dist/service-override-languages", "link": true diff --git a/demo/package.json b/demo/package.json index d2518c60..35e2b5e7 100644 --- a/demo/package.json +++ b/demo/package.json @@ -77,6 +77,20 @@ "@codingame/monaco-vscode-julia-default-extension": "file:../dist/default-extension-julia", "@codingame/monaco-vscode-keybindings-service-override": "file:../dist/service-override-keybindings", "@codingame/monaco-vscode-language-detection-worker-service-override": "file:../dist/service-override-language-detection-worker", + "@codingame/monaco-vscode-language-pack-cs": "file:../dist/vscode-language-pack-cs", + "@codingame/monaco-vscode-language-pack-de": "file:../dist/vscode-language-pack-de", + "@codingame/monaco-vscode-language-pack-es": "file:../dist/vscode-language-pack-es", + "@codingame/monaco-vscode-language-pack-fr": "file:../dist/vscode-language-pack-fr", + "@codingame/monaco-vscode-language-pack-it": "file:../dist/vscode-language-pack-it", + "@codingame/monaco-vscode-language-pack-ja": "file:../dist/vscode-language-pack-ja", + "@codingame/monaco-vscode-language-pack-ko": "file:../dist/vscode-language-pack-ko", + "@codingame/monaco-vscode-language-pack-pl": "file:../dist/vscode-language-pack-pl", + "@codingame/monaco-vscode-language-pack-pt-br": "file:../dist/vscode-language-pack-pt-BR", + "@codingame/monaco-vscode-language-pack-qps-ploc": "file:../dist/vscode-language-pack-qps-ploc", + "@codingame/monaco-vscode-language-pack-ru": "file:../dist/vscode-language-pack-ru", + "@codingame/monaco-vscode-language-pack-tr": "file:../dist/vscode-language-pack-tr", + "@codingame/monaco-vscode-language-pack-zh-hans": "file:../dist/vscode-language-pack-zh-hans", + "@codingame/monaco-vscode-language-pack-zh-hant": "file:../dist/vscode-language-pack-zh-hant", "@codingame/monaco-vscode-languages-service-override": "file:../dist/service-override-languages", "@codingame/monaco-vscode-latex-default-extension": "file:../dist/default-extension-latex", "@codingame/monaco-vscode-layout-service-override": "file:../dist/service-override-layout", @@ -162,4 +176,4 @@ "node": "18.18.0", "npm": "9.8.1" } -} \ No newline at end of file +} diff --git a/demo/vite.config.ts b/demo/vite.config.ts index 4757f314..60b4536a 100644 --- a/demo/vite.config.ts +++ b/demo/vite.config.ts @@ -71,7 +71,11 @@ export default defineConfig({ '@codingame/monaco-vscode-typescript-language-features-default-extension', '@codingame/monaco-vscode-markdown-language-features-default-extension', '@codingame/monaco-vscode-json-language-features-default-extension', '@codingame/monaco-vscode-css-language-features-default-extension', '@codingame/monaco-vscode-npm-default-extension', '@codingame/monaco-vscode-css-default-extension', '@codingame/monaco-vscode-markdown-basics-default-extension', '@codingame/monaco-vscode-html-default-extension', - '@codingame/monaco-vscode-html-language-features-default-extension', '@codingame/monaco-vscode-configuration-editing-default-extension', '@codingame/monaco-vscode-media-preview-default-extension', '@codingame/monaco-vscode-markdown-math-default-extension' + '@codingame/monaco-vscode-html-language-features-default-extension', '@codingame/monaco-vscode-configuration-editing-default-extension', '@codingame/monaco-vscode-media-preview-default-extension', '@codingame/monaco-vscode-markdown-math-default-extension', + '@codingame/monaco-vscode-language-pack-cs', '@codingame/monaco-vscode-language-pack-de', '@codingame/monaco-vscode-language-pack-es', '@codingame/monaco-vscode-language-pack-fr', + '@codingame/monaco-vscode-language-pack-it', '@codingame/monaco-vscode-language-pack-ja', '@codingame/monaco-vscode-language-pack-ko', '@codingame/monaco-vscode-language-pack-pl', + '@codingame/monaco-vscode-language-pack-pt-br', '@codingame/monaco-vscode-language-pack-qps-ploc', '@codingame/monaco-vscode-language-pack-ru', '@codingame/monaco-vscode-language-pack-tr', + '@codingame/monaco-vscode-language-pack-zh-hans', '@codingame/monaco-vscode-language-pack-zh-hant' ], esbuildOptions: { plugins: [{ From 01046d00246e580ff3c2b5656e2e9df43c8fab2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 17:59:35 +0200 Subject: [PATCH 19/28] feat(demo): load language pack from url param --- demo/index.html | 2 +- demo/src/loader.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 demo/src/loader.ts diff --git a/demo/index.html b/demo/index.html index df160c70..40120ad7 100644 --- a/demo/index.html +++ b/demo/index.html @@ -41,6 +41,6 @@

Keybindings

- + diff --git a/demo/src/loader.ts b/demo/src/loader.ts new file mode 100644 index 00000000..5bbc2f2a --- /dev/null +++ b/demo/src/loader.ts @@ -0,0 +1,31 @@ +const locale = new URLSearchParams(window.location.search).get('locale') + +const localeLoader: Partial Promise>> = { + cs: async () => { await import('@codingame/monaco-vscode-language-pack-cs') }, + de: async () => { await import('@codingame/monaco-vscode-language-pack-de') }, + es: async () => { await import('@codingame/monaco-vscode-language-pack-es') }, + fr: async () => { await import('@codingame/monaco-vscode-language-pack-fr') }, + it: async () => { await import('@codingame/monaco-vscode-language-pack-it') }, + ja: async () => { await import('@codingame/monaco-vscode-language-pack-ja') }, + ko: async () => { await import('@codingame/monaco-vscode-language-pack-ko') }, + pl: async () => { await import('@codingame/monaco-vscode-language-pack-pl') }, + 'pt-br': async () => { await import('@codingame/monaco-vscode-language-pack-pt-br') }, + 'qps-ploc': async () => { await import('@codingame/monaco-vscode-language-pack-qps-ploc') }, + ru: async () => { await import('@codingame/monaco-vscode-language-pack-ru') }, + tr: async () => { await import('@codingame/monaco-vscode-language-pack-tr') }, + 'zh-hans': async () => { await import('@codingame/monaco-vscode-language-pack-zh-hans') }, + 'zh-hant': async () => { await import('@codingame/monaco-vscode-language-pack-zh-hant') } +} + +if (locale != null) { + const loader = localeLoader[locale] + if (loader != null) { + await loader() + } else { + console.error(`Unknown locale ${locale}`) + } +} + +await import('./main') + +export {} From 614581dd07f67e9d96137e1d1f7bd5b56ea595ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 18:00:11 +0200 Subject: [PATCH 20/28] feat(demo): add locale selector --- demo/index.html | 19 +++++++++++++++++++ demo/src/main.ts | 13 +++++++++++++ 2 files changed, 32 insertions(+) diff --git a/demo/index.html b/demo/index.html index 40120ad7..6badb7b6 100644 --- a/demo/index.html +++ b/demo/index.html @@ -26,6 +26,25 @@

Editor


+
+ +
diff --git a/demo/src/main.ts b/demo/src/main.ts index 24cefde5..492defe4 100644 --- a/demo/src/main.ts +++ b/demo/src/main.ts @@ -216,3 +216,16 @@ document.querySelector('#togglePanel')!.addEventListener('click', async () => { document.querySelector('#toggleAuxiliary')!.addEventListener('click', async () => { setPartVisibility(Parts.AUXILIARYBAR_PART, !isPartVisibile(Parts.AUXILIARYBAR_PART)) }) + +const locale = new URLSearchParams(window.location.search).get('locale') ?? '' +const select: HTMLSelectElement = document.querySelector('#localeSelect')! +select.value = locale +select.addEventListener('change', () => { + const url = new URL(window.location.href) + if (select.value !== '') { + url.searchParams.set('locale', select.value) + } else { + url.searchParams.delete('locale') + } + window.location.href = url.toString() +}) From 81c856f0871b9d5dc25d806505c1c5000fba6eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 18:51:45 +0200 Subject: [PATCH 21/28] feat: take bundle file into account --- src/extension-tools.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/extension-tools.ts b/src/extension-tools.ts index 280522bf..3c87c261 100644 --- a/src/extension-tools.ts +++ b/src/extension-tools.ts @@ -193,6 +193,13 @@ export async function extractResourcesFromExtensionManifest (manifest: IExtensio path, mimeType: 'application/json' }))) + if (manifest.l10n != null) { + const bundleFiles = (await listFiles(manifest.l10n)).filter(file => /^bundle\.l10n(?:\..*)?\.json$/.exec(file) != null) + resources.push(...bundleFiles.map(path => ({ + path, + mimeType: 'application/json' + }))) + } resources = resources.map(r => { if (r.mimeType == null) { From 62761f57eae3469e5e3a566ce0a5f08452365207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 18:52:55 +0200 Subject: [PATCH 22/28] feat: add a simpler way to register remote extension --- src/extensions.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/extensions.ts b/src/extensions.ts index 6799daf6..1e9d0994 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -10,10 +10,11 @@ import { FileAccess, Schemas } from 'vs/base/common/network' import { Barrier } from 'vs/base/common/async' import { ExtensionHostKind } from 'vs/workbench/services/extensions/common/extensionHostKind' import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService' +import { parse } from 'vs/base/common/json' import { IExtensionWithExtHostKind, SimpleExtensionService, getLocalExtHostExtensionService } from './service-override/extensions' import { registerExtensionFile } from './service-override/files' import { setDefaultApi } from './api' -import { IInstantiationService, getService } from './services' +import { IFileService, IInstantiationService, getService } from './services' import { ExtensionManifestTranslator } from './tools/l10n' import { throttle } from './tools' @@ -80,6 +81,15 @@ const deltaExtensions = throttle(async ({ toAdd, toRemove }: ExtensionDelta) => await extensionService.deltaExtensions(toAdd, toRemove) }, (a, b) => ({ toAdd: [...a.toAdd, ...b.toAdd], toRemove: [...a.toRemove, ...b.toRemove] }), 0) +export async function registerRemoteExtension (directory: string): Promise { + const fileService = await getService(IFileService) + const remoteAuthority = (await getService(IWorkbenchEnvironmentService)).remoteAuthority + const content = await fileService.readFile(joinPath(URI.from({ scheme: Schemas.vscodeRemote, authority: remoteAuthority, path: directory }), 'package.json')) + const manifest: IExtensionManifest = parse(content.value.toString()) + + return registerExtension(manifest, ExtensionHostKind.Remote, { path: directory }) +} + export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalProcess, params?: RegisterExtensionParams): RegisterLocalProcessExtensionResult export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalWebWorker, params?: RegisterExtensionParams): RegisterLocalExtensionResult export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.Remote, params?: RegisterRemoteExtensionParams): RegisterRemoteExtensionResult From 9ca9686f8285ff903b8e831fc198fb63f8245d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 18:53:38 +0200 Subject: [PATCH 23/28] feat(demo): use new way to register remote extension --- demo/src/features/remoteExtension.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/demo/src/features/remoteExtension.ts b/demo/src/features/remoteExtension.ts index 7f58805b..3b039370 100644 --- a/demo/src/features/remoteExtension.ts +++ b/demo/src/features/remoteExtension.ts @@ -1,5 +1,4 @@ -import { ExtensionHostKind, registerExtension } from 'vscode/extensions' -import manifest from './remoteExtensionExample/package.json' +import { registerRemoteExtension } from 'vscode/extensions' declare global { interface Window { @@ -8,7 +7,5 @@ declare global { } if (window.rootDirectory != null) { - registerExtension(manifest, ExtensionHostKind.Remote, { - path: `${window.rootDirectory}/src/features/remoteExtensionExample/` - }) + registerRemoteExtension(`${window.rootDirectory}/src/features/remoteExtensionExample/`) } From 657d37de3d5d7972e30dfe417dd5c35b3dc0acda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 18:57:17 +0200 Subject: [PATCH 24/28] feat(demo): demonstrate extension localization --- .../remoteExtensionExample/l10n/bundle.l10n.de.json | 3 +++ .../remoteExtensionExample/l10n/bundle.l10n.fr.json | 3 +++ demo/src/features/remoteExtensionExample/main.js | 11 +++++++---- demo/src/features/remoteExtensionExample/package.json | 11 ++++++++++- .../remoteExtensionExample/package.nls.de.json | 3 +++ .../remoteExtensionExample/package.nls.fr.json | 3 +++ .../features/remoteExtensionExample/package.nls.json | 3 +++ 7 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 demo/src/features/remoteExtensionExample/l10n/bundle.l10n.de.json create mode 100644 demo/src/features/remoteExtensionExample/l10n/bundle.l10n.fr.json create mode 100644 demo/src/features/remoteExtensionExample/package.nls.de.json create mode 100644 demo/src/features/remoteExtensionExample/package.nls.fr.json create mode 100644 demo/src/features/remoteExtensionExample/package.nls.json diff --git a/demo/src/features/remoteExtensionExample/l10n/bundle.l10n.de.json b/demo/src/features/remoteExtensionExample/l10n/bundle.l10n.de.json new file mode 100644 index 00000000..c450daad --- /dev/null +++ b/demo/src/features/remoteExtensionExample/l10n/bundle.l10n.de.json @@ -0,0 +1,3 @@ +{ + "Hello from remote extension running from {0}!": "Hallo von der entfernten Nebenstelle, die auf {0} läuft!" +} \ No newline at end of file diff --git a/demo/src/features/remoteExtensionExample/l10n/bundle.l10n.fr.json b/demo/src/features/remoteExtensionExample/l10n/bundle.l10n.fr.json new file mode 100644 index 00000000..e8b83bb8 --- /dev/null +++ b/demo/src/features/remoteExtensionExample/l10n/bundle.l10n.fr.json @@ -0,0 +1,3 @@ +{ + "Hello from remote extension running from {0}!": "Bonjour depuis l'extension distante tournant sur {0}!" +} \ No newline at end of file diff --git a/demo/src/features/remoteExtensionExample/main.js b/demo/src/features/remoteExtensionExample/main.js index d6041de3..c08e37ef 100644 --- a/demo/src/features/remoteExtensionExample/main.js +++ b/demo/src/features/remoteExtensionExample/main.js @@ -1,8 +1,11 @@ const vscode = require('vscode') -const os = require("os") +const os = require('os') -void vscode.window.showInformationMessage('Hello', { - detail: `Hello from remote extension running from ${os.hostname()}`, - modal: true +vscode.commands.registerCommand('prompt-hello', () => { + void vscode.window.showInformationMessage('Hello', { + detail: vscode.l10n.t('Hello from remote extension running from {0}!', os.hostname()), + modal: true + }) }) +vscode.commands.executeCommand('prompt-hello') diff --git a/demo/src/features/remoteExtensionExample/package.json b/demo/src/features/remoteExtensionExample/package.json index 29bc36e1..2055817f 100644 --- a/demo/src/features/remoteExtensionExample/package.json +++ b/demo/src/features/remoteExtensionExample/package.json @@ -6,5 +6,14 @@ "engines": { "vscode": "*" }, - "main": "./main.js" + "l10n": "./l10n", + "main": "./main.js", + "browser": "./main.js", + "contributes": { + "commands": [{ + "command": "prompt-hello", + "title": "%prompt-hello%", + "category": "Custom" + }] + } } \ No newline at end of file diff --git a/demo/src/features/remoteExtensionExample/package.nls.de.json b/demo/src/features/remoteExtensionExample/package.nls.de.json new file mode 100644 index 00000000..6b2030b5 --- /dev/null +++ b/demo/src/features/remoteExtensionExample/package.nls.de.json @@ -0,0 +1,3 @@ +{ + "prompt-hello": "Hallo sagen von der entfernten Nebenstelle" +} \ No newline at end of file diff --git a/demo/src/features/remoteExtensionExample/package.nls.fr.json b/demo/src/features/remoteExtensionExample/package.nls.fr.json new file mode 100644 index 00000000..6f334474 --- /dev/null +++ b/demo/src/features/remoteExtensionExample/package.nls.fr.json @@ -0,0 +1,3 @@ +{ + "prompt-hello": "Dire bonjour depuis l'extension distante" +} \ No newline at end of file diff --git a/demo/src/features/remoteExtensionExample/package.nls.json b/demo/src/features/remoteExtensionExample/package.nls.json new file mode 100644 index 00000000..1030c460 --- /dev/null +++ b/demo/src/features/remoteExtensionExample/package.nls.json @@ -0,0 +1,3 @@ +{ + "prompt-hello": "Prompt hello from remote extension" +} \ No newline at end of file From 3dfbc6fda5e9a0d413f4328b0b8d4520cc65221d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Thu, 19 Oct 2023 19:10:07 +0200 Subject: [PATCH 25/28] chore: update documentation --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 1c6ff37a..ec8ccebd 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,27 @@ plugins: [ import './extension.vsix' ``` +### Localization + +This library also offers the possibility to localize vscode and the extensions in the supported languages. To do so, import one of the following packages before anything else: +- `@codingame/monaco-vscode-language-pack-cs` +- `@codingame/monaco-vscode-language-pack-de` +- `@codingame/monaco-vscode-language-pack-es` +- `@codingame/monaco-vscode-language-pack-fr` +- `@codingame/monaco-vscode-language-pack-it` +- `@codingame/monaco-vscode-language-pack-ja` +- `@codingame/monaco-vscode-language-pack-ko` +- `@codingame/monaco-vscode-language-pack-pl` +- `@codingame/monaco-vscode-language-pack-pt-br` +- `@codingame/monaco-vscode-language-pack-qps-ploc` +- `@codingame/monaco-vscode-language-pack-ru` +- `@codingame/monaco-vscode-language-pack-tr` +- `@codingame/monaco-vscode-language-pack-zh-hans` +- `@codingame/monaco-vscode-language-pack-zh-hant` + +⚠️ The language pack should be imported and loaded BEFORE anything else from monaco-editor or this library is loaded. Otherwise, some translations would be missing. ⚠️ + + ### Demo Try it out on https://codingame.github.io/monaco-vscode-api/ From ca51bbcf5a2a41931e4177416b1caa0d140fafb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Fri, 20 Oct 2023 10:22:14 +0200 Subject: [PATCH 26/28] fix(demo): update package-lock --- demo/package-lock.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/demo/package-lock.json b/demo/package-lock.json index 20ae2018..a9b8fb90 100644 --- a/demo/package-lock.json +++ b/demo/package-lock.json @@ -1224,6 +1224,7 @@ } }, "../dist/vscode-language-pack-cs": { + "name": "@codingame/monaco-vscode-language-pack-cs", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1231,6 +1232,7 @@ } }, "../dist/vscode-language-pack-de": { + "name": "@codingame/monaco-vscode-language-pack-de", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1238,6 +1240,7 @@ } }, "../dist/vscode-language-pack-es": { + "name": "@codingame/monaco-vscode-language-pack-es", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1253,6 +1256,7 @@ } }, "../dist/vscode-language-pack-it": { + "name": "@codingame/monaco-vscode-language-pack-it", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1260,6 +1264,7 @@ } }, "../dist/vscode-language-pack-ja": { + "name": "@codingame/monaco-vscode-language-pack-ja", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1267,6 +1272,7 @@ } }, "../dist/vscode-language-pack-ko": { + "name": "@codingame/monaco-vscode-language-pack-ko", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1274,6 +1280,7 @@ } }, "../dist/vscode-language-pack-pl": { + "name": "@codingame/monaco-vscode-language-pack-pl", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1281,6 +1288,7 @@ } }, "../dist/vscode-language-pack-pt-BR": { + "name": "@codingame/monaco-vscode-language-pack-pt-br", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1288,6 +1296,7 @@ } }, "../dist/vscode-language-pack-qps-ploc": { + "name": "@codingame/monaco-vscode-language-pack-qps-ploc", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1303,6 +1312,7 @@ } }, "../dist/vscode-language-pack-tr": { + "name": "@codingame/monaco-vscode-language-pack-tr", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1310,6 +1320,7 @@ } }, "../dist/vscode-language-pack-zh-hans": { + "name": "@codingame/monaco-vscode-language-pack-zh-hans", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { @@ -1317,6 +1328,7 @@ } }, "../dist/vscode-language-pack-zh-hant": { + "name": "@codingame/monaco-vscode-language-pack-zh-hant", "version": "0.0.0-semantic-release", "license": "MIT", "dependencies": { From 6add271ed6dc5d2062ca46f53de4a6f449be17d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Fri, 20 Oct 2023 10:48:48 +0200 Subject: [PATCH 27/28] fix: fix treemending script for other timezones --- src/monaco-treemending.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/monaco-treemending.ts b/src/monaco-treemending.ts index ea6f1f35..36588534 100644 --- a/src/monaco-treemending.ts +++ b/src/monaco-treemending.ts @@ -62,8 +62,8 @@ async function run () { return } try { - if (index.newHeader === '1970-01-01 01:00:00.000000000 +0100') { - // timestamp 0 means the fiel was removed + if (index.newHeader != null && Date.parse(index.newHeader) === 0) { + // timestamp 0 means the field was removed await fs.unlink(file) } else { await fs.mkdir(path.dirname(file), { recursive: true }) From 8eef44a5a19b449dc756f01a60e7d2c961f3b2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Fri, 20 Oct 2023 10:49:21 +0200 Subject: [PATCH 28/28] fix(demo): fix vite not liking that await for some reasons --- demo/src/loader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/loader.ts b/demo/src/loader.ts index 5bbc2f2a..a589f57c 100644 --- a/demo/src/loader.ts +++ b/demo/src/loader.ts @@ -26,6 +26,6 @@ if (locale != null) { } } -await import('./main') +import('./main') export {}