Skip to content

Commit 6e602af

Browse files
committed
npm run build
1 parent 8a492b6 commit 6e602af

File tree

1 file changed

+157
-60
lines changed

1 file changed

+157
-60
lines changed

lib/misc/blocks.js

Lines changed: 157 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,118 @@
11
'use babel'
22
// TODO: docstrings
3+
// TODO: Fix RangeCompatible types
34

45
import { forLines } from './scopes'
6+
/**
7+
* interface LineInfo {
8+
* scope: readonly string[]
9+
* line: string
10+
* }
11+
*/
512

6-
export function getLine (ed, l) {
13+
14+
/**
15+
*
16+
* @param {TextEditor} editor
17+
* @param {number} l
18+
* @returns {LineInfo}
19+
*/
20+
export function getLine(editor, l) {
721
return {
8-
scope: ed.scopeDescriptorForBufferPosition([l, 0]).scopes,
9-
line: ed.getTextInBufferRange([[l, 0], [l, Infinity]])
22+
scope: editor.scopeDescriptorForBufferPosition([l, 0]).getScopesArray(),
23+
line: editor.getTextInBufferRange([
24+
[l, 0],
25+
[l, Infinity],
26+
]),
1027
}
1128
}
1229

13-
function isBlank ({line, scope}, allowDocstrings = false) {
30+
/**
31+
*
32+
* @param {LineInfo.line} line
33+
* @param {LineInfo.scope} scope
34+
* @param {boolean} allowDocstrings
35+
*/
36+
function isBlank({ line, scope }, allowDocstrings = false) {
1437
for (const s of scope) {
1538
if (/\bcomment\b/.test(s) || (!allowDocstrings && /\bdocstring\b/.test(s))) {
1639
return true
1740
}
1841
}
1942
return /^\s*(#.*)?$/.test(line)
2043
}
21-
function isEnd ({ line, scope }) {
22-
if (isStringEnd({ line, scope })) {
44+
45+
/**
46+
*
47+
* @param {LineInfo} lineInfo
48+
*/
49+
function isEnd(lineInfo) {
50+
if (isStringEnd(lineInfo)) {
2351
return true
2452
}
25-
return /^(end\b|\)|\]|\})/.test(line)
53+
return /^(end\b|\)|]|})/.test(lineInfo.line)
2654
}
27-
function isStringEnd ({ line, scope }) {
28-
scope = scope.join(' ')
29-
return /\bstring\.multiline\.end\b/.test(scope) ||
30-
(/\bstring\.end\b/.test(scope) && /\bbacktick\b/.test(scope))
55+
56+
/**
57+
*
58+
* @param {LineInfo} lineInfo
59+
*/
60+
function isStringEnd(lineInfo) {
61+
const scope = lineInfo.scope.join(' ')
62+
return /\bstring\.multiline\.end\b/.test(scope) || (/\bstring\.end\b/.test(scope) && /\bbacktick\b/.test(scope))
3163
}
32-
function isCont ({ line, scope }) {
33-
scope = scope.join(' ')
34-
if (/\bstring\b/.test(scope) && !(/\bpunctuation\.definition\.string\b/.test(scope))) {
64+
65+
/**
66+
*
67+
* @param {LineInfo} lineInfo
68+
*/
69+
function isCont(lineInfo) {
70+
const scope = lineInfo.scope.join(' ')
71+
if (/\bstring\b/.test(scope) && !/\bpunctuation\.definition\.string\b/.test(scope)) {
3572
return true
3673
}
37-
38-
return line.match(/^(else|elseif|catch|finally)\b/)
74+
return lineInfo.line.match(/^(else|elseif|catch|finally)\b/)
3975
}
40-
function isStart (lineInfo) {
76+
77+
/**
78+
*
79+
* @param {LineInfo} lineInfo
80+
*/
81+
function isStart(lineInfo) {
4182
return !(/^\s/.test(lineInfo.line) || isBlank(lineInfo) || isEnd(lineInfo) || isCont(lineInfo))
4283
}
4384

44-
function walkBack(ed, row) {
45-
while ((row > 0) && !isStart(getLine(ed, row))) {
85+
/**
86+
*
87+
* @param {TextEditor} editor
88+
* @param {number} row
89+
*/
90+
function walkBack(editor, row) {
91+
while (row > 0 && !isStart(getLine(editor, row))) {
4692
row--
4793
}
4894
return row
4995
}
5096

51-
function walkForward (ed, start) {
97+
/**
98+
*
99+
* @param {TextEditor} editor
100+
* @param {number} start
101+
*/
102+
function walkForward(editor, start) {
52103
let end = start
53104
let mark = start
54-
while (mark < ed.getLastBufferRow()) {
105+
while (mark < editor.getLastBufferRow()) {
55106
mark++
56-
const lineInfo = getLine(ed, mark)
57-
107+
const lineInfo = getLine(editor, mark)
58108
if (isStart(lineInfo)) {
59109
break
60110
}
61111
if (isEnd(lineInfo)) {
62112
// An `end` only counts when there still are unclosed blocks (indicated by `forLines`
63113
// returning a non-empty array).
64114
// 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-
) {
115+
if (!(forLines(editor, start, mark - 1).length === 0) || isStringEnd(lineInfo)) {
69116
end = mark
70117
}
71118
} else if (!(isBlank(lineInfo) || isStart(lineInfo))) {
@@ -75,74 +122,119 @@ function walkForward (ed, start) {
75122
return end
76123
}
77124

78-
function getRange (ed, row) {
79-
const start = walkBack(ed, row)
80-
const end = walkForward(ed, start)
125+
/**
126+
*
127+
* @param {TextEditor} editor
128+
* @param {number} row
129+
* @returns {[[number, number], [number, number]] | undefined}
130+
*/
131+
function getRange(editor, row) {
132+
const start = walkBack(editor, row)
133+
const end = walkForward(editor, start)
81134
if (start <= row && row <= end) {
82-
return [[start, 0], [end, Infinity]]
135+
return [
136+
[start, 0],
137+
[end, Infinity],
138+
]
139+
} else {
140+
return undefined // TODO: make sure returned range from getRanges is not undefined
83141
}
84142
}
85143

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])) {
144+
/**
145+
*
146+
* @param {TextEditor} editor
147+
* @param {Selection} selection
148+
*/
149+
function getSelection(editor, selection) {
150+
const { start, end } = selection.getBufferRange()
151+
const range = [
152+
[start.row, start.column],
153+
[end.row, end.column],
154+
]
155+
while (isBlank(getLine(editor, range[0][0]), true) && range[0][0] <= range[1][0]) {
90156
range[0][0]++
91157
range[0][1] = 0
92158
}
93-
while (isBlank(getLine(ed, range[1][0]), true) && (range[1][0] >= range[0][0])) {
159+
while (isBlank(getLine(editor, range[1][0]), true) && range[1][0] >= range[0][0]) {
94160
range[1][0]--
95161
range[1][1] = Infinity
96162
}
97163
return range
98164
}
99165

100-
export function moveNext (ed, sel, range) {
166+
/**
167+
*
168+
* @param {TextEditor} editor
169+
* @param {Selection} selection
170+
* @param {[[number, number], [number, number]]} range
171+
*/
172+
export function moveNext(editor, selection, range) {
101173
// Ensure enough room at the end of the buffer
102174
const row = range[1][0]
103175
let last
104-
while ((last = ed.getLastBufferRow()) < (row+2)) {
105-
if ((last !== row) && !isBlank(getLine(ed, last))) {
176+
while ((last = editor.getLastBufferRow()) < row + 2) {
177+
if (last !== row && !isBlank(getLine(editor, last))) {
106178
break
107179
}
108-
sel.setBufferRange([[last, Infinity], [last, Infinity]])
109-
sel.insertText('\n')
180+
selection.setBufferRange([
181+
[last, Infinity],
182+
[last, Infinity],
183+
])
184+
selection.insertText('\n')
110185
}
111186
// Move the cursor
112187
let to = row + 1
113-
while ((to < ed.getLastBufferRow()) && isBlank(getLine(ed, to))) {
188+
while (to < editor.getLastBufferRow() && isBlank(getLine(editor, to))) {
114189
to++
115190
}
116-
to = walkForward(ed, to)
117-
return sel.setBufferRange([[to, Infinity], [to, Infinity]])
191+
to = walkForward(editor, to)
192+
return selection.setBufferRange([
193+
[to, Infinity],
194+
[to, Infinity],
195+
])
118196
}
119197

120-
function getRanges (ed) {
121-
const ranges = ed.getSelections().map(sel => {
198+
/**
199+
*
200+
* @param {TextEditor} editor
201+
*/
202+
function getRanges(editor) {
203+
const ranges = editor.getSelections().map((selection) => {
122204
return {
123-
selection: sel,
124-
range: sel.isEmpty() ?
125-
getRange(ed, sel.getHeadBufferPosition().row) :
126-
getSelection(ed, sel)
205+
selection: selection,
206+
range: selection.isEmpty()
207+
? getRange(editor, selection.getHeadBufferPosition().row)
208+
: getSelection(editor, selection),
127209
}
210+
// TODO: replace with getBufferRowRange? (getHeadBufferPosition isn't a public API)
128211
})
129212
return ranges.filter(({ range }) => {
130-
return range && ed.getTextInBufferRange(range).trim()
213+
return range && editor.getTextInBufferRange(range).trim()
131214
})
132215
}
133216

134-
export function get (ed) {
135-
return getRanges(ed).map(({ range, selection }) => {
217+
/**
218+
*
219+
* @param {TextEditor} editor
220+
*/
221+
export function get(editor) {
222+
return getRanges(editor).map(({ range, selection }) => {
136223
return {
137224
range,
138225
selection,
139226
line: range[0][0],
140-
text: ed.getTextInBufferRange(range)
227+
text: editor.getTextInBufferRange(range),
141228
}
142229
})
143230
}
144231

145-
export function getLocalContext (editor, row) {
232+
/**
233+
*
234+
* @param {TextEditor} editor
235+
* @param {number} row
236+
*/
237+
export function getLocalContext(editor, row) {
146238
const range = getRange(editor, row)
147239
const context = range ? editor.getTextInBufferRange(range) : ''
148240
// NOTE:
@@ -152,16 +244,21 @@ export function getLocalContext (editor, row) {
152244
const startRow = range ? range[0][0] : 0
153245
return {
154246
context,
155-
startRow
247+
startRow,
156248
}
157249
}
158250

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)
251+
/**
252+
*
253+
* @param {TextEditor | undefined} editor
254+
*/
255+
export function select(editor = atom.workspace.getActiveTextEditor()) {
256+
if (!editor) return
257+
return editor.mutateSelectedText((selection) => {
258+
const range = getRange(editor, selection.getHeadBufferPosition().row)
163259
if (range) {
164260
selection.setBufferRange(range)
165261
}
166262
})
263+
// TODO: replace with getBufferRowRange? (getHeadBufferPosition isn't a public API)
167264
}

0 commit comments

Comments
 (0)