annotate .cms/lib/codemirror/src/util/StringStream.js @ 0:78edf6b517a0 draft

24.10
author Coffee CMS <info@coffee-cms.ru>
date Fri, 11 Oct 2024 22:40:23 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
1 import { countColumn } from "./misc.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
2
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
3 // STRING STREAM
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
4
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
5 // Fed to the mode parsers, provides helper functions to make
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
6 // parsers more succinct.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
7
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
8 class StringStream {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
9 constructor(string, tabSize, lineOracle) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
10 this.pos = this.start = 0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
11 this.string = string
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
12 this.tabSize = tabSize || 8
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
13 this.lastColumnPos = this.lastColumnValue = 0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
14 this.lineStart = 0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
15 this.lineOracle = lineOracle
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
16 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
17
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
18 eol() {return this.pos >= this.string.length}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
19 sol() {return this.pos == this.lineStart}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
20 peek() {return this.string.charAt(this.pos) || undefined}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
21 next() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
22 if (this.pos < this.string.length)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
23 return this.string.charAt(this.pos++)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
24 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
25 eat(match) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
26 let ch = this.string.charAt(this.pos)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
27 let ok
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
28 if (typeof match == "string") ok = ch == match
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
29 else ok = ch && (match.test ? match.test(ch) : match(ch))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
30 if (ok) {++this.pos; return ch}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
31 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
32 eatWhile(match) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
33 let start = this.pos
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
34 while (this.eat(match)){}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
35 return this.pos > start
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
36 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
37 eatSpace() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
38 let start = this.pos
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
39 while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
40 return this.pos > start
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
41 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
42 skipToEnd() {this.pos = this.string.length}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
43 skipTo(ch) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
44 let found = this.string.indexOf(ch, this.pos)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
45 if (found > -1) {this.pos = found; return true}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
46 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
47 backUp(n) {this.pos -= n}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
48 column() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
49 if (this.lastColumnPos < this.start) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
50 this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
51 this.lastColumnPos = this.start
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
52 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
53 return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
54 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
55 indentation() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
56 return countColumn(this.string, null, this.tabSize) -
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
57 (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
58 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
59 match(pattern, consume, caseInsensitive) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
60 if (typeof pattern == "string") {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
61 let cased = str => caseInsensitive ? str.toLowerCase() : str
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
62 let substr = this.string.substr(this.pos, pattern.length)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
63 if (cased(substr) == cased(pattern)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
64 if (consume !== false) this.pos += pattern.length
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
65 return true
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
66 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
67 } else {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
68 let match = this.string.slice(this.pos).match(pattern)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
69 if (match && match.index > 0) return null
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
70 if (match && consume !== false) this.pos += match[0].length
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
71 return match
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
72 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
73 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
74 current(){return this.string.slice(this.start, this.pos)}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
75 hideFirstChars(n, inner) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
76 this.lineStart += n
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
77 try { return inner() }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
78 finally { this.lineStart -= n }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
79 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
80 lookAhead(n) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
81 let oracle = this.lineOracle
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
82 return oracle && oracle.lookAhead(n)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
83 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
84 baseToken() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
85 let oracle = this.lineOracle
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
86 return oracle && oracle.baseToken(this.pos)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
87 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
88 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
89
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
90 export default StringStream