| 
									
										
										
										
											2018-01-21 10:33:32 -05:00
										 |  |  | // CodeMirror, copyright (c) by Marijn Haverbeke and others
 | 
					
						
							| 
									
										
										
										
											2022-10-15 12:22:09 +02:00
										 |  |  | // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 | 
					
						
							| 
									
										
										
										
											2018-01-21 10:33:32 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | (function(mod) { | 
					
						
							|  |  |  |   if (typeof exports == "object" && typeof module == "object") // CommonJS
 | 
					
						
							|  |  |  |     mod(require("../../lib/codemirror")); | 
					
						
							|  |  |  |   else if (typeof define == "function" && define.amd) // AMD
 | 
					
						
							|  |  |  |     define(["../../lib/codemirror"], mod); | 
					
						
							|  |  |  |   else // Plain browser env
 | 
					
						
							|  |  |  |     mod(CodeMirror); | 
					
						
							|  |  |  | })(function(CodeMirror) { | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CodeMirror.defineMode('smalltalk', function(config) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/; | 
					
						
							|  |  |  |   var keywords = /true|false|nil|self|super|thisContext/; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var Context = function(tokenizer, parent) { | 
					
						
							|  |  |  |     this.next = tokenizer; | 
					
						
							|  |  |  |     this.parent = parent; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var Token = function(name, context, eos) { | 
					
						
							|  |  |  |     this.name = name; | 
					
						
							|  |  |  |     this.context = context; | 
					
						
							|  |  |  |     this.eos = eos; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var State = function() { | 
					
						
							|  |  |  |     this.context = new Context(next, null); | 
					
						
							|  |  |  |     this.expectVariable = true; | 
					
						
							|  |  |  |     this.indentation = 0; | 
					
						
							|  |  |  |     this.userIndentationDelta = 0; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   State.prototype.userIndent = function(indentation) { | 
					
						
							|  |  |  |     this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var next = function(stream, context, state) { | 
					
						
							|  |  |  |     var token = new Token(null, context, false); | 
					
						
							|  |  |  |     var aChar = stream.next(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (aChar === '"') { | 
					
						
							|  |  |  |       token = nextComment(stream, new Context(nextComment, context)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (aChar === '\'') { | 
					
						
							|  |  |  |       token = nextString(stream, new Context(nextString, context)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (aChar === '#') { | 
					
						
							|  |  |  |       if (stream.peek() === '\'') { | 
					
						
							|  |  |  |         stream.next(); | 
					
						
							|  |  |  |         token = nextSymbol(stream, new Context(nextSymbol, context)); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         if (stream.eatWhile(/[^\s.{}\[\]()]/)) | 
					
						
							|  |  |  |           token.name = 'string-2'; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           token.name = 'meta'; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (aChar === '$') { | 
					
						
							|  |  |  |       if (stream.next() === '<') { | 
					
						
							|  |  |  |         stream.eatWhile(/[^\s>]/); | 
					
						
							|  |  |  |         stream.next(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       token.name = 'string-2'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (aChar === '|' && state.expectVariable) { | 
					
						
							|  |  |  |       token.context = new Context(nextTemporaries, context); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (/[\[\]{}()]/.test(aChar)) { | 
					
						
							|  |  |  |       token.name = 'bracket'; | 
					
						
							|  |  |  |       token.eos = /[\[{(]/.test(aChar); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (aChar === '[') { | 
					
						
							|  |  |  |         state.indentation++; | 
					
						
							|  |  |  |       } else if (aChar === ']') { | 
					
						
							|  |  |  |         state.indentation = Math.max(0, state.indentation - 1); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (specialChars.test(aChar)) { | 
					
						
							|  |  |  |       stream.eatWhile(specialChars); | 
					
						
							|  |  |  |       token.name = 'operator'; | 
					
						
							|  |  |  |       token.eos = aChar !== ';'; // ; cascaded message expression
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (/\d/.test(aChar)) { | 
					
						
							|  |  |  |       stream.eatWhile(/[\w\d]/); | 
					
						
							|  |  |  |       token.name = 'number'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (/[\w_]/.test(aChar)) { | 
					
						
							|  |  |  |       stream.eatWhile(/[\w\d_]/); | 
					
						
							|  |  |  |       token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       token.eos = state.expectVariable; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return token; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var nextComment = function(stream, context) { | 
					
						
							|  |  |  |     stream.eatWhile(/[^"]/); | 
					
						
							|  |  |  |     return new Token('comment', stream.eat('"') ? context.parent : context, true); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var nextString = function(stream, context) { | 
					
						
							|  |  |  |     stream.eatWhile(/[^']/); | 
					
						
							|  |  |  |     return new Token('string', stream.eat('\'') ? context.parent : context, false); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var nextSymbol = function(stream, context) { | 
					
						
							|  |  |  |     stream.eatWhile(/[^']/); | 
					
						
							|  |  |  |     return new Token('string-2', stream.eat('\'') ? context.parent : context, false); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var nextTemporaries = function(stream, context) { | 
					
						
							|  |  |  |     var token = new Token(null, context, false); | 
					
						
							|  |  |  |     var aChar = stream.next(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (aChar === '|') { | 
					
						
							|  |  |  |       token.context = context.parent; | 
					
						
							|  |  |  |       token.eos = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       stream.eatWhile(/[^|]/); | 
					
						
							|  |  |  |       token.name = 'variable'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return token; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     startState: function() { | 
					
						
							|  |  |  |       return new State; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     token: function(stream, state) { | 
					
						
							|  |  |  |       state.userIndent(stream.indentation()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (stream.eatSpace()) { | 
					
						
							|  |  |  |         return null; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var token = state.context.next(stream, state.context, state); | 
					
						
							|  |  |  |       state.context = token.context; | 
					
						
							|  |  |  |       state.expectVariable = token.eos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return token.name; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blankLine: function(state) { | 
					
						
							|  |  |  |       state.userIndent(0); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     indent: function(state, textAfter) { | 
					
						
							|  |  |  |       var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta; | 
					
						
							|  |  |  |       return (state.indentation + i) * config.indentUnit; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     electricChars: ']' | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }); |