mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Highlighter emits change events.
Changes to the buffer may cause lines beyond the scope of the textual change to be re-highlighted. If so so, this is reflected in the pre/post range of Highlighter's change events.
This commit is contained in:
@@ -15,9 +15,16 @@ describe "Highlighter", ->
|
||||
expect(highlighter.tokensForRow(11)[1]).toEqual(type: 'keyword', value: 'return')
|
||||
|
||||
describe "when the buffer changes", ->
|
||||
changeHandler = null
|
||||
|
||||
beforeEach ->
|
||||
changeHandler = jasmine.createSpy('changeHandler')
|
||||
highlighter.on "change", changeHandler
|
||||
|
||||
describe "when lines are updated, but none are added or removed", ->
|
||||
it "updates tokens for each of the changed lines", ->
|
||||
buffer.change(new Range([0, 0], [2, 0]), "foo()\nbar()\n")
|
||||
range = new Range([0, 0], [2, 0])
|
||||
buffer.change(range, "foo()\nbar()\n")
|
||||
|
||||
expect(highlighter.tokensForRow(0)[0]).toEqual(type: 'identifier', value: 'foo')
|
||||
expect(highlighter.tokensForRow(1)[0]).toEqual(type: 'identifier', value: 'bar')
|
||||
@@ -25,16 +32,30 @@ describe "Highlighter", ->
|
||||
# line 2 is unchanged
|
||||
expect(highlighter.tokensForRow(2)[1]).toEqual(type: 'keyword', value: 'if')
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
|
||||
expect(event.preRange).toEqual range
|
||||
expect(event.postRange).toEqual new Range([0, 0], [2,0])
|
||||
|
||||
it "updates tokens for lines beyond the changed lines if needed", ->
|
||||
buffer.insert([5, 30], '/* */')
|
||||
changeHandler.reset()
|
||||
|
||||
buffer.insert([2, 0], '/*')
|
||||
expect(highlighter.tokensForRow(3)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(4)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(5)[0].type).toBe 'comment'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
expect(event.preRange).toEqual new Range([2, 0], [6, buffer.getLine(6).length])
|
||||
expect(event.postRange).toEqual new Range([2, 0], [6, buffer.getLine(6).length])
|
||||
|
||||
describe "when lines are both updated and removed", ->
|
||||
it "updates tokens to reflect the removed lines", ->
|
||||
buffer.change(new Range([1, 0], [3, 0]), "foo()")
|
||||
range = new Range([1, 0], [3, 0])
|
||||
buffer.change(range, "foo()")
|
||||
|
||||
# previous line 0 remains
|
||||
expect(highlighter.tokensForRow(0)[0]).toEqual(type: 'keyword.definition', value: 'var')
|
||||
@@ -48,9 +69,29 @@ describe "Highlighter", ->
|
||||
expect(highlighter.tokensForRow(3)[1]).toEqual(type: 'identifier', value: 'current')
|
||||
expect(highlighter.tokensForRow(4)[3]).toEqual(type: 'keyword.operator', value: '<')
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
expect(event.preRange).toEqual range
|
||||
expect(event.postRange).toEqual new Range([1, 0], [1, 5])
|
||||
|
||||
it "updates tokens for lines beyond the changed lines if needed", ->
|
||||
buffer.insert([5, 30], '/* */')
|
||||
changeHandler.reset()
|
||||
|
||||
buffer.change(new Range([2, 0], [3, 0]), '/*')
|
||||
expect(highlighter.tokensForRow(2)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(3)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(4)[0].type).toBe 'comment'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
expect(event.preRange).toEqual new Range([2, 0], [6, buffer.getLine(5).length])
|
||||
expect(event.postRange).toEqual new Range([2, 0], [5, buffer.getLine(5).length])
|
||||
|
||||
describe "when lines are both updated and inserted", ->
|
||||
it "updates tokens to reflect the inserted lines", ->
|
||||
buffer.change(new Range([1, 0], [2, 0]), "foo()\nbar()\nbaz()\nquux()")
|
||||
range = new Range([1, 0], [2, 0])
|
||||
buffer.change(range, "foo()\nbar()\nbaz()\nquux()")
|
||||
|
||||
# previous line 0 remains
|
||||
expect(highlighter.tokensForRow(0)[0]).toEqual(type: 'keyword.definition', value: 'var')
|
||||
@@ -67,3 +108,25 @@ describe "Highlighter", ->
|
||||
# previous line 3 is pushed down to become line 5
|
||||
expect(highlighter.tokensForRow(5)[3]).toEqual(type: 'identifier', value: 'pivot')
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
expect(event.preRange).toEqual range
|
||||
expect(event.postRange).toEqual new Range([1, 0], [4, 6])
|
||||
|
||||
it "updates tokens for lines beyond the changed lines if needed", ->
|
||||
buffer.insert([5, 30], '/* */')
|
||||
changeHandler.reset()
|
||||
|
||||
buffer.insert([2, 0], '/*\nabcde\nabcder')
|
||||
expect(highlighter.tokensForRow(2)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(3)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(4)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(5)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(6)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(7)[0].type).toBe 'comment'
|
||||
expect(highlighter.tokensForRow(8)[0].type).not.toBe 'comment'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
expect(event.preRange).toEqual new Range([2, 0], [6, buffer.getLine(8).length])
|
||||
expect(event.postRange).toEqual new Range([2, 0], [8, buffer.getLine(8).length])
|
||||
|
||||
@@ -16,7 +16,8 @@ class Highlighter
|
||||
@tokenizer = (new Mode).getTokenizer()
|
||||
|
||||
handleBufferChange: (e) ->
|
||||
{ preRange, postRange } = e
|
||||
preRange = e.preRange.copy()
|
||||
postRange = e.postRange.copy()
|
||||
|
||||
previousState = @lines[preRange.end.row].state
|
||||
newLines = @tokenizeRows('start', postRange.start.row, postRange.end.row)
|
||||
@@ -28,6 +29,13 @@ class Highlighter
|
||||
previousState = @lines[nextRow].state
|
||||
@lines[nextRow] = @tokenizeRow(@lines[row].state, nextRow)
|
||||
|
||||
preRange.end.row++
|
||||
preRange.end.column = @buffer.getLine(nextRow).length
|
||||
postRange.end.row++
|
||||
postRange.end.column = @buffer.getLine(nextRow).length
|
||||
|
||||
@trigger("change", {preRange, postRange})
|
||||
|
||||
tokenizeRows: (startState, startRow, endRow) ->
|
||||
state = startState
|
||||
for row in [startRow..endRow]
|
||||
@@ -41,3 +49,10 @@ class Highlighter
|
||||
tokensForRow: (row) ->
|
||||
@lines[row].tokens
|
||||
|
||||
on: (eventName, handler) ->
|
||||
@eventHandlers ?= {}
|
||||
@eventHandlers[eventName] ?= []
|
||||
@eventHandlers[eventName].push(handler)
|
||||
|
||||
trigger: (eventName, event) ->
|
||||
@eventHandlers?[eventName]?.forEach (handler) -> handler(event)
|
||||
|
||||
Reference in New Issue
Block a user