diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index b3f268b56..6d8cb5d3b 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -2268,6 +2268,108 @@ describe "TextEditorComponent", -> expect(editor.getCursorBufferPosition()).toEqual [0, 1] + describe 'scoped config settings', -> + [coffeeEditor, coffeeComponent] = [] + + beforeEach -> + waitsForPromise -> + atom.packages.activatePackage('language-coffee-script') + waitsForPromise -> + atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o + + afterEach: -> + atom.packages.deactivatePackages() + atom.packages.unloadPackages() + + describe 'soft wrap settings', -> + beforeEach -> + atom.config.set '.source.coffee', 'editor.softWrap', true + atom.config.set '.source.coffee', 'editor.preferredLineLength', 17 + atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', true + + editor.setEditorWidthInChars(20) + coffeeEditor.setEditorWidthInChars(20) + + it 'isSoftWrapped() returns true for coffeescript', -> + expect(editor.isSoftWrapped()).toBe false + expect(coffeeEditor.isSoftWrapped()).toBe true + + it 'correctly wraps coffeescript file', -> + expect(editor.lineTextForScreenRow(2)).toEqual ' if (items.length <= 1) return items;' + expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items ' + + it 'updates the wrapped lines when editor.preferredLineLength changes', -> + atom.config.set '.source.coffee', 'editor.preferredLineLength', 20 + expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if ' + + it 'updates the wrapped lines when editor.softWrapAtPreferredLineLength changes', -> + atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', false + expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if ' + + it 'updates the wrapped lines when editor.softWrap changes', -> + atom.config.set '.source.coffee', 'editor.softWrap', false + expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if items.length <= 1' + + atom.config.set '.source.coffee', 'editor.softWrap', true + expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items ' + + it 'updates the wrapped lines when the grammar changes', -> + editor.setGrammar(coffeeEditor.getGrammar()) + expect(editor.isSoftWrapped()).toBe true + expect(editor.lineTextForScreenRow(0)).toEqual 'var quicksort = ' + + describe 'invisibles settings', -> + [jsInvisibles, coffeeInvisibles] = [] + beforeEach -> + jsInvisibles = + eol: 'J' + space: 'A' + tab: 'V' + cr: 'A' + + coffeeInvisibles = + eol: 'C' + space: 'O' + tab: 'F' + cr: 'E' + + atom.config.set '.source.js', 'editor.showInvisibles', true + atom.config.set '.source.js', 'editor.invisibles', jsInvisibles + + atom.config.set '.source.coffee', 'editor.showInvisibles', false + atom.config.set '.source.coffee', 'editor.invisibles', coffeeInvisibles + + editor.setText " a line with tabs\tand spaces \n" + nextAnimationFrame() + + it "renders the invisibles for the javascript scoped invisibles", -> + expect(component.lineNodeForScreenRow(0).textContent).toBe "#{jsInvisibles.space}a line with tabs#{jsInvisibles.tab}and spaces#{jsInvisibles.space}#{jsInvisibles.eol}" + + it "does not renders the invisibles for the coffeescript scope because editor.showInvisibles is false", -> + editor.setGrammar(coffeeEditor.getGrammar()) + nextAnimationFrame() + expect(component.lineNodeForScreenRow(0).textContent).toBe " a line with tabs and spaces " + + it "re-renders the invisibles for the when the invisible settings change", -> + jsGrammar = editor.getGrammar() + editor.setGrammar(coffeeEditor.getGrammar()) + atom.config.set '.source.coffee', 'editor.showInvisibles', true + nextAnimationFrame() + expect(component.lineNodeForScreenRow(0).textContent).toBe "#{coffeeInvisibles.space}a line with tabs#{coffeeInvisibles.tab}and spaces#{coffeeInvisibles.space}#{coffeeInvisibles.eol}" + + newInvisibles = + eol: 'N' + space: 'E' + tab: 'W' + cr: 'I' + atom.config.set '.source.coffee', 'editor.invisibles', newInvisibles + nextAnimationFrame() + expect(component.lineNodeForScreenRow(0).textContent).toBe "#{newInvisibles.space}a line with tabs#{newInvisibles.tab}and spaces#{newInvisibles.space}#{newInvisibles.eol}" + + editor.setGrammar(jsGrammar) + nextAnimationFrame() + expect(component.lineNodeForScreenRow(0).textContent).toBe "#{jsInvisibles.space}a line with tabs#{jsInvisibles.tab}and spaces#{jsInvisibles.space}#{jsInvisibles.eol}" + buildMouseEvent = (type, properties...) -> properties = extend({bubbles: true, cancelable: true}, properties...) properties.detail ?= 1 diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 297dfee52..55c466cc8 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -3769,52 +3769,3 @@ describe "TextEditor", -> editor.setCursorBufferPosition [0, 7] editor.selectWordsContainingCursors() expect(editor.getSelectedBufferRange()).toEqual [[0, 4], [0, 13]] - - describe 'scoped config settings', -> - coffeeEditor = null - beforeEach -> - waitsForPromise -> - atom.packages.activatePackage('language-coffee-script') - waitsForPromise -> - atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o - - afterEach: -> - atom.packages.deactivatePackages() - atom.packages.unloadPackages() - - describe 'soft wrap config settings', -> - beforeEach -> - atom.config.set '.source.coffee', 'editor.softWrap', true - atom.config.set '.source.coffee', 'editor.preferredLineLength', 17 - atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', true - - editor.setEditorWidthInChars(20) - coffeeEditor.setEditorWidthInChars(20) - - it 'isSoftWrapped() returns true for coffeescript', -> - expect(editor.isSoftWrapped()).toBe false - expect(coffeeEditor.isSoftWrapped()).toBe true - - it 'correctly wraps coffeescript file', -> - expect(editor.lineTextForScreenRow(2)).toEqual ' if (items.length <= 1) return items;' - expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items ' - - it 'updates the wrapped lines when editor.preferredLineLength changes', -> - atom.config.set '.source.coffee', 'editor.preferredLineLength', 20 - expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if ' - - it 'updates the wrapped lines when editor.softWrapAtPreferredLineLength changes', -> - atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', false - expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if ' - - it 'updates the wrapped lines when editor.softWrap changes', -> - atom.config.set '.source.coffee', 'editor.softWrap', false - expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if items.length <= 1' - - atom.config.set '.source.coffee', 'editor.softWrap', true - expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items ' - - it 'updates the wrapped lines when the grammar changes', -> - editor.setGrammar(coffeeEditor.getGrammar()) - expect(editor.isSoftWrapped()).toBe true - expect(editor.lineTextForScreenRow(0)).toEqual 'var quicksort = ' diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 3d6934cc8..9e5d68bcf 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -5,7 +5,7 @@ Delegator = require 'delegato' {deprecate} = require 'grim' {Model} = require 'theorist' EmitterMixin = require('emissary').Emitter -{Emitter} = require 'event-kit' +{CompositeDisposable, Emitter} = require 'event-kit' {Point, Range} = require 'text-buffer' LanguageMode = require './language-mode' DisplayBuffer = require './display-buffer' @@ -84,20 +84,20 @@ class TextEditor extends Model @cursors = [] @selections = [] - if @shouldShowInvisibles() - invisibles = atom.config.get('editor.invisibles') - @displayBuffer?.setInvisibles(invisibles) - @displayBuffer ?= new DisplayBuffer({buffer, tabLength, softWrapped, invisibles}) + @displayBuffer ?= new DisplayBuffer({buffer, tabLength, softWrapped}) @buffer = @displayBuffer.buffer @softTabs = @usesSoftTabs() ? @softTabs ? atom.config.get('editor.softTabs') ? true + @updateInvisibles() + for marker in @findMarkers(@getSelectionMarkerAttributes()) marker.setProperties(preserveFolds: true) @addSelection(marker) @subscribeToBuffer() @subscribeToDisplayBuffer() + @subscribeToInvisiblesConfigChanges() if @getCursors().length is 0 and not suppressCursorCreation initialLine = Math.max(parseInt(initialLine) or 0, 0) @@ -113,9 +113,6 @@ class TextEditor extends Model @emit 'scroll-left-changed', scrollLeft @emitter.emit 'did-change-scroll-left', scrollLeft - @subscribe atom.config.onDidChange 'editor.showInvisibles', => @updateInvisibles() - @subscribe atom.config.onDidChange 'editor.invisibles', => @updateInvisibles() - atom.workspace?.editorAdded(this) if registerEditor serializeParams: -> @@ -162,6 +159,18 @@ class TextEditor extends Model @subscribe @displayBuffer.onDidAddDecoration (decoration) => @emit 'decoration-added', decoration @subscribe @displayBuffer.onDidRemoveDecoration (decoration) => @emit 'decoration-removed', decoration + subscribeToInvisiblesConfigChanges: -> + @invisiblesConfigSubscriptions?.dispose() + @invisiblesConfigSubscriptions = new CompositeDisposable + + scopeDescriptor = @getGrammarScopeDescriptor() + + @invisiblesConfigSubscriptions.add atom.config.onDidChange scopeDescriptor, 'editor.showInvisibles', => @updateInvisibles() + @invisiblesConfigSubscriptions.add atom.config.onDidChange scopeDescriptor, 'editor.invisibles', => @updateInvisibles() + + getViewClass: -> + require './text-editor-view' + destroyed: -> @unsubscribe() selection.destroy() for selection in @getSelections() @@ -2354,7 +2363,11 @@ class TextEditor extends Model # position. See {::scopesForBufferPosition} for more information. # # Returns an {Array} of {String}s. - scopesAtCursor: -> @getLastCursor().getScopes() + scopesAtCursor: -> + if cursor = @getLastCursor() + cursor.getScopes() + else + @getGrammarScopeDescriptor() getCursorScopes: -> deprecate 'Use TextEditor::scopesAtCursor() instead' @scopesAtCursor() @@ -2381,6 +2394,9 @@ class TextEditor extends Model bufferRangeForScopeAtCursor: (selector) -> @displayBuffer.bufferRangeForScopeAtPosition(selector, @getCursorBufferPosition()) + getGrammarScopeDescriptor: -> + @displayBuffer.getGrammarScopeDescriptor() + logCursorScope: -> console.log @scopesAtCursor() @@ -2653,11 +2669,11 @@ class TextEditor extends Model atom.config.get("editor.autoIndent") shouldShowInvisibles: -> - not @mini and atom.config.get('editor.showInvisibles') + not @mini and atom.config.get(@getGrammarScopeDescriptor(), 'editor.showInvisibles') updateInvisibles: -> if @shouldShowInvisibles() - @displayBuffer.setInvisibles(atom.config.get('editor.invisibles')) + @displayBuffer.setInvisibles(atom.config.get(@getGrammarScopeDescriptor(), 'editor.invisibles')) else @displayBuffer.setInvisibles(null) @@ -2669,6 +2685,8 @@ class TextEditor extends Model @softTabs = @usesSoftTabs() ? @softTabs handleGrammarChange: -> + @updateInvisibles() + @subscribeToInvisiblesConfigChanges() @unfoldAll() @emit 'grammar-changed' @emitter.emit 'did-change-grammar'