@@ -25,7 +25,7 @@ const portable = bootstrap.configurePortable();
2525// Enable ASAR support
2626bootstrap . enableASARSupport ( ) ;
2727
28- // Set userData path before app 'ready' event and call to process.chdir
28+ // Set userData path before app 'ready' event
2929const args = parseCLIArgs ( ) ;
3030const userDataPath = getUserDataPath ( args ) ;
3131app . setPath ( 'userData' , userDataPath ) ;
@@ -37,17 +37,18 @@ setCurrentWorkingDirectory();
3737registerListeners ( ) ;
3838
3939/**
40- * Support user defined locale
40+ * Support user defined locale: load it early before app('ready')
41+ * to have more things running in parallel.
4142 *
42- * @type {Promise }
43+ * @type {Promise<import('./vs/base/node/languagePacks').NLSConfiguration> } nlsConfig | undefined
4344 */
44- let nlsConfiguration = undefined ;
45+ let nlsConfigurationPromise = undefined ;
4546const userDefinedLocale = getUserDefinedLocale ( ) ;
4647const metaDataFile = path . join ( __dirname , 'nls.metadata.json' ) ;
4748
4849userDefinedLocale . then ( locale => {
49- if ( locale && ! nlsConfiguration ) {
50- nlsConfiguration = lp . getNLSConfiguration ( product . commit , userDataPath , metaDataFile , locale ) ;
50+ if ( locale && ! nlsConfigurationPromise ) {
51+ nlsConfigurationPromise = lp . getNLSConfiguration ( product . commit , userDataPath , metaDataFile , locale ) ;
5152 }
5253} ) ;
5354
@@ -74,62 +75,35 @@ app.once('ready', function () {
7475 }
7576} ) ;
7677
77- function onReady ( ) {
78- perf . mark ( 'main:appReady' ) ;
78+ /**
79+ * Main startup routine
80+ *
81+ * @param {string | undefined } cachedDataDir
82+ * @param {import('./vs/base/node/languagePacks').NLSConfiguration } nlsConfig
83+ */
84+ function startup ( cachedDataDir , nlsConfig ) {
85+ nlsConfig . _languagePackSupport = true ;
7986
80- Promise . all ( [ nodeCachedDataDir . ensureExists ( ) , userDefinedLocale ] ) . then ( ( [ cachedDataDir , locale ] ) => {
81- if ( locale && ! nlsConfiguration ) {
82- nlsConfiguration = lp . getNLSConfiguration ( product . commit , userDataPath , metaDataFile , locale ) ;
83- }
87+ process . env [ 'VSCODE_NLS_CONFIG' ] = JSON . stringify ( nlsConfig ) ;
88+ process . env [ 'VSCODE_NODE_CACHED_DATA_DIR' ] = cachedDataDir || '' ;
8489
85- if ( ! nlsConfiguration ) {
86- nlsConfiguration = Promise . resolve ( undefined ) ;
87- }
90+ // Load main in AMD
91+ perf . mark ( 'willLoadMainBundle' ) ;
92+ require ( './bootstrap-amd' ) . load ( 'vs/code/electron-main/main' , ( ) => {
93+ perf . mark ( 'didLoadMainBundle' ) ;
94+ } ) ;
95+ }
8896
89- // First, we need to test a user defined locale. If it fails we try the app locale.
90- // If that fails we fall back to English.
91- nlsConfiguration . then ( nlsConfig => {
92-
93- const startup = nlsConfig => {
94- nlsConfig . _languagePackSupport = true ;
95- process . env [ 'VSCODE_NLS_CONFIG' ] = JSON . stringify ( nlsConfig ) ;
96- process . env [ 'VSCODE_NODE_CACHED_DATA_DIR' ] = cachedDataDir || '' ;
97-
98- // Load main in AMD
99- perf . mark ( 'willLoadMainBundle' ) ;
100- require ( './bootstrap-amd' ) . load ( 'vs/code/electron-main/main' , ( ) => {
101- perf . mark ( 'didLoadMainBundle' ) ;
102- } ) ;
103- } ;
104-
105- // We received a valid nlsConfig from a user defined locale
106- if ( nlsConfig ) {
107- startup ( nlsConfig ) ;
108- }
97+ async function onReady ( ) {
98+ perf . mark ( 'main:appReady' ) ;
10999
110- // Try to use the app locale. Please note that the app locale is only
111- // valid after we have received the app ready event. This is why the
112- // code is here.
113- else {
114- let appLocale = app . getLocale ( ) ;
115- if ( ! appLocale ) {
116- startup ( { locale : 'en' , availableLanguages : { } } ) ;
117- } else {
118-
119- // See above the comment about the loader and case sensitiviness
120- appLocale = appLocale . toLowerCase ( ) ;
121-
122- lp . getNLSConfiguration ( product . commit , userDataPath , metaDataFile , appLocale ) . then ( nlsConfig => {
123- if ( ! nlsConfig ) {
124- nlsConfig = { locale : appLocale , availableLanguages : { } } ;
125- }
126-
127- startup ( nlsConfig ) ;
128- } ) ;
129- }
130- }
131- } ) ;
132- } , console . error ) ;
100+ try {
101+ const [ cachedDataDir , locale ] = await Promise . all ( [ nodeCachedDataDir . ensureExists ( ) , userDefinedLocale ] ) ;
102+
103+ startup ( cachedDataDir , await resolveNlsConfiguration ( locale ) ) ;
104+ } catch ( error ) {
105+ console . error ( error ) ;
106+ }
133107}
134108
135109/**
@@ -249,7 +223,7 @@ function registerListeners() {
249223}
250224
251225/**
252- * @returns {{ ensureExists: () => Promise<string | void > } }
226+ * @returns {{ ensureExists: () => Promise<string | undefined > } }
253227 */
254228function getNodeCachedDir ( ) {
255229 return new class {
@@ -258,8 +232,14 @@ function getNodeCachedDir() {
258232 this . value = this . _compute ( ) ;
259233 }
260234
261- ensureExists ( ) {
262- return bootstrap . mkdirp ( this . value ) . then ( ( ) => this . value , ( ) => { /*ignore*/ } ) ;
235+ async ensureExists ( ) {
236+ try {
237+ await bootstrap . mkdirp ( this . value ) ;
238+
239+ return this . value ;
240+ } catch ( error ) {
241+ // ignore
242+ }
263243 }
264244
265245 _compute ( ) {
@@ -284,6 +264,50 @@ function getNodeCachedDir() {
284264}
285265
286266//#region NLS Support
267+ /**
268+ * Resolve the NLS configuration
269+ *
270+ * @param {string | undefined } locale
271+ * @return {Promise<import('./vs/base/node/languagePacks').NLSConfiguration> }
272+ */
273+ async function resolveNlsConfiguration ( locale ) {
274+
275+ // First, we need to test a user defined locale. If it fails we try the app locale.
276+ // If that fails we fall back to English.
277+ if ( locale && ! nlsConfigurationPromise ) {
278+ nlsConfigurationPromise = lp . getNLSConfiguration ( product . commit , userDataPath , metaDataFile , locale ) ;
279+ } else if ( ! nlsConfigurationPromise ) {
280+ nlsConfigurationPromise = Promise . resolve ( undefined ) ;
281+ }
282+
283+ // First, we need to test a user defined locale. If it fails we try the app locale.
284+ // If that fails we fall back to English.
285+ let nlsConfiguration = await nlsConfigurationPromise ;
286+ if ( ! nlsConfiguration ) {
287+
288+ // Try to use the app locale. Please note that the app locale is only
289+ // valid after we have received the app ready event. This is why the
290+ // code is here.
291+ let appLocale = app . getLocale ( ) ;
292+ if ( ! appLocale ) {
293+ nlsConfiguration = { locale : 'en' , availableLanguages : { } } ;
294+ } else {
295+
296+ // See above the comment about the loader and case sensitiviness
297+ appLocale = appLocale . toLowerCase ( ) ;
298+
299+ nlsConfiguration = await lp . getNLSConfiguration ( product . commit , userDataPath , metaDataFile , appLocale ) ;
300+ if ( ! nlsConfiguration ) {
301+ nlsConfiguration = { locale : appLocale , availableLanguages : { } } ;
302+ }
303+ }
304+ } else {
305+ // We received a valid nlsConfig from a user defined locale
306+ }
307+
308+ return nlsConfiguration ;
309+ }
310+
287311/**
288312 * @param {string } content
289313 * @returns {string }
@@ -312,30 +336,29 @@ function stripComments(content) {
312336 } ) ;
313337}
314338
315- // Language tags are case insensitive however an amd loader is case sensitive
316- // To make this work on case preserving & insensitive FS we do the following:
317- // the language bundles have lower case language tags and we always lower case
318- // the locale we receive from the user or OS.
319339/**
340+ * Language tags are case insensitive however an amd loader is case sensitive
341+ * To make this work on case preserving & insensitive FS we do the following:
342+ * the language bundles have lower case language tags and we always lower case
343+ * the locale we receive from the user or OS.
344+ *
320345 * @returns {Promise<string> }
321346 */
322- function getUserDefinedLocale ( ) {
347+ async function getUserDefinedLocale ( ) {
323348 const locale = args [ 'locale' ] ;
324349 if ( locale ) {
325- return Promise . resolve ( locale . toLowerCase ( ) ) ;
350+ return locale . toLowerCase ( ) ;
326351 }
327352
328353 const localeConfig = path . join ( userDataPath , 'User' , 'locale.json' ) ;
329- return bootstrap . readFile ( localeConfig ) . then ( content => {
330- content = stripComments ( content ) ;
331- try {
332- const value = JSON . parse ( content ) . locale ;
333- return value && typeof value === 'string' ? value . toLowerCase ( ) : undefined ;
334- } catch ( e ) {
335- return undefined ;
336- }
337- } , ( ) => {
338- return undefined ;
339- } ) ;
354+
355+ try {
356+ const content = stripComments ( await bootstrap . readFile ( localeConfig ) ) ;
357+
358+ const value = JSON . parse ( content ) . locale ;
359+ return value && typeof value === 'string' ? value . toLowerCase ( ) : undefined ;
360+ } catch ( error ) {
361+ // ignore
362+ }
340363}
341364//#endregion
0 commit comments