Remove all config observation from text editor

This commit is contained in:
Max Brunsfeld
2016-07-11 12:43:18 -07:00
parent 54a9f3004d
commit 5acab853cd
3 changed files with 172 additions and 48 deletions

View File

@@ -77,7 +77,7 @@ describe('TextEditorRegistry', function () {
registry.maintainGrammar(editor)
await atom.packages.activatePackage('language-javascript')
expect(editor.getGrammar().name).toBe('JavaScript')
});
})
})
describe('.maintainConfig(editor)', function () {
@@ -91,7 +91,7 @@ describe('TextEditorRegistry', function () {
atom.config.set('core.fileEncoding', 'utf8')
expect(editor.getEncoding()).toBe('utf8')
});
})
it('sets the tab length based on the config', function () {
editor.setTabLength(4)
@@ -103,7 +103,63 @@ describe('TextEditorRegistry', function () {
atom.config.set('editor.tabLength', 4)
expect(editor.getTabLength()).toBe(4)
});
})
it('enables soft tabs when the tabType config setting is "soft"', function () {
atom.config.set('editor.tabType', 'soft')
registry.maintainConfig(editor)
expect(editor.getSoftTabs()).toBe(true)
})
it('disables soft tabs when the tabType config setting is "hard"', function () {
atom.config.set('editor.tabType', 'hard')
registry.maintainConfig(editor)
expect(editor.getSoftTabs()).toBe(false)
})
describe('when the "tabType" config setting is "auto"', function () {
it('enables or disables soft tabs based on the editor\'s content', function () {
registry.maintainConfig(editor)
atom.config.set('editor.tabType', 'auto')
editor.setText('{\n hello;\n}')
expect(editor.getSoftTabs()).toBe(true)
editor.setText('{\n\thello;\n}')
editor.tokenizedBuffer.retokenizeLines()
expect(editor.getSoftTabs()).toBe(false)
})
})
describe('when the "tabType" config setting is "auto"', function () {
it('enables or disables soft tabs based on the "softTabs" config setting', function () {
registry.maintainConfig(editor)
editor.setText('abc\ndef')
atom.config.set('editor.softTabs', true)
atom.config.set('editor.tabType', 'auto')
expect(editor.getSoftTabs()).toBe(true)
atom.config.set('editor.softTabs', false)
expect(editor.getSoftTabs()).toBe(false)
})
})
it('enables or disables soft tabs based on the config', function () {
editor.setSoftTabs(true)
expect(editor.getSoftTabs()).toBe(true)
atom.config.set('editor.tabType', 'hard')
registry.maintainConfig(editor)
expect(editor.getSoftTabs()).toBe(false)
atom.config.set('editor.tabType', 'soft')
expect(editor.getSoftTabs()).toBe(true)
atom.config.set('editor.tabType', 'auto')
atom.config.set('editor.softTabs', true)
expect(editor.getSoftTabs()).toBe(true)
})
it('enables or disables atomic soft tabs based on the config', function () {
editor.setAtomicSoftTabs(true)
@@ -115,7 +171,7 @@ describe('TextEditorRegistry', function () {
atom.config.set('editor.atomicSoftTabs', true)
expect(editor.hasAtomicSoftTabs()).toBe(true)
});
})
it('enables or disables invisible based on the config', function () {
editor.setShowInvisibles(true)
@@ -127,7 +183,7 @@ describe('TextEditorRegistry', function () {
atom.config.set('editor.showInvisibles', true)
expect(editor.doesShowInvisibles()).toBe(true)
});
})
it('sets the invisibles based on the config', function () {
editor.setShowInvisibles(true)
@@ -145,7 +201,7 @@ describe('TextEditorRegistry', function () {
atom.config.set('editor.invisibles', invisibles1)
expect(editor.getInvisibles()).toEqual(invisibles1)
});
})
it('enables or disables the indent guide based on the config', function () {
editor.setShowIndentGuide(true)
@@ -157,7 +213,7 @@ describe('TextEditorRegistry', function () {
atom.config.set('editor.showIndentGuide', true)
expect(editor.doesShowIndentGuide()).toBe(true)
});
})
it('enables or disables soft wrap based on the config', function () {
editor.setSoftWrapped(true)
@@ -169,6 +225,42 @@ describe('TextEditorRegistry', function () {
atom.config.set('editor.softWrap', true)
expect(editor.isSoftWrapped()).toBe(true)
});
})
it('sets the soft wrap indent length based on the config', function () {
editor.setSoftWrapIndentLength(4)
expect(editor.getSoftWrapIndentLength()).toBe(4)
atom.config.set('editor.softWrapHangingIndent', 2)
registry.maintainConfig(editor)
expect(editor.getSoftWrapIndentLength()).toBe(2)
atom.config.set('editor.softWrapHangingIndent', 4)
expect(editor.getSoftWrapIndentLength()).toBe(4)
})
it('enables or disables preferred line length-based soft wrap based on the config', function () {
editor.setSoftWrapAtPreferredLineLength(true)
expect(editor.doesSoftWrapAtPreferredLineLength()).toBe(true)
atom.config.set('editor.softWrapAtPreferredLineLength', false)
registry.maintainConfig(editor)
expect(editor.doesSoftWrapAtPreferredLineLength()).toBe(false)
atom.config.set('editor.softWrapAtPreferredLineLength', true)
expect(editor.doesSoftWrapAtPreferredLineLength()).toBe(true)
})
it('sets the preferred line length based on the config', function () {
editor.setPreferredLineLength(80)
expect(editor.getPreferredLineLength()).toBe(80)
atom.config.set('editor.preferredLineLength', 110)
registry.maintainConfig(editor)
expect(editor.getPreferredLineLength()).toBe(110)
atom.config.set('editor.preferredLineLength', 80)
expect(editor.getPreferredLineLength()).toBe(80)
})
})
})

