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