From 388e8ee19f4f4039e2445900cdee40435125d20e Mon Sep 17 00:00:00 2001 From: Blake Winton Date: Wed, 29 Jul 2015 22:52:33 -0400 Subject: [PATCH 1/4] :bug: Expand the selection on repeated uses of ctrl-cmd-m. --- lib/bracket-matcher-view.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/bracket-matcher-view.coffee b/lib/bracket-matcher-view.coffee index b1acb83..52c198b 100644 --- a/lib/bracket-matcher-view.coffee +++ b/lib/bracket-matcher-view.coffee @@ -279,9 +279,11 @@ class BracketMatcherView endPosition = endRange.start else if startPosition = @findAnyStartPair(@editor.getCursorBufferPosition()) + startPositionExternal = startPosition startPair = @editor.getTextInRange(Range.fromPointWithDelta(startPosition, 0, 1)) - endPosition = @findMatchingEndPair(startPosition, startPair, @matchManager.pairedCharacters[startPair]) startPosition = startPosition.traverse([0, 1]) + endPosition = @findMatchingEndPair(startPosition, startPair, @matchManager.pairedCharacters[startPair]) + endPositionExternal = endPosition.traverse([0, 1]) else if pair = @tagFinder.findStartEndTags(true) # NOTE: findEnclosingTags is not used as it has a scope check # that will fail on very long lines @@ -294,6 +296,8 @@ class BracketMatcherView if startPosition? and endPosition? rangeToSelect = new Range(startPosition, endPosition) + if @editor.getSelectedBufferRange().containsRange(rangeToSelect) + rangeToSelect = new Range(startPositionExternal, endPositionExternal) @editor.setSelectedBufferRange(rangeToSelect) # Insert at the current cursor position a closing tag if there exists an From 319f134b350297088083991a492d7033faea58ad Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 12 Dec 2017 00:43:58 +0100 Subject: [PATCH 2/4] Check if ranges are equal instead --- lib/bracket-matcher-view.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bracket-matcher-view.coffee b/lib/bracket-matcher-view.coffee index 52c198b..0fbc4ec 100644 --- a/lib/bracket-matcher-view.coffee +++ b/lib/bracket-matcher-view.coffee @@ -296,7 +296,7 @@ class BracketMatcherView if startPosition? and endPosition? rangeToSelect = new Range(startPosition, endPosition) - if @editor.getSelectedBufferRange().containsRange(rangeToSelect) + if rangeToSelect.isEqual(@editor.getSelectedBufferRange()) rangeToSelect = new Range(startPositionExternal, endPositionExternal) @editor.setSelectedBufferRange(rangeToSelect) From 0f31eb67f0c55110e33c29f60adcf3464514524a Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 12 Dec 2017 00:44:58 +0100 Subject: [PATCH 3/4] Handle empty pairs --- lib/bracket-matcher-view.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/bracket-matcher-view.coffee b/lib/bracket-matcher-view.coffee index 0fbc4ec..a090107 100644 --- a/lib/bracket-matcher-view.coffee +++ b/lib/bracket-matcher-view.coffee @@ -277,6 +277,9 @@ class BracketMatcherView startPosition = startRange.end endPosition = endRange.start + + startPositionExternal = startRange.start + endPositionExternal = endRange.end else if startPosition = @findAnyStartPair(@editor.getCursorBufferPosition()) startPositionExternal = startPosition From f602eda1d012576a4e54db5b147e05ff85451f2d Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 21 Dec 2017 22:01:02 -0500 Subject: [PATCH 4/4] Initial working prototype for tags --- lib/bracket-matcher-view.coffee | 4 +++ lib/tag-finder.coffee | 62 ++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/lib/bracket-matcher-view.coffee b/lib/bracket-matcher-view.coffee index a090107..0528c47 100644 --- a/lib/bracket-matcher-view.coffee +++ b/lib/bracket-matcher-view.coffee @@ -297,9 +297,13 @@ class BracketMatcherView startPosition = startRange.end endPosition = endRange.start + startPositionExternal = startRange.start + endPositionExternal = endRange.end + if startPosition? and endPosition? rangeToSelect = new Range(startPosition, endPosition) if rangeToSelect.isEqual(@editor.getSelectedBufferRange()) + # Expand selection rangeToSelect = new Range(startPositionExternal, endPositionExternal) @editor.setSelectedBufferRange(rangeToSelect) diff --git a/lib/tag-finder.coffee b/lib/tag-finder.coffee index 29378c9..be865b2 100644 --- a/lib/tag-finder.coffee +++ b/lib/tag-finder.coffee @@ -27,7 +27,7 @@ class TagFinder # 4. Attributes (ids, classes, etc. - optional) # 5. Tag suffix # 6. Self-closing tag (optional) - @tagPattern = /(<(\/)?)(.+?)(\s+.*?)?((\/)?>|$)/ + @tagPattern = /(<(\/)?)(.+?)(\s+.*?)?((\/)?>|$)/g @wordRegex = /.*?(>|$)/ patternForTagName: (tagName) -> @@ -122,12 +122,37 @@ class TagFinder findStartEndTags: (fullRange=false) -> ranges = null - endPosition = @editor.getLastCursor().getCurrentWordBufferRange({@wordRegex}).end + unpairedCount = 0 + endPosition = @editor.getCursorBufferPosition() + {scopes} = @editor.scopeDescriptorForBufferPosition(endPosition) + for scope in scopes + if scope.startsWith('meta.tag') + endPosition = @editor.getLastCursor().getCurrentWordBufferRange({wordRegex: /(.|\s)*?>/}).end + break + @editor.backwardsScanInBufferRange @tagPattern, [[0, 0], endPosition], ({match, range, stop}) => - stop() + return if @isRangeCommented(range) [entireMatch, prefix, isClosingTag, tagName, attributes, suffix, isSelfClosingTag] = match + if isSelfClosingTag or SelfClosingTags.includes(tagName) + if range.containsPoint(@editor.getCursorBufferPosition()) and not range.isEqual(@editor.getSelectedBufferRange()) + stop() + else + return + else if isClosingTag + if range.start.isEqual(@editor.getCursorBufferPosition()) or range.containsPoint(@editor.getCursorBufferPosition(), true) + return + + unpairedCount++ + return + else + unpairedCount-- + if unpairedCount < 0 + stop() + else + return + startRange = range unless fullRange if range.start.row is range.end.row @@ -138,7 +163,7 @@ class TagFinder else startRange = Range.fromObject([range.start.translate([0, prefix.length]), [range.start.row, Infinity]]) - if isSelfClosingTag + if isSelfClosingTag or SelfClosingTags.includes(tagName) endRange = startRange else if isClosingTag endRange = @findStartTag(tagName, startRange.start, fullRange) @@ -148,6 +173,33 @@ class TagFinder ranges = {startRange, endRange} if startRange? and endRange? ranges + findCurrentTags: -> + ranges = null + endPosition = @editor.getLastCursor().getCurrentWordBufferRange({@wordRegex}).end + @editor.backwardsScanInBufferRange @tagPattern, [[0, 0], endPosition], ({match, range, stop}) => + stop() + + [entireMatch, prefix, isClosingTag, tagName, attributes, suffix, isSelfClosingTag] = match + + startRange = range + if range.start.row is range.end.row + # Move the start past the initial < + startRange.start = startRange.start.translate([0, prefix.length]) + # End right after the tag name + startRange.end = startRange.start.translate([0, tagName.length]) + else + startRange = Range.fromObject([range.start.translate([0, prefix.length]), [range.start.row, Infinity]]) + + if isSelfClosingTag or SelfClosingTags.includes(tagName) + endRange = startRange + else if isClosingTag + endRange = @findStartTag(tagName, startRange.start) + else + endRange = @findEndTag(tagName, startRange.end) + + ranges = {startRange, endRange} if startRange? and endRange? + ranges + findEnclosingTags: -> if ranges = @findStartEndTags() if @isTagRange(ranges.startRange) and @isTagRange(ranges.endRange) @@ -156,7 +208,7 @@ class TagFinder null findMatchingTags: -> - @findStartEndTags() if @isCursorOnTag() + @findCurrentTags() if @isCursorOnTag() # Parses a fragment of html returning the stack (i.e., an array) of open tags #