Change:
}); } <del> /** * This routine makes the following assumptions: * The root element is an object literal */ private replaceNLStrings<T extends object>(pseudo: boolean, literal: T, messages: MessageBag, originalMessages: MessageBag | null, extensionLocation: URI): void { const processEntry = (obj: any, key: string | number, command?: boolean) => { const value = obj[key]; if (isString(value)) { const str = <string>value; const length = str.length; if (length > 1 && str[0] === '%' && str[length - 1] === '%') { const messageKey = str.substr(1, length - 2); let translated = messages[messageKey]; // If the messages come from a language pack they might miss some keys // Fill them from the original messages. if (translated === undefined && originalMessages) { translated = originalMessages[messageKey]; } let message: string | undefined = typeof translated === 'string' ? translated : translated.message; if (message !== undefined) { if (pseudo) { // FF3B and FF3D is the Unicode zenkaku representation for [ and ] message = 'uFF3B' + message.replace(/[aouei]/g, '$&$&') + 'uFF3D'; } // This branch returns ILocalizedString's instead of Strings so that the Command Palette can contain both the localized and the original value. if (command && originalMessages && (key === 'title' || key === 'category')) { const originalMessage = originalMessages[messageKey]; const localizedString: ILocalizedString = { value: message, original: typeof originalMessage === 'string' ? originalMessage : originalMessage?.message }; obj[key] = localizedString; } else { obj[key] = message; } } else { this.logService.warn(this.formatMessage(extensionLocation, localize('missingNLSKey', "Couldn't find message for key {0}.", messageKey))); } } } else if (isObject(value)) { for (const k in value) { if (value.hasOwnProperty(k)) { k === 'commands' ? processEntry(value, k, true) : processEntry(value, k, command); } } } else if (Array.isArray(value)) { for (let i = 0; i < value.length; i++) { processEntry(value, i, command); } } }; for (const key in literal) { if (literal.hasOwnProperty(key)) { processEntry(literal, key); } } } </del> private formatMessage(extensionLocation: URI, message: string): string { return `[${extensionLocation.path}]: ${message}`; }

Discussion:
Testing in Firefox with de-ch (Swiss German) set. Open command palette and search for Remote Repositories commands :bug: The first command has a partly English, partly de-ch line under it ( and in English, seems to be de-ch translated) !
Hmm yeah it should look like this (Desktop screenshot) with the English strings next to the German strings. I think this is a bug in how I'm applying the translations... !
Just found out about these functions on the desktop side: Which seems to go through the manifest and turn some s into s. I followed up with to understand how this works.
This code was originally written by so I would ask him to know how this works.
Not quite, it was originally written by , but I'm happy to try and help. My understanding is that the code is taking a JSON object that looks like this: Together with another JSON object that looks like this: And produces a JSON object that looks like this by substituting all string values of the shape with their corresponding value:
I still see this on firefox: ! The first option's english translation still looks wrong? (tested on )
The first one is still wrong because of so we'll track that there. However, the rest now have the English string underneath which they use to not have, which means this is fixed and verified