move a few things away in to-be-integrated/
[myslice.git] / to-be-integrated / third-party / codemirror-3.15 / mode / smalltalk / smalltalk.js
1 CodeMirror.defineMode('smalltalk', function(config) {
2
3   var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
4   var keywords = /true|false|nil|self|super|thisContext/;
5
6   var Context = function(tokenizer, parent) {
7     this.next = tokenizer;
8     this.parent = parent;
9   };
10
11   var Token = function(name, context, eos) {
12     this.name = name;
13     this.context = context;
14     this.eos = eos;
15   };
16
17   var State = function() {
18     this.context = new Context(next, null);
19     this.expectVariable = true;
20     this.indentation = 0;
21     this.userIndentationDelta = 0;
22   };
23
24   State.prototype.userIndent = function(indentation) {
25     this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
26   };
27
28   var next = function(stream, context, state) {
29     var token = new Token(null, context, false);
30     var aChar = stream.next();
31
32     if (aChar === '"') {
33       token = nextComment(stream, new Context(nextComment, context));
34
35     } else if (aChar === '\'') {
36       token = nextString(stream, new Context(nextString, context));
37
38     } else if (aChar === '#') {
39       if (stream.peek() === '\'') {
40         stream.next();
41         token = nextSymbol(stream, new Context(nextSymbol, context));
42       } else {
43         stream.eatWhile(/[^ .\[\]()]/);
44         token.name = 'string-2';
45       }
46
47     } else if (aChar === '$') {
48       if (stream.next() === '<') {
49         stream.eatWhile(/[^ >]/);
50         stream.next();
51       }
52       token.name = 'string-2';
53
54     } else if (aChar === '|' && state.expectVariable) {
55       token.context = new Context(nextTemporaries, context);
56
57     } else if (/[\[\]{}()]/.test(aChar)) {
58       token.name = 'bracket';
59       token.eos = /[\[{(]/.test(aChar);
60
61       if (aChar === '[') {
62         state.indentation++;
63       } else if (aChar === ']') {
64         state.indentation = Math.max(0, state.indentation - 1);
65       }
66
67     } else if (specialChars.test(aChar)) {
68       stream.eatWhile(specialChars);
69       token.name = 'operator';
70       token.eos = aChar !== ';'; // ; cascaded message expression
71
72     } else if (/\d/.test(aChar)) {
73       stream.eatWhile(/[\w\d]/);
74       token.name = 'number';
75
76     } else if (/[\w_]/.test(aChar)) {
77       stream.eatWhile(/[\w\d_]/);
78       token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null;
79
80     } else {
81       token.eos = state.expectVariable;
82     }
83
84     return token;
85   };
86
87   var nextComment = function(stream, context) {
88     stream.eatWhile(/[^"]/);
89     return new Token('comment', stream.eat('"') ? context.parent : context, true);
90   };
91
92   var nextString = function(stream, context) {
93     stream.eatWhile(/[^']/);
94     return new Token('string', stream.eat('\'') ? context.parent : context, false);
95   };
96
97   var nextSymbol = function(stream, context) {
98     stream.eatWhile(/[^']/);
99     return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
100   };
101
102   var nextTemporaries = function(stream, context) {
103     var token = new Token(null, context, false);
104     var aChar = stream.next();
105
106     if (aChar === '|') {
107       token.context = context.parent;
108       token.eos = true;
109
110     } else {
111       stream.eatWhile(/[^|]/);
112       token.name = 'variable';
113     }
114
115     return token;
116   };
117
118   return {
119     startState: function() {
120       return new State;
121     },
122
123     token: function(stream, state) {
124       state.userIndent(stream.indentation());
125
126       if (stream.eatSpace()) {
127         return null;
128       }
129
130       var token = state.context.next(stream, state.context, state);
131       state.context = token.context;
132       state.expectVariable = token.eos;
133
134       return token.name;
135     },
136
137     blankLine: function(state) {
138       state.userIndent(0);
139     },
140
141     indent: function(state, textAfter) {
142       var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
143       return (state.indentation + i) * config.indentUnit;
144     },
145
146     electricChars: ']'
147   };
148
149 });
150
151 CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'});