merge dev, fix conflicts

This commit is contained in:
Justin Palmer 2013-02-05 08:18:59 -08:00
commit dd7835faf4
13 changed files with 236 additions and 12 deletions

7
.atom/config.cson Normal file
View File

@ -0,0 +1,7 @@
'editor':
'fontSize': 16
'core':
'themes': [
'atom-dark-ui'
'atom-dark-syntax'
]

View File

@ -1,11 +0,0 @@
{
"editor": {
"fontSize": 16
},
"core": {
"themes": [
"atom-dark-ui",
"atom-dark-syntax"
]
}
}

View File

@ -69,6 +69,7 @@
[self initWithBootstrapScript:@"window-bootstrap" background:YES alwaysUseBundleResourcePath:stable];
[self.window setFrame:NSMakeRect(0, 0, 0, 0) display:NO];
[self.window setExcludedFromWindowsMenu:YES];
[self.window setCollectionBehavior:NSWindowCollectionBehaviorStationary];
return self;
}

View File

@ -307,6 +307,9 @@ class EditSession
fold.destroy()
@setCursorBufferPosition([fold.startRow, 0])
isFoldedAtCursorRow: ->
@isFoldedAtScreenRow(@getCursorScreenRow())
isFoldedAtBufferRow: (bufferRow) ->
screenRow = @screenPositionForBufferPosition([bufferRow]).row
@isFoldedAtScreenRow(screenRow)

View File

@ -277,6 +277,7 @@ class Editor extends View
destroyFoldsContainingBufferRow: (bufferRow) -> @activeEditSession.destroyFoldsContainingBufferRow(bufferRow)
isFoldedAtScreenRow: (screenRow) -> @activeEditSession.isFoldedAtScreenRow(screenRow)
isFoldedAtBufferRow: (bufferRow) -> @activeEditSession.isFoldedAtBufferRow(bufferRow)
isFoldedAtCursorRow: -> @activeEditSession.isFoldedAtCursorRow()
lineForScreenRow: (screenRow) -> @activeEditSession.lineForScreenRow(screenRow)
linesForScreenRows: (start, end) -> @activeEditSession.linesForScreenRows(start, end)

View File

