Add Highlighter.findClosingBracket

Takes a position, and finds the position of the closing bracket that matches the opening bracket at that position. Only works with curly-braces for now.
This commit is contained in:
Corey Johnson & Nathan Sobo 2012-05-30 15:58:59 -06:00
parent 51ec8b4ca2
commit e10383a9e9
3 changed files with 42 additions and 0 deletions

View File

@ -157,3 +157,9 @@ describe "Highlighter", ->
expect(tokens[1].isAtomic).toBeTruthy()
expect(highlighter.lineForScreenRow(2).text).toBe "#{tabText} buy()#{tabText}while supply > demand"
describe ".findClosingBracket(startBracketPosition)", ->
describe "when called with a bracket type of '{'", ->
it "returns the position of the matching bracket, skipping any nested brackets", ->
expect(highlighter.findClosingBracket([1, 29])).toEqual [9, 2]

View File

@ -2,6 +2,8 @@ _ = require 'underscore'
ScreenLineFragment = require 'screen-line-fragment'
EventEmitter = require 'event-emitter'
Token = require 'token'
Range = require 'range'
Point = require 'point'
module.exports =
class Highlighter
@ -75,4 +77,34 @@ class Highlighter
destroy: ->
@buffer.off ".highlighter#{@id}"
iterateTokensInBufferRange: (bufferRange, iterator) ->
bufferRange = Range.fromObject(bufferRange)
{ start, end } = bufferRange
keepLooping = true
stop = -> keepLooping = false
for bufferRow in [start.row..end.row]
bufferColumn = 0
for token in @screenLines[bufferRow].tokens
startOfToken = new Point(bufferRow, bufferColumn)
iterator(token, startOfToken, { stop }) if bufferRange.containsPoint(startOfToken)
return unless keepLooping
bufferColumn += token.bufferDelta
findClosingBracket: (startBufferPosition) ->
range = [startBufferPosition, @buffer.getEofPosition()]
position = null
depth = 0
@iterateTokensInBufferRange range, (token, startPosition, { stop }) ->
if token.type.match /lparen|rparen/
if token.value == '{'
depth++
else if token.value == '}'
depth--
if depth == 0
position = startPosition
stop()
position
_.extend(Highlighter.prototype, EventEmitter)

View File

@ -45,6 +45,10 @@ class Range
else
otherRange.intersectsWith(this)
containsPoint: (point) ->
point = Point.fromObject(point)
point.isGreaterThanOrEqual(@start) and point.isLessThanOrEqual(@end)
union: (otherRange) ->
start = if @start.isLessThan(otherRange.start) then @start else otherRange.start
end = if @end.isGreaterThan(otherRange.end) then @end else otherRange.end