From d52c4bc33b8ed13c1cb008ad7ec28e83760dda87 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 20 Nov 2017 14:50:00 -0800 Subject: [PATCH] Serialize the grammar registry --- spec/atom-environment-spec.js | 7 +++-- spec/grammar-registry-spec.js | 39 +++++++++++++++++++++++++++- spec/text-editor-registry-spec.js | 40 ---------------------------- src/atom-environment.js | 5 ++-- src/grammar-registry.js | 43 ++++++++++++++++++++++--------- 5 files changed, 76 insertions(+), 58 deletions(-) diff --git a/spec/atom-environment-spec.js b/spec/atom-environment-spec.js index 84b415eab..360d7cafb 100644 --- a/spec/atom-environment-spec.js +++ b/spec/atom-environment-spec.js @@ -301,8 +301,9 @@ describe('AtomEnvironment', () => { }) it('serializes the text editor registry', async () => { + await atom.packages.activatePackage('language-text') const editor = await atom.workspace.open('sample.js') - atom.textEditors.setGrammarOverride(editor, 'text.plain') + expect(atom.grammars.assignLanguageMode(editor, 'plain text')).toBe(true) const atom2 = new AtomEnvironment({ applicationDelegate: atom.applicationDelegate, @@ -318,7 +319,9 @@ describe('AtomEnvironment', () => { atom2.initialize({document, window}) await atom2.deserialize(atom.serialize()) - expect(atom2.textEditors.getGrammarOverride(editor)).toBe('text.plain') + await atom2.packages.activatePackage('language-text') + const editor2 = atom2.workspace.getActiveTextEditor() + expect(editor2.getBuffer().getLanguageMode().getLanguageName()).toBe('Plain Text') atom2.destroy() }) diff --git a/spec/grammar-registry-spec.js b/spec/grammar-registry-spec.js index c49d072ef..8c66ffe83 100644 --- a/spec/grammar-registry-spec.js +++ b/spec/grammar-registry-spec.js @@ -58,7 +58,7 @@ describe('GrammarRegistry', () => { expect(grammarRegistry.assignLanguageMode(buffer, 'css')).toBe(true) expect(buffer.getLanguageMode().getLanguageName()).toBe('CSS') - expect(grammarRegistry.autoAssignLanguageMode(buffer)).toBe(true) + grammarRegistry.autoAssignLanguageMode(buffer) expect(buffer.getLanguageMode().getLanguageName()).toBe('JavaScript') }) }) @@ -315,6 +315,43 @@ describe('GrammarRegistry', () => { expect(atom.grammars.selectGrammar('foo.js').name).not.toBe(grammar.name) }) }) + + describe('serialization', () => { + it('persists editors\' grammar overrides', async () => { + const buffer1 = new TextBuffer() + const buffer2 = new TextBuffer() + + grammarRegistry.loadGrammarSync(require.resolve('language-c/grammars/c.cson')) + grammarRegistry.loadGrammarSync(require.resolve('language-html/grammars/html.cson')) + grammarRegistry.loadGrammarSync(require.resolve('language-javascript/grammars/javascript.cson')) + + grammarRegistry.maintainLanguageMode(buffer1) + grammarRegistry.maintainLanguageMode(buffer2) + grammarRegistry.assignLanguageMode(buffer1, 'c') + grammarRegistry.assignLanguageMode(buffer2, 'javascript') + + const buffer1Copy = await TextBuffer.deserialize(buffer1.serialize()) + const buffer2Copy = await TextBuffer.deserialize(buffer2.serialize()) + + const grammarRegistryCopy = new GrammarRegistry({config: atom.config}) + grammarRegistryCopy.deserialize(JSON.parse(JSON.stringify(grammarRegistry.serialize()))) + + grammarRegistryCopy.loadGrammarSync(require.resolve('language-c/grammars/c.cson')) + grammarRegistryCopy.loadGrammarSync(require.resolve('language-html/grammars/html.cson')) + + expect(buffer1Copy.getLanguageMode().getLanguageName()).toBe('None') + expect(buffer2Copy.getLanguageMode().getLanguageName()).toBe('None') + + grammarRegistryCopy.maintainLanguageMode(buffer1Copy) + grammarRegistryCopy.maintainLanguageMode(buffer2Copy) + expect(buffer1Copy.getLanguageMode().getLanguageName()).toBe('C') + expect(buffer2Copy.getLanguageMode().getLanguageName()).toBe('None') + + grammarRegistryCopy.loadGrammarSync(require.resolve('language-javascript/grammars/javascript.cson')) + expect(buffer1Copy.getLanguageMode().getLanguageName()).toBe('C') + expect(buffer2Copy.getLanguageMode().getLanguageName()).toBe('JavaScript') + }) + }) }) function retainedBufferCount (grammarRegistry) { diff --git a/spec/text-editor-registry-spec.js b/spec/text-editor-registry-spec.js index ced64dfb9..d80f46399 100644 --- a/spec/text-editor-registry-spec.js +++ b/spec/text-editor-registry-spec.js @@ -546,46 +546,6 @@ describe('TextEditorRegistry', function () { }) }) }) - - describe('serialization', function () { - it('persists editors\' grammar overrides', async function () { - const editor2 = new TextEditor() - - await atom.packages.activatePackage('language-c') - await atom.packages.activatePackage('language-html') - await atom.packages.activatePackage('language-javascript') - - registry.maintainGrammar(editor) - registry.maintainGrammar(editor2) - atom.grammars.assignLanguageMode(editor, 'c') - atom.grammars.assignLanguageMode(editor2, 'javascript') - - await atom.packages.deactivatePackage('language-javascript') - - const editorCopy = TextEditor.deserialize(editor.serialize(), atom) - const editor2Copy = TextEditor.deserialize(editor2.serialize(), atom) - - const registryCopy = new TextEditorRegistry({ - assert: atom.assert, - config: atom.config, - grammarRegistry: atom.grammars, - packageManager: {deferredActivationHooks: null} - }) - registryCopy.deserialize(JSON.parse(JSON.stringify(registry.serialize()))) - - expect(editorCopy.getGrammar().name).toBe('Null Grammar') - expect(editor2Copy.getGrammar().name).toBe('Null Grammar') - - registryCopy.maintainGrammar(editorCopy) - registryCopy.maintainGrammar(editor2Copy) - expect(editorCopy.getGrammar().name).toBe('C') - expect(editor2Copy.getGrammar().name).toBe('Null Grammar') - - await atom.packages.activatePackage('language-javascript') - expect(editorCopy.getGrammar().name).toBe('C') - expect(editor2Copy.getGrammar().name).toBe('JavaScript') - }) - }) }) function getSubscriptionCount (editor) { diff --git a/src/atom-environment.js b/src/atom-environment.js index 38f18710c..1728064c8 100644 --- a/src/atom-environment.js +++ b/src/atom-environment.js @@ -821,10 +821,9 @@ class AtomEnvironment { project: this.project.serialize(options), workspace: this.workspace.serialize(), packageStates: this.packages.serialize(), - grammars: {grammarOverridesByPath: this.grammars.grammarOverridesByPath}, + grammars: this.grammars.serialize(), fullScreen: this.isFullScreen(), windowDimensions: this.windowDimensions, - textEditors: this.textEditors.serialize() } } @@ -1147,7 +1146,7 @@ class AtomEnvironment { this.deserializeTimings.project = Date.now() - startTime - if (state.textEditors) this.textEditors.deserialize(state.textEditors) + if (state.grammars) this.grammars.deserialize(state.grammars) startTime = Date.now() if (state.workspace) this.workspace.deserialize(state.workspace, this.deserializers) diff --git a/src/grammar-registry.js b/src/grammar-registry.js index 8ccddc872..88ddea99e 100644 --- a/src/grammar-registry.js +++ b/src/grammar-registry.js @@ -33,11 +33,30 @@ class GrammarRegistry extends FirstMate.GrammarRegistry { this.onDidUpdateGrammar(grammarAddedOrUpdated) } + serialize () { + const languageNameOverridesByBufferId = {} + this.languageNameOverridesByBufferId.forEach((languageName, bufferId) => { + languageNameOverridesByBufferId[bufferId] = languageName + }) + return {languageNameOverridesByBufferId} + } + + deserialize (params) { + for (const bufferId in params.languageNameOverridesByBufferId || {}) { + this.languageNameOverridesByBufferId.set( + bufferId, + params.languageNameOverridesByBufferId[bufferId] + ) + } + } + createToken (value, scopes) { return new Token({value, scopes}) } maintainLanguageMode (buffer) { + this.grammarScoresByBuffer.set(buffer, null) + const languageNameOverride = this.languageNameOverridesByBufferId.get(buffer.id) if (languageNameOverride) { this.assignLanguageMode(buffer, languageNameOverride) @@ -86,16 +105,10 @@ class GrammarRegistry extends FirstMate.GrammarRegistry { buffer.getPath(), buffer.getTextInRange(GRAMMAR_SELECTION_RANGE) ) - const currentScore = this.grammarScoresByBuffer.get(buffer) - if (currentScore == null || result.score > currentScore) { - this.languageNameOverridesByBufferId.delete(buffer.id) - this.grammarScoresByBuffer.set(buffer, result.score) - if (result.grammar.name !== buffer.getLanguageMode().getLanguageName()) { - buffer.setLanguageMode(this.languageModeForGrammarAndBuffer(result.grammar, buffer)) - } - return true - } else { - return false + this.languageNameOverridesByBufferId.delete(buffer.id) + this.grammarScoresByBuffer.set(buffer, result.score) + if (result.grammar.name !== buffer.getLanguageMode().getLanguageName()) { + buffer.setLanguageMode(this.languageModeForGrammarAndBuffer(result.grammar, buffer)) } } @@ -244,6 +257,8 @@ class GrammarRegistry extends FirstMate.GrammarRegistry { grammarAddedOrUpdated (grammar) { this.grammarScoresByBuffer.forEach((score, buffer) => { + if (global.debug) debugger + const languageMode = buffer.getLanguageMode() if (grammar.injectionSelector) { if (languageMode.hasTokenForSelector(grammar.injectionSelector)) { @@ -252,9 +267,13 @@ class GrammarRegistry extends FirstMate.GrammarRegistry { return } - if (grammar.name === buffer.getLanguageMode().getLanguageName()) { + const overrideName = this.languageNameOverridesByBufferId.get(buffer.id) + + if (grammar.name && + (grammar.name === buffer.getLanguageMode().getLanguageName() || + grammar.name.toLowerCase() === overrideName)) { buffer.setLanguageMode(this.languageModeForGrammarAndBuffer(grammar, buffer)) - } else if (!this.languageNameOverridesByBufferId.has(buffer.id)) { + } else if (!overrideName) { const score = this.getGrammarScore( grammar, buffer.getPath(),