diff --git a/package.json b/package.json index 99b62519e..3db04d4c2 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "autocomplete-atom-api": "0.9.2", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.24.0", + "autocomplete-plus": "2.25.0", "autocomplete-snippets": "1.9.0", "autoflow": "0.26.0", "autosave": "0.23.0", @@ -98,7 +98,7 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.3.0", "link": "0.31.0", - "markdown-preview": "0.157.0", + "markdown-preview": "0.157.1", "metrics": "0.53.1", "notifications": "0.62.1", "open-on-github": "0.40.0", @@ -118,7 +118,7 @@ "whitespace": "0.32.1", "wrap-guide": "0.38.1", "language-c": "0.51.1", - "language-clojure": "0.19.0", + "language-clojure": "0.19.1", "language-coffee-script": "0.46.0", "language-csharp": "0.11.0", "language-css": "0.36.0", diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 76314681c..9c53b3c07 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -26,8 +26,13 @@ describe "TokenizedBuffer", -> describe "serialization", -> describe "when the underlying buffer has a path", -> - it "deserializes it searching among the buffers in the current project", -> + beforeEach -> buffer = atom.project.bufferForPathSync('sample.js') + + waitsForPromise -> + atom.packages.activatePackage('language-coffee-script') + + it "deserializes it searching among the buffers in the current project", -> tokenizedBufferA = new TokenizedBuffer({ buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert }) @@ -38,10 +43,25 @@ describe "TokenizedBuffer", -> expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer) + it "does not serialize / deserialize the current grammar", -> + tokenizedBufferA = new TokenizedBuffer({ + buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert + }) + autoSelectedGrammar = tokenizedBufferA.grammar + + tokenizedBufferA.setGrammar(atom.grammars.grammarForScopeName('source.coffee')) + tokenizedBufferB = TokenizedBuffer.deserialize( + JSON.parse(JSON.stringify(tokenizedBufferA.serialize())), + atom + ) + + expect(tokenizedBufferB.grammar).toBe(atom.grammars.grammarForScopeName('source.js')) + describe "when the underlying buffer has no path", -> - it "deserializes it searching among the buffers in the current project", -> + beforeEach -> buffer = atom.project.bufferForPathSync(null) + it "deserializes it searching among the buffers in the current project", -> tokenizedBufferA = new TokenizedBuffer({ buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert }) @@ -52,6 +72,38 @@ describe "TokenizedBuffer", -> expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer) + it "deserializes the previously selected grammar as soon as it's added when not available in the grammar registry", -> + tokenizedBufferA = new TokenizedBuffer({ + buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert + }) + + tokenizedBufferA.setGrammar(atom.grammars.grammarForScopeName("source.js")) + atom.grammars.removeGrammarForScopeName(tokenizedBufferA.grammar.scopeName) + tokenizedBufferB = TokenizedBuffer.deserialize( + JSON.parse(JSON.stringify(tokenizedBufferA.serialize())), + atom + ) + + expect(tokenizedBufferB.grammar).not.toBeFalsy() + expect(tokenizedBufferB.grammar).not.toBe(tokenizedBufferA.grammar) + + atom.grammars.addGrammar(tokenizedBufferA.grammar) + + expect(tokenizedBufferB.grammar).toBe(tokenizedBufferA.grammar) + + it "deserializes the previously selected grammar on construction when available in the grammar registry", -> + tokenizedBufferA = new TokenizedBuffer({ + buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert + }) + + tokenizedBufferA.setGrammar(atom.grammars.grammarForScopeName("source.js")) + tokenizedBufferB = TokenizedBuffer.deserialize( + JSON.parse(JSON.stringify(tokenizedBufferA.serialize())), + atom + ) + + expect(tokenizedBufferB.grammar).toBe(tokenizedBufferA.grammar) + describe "when the buffer is destroyed", -> beforeEach -> buffer = atom.project.bufferForPathSync('sample.js') diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index cdafc2869..0fdf4eea8 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -36,7 +36,7 @@ class TokenizedBuffer extends Model constructor: (params) -> { @buffer, @tabLength, @ignoreInvisibles, @largeFileMode, @config, - @grammarRegistry, @packageManager, @assert + @grammarRegistry, @packageManager, @assert, grammarScopeName } = params @emitter = new Emitter @@ -49,18 +49,26 @@ class TokenizedBuffer extends Model @disposables.add @buffer.preemptDidChange (e) => @handleBufferChange(e) @disposables.add @buffer.onDidChangePath (@bufferPath) => @reloadGrammar() - @reloadGrammar() + if grammar = @grammarRegistry.grammarForScopeName(grammarScopeName) + @setGrammar(grammar) + else + @reloadGrammar() + @grammarToRestoreScopeName = grammarScopeName destroyed: -> @disposables.dispose() serialize: -> - deserializer: 'TokenizedBuffer' - bufferPath: @buffer.getPath() - bufferId: @buffer.getId() - tabLength: @tabLength - ignoreInvisibles: @ignoreInvisibles - largeFileMode: @largeFileMode + state = { + deserializer: 'TokenizedBuffer' + bufferPath: @buffer.getPath() + bufferId: @buffer.getId() + tabLength: @tabLength + ignoreInvisibles: @ignoreInvisibles + largeFileMode: @largeFileMode + } + state.grammarScopeName = @grammar?.scopeName unless @buffer.getPath() + state observeGrammar: (callback) -> callback(@grammar) @@ -76,7 +84,9 @@ class TokenizedBuffer extends Model @emitter.on 'did-tokenize', callback grammarAddedOrUpdated: (grammar) => - if grammar.injectionSelector? + if @grammarToRestoreScopeName is grammar.scopeName + @setGrammar(grammar) + else if grammar.injectionSelector? @retokenizeLines() if @hasTokenForSelector(grammar.injectionSelector) else newScore = @grammarRegistry.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent()) @@ -89,6 +99,8 @@ class TokenizedBuffer extends Model @rootScopeDescriptor = new ScopeDescriptor(scopes: [@grammar.scopeName]) @currentGrammarScore = score ? @grammarRegistry.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent()) + @grammarToRestoreScopeName = null + @grammarUpdateDisposable?.dispose() @grammarUpdateDisposable = @grammar.onDidUpdate => @retokenizeLines() @disposables.add(@grammarUpdateDisposable)