Merge pull request #16542 from atom/dw-preserve-editor-settings

Preserve some TextEditor settings when language mode changes
This commit is contained in:
David Wilson 2018-01-12 13:52:47 -08:00 committed by GitHub
commit 3f7a29b86c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 9 deletions

View File

@ -154,6 +154,45 @@ describe('TextEditorRegistry', function () {
expect(editor.getEncoding()).toBe('utf8')
})
it('preserves editor settings that haven\'t changed between previous and current language modes', async function () {
await atom.packages.activatePackage('language-javascript')
registry.maintainConfig(editor)
await initialPackageActivation
expect(editor.getEncoding()).toBe('utf8')
editor.setEncoding('utf16le')
expect(editor.getEncoding()).toBe('utf16le')
expect(editor.isSoftWrapped()).toBe(false)
editor.setSoftWrapped(true)
expect(editor.isSoftWrapped()).toBe(true)
atom.grammars.assignLanguageMode(editor, 'source.js')
await initialPackageActivation
expect(editor.getEncoding()).toBe('utf16le')
expect(editor.isSoftWrapped()).toBe(true)
})
it('updates editor settings that have changed between previous and current language modes', async function () {
await atom.packages.activatePackage('language-javascript')
registry.maintainConfig(editor)
await initialPackageActivation
expect(editor.getEncoding()).toBe('utf8')
atom.config.set('core.fileEncoding', 'utf16be', {scopeSelector: '.text.plain.null-grammar'})
atom.config.set('core.fileEncoding', 'utf16le', {scopeSelector: '.source.js'})
expect(editor.getEncoding()).toBe('utf16be')
editor.setEncoding('utf8')
expect(editor.getEncoding()).toBe('utf8')
atom.grammars.assignLanguageMode(editor, 'source.js')
await initialPackageActivation
expect(editor.getEncoding()).toBe('utf16le')
})
it('returns a disposable that can be used to stop the registry from updating the editor\'s config', async function () {
await atom.packages.activatePackage('language-javascript')

View File

@ -1,3 +1,4 @@
const _ = require('underscore-plus')
const {Emitter, Disposable, CompositeDisposable} = require('event-kit')
const TextEditor = require('./text-editor')
const ScopeDescriptor = require('./scope-descriptor')
@ -147,11 +148,11 @@ class TextEditorRegistry {
}
this.editorsWithMaintainedConfig.add(editor)
this.subscribeToSettingsForEditorScope(editor)
const grammarChangeSubscription = editor.onDidChangeGrammar(() => {
this.subscribeToSettingsForEditorScope(editor)
this.updateAndMonitorEditorSettings(editor)
const languageChangeSubscription = editor.buffer.onDidChangeLanguageMode((newLanguageMode, oldLanguageMode) => {
this.updateAndMonitorEditorSettings(editor, oldLanguageMode)
})
this.subscriptions.add(grammarChangeSubscription)
this.subscriptions.add(languageChangeSubscription)
const updateTabTypes = () => {
const configOptions = {scope: editor.getRootScopeDescriptor()}
@ -169,8 +170,8 @@ class TextEditorRegistry {
return new Disposable(() => {
this.editorsWithMaintainedConfig.delete(editor)
tokenizeSubscription.dispose()
grammarChangeSubscription.dispose()
this.subscriptions.remove(grammarChangeSubscription)
languageChangeSubscription.dispose()
this.subscriptions.remove(languageChangeSubscription)
this.subscriptions.remove(tokenizeSubscription)
})
}
@ -214,14 +215,41 @@ class TextEditorRegistry {
atom.grammars.autoAssignLanguageMode(editor.getBuffer())
}
async subscribeToSettingsForEditorScope (editor) {
async updateAndMonitorEditorSettings (editor, oldLanguageMode) {
await this.initialPackageActivationPromise
this.updateEditorSettingsForLanguageMode(editor, oldLanguageMode)
await this.subscribeToSettingsForEditorScope(editor)
}
updateEditorSettingsForLanguageMode (editor, oldLanguageMode) {
const newLanguageMode = editor.buffer.getLanguageMode()
if (oldLanguageMode) {
const newSettings = this.textEditorParamsForScope(newLanguageMode.rootScopeDescriptor)
const oldSettings = this.textEditorParamsForScope(oldLanguageMode.rootScopeDescriptor)
const updatedSettings = {}
for (const [, paramName] of EDITOR_PARAMS_BY_SETTING_KEY) {
// Update the setting only if it has changed between the two language
// modes. This prevents user-modified settings in an editor (like
// 'softWrapped') from being reset when the language mode changes.
if (!_.isEqual(newSettings[paramName], oldSettings[paramName])) {
updatedSettings[paramName] = newSettings[paramName]
}
}
if (_.size(updatedSettings) > 0) {
editor.update(updatedSettings)
}
} else {
editor.update(this.textEditorParamsForScope(newLanguageMode.rootScopeDescriptor))
}
}
async subscribeToSettingsForEditorScope (editor) {
const scopeDescriptor = editor.getRootScopeDescriptor()
const scopeChain = scopeDescriptor.getScopeChain()
editor.update(this.textEditorParamsForScope(scopeDescriptor))
if (!this.scopesWithConfigSubscriptions.has(scopeChain)) {
this.scopesWithConfigSubscriptions.add(scopeChain)
const configOptions = {scope: scopeDescriptor}