@ -0,0 +1,120 @@
AtomPackage = require 'atom-package'
_ = require 'underscore'
{$$} = require 'space-pen'
Range = require 'range'
module.exports =
class BracketMatcher extends AtomPackage
startPairMatches:
'(': ')'
'[': ']'
'{': '}'
endPairMatches:
')': '('
']': '['
'}': '{'
pairHighlighted: false
activate: (rootView) ->
rootView.eachEditor (editor) => @subscribeToEditor(editor) if editor.attached
subscribeToEditor: (editor) ->
editor.on 'cursor:moved.bracket-matcher', => @updateMatch(editor)
editor.command 'editor:go-to-matching-bracket.bracket-matcher', =>
@goToMatchingPair(editor)
editor.on 'editor:will-be-removed', => editor.off('.bracket-matcher')
goToMatchingPair: (editor) ->
return unless @pairHighlighted
return unless underlayer = editor.pane()?.find('.underlayer')
position = editor.getCursorBufferPosition()
previousPosition = position.translate([0, -1])
startPosition = underlayer.find('.bracket-matcher:first').data('bufferPosition')
endPosition = underlayer.find('.bracket-matcher:last').data('bufferPosition')
if position.isEqual(startPosition)
editor.setCursorBufferPosition(endPosition.translate([0, 1]))
else if previousPosition.isEqual(startPosition)
editor.setCursorBufferPosition(endPosition)
else if position.isEqual(endPosition)
editor.setCursorBufferPosition(startPosition.translate([0, 1]))
else if previousPosition.isEqual(endPosition)
editor.setCursorBufferPosition(startPosition)
createView: (editor, bufferPosition) ->
pixelPosition = editor.pixelPositionForBufferPosition(bufferPosition)
view = $$ -> @div class: 'bracket-matcher'
view.data('bufferPosition', bufferPosition)
view.css('top', pixelPosition.top).css('left', pixelPosition.left)
view.width(editor.charWidth).height(editor.charHeight)
findCurrentPair: (editor, buffer, matches) ->
position = editor.getCursorBufferPosition()
currentPair = buffer.getTextInRange(Range.fromPointWithDelta(position, 0, 1))
unless matches[currentPair]
position = position.translate([0, -1])
currentPair = buffer.getTextInRange(Range.fromPointWithDelta(position, 0, 1))
matchingPair = matches[currentPair]
if matchingPair
{position, currentPair, matchingPair}
else
{}
findMatchingEndPair: (buffer, startPairPosition, startPair, endPair) ->
scanRange = new Range(startPairPosition.translate([0, 1]), buffer.getEofPosition())
regex = new RegExp("[#{_.escapeRegExp(startPair + endPair)}]", 'g')
endPairPosition = null
unpairedCount = 0
buffer.scanInRange regex, scanRange, (match, range, {stop}) =>
if match[0] is startPair
unpairedCount++
else if match[0] is endPair
unpairedCount--
endPairPosition = range.start
stop() if unpairedCount < 0
endPairPosition
findMatchingStartPair: (buffer, endPairPosition, startPair, endPair) ->
scanRange = new Range([0, 0], endPairPosition)
regex = new RegExp("[#{_.escapeRegExp(startPair + endPair)}]", 'g')
startPairPosition = null
unpairedCount = 0
scanner = (match, range, {stop}) =>
if match[0] is endPair
unpairedCount++
else if match[0] is startPair
unpairedCount--
startPairPosition = range.start
stop() if unpairedCount < 0
buffer.scanInRange(regex, scanRange, scanner, true)
startPairPosition
updateMatch: (editor) ->
return unless underlayer = editor.pane()?.find('.underlayer')
underlayer.find('.bracket-matcher').remove() if @pairHighlighted
@pairHighlighted = false
return unless editor.getSelection().isEmpty()
return if editor.isFoldedAtCursorRow()
buffer = editor.getBuffer()
{position, currentPair, matchingPair} = @findCurrentPair(editor, buffer, @startPairMatches)
if position
matchPosition = @findMatchingEndPair(buffer, position, currentPair, matchingPair)
else
{position, currentPair, matchingPair} = @findCurrentPair(editor, buffer, @endPairMatches)
if position
matchPosition = @findMatchingStartPair(buffer, position, matchingPair, currentPair)
if position? and matchPosition?
if position.isLessThan(matchPosition)
underlayer.append(@createView(editor, position))
underlayer.append(@createView(editor, matchPosition))
else
underlayer.append(@createView(editor, matchPosition))
underlayer.append(@createView(editor, position))
@pairHighlighted = true

View File

@ -0,0 +1,2 @@
'.editor':
'ctrl-j': 'editor:go-to-matching-bracket'

View File

