diff --git a/spec/app/highlighter-spec.coffee b/spec/app/highlighter-spec.coffee index d0cd85361..8677dcc25 100644 --- a/spec/app/highlighter-spec.coffee +++ b/spec/app/highlighter-spec.coffee @@ -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] + diff --git a/src/app/highlighter.coffee b/src/app/highlighter.coffee index a0e8035b9..1b2599713 100644 --- a/src/app/highlighter.coffee +++ b/src/app/highlighter.coffee @@ -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) diff --git a/src/app/range.coffee b/src/app/range.coffee index 57dc18006..f95cc1357 100644 --- a/src/app/range.coffee +++ b/src/app/range.coffee @@ -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