2019-08-03 00:26:41 +00:00
|
|
|
import * as fs from "fs";
|
2019-08-09 23:50:05 +00:00
|
|
|
import * as path from "path";
|
2019-08-03 00:26:41 +00:00
|
|
|
import * as util from "util";
|
|
|
|
import { getPathFromAmdModule } from "vs/base/common/amd";
|
|
|
|
import * as lp from "vs/base/node/languagePacks";
|
2019-10-18 23:20:02 +00:00
|
|
|
import product from "vs/platform/product/common/product";
|
2019-08-03 00:26:41 +00:00
|
|
|
import { Translations } from "vs/workbench/services/extensions/common/extensionPoints";
|
|
|
|
|
|
|
|
const configurations = new Map<string, Promise<lp.NLSConfiguration>>();
|
|
|
|
const metadataPath = path.join(getPathFromAmdModule(require, ""), "nls.metadata.json");
|
|
|
|
|
|
|
|
export const isInternalConfiguration = (config: lp.NLSConfiguration): config is lp.InternalNLSConfiguration => {
|
|
|
|
return config && !!(<lp.InternalNLSConfiguration>config)._languagePackId;
|
|
|
|
};
|
|
|
|
|
|
|
|
const DefaultConfiguration = {
|
|
|
|
locale: "en",
|
|
|
|
availableLanguages: {},
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getNlsConfiguration = async (locale: string, userDataPath: string): Promise<lp.NLSConfiguration> => {
|
|
|
|
const id = `${locale}: ${userDataPath}`;
|
|
|
|
if (!configurations.has(id)) {
|
|
|
|
configurations.set(id, new Promise(async (resolve) => {
|
|
|
|
const config = product.commit && await util.promisify(fs.exists)(metadataPath)
|
|
|
|
? await lp.getNLSConfiguration(product.commit, userDataPath, metadataPath, locale)
|
|
|
|
: DefaultConfiguration;
|
|
|
|
if (isInternalConfiguration(config)) {
|
|
|
|
config._languagePackSupport = true;
|
|
|
|
}
|
2019-10-18 23:20:02 +00:00
|
|
|
// If the configuration has no results keep trying since code-server
|
|
|
|
// doesn't restart when a language is installed so this result would
|
|
|
|
// persist (the plugin might not be installed yet or something).
|
|
|
|
if (config.locale !== "en" && config.locale !== "en-us" && Object.keys(config.availableLanguages).length === 0) {
|
|
|
|
configurations.delete(id);
|
|
|
|
}
|
2019-08-03 00:26:41 +00:00
|
|
|
resolve(config);
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
return configurations.get(id)!;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getTranslations = async (locale: string, userDataPath: string): Promise<Translations> => {
|
|
|
|
const config = await getNlsConfiguration(locale, userDataPath);
|
|
|
|
if (isInternalConfiguration(config)) {
|
|
|
|
try {
|
|
|
|
return JSON.parse(await util.promisify(fs.readFile)(config._translationsConfigFile, "utf8"));
|
|
|
|
} catch (error) { /* Nothing yet. */}
|
|
|
|
}
|
|
|
|
return {};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getLocaleFromConfig = async (userDataPath: string): Promise<string> => {
|
|
|
|
let locale = "en";
|
|
|
|
try {
|
|
|
|
const localeConfigUri = path.join(userDataPath, "User/locale.json");
|
|
|
|
const content = stripComments(await util.promisify(fs.readFile)(localeConfigUri, "utf8"));
|
|
|
|
locale = JSON.parse(content).locale;
|
|
|
|
} catch (error) { /* Ignore. */ }
|
|
|
|
return locale;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Taken from src/main.js in the main VS Code source.
|
|
|
|
const stripComments = (content: string): string => {
|
|
|
|
const regexp = /("(?:[^\\"]*(?:\\.)?)*")|('(?:[^\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g;
|
|
|
|
|
|
|
|
return content.replace(regexp, (match, _m1, _m2, m3, m4) => {
|
|
|
|
// Only one of m1, m2, m3, m4 matches
|
|
|
|
if (m3) {
|
|
|
|
// A block comment. Replace with nothing
|
|
|
|
return '';
|
|
|
|
} else if (m4) {
|
|
|
|
// A line comment. If it ends in \r?\n then keep it.
|
|
|
|
const length_1 = m4.length;
|
|
|
|
if (length_1 > 2 && m4[length_1 - 1] === '\n') {
|
|
|
|
return m4[length_1 - 2] === '\r' ? '\r\n' : '\n';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// We match a string
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|