View File

@@ -10,6 +10,9 @@ const EDITOR_SETTER_NAMES_BY_SETTING_KEY = [
['editor.invisibles', 'setInvisibles'],
['editor.showIndentGuide', 'setShowIndentGuide'],
['editor.softWrap', 'setSoftWrapped'],
['editor.softWrapHangingIndent', 'setSoftWrapIndentLength'],
['editor.softWrapAtPreferredLineLength', 'setSoftWrapAtPreferredLineLength'],
['editor.preferredLineLength', 'setPreferredLineLength'],
]
// Experimental: This global registry tracks registered `TextEditors`.
@@ -87,6 +90,17 @@ export default class TextEditorRegistry {
for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) {
editor[setterName](atom.config.get(settingKey, configOptions))
}
const updateTabTypes = () => {
editor.setSoftTabs(shouldEditorUseSoftTabs(
editor,
atom.config.get('editor.tabType', configOptions),
atom.config.get('editor.softTabs', configOptions)
))
}
updateTabTypes()
this.subscriptions.add(editor.onDidTokenize(updateTabTypes))
}
subscribeToSettingsForEditorScope (editor) {
@@ -97,6 +111,7 @@ export default class TextEditorRegistry {
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}) => {
@@ -108,6 +123,40 @@ 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().getScopeChain() === scopeChain) {
editor.setSoftTabs(shouldEditorUseSoftTabs(editor, tabType, softTabs))
}
})
}
this.subscriptions.add(
this.config.onDidChange('editor.tabType', configOptions, updateTabTypes),
this.config.onDidChange('editor.softTabs', configOptions, updateTabTypes)
)
}
}
}
function shouldEditorUseSoftTabs (editor, tabType, softTabs) {
switch (tabType) {
case 'hard':
return false
case 'soft':
return true
case 'auto':
switch (editor.usesSoftTabs()) {
case true:
return true
case false:
return false
default:
return softTabs
}
}
}

View File

