From eb9d89f8c8b5bc1ebf9375d0484740fc013c13c2 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 8 Aug 2016 12:10:56 -0700 Subject: [PATCH] Observe grammar changes on editors in maintainConfig --- spec/text-editor-registry-spec.js | 44 ++++++++++++++++++++++++++++++- spec/text-editor-spec.coffee | 2 +- src/text-editor-registry.js | 40 +++++++++++++++++++--------- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/spec/text-editor-registry-spec.js b/spec/text-editor-registry-spec.js index a6a648ac0..4d1bf26c9 100644 --- a/spec/text-editor-registry-spec.js +++ b/spec/text-editor-registry-spec.js @@ -82,6 +82,22 @@ describe('TextEditorRegistry', function () { await atom.packages.activatePackage('language-javascript') expect(editor.getGrammar().name).toBe('JavaScript') }) + + it('returns a disposable that can be used to stop updating the editor', async function () { + await atom.packages.activatePackage('language-javascript') + + const disposable = registry.maintainGrammar(editor) + + editor.getBuffer().setPath('test.js') + expect(editor.getGrammar().name).toBe('JavaScript') + + editor.getBuffer().setPath('test.txt') + expect(editor.getGrammar().name).toBe('Null Grammar') + + disposable.dispose() + editor.getBuffer().setPath('test.js') + expect(editor.getGrammar().name).toBe('Null Grammar') + }) }) describe('.setGrammarOverride', function () { @@ -129,7 +145,7 @@ describe('TextEditorRegistry', function () { }) describe('.maintainConfig(editor)', function () { - it('does not update editors when config settings change for unrelated scope selectors', async function () { + it('does not update the editor when config settings change for unrelated scope selectors', async function () { await atom.packages.activatePackage('language-javascript') const editor2 = new TextEditor({ @@ -155,6 +171,32 @@ describe('TextEditorRegistry', function () { expect(editor2.getEncoding()).toBe('utf16be') }) + it('updates the editor\'s settings when its grammar changes', async function () { + await atom.packages.activatePackage('language-javascript') + + const disposable = registry.maintainConfig(editor) + + atom.config.set('core.fileEncoding', 'utf16be', {scopeSelector: '.source.js'}) + expect(editor.getEncoding()).toBe('utf8') + + atom.config.set('core.fileEncoding', 'utf16le', {scopeSelector: '.source.js'}) + expect(editor.getEncoding()).toBe('utf8') + + editor.setGrammar(atom.grammars.grammarForScopeName('source.js')) + expect(editor.getEncoding()).toBe('utf16le') + + atom.config.set('core.fileEncoding', 'utf16be', {scopeSelector: '.source.js'}) + expect(editor.getEncoding()).toBe('utf16be') + + editor.setGrammar(atom.grammars.selectGrammar('test.txt')) + expect(editor.getEncoding()).toBe('utf8') + + disposable.dispose() + + editor.setGrammar(atom.grammars.grammarForScopeName('source.js')) + expect(editor.getEncoding()).toBe('utf8') + }) + it('sets the encoding based on the config', function () { editor.setEncoding('utf8') expect(editor.getEncoding()).toBe('utf8') diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 9a2d1e004..f96b7b9f3 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -3095,8 +3095,8 @@ describe "TextEditor", -> it "indents the new line to the current level when editor.autoIndent is true and no increaseIndentPattern is specified", -> runs -> - editor.setAutoIndent(true) editor.setGrammar(atom.grammars.selectGrammar("file")) + editor.setAutoIndent(true) editor.setText(' if true') editor.setCursorBufferPosition([0, 8]) editor.insertNewline() diff --git a/src/text-editor-registry.js b/src/text-editor-registry.js index 5aeece784..0c93a73b4 100644 --- a/src/text-editor-registry.js +++ b/src/text-editor-registry.js @@ -135,10 +135,18 @@ export default class TextEditorRegistry { } this.selectGrammarForEditor(editor) - this.subscriptions.add(editor.onDidChangePath(() => { + + const pathChangeSubscription = editor.onDidChangePath(() => { this.editorGrammarScores.delete(editor) this.selectGrammarForEditor(editor) - })) + }) + + this.subscriptions.add(pathChangeSubscription) + + return new Disposable(() => { + this.subscriptions.remove(pathChangeSubscription) + pathChangeSubscription.dispose() + }) } setGrammarOverride (editor, scopeName) { @@ -160,17 +168,18 @@ export default class TextEditorRegistry { if (this.editorsWithMaintainedConfig.has(editor)) { return } - this.editorsWithMaintainedConfig.add(editor) - this.subscribeToSettingsForEditorScope(editor) + editor.setScopedSettingsDelegate(this.scopedSettingsDelegate) - const configOptions = {scope: editor.getRootScopeDescriptor()} - for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) { - editor[setterName](this.config.get(settingKey, configOptions)) - } + this.subscribeToSettingsForEditorScope(editor) + const grammarChangeSubscription = editor.onDidChangeGrammar(() => { + this.subscribeToSettingsForEditorScope(editor) + }) + this.subscriptions.add(grammarChangeSubscription) const updateTabTypes = () => { + const configOptions = {scope: editor.getRootScopeDescriptor()} editor.setSoftTabs(shouldEditorUseSoftTabs( editor, this.config.get('editor.tabType', configOptions), @@ -180,6 +189,12 @@ export default class TextEditorRegistry { updateTabTypes() this.subscriptions.add(editor.onDidTokenize(updateTabTypes)) + + return new Disposable(() => { + editor.setScopedSettingsDelegate(null) + this.subscriptions.remove(grammarChangeSubscription) + grammarChangeSubscription.dispose() + }) } // Private @@ -209,7 +224,6 @@ export default class TextEditorRegistry { if (currentScore == null || score > currentScore) { editor.setGrammar(grammar, score) this.editorGrammarScores.set(editor, score) - this.subscribeToSettingsForEditorScope(editor) } } }) @@ -243,12 +257,15 @@ export default class TextEditorRegistry { subscribeToSettingsForEditorScope (editor) { const scopeDescriptor = editor.getRootScopeDescriptor() const scopeChain = scopeDescriptor.getScopeChain() + const configOptions = {scope: scopeDescriptor} + + for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) { + editor[setterName](this.config.get(settingKey, configOptions)) + } if (!this.scopesWithConfigSubscriptions.has(scopeChain)) { this.scopesWithConfigSubscriptions.add(scopeChain) - const configOptions = {scope: scopeDescriptor} - for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) { this.subscriptions.add( this.config.onDidChange(settingKey, configOptions, ({newValue}) => { @@ -264,7 +281,6 @@ export default class TextEditorRegistry { const updateTabTypes = () => { const tabType = this.config.get('editor.tabType', configOptions) const softTabs = this.config.get('editor.softTabs', configOptions) - this.editorsWithMaintainedConfig.forEach(editor => { if (editor.getRootScopeDescriptor().isEqual(scopeDescriptor)) { editor.setSoftTabs(shouldEditorUseSoftTabs(editor, tabType, softTabs))