diff --git a/lib/bracket-matcher-view.coffee b/lib/bracket-matcher-view.coffee index 4804113..1ccea7a 100644 --- a/lib/bracket-matcher-view.coffee +++ b/lib/bracket-matcher-view.coffee @@ -13,6 +13,14 @@ endPairMatches = ']': '[' '}': '{' +braceClasses = + '(': 'bracket-matcher-round-brace-open' + ')': 'bracket-matcher-round-brace-close' + '{': 'bracket-matcher-curly-brace-open' + '}': 'bracket-matcher-curly-brace-close' + '[': 'bracket-matcher-square-brace-open' + ']': 'bracket-matcher-square-brace-close' + pairRegexes = {} for startPair, endPair of startPairMatches pairRegexes[startPair] = new RegExp("[#{_.escapeRegExp(startPair + endPair)}]", 'g') @@ -24,6 +32,7 @@ class BracketMatcherView @tagFinder = new TagFinder(@editor) @pairHighlighted = false @tagHighlighted = false + @gutter = if atom.config.get('bracket-matcher.show-brackets-in-gutter') then @editor.addGutter({name: 'bracketMatcherGutter'}) else null @subscriptions.add @editor.onDidChange => @updateMatch() @@ -48,6 +57,9 @@ class BracketMatcherView @subscriptions.add atom.commands.add editorElement, 'bracket-matcher:remove-matching-brackets', => @removeMatchingBrackets() + @subscriptions.add atom.commands.add editorElement, 'bracket-matcher:show-brackets-in-gutter', => + @showBracketsInGutter() + @updateMatch() subscribeToCursor: -> @@ -83,13 +95,13 @@ class BracketMatcherView matchPosition = @findMatchingStartPair(position, matchingPair, currentPair) if position? and matchPosition? - @startMarker = @createMarker([position, position.traverse([0, 1])]) - @endMarker = @createMarker([matchPosition, matchPosition.traverse([0, 1])]) + @startMarker = @createMarker([position, position.traverse([0, 1])], {brace: currentPair}) + @endMarker = @createMarker([matchPosition, matchPosition.traverse([0, 1])], {brace: matchingPair}) @pairHighlighted = true else if pair = @tagFinder.findMatchingTags() - @startMarker = @createMarker(pair.startRange) - @endMarker = @createMarker(pair.endRange) + @startMarker = @createMarker(pair.startRange, {brace: currentPair}) + @endMarker = @createMarker(pair.endRange, {brace: matchingPair}) @pairHighlighted = true @tagHighlighted = true @@ -174,9 +186,10 @@ class BracketMatcherView result.stop() startPosition - createMarker: (bufferRange) -> + createMarker: (bufferRange, options) -> marker = @editor.markBufferRange(bufferRange) @editor.decorateMarker(marker, type: 'highlight', class: 'bracket-matcher', deprecatedRegionClass: 'bracket-matcher') + @gutter?.decorateMarker(marker, {class: braceClasses[options.brace]}) marker findCurrentPair: (matches) -> @@ -280,3 +293,11 @@ class BracketMatcherView if tag = @tagFinder.closingTagForFragments(preFragment, postFragment) @editor.insertText("") + + showBracketsInGutter: -> + if @gutter + @gutter.destroy() + @gutter = null + else + @gutter = @editor.addGutter({name: 'bracketMatcherGutter'}) + @updateMatch() diff --git a/lib/bracket-matcher.coffee b/lib/bracket-matcher.coffee index 3cf7f72..97cc4b6 100644 --- a/lib/bracket-matcher.coffee +++ b/lib/bracket-matcher.coffee @@ -155,6 +155,11 @@ class BracketMatcher return false unless @isOpeningBracket(bracket) pair = @pairedCharacters[bracket] + defaultPairs = @defaultPairs + cursorBufferPosition = @editor.getCursorBufferPosition() + endPosition = @editor.buffer.getEndPosition() + editor = @editor + selectionWrapped = false @editor.mutateSelectedText (selection) -> return if selection.isEmpty() @@ -165,12 +170,33 @@ class BracketMatcher selectionWrapped = true range = selection.getBufferRange() options = reversed: selection.isReversed() - selection.insertText("#{bracket}#{selection.getText()}#{pair}") + + selectionIsQuote = defaultPairs.hasOwnProperty(selection.getText()) and defaultPairs[selection.getText()] == selection.getText() + + if selectionIsQuote + # + # scanRange = new Range(cursorBufferPosition, endPosition) + # endPairPosition = null + # unpairedCount = 0 + # console.log(selection) + # editor.scanInBufferRange new RegExp(selection.getText()), [selection.getBufferRange().end, [Infinity, 0]], ({range, stop}) -> + # unpairedCount-- + # if unpairedCount < 0 + # endPairPosition = range.start + # stop() + # + # console.log(endPairPosition) + + selection.insertText("#{bracket}") + else + selection.insertText("#{bracket}#{selection.getText()}#{pair}") + selectionStart = range.start.traverse([0, bracket.length]) - if range.start.row is range.end.row + if not selectionIsQuote and range.start.row is range.end.row selectionEnd = range.end.traverse([0, bracket.length]) else selectionEnd = range.end + selection.setBufferRange([selectionStart, selectionEnd], options) selectionWrapped diff --git a/lib/main.coffee b/lib/main.coffee index 1c4e1b7..6e3a022 100644 --- a/lib/main.coffee +++ b/lib/main.coffee @@ -12,6 +12,9 @@ module.exports = wrapSelectionsInBrackets: type: 'boolean' default: true + showBracketsInGutter: + type: 'boolean' + default: false activate: -> atom.workspace.observeTextEditors (editor) -> diff --git a/menus/bracket-matcher.cson b/menus/bracket-matcher.cson index c8825d5..cb09017 100644 --- a/menus/bracket-matcher.cson +++ b/menus/bracket-matcher.cson @@ -9,6 +9,7 @@ { 'label': 'Remove Brackets From Selection', 'command': 'bracket-matcher:remove-brackets-from-selection' } { 'label': 'Close Current Tag', 'command': 'bracket-matcher:close-tag' } { 'label': 'Remove Matching Brackets', 'command': 'bracket-matcher:remove-matching-brackets' } + { 'label': 'Show in Gutter', 'command': 'bracket-matcher:show-brackets-in-gutter'} ] ] }, diff --git a/styles/bracket-matcher.atom-text-editor.less b/styles/bracket-matcher.atom-text-editor.less index a9e2c4b..cb6abb6 100644 --- a/styles/bracket-matcher.atom-text-editor.less +++ b/styles/bracket-matcher.atom-text-editor.less @@ -2,3 +2,27 @@ border-bottom: 1px dotted lime; position: absolute; } + +.bracket-matcher-curly-brace-open::before { + content: '{'; +} + +.bracket-matcher-curly-brace-close::after { + content: '}'; +} + +.bracket-matcher-round-brace-open::before { + content: '('; +} + +.bracket-matcher-round-brace-close::after { + content: ')'; +} + +.bracket-matcher-square-brace-open::before { + content: '['; +} + +.bracket-matcher-square-brace-close::after { + content: ']'; +}