1
1
'use babel'
2
2
// TODO: docstrings
3
-
3
+ // TODO: Fix RangeCompatible types
4
4
import { forLines } from './scopes'
5
5
6
- export function getLine ( ed , l ) {
6
+ export function getLine ( editor , l ) {
7
7
return {
8
- scope : ed . scopeDescriptorForBufferPosition ( [ l , 0 ] ) . scopes ,
9
- line : ed . getTextInBufferRange ( [ [ l , 0 ] , [ l , Infinity ] ] )
8
+ scope : editor . scopeDescriptorForBufferPosition ( [ l , 0 ] ) . getScopesArray ( ) ,
9
+ line : editor . getTextInBufferRange ( [
10
+ [ l , 0 ] ,
11
+ [ l , Infinity ]
12
+ ] )
10
13
}
11
14
}
12
15
13
- function isBlank ( { line, scope} , allowDocstrings = false ) {
16
+ function isBlank ( { line, scope } , allowDocstrings = false ) {
14
17
for ( const s of scope ) {
15
18
if ( / \b c o m m e n t \b / . test ( s ) || ( ! allowDocstrings && / \b d o c s t r i n g \b / . test ( s ) ) ) {
16
19
return true
17
20
}
18
21
}
19
22
return / ^ \s * ( # .* ) ? $ / . test ( line )
20
23
}
21
- function isEnd ( { line, scope } ) {
22
- if ( isStringEnd ( { line, scope } ) ) {
24
+
25
+ function isEnd ( lineInfo ) {
26
+ if ( isStringEnd ( lineInfo ) ) {
23
27
return true
24
28
}
25
- return / ^ ( e n d \b | \) | \] | \ }) / . test ( line )
29
+ return / ^ ( e n d \b | \) | ] | } ) / . test ( lineInfo . line )
26
30
}
27
- function isStringEnd ( { line, scope } ) {
28
- scope = scope . join ( ' ' )
31
+
32
+ function isStringEnd ( lineInfo ) {
33
+ const scope = lineInfo . scope . join ( ' ' )
29
34
return / \b s t r i n g \. m u l t i l i n e \. e n d \b / . test ( scope ) ||
30
35
( / \b s t r i n g \. e n d \b / . test ( scope ) && / \b b a c k t i c k \b / . test ( scope ) )
31
36
}
32
- function isCont ( { line, scope } ) {
33
- scope = scope . join ( ' ' )
34
- if ( / \b s t r i n g \b / . test ( scope ) && ! ( / \b p u n c t u a t i o n \. d e f i n i t i o n \. s t r i n g \b / . test ( scope ) ) ) {
37
+
38
+ function isCont ( lineInfo ) {
39
+ const scope = lineInfo . scope . join ( ' ' )
40
+ if ( / \b s t r i n g \b / . test ( scope ) && ! / \b p u n c t u a t i o n \. d e f i n i t i o n \. s t r i n g \b / . test ( scope ) ) {
35
41
return true
36
42
}
37
-
38
- return line . match ( / ^ ( e l s e | e l s e i f | c a t c h | f i n a l l y ) \b / )
43
+ return lineInfo . line . match ( / ^ ( e l s e | e l s e i f | c a t c h | f i n a l l y ) \b / )
39
44
}
40
- function isStart ( lineInfo ) {
45
+
46
+ function isStart ( lineInfo ) {
41
47
return ! ( / ^ \s / . test ( lineInfo . line ) || isBlank ( lineInfo ) || isEnd ( lineInfo ) || isCont ( lineInfo ) )
42
48
}
43
49
44
- function walkBack ( ed , row ) {
45
- while ( ( row > 0 ) && ! isStart ( getLine ( ed , row ) ) ) {
50
+ function walkBack ( editor , row ) {
51
+ while ( row > 0 && ! isStart ( getLine ( editor , row ) ) ) {
46
52
row --
47
53
}
48
54
return row
49
55
}
50
56
51
- function walkForward ( ed , start ) {
57
+ function walkForward ( editor , start ) {
52
58
let end = start
53
59
let mark = start
54
- while ( mark < ed . getLastBufferRow ( ) ) {
60
+ while ( mark < editor . getLastBufferRow ( ) ) {
55
61
mark ++
56
- const lineInfo = getLine ( ed , mark )
57
-
62
+ const lineInfo = getLine ( editor , mark )
58
63
if ( isStart ( lineInfo ) ) {
59
64
break
60
65
}
61
66
if ( isEnd ( lineInfo ) ) {
62
67
// An `end` only counts when there still are unclosed blocks (indicated by `forLines`
63
68
// returning a non-empty array).
64
69
// If the line closes a multiline string we also take that as ending the block.
65
- if (
66
- ! ( forLines ( ed , start , mark - 1 ) . length === 0 ) ||
67
- isStringEnd ( lineInfo )
68
- ) {
70
+ if ( ! ( forLines ( editor , start , mark - 1 ) . length === 0 ) || isStringEnd ( lineInfo ) ) {
69
71
end = mark
70
72
}
71
73
} else if ( ! ( isBlank ( lineInfo ) || isStart ( lineInfo ) ) ) {
@@ -75,74 +77,89 @@ function walkForward (ed, start) {
75
77
return end
76
78
}
77
79
78
- function getRange ( ed , row ) {
79
- const start = walkBack ( ed , row )
80
- const end = walkForward ( ed , start )
80
+ function getRange ( editor , row ) {
81
+ const start = walkBack ( editor , row )
82
+ const end = walkForward ( editor , start )
81
83
if ( start <= row && row <= end ) {
82
- return [ [ start , 0 ] , [ end , Infinity ] ]
84
+ return [
85
+ [ start , 0 ] ,
86
+ [ end , Infinity ]
87
+ ]
88
+ } else {
89
+ return undefined // TODO: make sure returned range from getRanges is not undefined
83
90
}
84
91
}
85
92
86
- function getSelection ( ed , sel ) {
87
- const { start, end} = sel . getBufferRange ( )
88
- const range = [ [ start . row , start . column ] , [ end . row , end . column ] ]
89
- while ( isBlank ( getLine ( ed , range [ 0 ] [ 0 ] ) , true ) && ( range [ 0 ] [ 0 ] <= range [ 1 ] [ 0 ] ) ) {
93
+ function getSelection ( editor , selection ) {
94
+ const { start, end } = selection . getBufferRange ( )
95
+ const range = [
96
+ [ start . row , start . column ] ,
97
+ [ end . row , end . column ]
98
+ ]
99
+ while ( isBlank ( getLine ( editor , range [ 0 ] [ 0 ] ) , true ) && range [ 0 ] [ 0 ] <= range [ 1 ] [ 0 ] ) {
90
100
range [ 0 ] [ 0 ] ++
91
101
range [ 0 ] [ 1 ] = 0
92
102
}
93
- while ( isBlank ( getLine ( ed , range [ 1 ] [ 0 ] ) , true ) && ( range [ 1 ] [ 0 ] >= range [ 0 ] [ 0 ] ) ) {
103
+ while ( isBlank ( getLine ( editor , range [ 1 ] [ 0 ] ) , true ) && range [ 1 ] [ 0 ] >= range [ 0 ] [ 0 ] ) {
94
104
range [ 1 ] [ 0 ] --
95
105
range [ 1 ] [ 1 ] = Infinity
96
106
}
97
107
return range
98
108
}
99
109
100
- export function moveNext ( ed , sel , range ) {
110
+ export function moveNext ( editor , selection , range ) {
101
111
// Ensure enough room at the end of the buffer
102
112
const row = range [ 1 ] [ 0 ]
103
113
let last
104
- while ( ( last = ed . getLastBufferRow ( ) ) < ( row + 2 ) ) {
105
- if ( ( last !== row ) && ! isBlank ( getLine ( ed , last ) ) ) {
114
+ while ( ( last = editor . getLastBufferRow ( ) ) < row + 2 ) {
115
+ if ( last !== row && ! isBlank ( getLine ( editor , last ) ) ) {
106
116
break
107
117
}
108
- sel . setBufferRange ( [ [ last , Infinity ] , [ last , Infinity ] ] )
109
- sel . insertText ( '\n' )
118
+ selection . setBufferRange ( [
119
+ [ last , Infinity ] ,
120
+ [ last , Infinity ]
121
+ ] )
122
+ selection . insertText ( '\n' )
110
123
}
111
124
// Move the cursor
112
125
let to = row + 1
113
- while ( ( to < ed . getLastBufferRow ( ) ) && isBlank ( getLine ( ed , to ) ) ) {
126
+ while ( to < editor . getLastBufferRow ( ) && isBlank ( getLine ( editor , to ) ) ) {
114
127
to ++
115
128
}
116
- to = walkForward ( ed , to )
117
- return sel . setBufferRange ( [ [ to , Infinity ] , [ to , Infinity ] ] )
129
+ to = walkForward ( editor , to )
130
+ return selection . setBufferRange ( [
131
+ [ to , Infinity ] ,
132
+ [ to , Infinity ]
133
+ ] )
118
134
}
119
135
120
- function getRanges ( ed ) {
121
- const ranges = ed . getSelections ( ) . map ( sel => {
136
+ function getRanges ( editor ) {
137
+ const ranges = editor . getSelections ( ) . map ( selection => {
122
138
return {
123
- selection : sel ,
124
- range : sel . isEmpty ( ) ?
125
- getRange ( ed , sel . getHeadBufferPosition ( ) . row ) :
126
- getSelection ( ed , sel )
139
+ selection : selection ,
140
+ range : selection . isEmpty ( )
141
+ ? getRange ( editor , selection . getHeadBufferPosition ( ) . row )
142
+ : getSelection ( editor , selection )
127
143
}
144
+ // TODO: replace with getBufferRowRange? (getHeadBufferPosition isn't a public API)
128
145
} )
129
146
return ranges . filter ( ( { range } ) => {
130
- return range && ed . getTextInBufferRange ( range ) . trim ( )
147
+ return range && editor . getTextInBufferRange ( range ) . trim ( )
131
148
} )
132
149
}
133
150
134
- export function get ( ed ) {
135
- return getRanges ( ed ) . map ( ( { range, selection } ) => {
151
+ export function get ( editor ) {
152
+ return getRanges ( editor ) . map ( ( { range, selection } ) => {
136
153
return {
137
154
range,
138
155
selection,
139
156
line : range [ 0 ] [ 0 ] ,
140
- text : ed . getTextInBufferRange ( range )
157
+ text : editor . getTextInBufferRange ( range )
141
158
}
142
159
} )
143
160
}
144
161
145
- export function getLocalContext ( editor , row ) {
162
+ export function getLocalContext ( editor , row ) {
146
163
const range = getRange ( editor , row )
147
164
const context = range ? editor . getTextInBufferRange ( range ) : ''
148
165
// NOTE:
@@ -156,12 +173,13 @@ export function getLocalContext (editor, row) {
156
173
}
157
174
}
158
175
159
- export function select ( ed = atom . workspace . getActiveTextEditor ( ) ) {
160
- if ( ! ed ) return
161
- return ed . mutateSelectedText ( selection => {
162
- const range = getRange ( ed , selection . getHeadBufferPosition ( ) . row )
176
+ export function select ( editor = atom . workspace . getActiveTextEditor ( ) ) {
177
+ if ( ! editor ) return
178
+ return editor . mutateSelectedText ( selection => {
179
+ const range = getRange ( editor , selection . getHeadBufferPosition ( ) . row )
163
180
if ( range ) {
164
181
selection . setBufferRange ( range )
165
182
}
166
183
} )
184
+ // TODO: replace with getBufferRowRange? (getHeadBufferPosition isn't a public API)
167
185
}
0 commit comments