]> git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/vim-mode/lib/text-objects.coffee
6d9741b93038ae16987ea7191d301fcdb8c509f8
[rbdr/dotfiles] / atom / packages / vim-mode / lib / text-objects.coffee
1 {Range} = require 'atom'
2 AllWhitespace = /^\s$/
3
4 class TextObject
5 constructor: (@editor, @state) ->
6
7 isComplete: -> true
8 isRecordable: -> false
9
10 class SelectInsideWord extends TextObject
11 select: ->
12 @editor.selectWordsContainingCursors()
13 [true]
14
15 # SelectInsideQuotes and the next class defined (SelectInsideBrackets) are
16 # almost-but-not-quite-repeated code. They are different because of the depth
17 # checks in the bracket matcher.
18
19 class SelectInsideQuotes extends TextObject
20 constructor: (@editor, @char, @includeQuotes) ->
21
22 findOpeningQuote: (pos) ->
23 start = pos.copy()
24 pos = pos.copy()
25 while pos.row >= 0
26 line = @editor.lineTextForBufferRow(pos.row)
27 pos.column = line.length - 1 if pos.column is -1
28 while pos.column >= 0
29 if line[pos.column] is @char
30 if pos.column is 0 or line[pos.column - 1] isnt '\\'
31 if @isStartQuote(pos)
32 return pos
33 else
34 return @lookForwardOnLine(start)
35 -- pos.column
36 pos.column = -1
37 -- pos.row
38 @lookForwardOnLine(start)
39
40 isStartQuote: (end) ->
41 line = @editor.lineTextForBufferRow(end.row)
42 numQuotes = line.substring(0, end.column + 1).replace( "'#{@char}", '').split(@char).length - 1
43 numQuotes % 2
44
45 lookForwardOnLine: (pos) ->
46 line = @editor.lineTextForBufferRow(pos.row)
47
48 index = line.substring(pos.column).indexOf(@char)
49 if index >= 0
50 pos.column += index
51 return pos
52 null
53
54 findClosingQuote: (start) ->
55 end = start.copy()
56 escaping = false
57
58 while end.row < @editor.getLineCount()
59 endLine = @editor.lineTextForBufferRow(end.row)
60 while end.column < endLine.length
61 if endLine[end.column] is '\\'
62 ++ end.column
63 else if endLine[end.column] is @char
64 -- start.column if @includeQuotes
65 ++ end.column if @includeQuotes
66 return end
67 ++ end.column
68 end.column = 0
69 ++ end.row
70 return
71
72 select: ->
73 for selection in @editor.getSelections()
74 start = @findOpeningQuote(selection.cursor.getBufferPosition())
75 if start?
76 ++ start.column # skip the opening quote
77 end = @findClosingQuote(start)
78 if end?
79 selection.setBufferRange([start, end])
80 not selection.isEmpty()
81
82 # SelectInsideBrackets and the previous class defined (SelectInsideQuotes) are
83 # almost-but-not-quite-repeated code. They are different because of the depth
84 # checks in the bracket matcher.
85
86 class SelectInsideBrackets extends TextObject
87 constructor: (@editor, @beginChar, @endChar, @includeBrackets) ->
88
89 findOpeningBracket: (pos) ->
90 pos = pos.copy()
91 depth = 0
92 while pos.row >= 0
93 line = @editor.lineTextForBufferRow(pos.row)
94 pos.column = line.length - 1 if pos.column is -1
95 while pos.column >= 0
96 switch line[pos.column]
97 when @endChar then ++ depth
98 when @beginChar
99 return pos if -- depth < 0
100 -- pos.column
101 pos.column = -1
102 -- pos.row
103
104 findClosingBracket: (start) ->
105 end = start.copy()
106 depth = 0
107 while end.row < @editor.getLineCount()
108 endLine = @editor.lineTextForBufferRow(end.row)
109 while end.column < endLine.length
110 switch endLine[end.column]
111 when @beginChar then ++ depth
112 when @endChar
113 if -- depth < 0
114 -- start.column if @includeBrackets
115 ++ end.column if @includeBrackets
116 return end
117 ++ end.column
118 end.column = 0
119 ++ end.row
120 return
121
122 select: ->
123 for selection in @editor.getSelections()
124 start = @findOpeningBracket(selection.cursor.getBufferPosition())
125 if start?
126 ++ start.column # skip the opening quote
127 end = @findClosingBracket(start)
128 if end?
129 selection.setBufferRange([start, end])
130 not selection.isEmpty()
131
132 class SelectAWord extends TextObject
133 select: ->
134 for selection in @editor.getSelections()
135 selection.selectWord()
136 loop
137 endPoint = selection.getBufferRange().end
138 char = @editor.getTextInRange(Range.fromPointWithDelta(endPoint, 0, 1))
139 break unless AllWhitespace.test(char)
140 selection.selectRight()
141 true
142
143 class SelectInsideParagraph extends TextObject
144 constructor: (@editor, @inclusive) ->
145 select: ->
146 for selection in @editor.getSelections()
147 range = selection.cursor.getCurrentParagraphBufferRange()
148 if range?
149 selection.setBufferRange(range)
150 selection.selectToBeginningOfNextParagraph()
151 true
152
153 class SelectAParagraph extends TextObject
154 constructor: (@editor, @inclusive) ->
155 select: ->
156 for selection in @editor.getSelections()
157 range = selection.cursor.getCurrentParagraphBufferRange()
158 if range?
159 selection.setBufferRange(range)
160 selection.selectToBeginningOfNextParagraph()
161 selection.selectDown()
162 true
163
164 module.exports = {TextObject, SelectInsideWord, SelectInsideQuotes, SelectInsideBrackets, SelectAWord, SelectInsideParagraph, SelectAParagraph}