@ -0,0 +1,86 @@
RootView = require 'root-view'
describe "bracket matching", ->
[rootView, editor] = []
beforeEach ->
rootView = new RootView(require.resolve('fixtures/sample.js'))
atom.loadPackage('bracket-matcher')
rootView.attachToDom()
editor = rootView.getActiveEditor()
afterEach ->
rootView.deactivate()
describe "when the cursor is before a starting pair", ->
it "highlights the starting pair and ending pair", ->
editor.moveCursorToEndOfLine()
editor.moveCursorLeft()
expect(editor.underlayer.find('.bracket-matcher').length).toBe 2
expect(editor.underlayer.find('.bracket-matcher:first').position()).toEqual editor.pixelPositionForBufferPosition([0,28])
expect(editor.underlayer.find('.bracket-matcher:last').position()).toEqual editor.pixelPositionForBufferPosition([12,0])
describe "when the cursor is after a starting pair", ->
it "highlights the starting pair and ending pair", ->
editor.moveCursorToEndOfLine()
expect(editor.underlayer.find('.bracket-matcher').length).toBe 2
expect(editor.underlayer.find('.bracket-matcher:first').position()).toEqual editor.pixelPositionForBufferPosition([0,28])
expect(editor.underlayer.find('.bracket-matcher:last').position()).toEqual editor.pixelPositionForBufferPosition([12,0])
describe "when the cursor is before an ending pair", ->
it "highlights the starting pair and ending pair", ->
editor.moveCursorToBottom()
editor.moveCursorLeft()
editor.moveCursorLeft()
expect(editor.underlayer.find('.bracket-matcher').length).toBe 2
expect(editor.underlayer.find('.bracket-matcher:last').position()).toEqual editor.pixelPositionForBufferPosition([12,0])
expect(editor.underlayer.find('.bracket-matcher:first').position()).toEqual editor.pixelPositionForBufferPosition([0,28])
describe "when the cursor is after an ending pair", ->
it "highlights the starting pair and ending pair", ->
editor.moveCursorToBottom()
editor.moveCursorLeft()
expect(editor.underlayer.find('.bracket-matcher').length).toBe 2
expect(editor.underlayer.find('.bracket-matcher:last').position()).toEqual editor.pixelPositionForBufferPosition([12,0])
expect(editor.underlayer.find('.bracket-matcher:first').position()).toEqual editor.pixelPositionForBufferPosition([0,28])
describe "when the cursor is moved off a pair", ->
it "removes the starting pair and ending pair highlights", ->
editor.moveCursorToEndOfLine()
expect(editor.underlayer.find('.bracket-matcher').length).toBe 2
editor.moveCursorToBeginningOfLine()
expect(editor.underlayer.find('.bracket-matcher').length).toBe 0
describe "pair balancing", ->
describe "when a second starting pair preceeds the first ending pair", ->
it "advances to the second ending pair", ->
editor.setCursorBufferPosition([8,42])
expect(editor.underlayer.find('.bracket-matcher').length).toBe 2
expect(editor.underlayer.find('.bracket-matcher:first').position()).toEqual editor.pixelPositionForBufferPosition([8,42])
expect(editor.underlayer.find('.bracket-matcher:last').position()).toEqual editor.pixelPositionForBufferPosition([8,54])
describe "when editor:go-to-matching-bracket is triggered", ->
describe "when the cursor is before the starting pair", ->
it "moves the cursor to after the ending pair", ->
editor.moveCursorToEndOfLine()
editor.moveCursorLeft()
editor.trigger "editor:go-to-matching-bracket"
expect(editor.getCursorBufferPosition()).toEqual [12, 1]
describe "when the cursor is after the starting pair", ->
it "moves the cursor to before the ending pair", ->
editor.moveCursorToEndOfLine()
editor.trigger "editor:go-to-matching-bracket"
expect(editor.getCursorBufferPosition()).toEqual [12, 0]
describe "when the cursor is before the ending pair", ->
it "moves the cursor to after the starting pair", ->
editor.setCursorBufferPosition([12, 0])
editor.trigger "editor:go-to-matching-bracket"
expect(editor.getCursorBufferPosition()).toEqual [0, 29]
describe "when the cursor is after the ending pair", ->
it "moves the cursor to before the starting pair", ->
editor.setCursorBufferPosition([12, 1])
editor.trigger "editor:go-to-matching-bracket"
expect(editor.getCursorBufferPosition()).toEqual [0, 28]

View File

@ -0,0 +1,3 @@
.bracket-matcher {
position: absolute;
}

View File

@ -0,0 +1,5 @@
.bracket-matcher {
border-bottom: 1px solid #f8de7e;
margin-top: -1px;
opacity: .7;
}

View File

@ -10,5 +10,6 @@
"command-panel.css",
"command-logger.css",
"blurred.css"
"bracket-matcher.css"
]
}

View File

@ -0,0 +1,5 @@
.bracket-matcher {
border-bottom: 1px solid #f8de7e;
margin-top: -1px;
opacity: .7;
}

View File

@ -8,6 +8,7 @@
"status-bar.css",
"markdown-preview.css",
"command-panel.css",
"command-logger.css"
"command-logger.css",
"bracket-matcher.css"
]
}