Mercurial
comparison .cms/lib/codemirror/mode/smalltalk/smalltalk.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others | |
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE | |
3 | |
4 (function(mod) { | |
5 if (typeof exports == "object" && typeof module == "object") // CommonJS | |
6 mod(require("../../lib/codemirror")); | |
7 else if (typeof define == "function" && define.amd) // AMD | |
8 define(["../../lib/codemirror"], mod); | |
9 else // Plain browser env | |
10 mod(CodeMirror); | |
11 })(function(CodeMirror) { | |
12 "use strict"; | |
13 | |
14 CodeMirror.defineMode('smalltalk', function(config) { | |
15 | |
16 var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/; | |
17 var keywords = /true|false|nil|self|super|thisContext/; | |
18 | |
19 var Context = function(tokenizer, parent) { | |
20 this.next = tokenizer; | |
21 this.parent = parent; | |
22 }; | |
23 | |
24 var Token = function(name, context, eos) { | |
25 this.name = name; | |
26 this.context = context; | |
27 this.eos = eos; | |
28 }; | |
29 | |
30 var State = function() { | |
31 this.context = new Context(next, null); | |
32 this.expectVariable = true; | |
33 this.indentation = 0; | |
34 this.userIndentationDelta = 0; | |
35 }; | |
36 | |
37 State.prototype.userIndent = function(indentation) { | |
38 this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0; | |
39 }; | |
40 | |
41 var next = function(stream, context, state) { | |
42 var token = new Token(null, context, false); | |
43 var aChar = stream.next(); | |
44 | |
45 if (aChar === '"') { | |
46 token = nextComment(stream, new Context(nextComment, context)); | |
47 | |
48 } else if (aChar === '\'') { | |
49 token = nextString(stream, new Context(nextString, context)); | |
50 | |
51 } else if (aChar === '#') { | |
52 if (stream.peek() === '\'') { | |
53 stream.next(); | |
54 token = nextSymbol(stream, new Context(nextSymbol, context)); | |
55 } else { | |
56 if (stream.eatWhile(/[^\s.{}\[\]()]/)) | |
57 token.name = 'string-2'; | |
58 else | |
59 token.name = 'meta'; | |
60 } | |
61 | |
62 } else if (aChar === '$') { | |
63 if (stream.next() === '<') { | |
64 stream.eatWhile(/[^\s>]/); | |
65 stream.next(); | |
66 } | |
67 token.name = 'string-2'; | |
68 | |
69 } else if (aChar === '|' && state.expectVariable) { | |
70 token.context = new Context(nextTemporaries, context); | |
71 | |
72 } else if (/[\[\]{}()]/.test(aChar)) { | |
73 token.name = 'bracket'; | |
74 token.eos = /[\[{(]/.test(aChar); | |
75 | |
76 if (aChar === '[') { | |
77 state.indentation++; | |
78 } else if (aChar === ']') { | |
79 state.indentation = Math.max(0, state.indentation - 1); | |
80 } | |
81 | |
82 } else if (specialChars.test(aChar)) { | |
83 stream.eatWhile(specialChars); | |
84 token.name = 'operator'; | |
85 token.eos = aChar !== ';'; // ; cascaded message expression | |
86 | |
87 } else if (/\d/.test(aChar)) { | |
88 stream.eatWhile(/[\w\d]/); | |
89 token.name = 'number'; | |
90 | |
91 } else if (/[\w_]/.test(aChar)) { | |
92 stream.eatWhile(/[\w\d_]/); | |
93 token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null; | |
94 | |
95 } else { | |
96 token.eos = state.expectVariable; | |
97 } | |
98 | |
99 return token; | |
100 }; | |
101 | |
102 var nextComment = function(stream, context) { | |
103 stream.eatWhile(/[^"]/); | |
104 return new Token('comment', stream.eat('"') ? context.parent : context, true); | |
105 }; | |
106 | |
107 var nextString = function(stream, context) { | |
108 stream.eatWhile(/[^']/); | |
109 return new Token('string', stream.eat('\'') ? context.parent : context, false); | |
110 }; | |
111 | |
112 var nextSymbol = function(stream, context) { | |
113 stream.eatWhile(/[^']/); | |
114 return new Token('string-2', stream.eat('\'') ? context.parent : context, false); | |
115 }; | |
116 | |
117 var nextTemporaries = function(stream, context) { | |
118 var token = new Token(null, context, false); | |
119 var aChar = stream.next(); | |
120 | |
121 if (aChar === '|') { | |
122 token.context = context.parent; | |
123 token.eos = true; | |
124 | |
125 } else { | |
126 stream.eatWhile(/[^|]/); | |
127 token.name = 'variable'; | |
128 } | |
129 | |
130 return token; | |
131 }; | |
132 | |
133 return { | |
134 startState: function() { | |
135 return new State; | |
136 }, | |
137 | |
138 token: function(stream, state) { | |
139 state.userIndent(stream.indentation()); | |
140 | |
141 if (stream.eatSpace()) { | |
142 return null; | |
143 } | |
144 | |
145 var token = state.context.next(stream, state.context, state); | |
146 state.context = token.context; | |
147 state.expectVariable = token.eos; | |
148 | |
149 return token.name; | |
150 }, | |
151 | |
152 blankLine: function(state) { | |
153 state.userIndent(0); | |
154 }, | |
155 | |
156 indent: function(state, textAfter) { | |
157 var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta; | |
158 return (state.indentation + i) * config.indentUnit; | |
159 }, | |
160 | |
161 electricChars: ']' | |
162 }; | |
163 | |
164 }); | |
165 | |
166 CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'}); | |
167 | |
168 }); |