@@ -162,12 +162,9 @@ class TextEditor extends Model
@decorateMarkerLayer(@displayLayer.foldsMarkerLayer, {type: 'line-number', class: 'folded'})
@disposables.add @tokenizedBuffer.observeGrammar @subscribeToScopedConfigSettings
for marker in @selectionsMarkerLayer.getMarkers()
@addSelection(marker)
@subscribeToTabTypeConfig()
@subscribeToBuffer()
@subscribeToDisplayLayer()
@@ -226,36 +223,19 @@ class TextEditor extends Model
onDidTerminatePendingState: (callback) ->
@emitter.on 'did-terminate-pending-state', callback
subscribeToScopedConfigSettings: =>
@scopedConfigSubscriptions?.dispose()
@scopedConfigSubscriptions = subscriptions = new CompositeDisposable
scopeDescriptor = @getRootScopeDescriptor()
subscriptions.add @config.onDidChange 'editor.softWrapHangingIndent', scope: scopeDescriptor, @resetDisplayLayer.bind(this)
subscriptions.add @config.onDidChange 'editor.softWrapAtPreferredLineLength', scope: scopeDescriptor, @resetDisplayLayer.bind(this)
subscriptions.add @config.onDidChange 'editor.preferredLineLength', scope: scopeDescriptor, @resetDisplayLayer.bind(this)
@resetDisplayLayer()
subscribeToDisplayLayer: ->
@disposables.add @selectionsMarkerLayer.onDidCreateMarker @addSelection.bind(this)
@disposables.add @tokenizedBuffer.onDidChangeGrammar @handleGrammarChange.bind(this)
@disposables.add @tokenizedBuffer.onDidTokenize @handleTokenization.bind(this)
@disposables.add @displayLayer.onDidChangeSync (e) =>
@mergeIntersectingSelections()
@emitter.emit 'did-change', e
subscribeToTabTypeConfig: ->
@tabTypeSubscription?.dispose()
@tabTypeSubscription = @config.observe 'editor.tabType', scope: @getRootScopeDescriptor(), =>
@softTabs = @shouldUseSoftTabs(defaultValue: @softTabs)
resetDisplayLayer: ->
@displayLayer.reset({
invisibles: @getInvisibles(),
softWrapColumn: @getSoftWrapColumn(),
showIndentGuides: not @isMini() and @config.get('editor.showIndentGuide', scope: @getRootScopeDescriptor()),
atomicSoftTabs: @config.get('editor.atomicSoftTabs', scope: @getRootScopeDescriptor()),
showIndentGuides: not @isMini() and @doesShowIndentGuide(),
atomicSoftTabs: @hasAtomicSoftTabs(),
tabLength: @getTabLength(),
ratioForCharacter: @ratioForCharacter.bind(this),
isWrapBoundary: isWrapBoundary,
@@ -2765,6 +2745,13 @@ class TextEditor extends Model
@showIndentGuide = showIndentGuide
@resetDisplayLayer()
setSoftWrapIndentLength: (softWrapIndentLength) ->
return if softWrapIndentLength is @softWrapIndentLength
@softWrapIndentLength = softWrapIndentLength
@resetDisplayLayer()
getSoftWrapIndentLength: -> @softWrapIndentLength
# Extended: Determine if the buffer uses hard or soft tabs.
#
# Returns `true` if the first non-comment line with leading whitespace starts
@@ -2796,20 +2783,6 @@ class TextEditor extends Model
return unless @getSoftTabs()
@scanInBufferRange /\t/g, bufferRange, ({replace}) => replace(@getTabText())
# Private: Computes whether or not this editor should use softTabs based on
# the `editor.tabType` setting.
#
# Returns a {Boolean}
shouldUseSoftTabs: ({defaultValue}) ->
tabType = @config.get('editor.tabType', scope: @getRootScopeDescriptor())
switch tabType
when 'auto'
@usesSoftTabs() ? defaultValue ? @config.get('editor.softTabs') ? true
when 'hard'
false
when 'soft'
true
###
Section: Soft Wrap Behavior
###
@@ -2838,6 +2811,20 @@ class TextEditor extends Model
else
@isSoftWrapped()
setSoftWrapAtPreferredLineLength: (softWrapAtPreferredLineLength) ->
return if softWrapAtPreferredLineLength is @softWrapAtPreferredLineLength
@softWrapAtPreferredLineLength = softWrapAtPreferredLineLength
@resetDisplayLayer()
doesSoftWrapAtPreferredLineLength: -> @softWrapAtPreferredLineLength
setPreferredLineLength: (preferredLineLength) ->
return if preferredLineLength is @preferredLineLength
@preferredLineLength = preferredLineLength
@resetDisplayLayer()
getPreferredLineLength: -> @preferredLineLength
# Essential: Toggle soft wrapping for this editor
#
# Returns a {Boolean}.
@@ -3342,12 +3329,8 @@ class TextEditor extends Model
Section: Event Handlers
###
handleTokenization: ->
@softTabs = @shouldUseSoftTabs(defaultValue: @softTabs)
handleGrammarChange: ->
@unfoldAll()
@subscribeToTabTypeConfig()
@emitter.emit 'did-change-grammar', @getGrammar()
###