diff options
| author | Ben Beltran <ben@nsovocal.com> | 2015-07-10 11:12:25 -0500 |
|---|---|---|
| committer | Ben Beltran <ben@nsovocal.com> | 2015-07-10 11:12:25 -0500 |
| commit | 24c7594d62d8d7fbbcdb64b11ce4adc5d8e6991a (patch) | |
| tree | ded312222bb108923da1820ba40b04d710d20e5b /atom/packages/vim-mode/lib/text-objects.coffee | |
| parent | eb786e82d170e2abc351a432ade616d6ecdeeb6b (diff) | |
Adds atom
Diffstat (limited to 'atom/packages/vim-mode/lib/text-objects.coffee')
| -rw-r--r-- | atom/packages/vim-mode/lib/text-objects.coffee | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/atom/packages/vim-mode/lib/text-objects.coffee b/atom/packages/vim-mode/lib/text-objects.coffee new file mode 100644 index 0000000..6d9741b --- /dev/null +++ b/atom/packages/vim-mode/lib/text-objects.coffee @@ -0,0 +1,164 @@ +{Range} = require 'atom' +AllWhitespace = /^\s$/ + +class TextObject + constructor: (@editor, @state) -> + + isComplete: -> true + isRecordable: -> false + +class SelectInsideWord extends TextObject + select: -> + @editor.selectWordsContainingCursors() + [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. + +class SelectInsideQuotes extends TextObject + constructor: (@editor, @char, @includeQuotes) -> + + findOpeningQuote: (pos) -> + start = pos.copy() + pos = pos.copy() + while pos.row >= 0 + line = @editor.lineTextForBufferRow(pos.row) + pos.column = line.length - 1 if pos.column is -1 + while pos.column >= 0 + if line[pos.column] is @char + if pos.column is 0 or line[pos.column - 1] isnt '\\' + if @isStartQuote(pos) + return pos + else + return @lookForwardOnLine(start) + -- pos.column + pos.column = -1 + -- pos.row + @lookForwardOnLine(start) + + isStartQuote: (end) -> + line = @editor.lineTextForBufferRow(end.row) + numQuotes = line.substring(0, end.column + 1).replace( "'#{@char}", '').split(@char).length - 1 + numQuotes % 2 + + lookForwardOnLine: (pos) -> + line = @editor.lineTextForBufferRow(pos.row) + + index = line.substring(pos.column).indexOf(@char) + if index >= 0 + pos.column += index + return pos + null + + findClosingQuote: (start) -> + end = start.copy() + escaping = false + + while end.row < @editor.getLineCount() + endLine = @editor.lineTextForBufferRow(end.row) + while end.column < endLine.length + if endLine[end.column] is '\\' + ++ end.column + else if endLine[end.column] is @char + -- start.column if @includeQuotes + ++ end.column if @includeQuotes + return end + ++ end.column + end.column = 0 + ++ end.row + return + + select: -> + for selection in @editor.getSelections() + start = @findOpeningQuote(selection.cursor.getBufferPosition()) + if start? + ++ start.column # skip the opening quote + end = @findClosingQuote(start) + if end? + selection.setBufferRange([start, end]) + not selection.isEmpty() + +# SelectInsideBrackets and the previous class defined (SelectInsideQuotes) are +# almost-but-not-quite-repeated code. They are different because of the depth +# checks in the bracket matcher. + +class SelectInsideBrackets extends TextObject + constructor: (@editor, @beginChar, @endChar, @includeBrackets) -> + + findOpeningBracket: (pos) -> + pos = pos.copy() + depth = 0 + while pos.row >= 0 + line = @editor.lineTextForBufferRow(pos.row) + pos.column = line.length - 1 if pos.column is -1 + while pos.column >= 0 + switch line[pos.column] + when @endChar then ++ depth + when @beginChar + return pos if -- depth < 0 + -- pos.column + pos.column = -1 + -- pos.row + + findClosingBracket: (start) -> + end = start.copy() + depth = 0 + while end.row < @editor.getLineCount() + endLine = @editor.lineTextForBufferRow(end.row) + while end.column < endLine.length + switch endLine[end.column] + when @beginChar then ++ depth + when @endChar + if -- depth < 0 + -- start.column if @includeBrackets + ++ end.column if @includeBrackets + return end + ++ end.column + end.column = 0 + ++ end.row + return + + select: -> + for selection in @editor.getSelections() + start = @findOpeningBracket(selection.cursor.getBufferPosition()) + if start? + ++ start.column # skip the opening quote + end = @findClosingBracket(start) + if end? + selection.setBufferRange([start, end]) + not selection.isEmpty() + +class SelectAWord extends TextObject + select: -> + for selection in @editor.getSelections() + selection.selectWord() + loop + endPoint = selection.getBufferRange().end + char = @editor.getTextInRange(Range.fromPointWithDelta(endPoint, 0, 1)) + break unless AllWhitespace.test(char) + selection.selectRight() + true + +class SelectInsideParagraph extends TextObject + constructor: (@editor, @inclusive) -> + select: -> + for selection in @editor.getSelections() + range = selection.cursor.getCurrentParagraphBufferRange() + if range? + selection.setBufferRange(range) + selection.selectToBeginningOfNextParagraph() + true + +class SelectAParagraph extends TextObject + constructor: (@editor, @inclusive) -> + select: -> + for selection in @editor.getSelections() + range = selection.cursor.getCurrentParagraphBufferRange() + if range? + selection.setBufferRange(range) + selection.selectToBeginningOfNextParagraph() + selection.selectDown() + true + +module.exports = {TextObject, SelectInsideWord, SelectInsideQuotes, SelectInsideBrackets, SelectAWord, SelectInsideParagraph, SelectAParagraph} |