aboutsummaryrefslogtreecommitdiff
path: root/atom/packages/vim-mode/lib/text-objects.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'atom/packages/vim-mode/lib/text-objects.coffee')
-rw-r--r--atom/packages/vim-mode/lib/text-objects.coffee81
1 files changed, 62 insertions, 19 deletions
diff --git a/atom/packages/vim-mode/lib/text-objects.coffee b/atom/packages/vim-mode/lib/text-objects.coffee
index 6d9741b..bf38605 100644
--- a/atom/packages/vim-mode/lib/text-objects.coffee
+++ b/atom/packages/vim-mode/lib/text-objects.coffee
@@ -1,5 +1,7 @@
{Range} = require 'atom'
AllWhitespace = /^\s$/
+WholeWordRegex = /\S+/
+{mergeRanges} = require './utils'
class TextObject
constructor: (@editor, @state) ->
@@ -7,11 +9,21 @@ class TextObject
isComplete: -> true
isRecordable: -> false
+ execute: -> @select.apply(this, arguments)
+
class SelectInsideWord extends TextObject
select: ->
- @editor.selectWordsContainingCursors()
+ for selection in @editor.getSelections()
+ selection.expandOverWord()
[true]
+class SelectInsideWholeWord extends TextObject
+ select: ->
+ for selection in @editor.getSelections()
+ range = selection.cursor.getCurrentWordBufferRange({wordRegex: WholeWordRegex})
+ selection.setBufferRange(mergeRanges(selection.getBufferRange(), range))
+ true
+
# SelectInsideQuotes and the next class defined (SelectInsideBrackets) are
# almost-but-not-quite-repeated code. They are different because of the depth
# checks in the bracket matcher.
@@ -76,7 +88,7 @@ class SelectInsideQuotes extends TextObject
++ start.column # skip the opening quote
end = @findClosingQuote(start)
if end?
- selection.setBufferRange([start, end])
+ selection.setBufferRange(mergeRanges(selection.getBufferRange(), [start, end]))
not selection.isEmpty()
# SelectInsideBrackets and the previous class defined (SelectInsideQuotes) are
@@ -126,13 +138,13 @@ class SelectInsideBrackets extends TextObject
++ start.column # skip the opening quote
end = @findClosingBracket(start)
if end?
- selection.setBufferRange([start, end])
+ selection.setBufferRange(mergeRanges(selection.getBufferRange(), [start, end]))
not selection.isEmpty()
class SelectAWord extends TextObject
select: ->
for selection in @editor.getSelections()
- selection.selectWord()
+ selection.expandOverWord()
loop
endPoint = selection.getBufferRange().end
char = @editor.getTextInRange(Range.fromPointWithDelta(endPoint, 0, 1))
@@ -140,25 +152,56 @@ class SelectAWord extends TextObject
selection.selectRight()
true
-class SelectInsideParagraph extends TextObject
- constructor: (@editor, @inclusive) ->
+class SelectAWholeWord extends TextObject
select: ->
for selection in @editor.getSelections()
- range = selection.cursor.getCurrentParagraphBufferRange()
- if range?
- selection.setBufferRange(range)
- selection.selectToBeginningOfNextParagraph()
+ range = selection.cursor.getCurrentWordBufferRange({wordRegex: WholeWordRegex})
+ selection.setBufferRange(mergeRanges(selection.getBufferRange(), range))
+ loop
+ endPoint = selection.getBufferRange().end
+ char = @editor.getTextInRange(Range.fromPointWithDelta(endPoint, 0, 1))
+ break unless AllWhitespace.test(char)
+ selection.selectRight()
true
-class SelectAParagraph extends TextObject
- constructor: (@editor, @inclusive) ->
+class Paragraph extends TextObject
+
select: ->
for selection in @editor.getSelections()
- range = selection.cursor.getCurrentParagraphBufferRange()
- if range?
- selection.setBufferRange(range)
- selection.selectToBeginningOfNextParagraph()
- selection.selectDown()
- true
+ @selectParagraph(selection)
+
+ # Return a range delimted by the start or the end of a paragraph
+ paragraphDelimitedRange: (startPoint) ->
+ inParagraph = @isParagraphLine(@editor.lineTextForBufferRow(startPoint.row))
+ upperRow = @searchLines(startPoint.row, -1, inParagraph)
+ lowerRow = @searchLines(startPoint.row, @editor.getLineCount(), inParagraph)
+ new Range([upperRow + 1, 0], [lowerRow, 0])
+
+ searchLines: (startRow, rowLimit, startedInParagraph) ->
+ for currentRow in [startRow..rowLimit]
+ line = @editor.lineTextForBufferRow(currentRow)
+ if startedInParagraph isnt @isParagraphLine(line)
+ return currentRow
+ rowLimit
+
+ isParagraphLine: (line) -> (/\S/.test(line))
+
+class SelectInsideParagraph extends Paragraph
+ selectParagraph: (selection) ->
+ oldRange = selection.getBufferRange()
+ startPoint = selection.cursor.getBufferPosition()
+ newRange = @paragraphDelimitedRange(startPoint)
+ selection.setBufferRange(mergeRanges(oldRange, newRange))
+ true
+
+class SelectAParagraph extends Paragraph
+ selectParagraph: (selection) ->
+ oldRange = selection.getBufferRange()
+ startPoint = selection.cursor.getBufferPosition()
+ newRange = @paragraphDelimitedRange(startPoint)
+ nextRange = @paragraphDelimitedRange(newRange.end)
+ selection.setBufferRange(mergeRanges(oldRange, [newRange.start, nextRange.end]))
+ true
-module.exports = {TextObject, SelectInsideWord, SelectInsideQuotes, SelectInsideBrackets, SelectAWord, SelectInsideParagraph, SelectAParagraph}
+module.exports = {TextObject, SelectInsideWord, SelectInsideWholeWord, SelectInsideQuotes,
+ SelectInsideBrackets, SelectAWord, SelectAWholeWord, SelectInsideParagraph, SelectAParagraph}