-
Notifications
You must be signed in to change notification settings - Fork 138
Expand file tree
/
Copy pathlineCache.ts
More file actions
75 lines (68 loc) · 2.34 KB
/
lineCache.ts
File metadata and controls
75 lines (68 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
'use strict';
/**
* Class to hold lines that have been fetched from the document after they have been preprocessed.
*/
export class LineCache {
public endsInOperatorCache: Map<number, boolean>;
public getLine: (line: number) => string;
public lineCache: Map<number, string>;
public lineCount: number;
public constructor(getLine: (line: number) => string, lineCount: number) {
this.getLine = getLine;
this.lineCount = lineCount;
this.lineCache = new Map<number, string>();
this.endsInOperatorCache = new Map<number, boolean>();
}
// Returns [Line, EndsInOperator]
public addLineToCache(line: number): [string, boolean] {
const cleaned = cleanLine(this.getLine(line));
const endsInOperator = doesLineEndInOperator(cleaned);
this.lineCache.set(line, cleaned);
this.endsInOperatorCache.set(line, endsInOperator);
return [cleaned, endsInOperator];
}
public getEndsInOperatorFromCache(line: number): boolean {
const lineInCache = this.endsInOperatorCache.get(line);
if (lineInCache === undefined) {
return this.addLineToCache(line)[1];
}
return lineInCache;
}
public getLineFromCache(line: number): string {
const lineInCache = this.lineCache.get(line);
if (lineInCache === undefined) {
return this.addLineToCache(line)[0];
}
return lineInCache;
}
}
function isQuote(c: string) {
return c === '"' || c === '\'' || c === '`';
}
function isComment(c: string) {
return c === '#';
}
export function cleanLine(text: string): string {
let cleaned = '';
let withinQuotes = null;
for (let i = 0; i < text.length; i++) {
const c = text[i];
if (isQuote(c)) {
if (withinQuotes === null) {
withinQuotes = c;
} else if (withinQuotes === c) {
withinQuotes = null;
}
}
if (isComment(c) && !withinQuotes) {
break;
}
cleaned += c;
}
return (cleaned.trimEnd());
}
function doesLineEndInOperator(text: string) {
const endingOperatorIndex = text.search(/(\(|,|\+|!|\$|\^|&|\*|-|=|:|~|\||\/|\?|<|>|%.*%)(\s*|\s*#.*)$/);
const spacesOnlyIndex = text.search(/^\s*$/);
return ((endingOperatorIndex >= 0) || (spacesOnlyIndex >= 0));
}