mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	moved all sources to src directory
This commit is contained in:
		
							
								
								
									
										619
									
								
								src/public/libraries/codemirror/mode/erlang/erlang.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										619
									
								
								src/public/libraries/codemirror/mode/erlang/erlang.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,619 @@ | ||||
| // CodeMirror, copyright (c) by Marijn Haverbeke and others | ||||
| // Distributed under an MIT license: http://codemirror.net/LICENSE | ||||
|  | ||||
| /*jshint unused:true, eqnull:true, curly:true, bitwise:true */ | ||||
| /*jshint undef:true, latedef:true, trailing:true */ | ||||
| /*global CodeMirror:true */ | ||||
|  | ||||
| // erlang mode. | ||||
| // tokenizer -> token types -> CodeMirror styles | ||||
| // tokenizer maintains a parse stack | ||||
| // indenter uses the parse stack | ||||
|  | ||||
| // TODO indenter: | ||||
| //   bit syntax | ||||
| //   old guard/bif/conversion clashes (e.g. "float/1") | ||||
| //   type/spec/opaque | ||||
|  | ||||
| (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.defineMIME("text/x-erlang", "erlang"); | ||||
|  | ||||
| CodeMirror.defineMode("erlang", function(cmCfg) { | ||||
|   "use strict"; | ||||
|  | ||||
| ///////////////////////////////////////////////////////////////////////////// | ||||
| // constants | ||||
|  | ||||
|   var typeWords = [ | ||||
|     "-type", "-spec", "-export_type", "-opaque"]; | ||||
|  | ||||
|   var keywordWords = [ | ||||
|     "after","begin","catch","case","cond","end","fun","if", | ||||
|     "let","of","query","receive","try","when"]; | ||||
|  | ||||
|   var separatorRE    = /[\->,;]/; | ||||
|   var separatorWords = [ | ||||
|     "->",";",","]; | ||||
|  | ||||
|   var operatorAtomWords = [ | ||||
|     "and","andalso","band","bnot","bor","bsl","bsr","bxor", | ||||
|     "div","not","or","orelse","rem","xor"]; | ||||
|  | ||||
|   var operatorSymbolRE    = /[\+\-\*\/<>=\|:!]/; | ||||
|   var operatorSymbolWords = [ | ||||
|     "=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"]; | ||||
|  | ||||
|   var openParenRE    = /[<\(\[\{]/; | ||||
|   var openParenWords = [ | ||||
|     "<<","(","[","{"]; | ||||
|  | ||||
|   var closeParenRE    = /[>\)\]\}]/; | ||||
|   var closeParenWords = [ | ||||
|     "}","]",")",">>"]; | ||||
|  | ||||
|   var guardWords = [ | ||||
|     "is_atom","is_binary","is_bitstring","is_boolean","is_float", | ||||
|     "is_function","is_integer","is_list","is_number","is_pid", | ||||
|     "is_port","is_record","is_reference","is_tuple", | ||||
|     "atom","binary","bitstring","boolean","function","integer","list", | ||||
|     "number","pid","port","record","reference","tuple"]; | ||||
|  | ||||
|   var bifWords = [ | ||||
|     "abs","adler32","adler32_combine","alive","apply","atom_to_binary", | ||||
|     "atom_to_list","binary_to_atom","binary_to_existing_atom", | ||||
|     "binary_to_list","binary_to_term","bit_size","bitstring_to_list", | ||||
|     "byte_size","check_process_code","contact_binary","crc32", | ||||
|     "crc32_combine","date","decode_packet","delete_module", | ||||
|     "disconnect_node","element","erase","exit","float","float_to_list", | ||||
|     "garbage_collect","get","get_keys","group_leader","halt","hd", | ||||
|     "integer_to_list","internal_bif","iolist_size","iolist_to_binary", | ||||
|     "is_alive","is_atom","is_binary","is_bitstring","is_boolean", | ||||
|     "is_float","is_function","is_integer","is_list","is_number","is_pid", | ||||
|     "is_port","is_process_alive","is_record","is_reference","is_tuple", | ||||
|     "length","link","list_to_atom","list_to_binary","list_to_bitstring", | ||||
|     "list_to_existing_atom","list_to_float","list_to_integer", | ||||
|     "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded", | ||||
|     "monitor_node","node","node_link","node_unlink","nodes","notalive", | ||||
|     "now","open_port","pid_to_list","port_close","port_command", | ||||
|     "port_connect","port_control","pre_loaded","process_flag", | ||||
|     "process_info","processes","purge_module","put","register", | ||||
|     "registered","round","self","setelement","size","spawn","spawn_link", | ||||
|     "spawn_monitor","spawn_opt","split_binary","statistics", | ||||
|     "term_to_binary","time","throw","tl","trunc","tuple_size", | ||||
|     "tuple_to_list","unlink","unregister","whereis"]; | ||||
|  | ||||
| // upper case: [A-Z] [Ø-Þ] [À-Ö] | ||||
| // lower case: [a-z] [ß-ö] [ø-ÿ] | ||||
|   var anumRE       = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/; | ||||
|   var escapesRE    = | ||||
|     /[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/; | ||||
|  | ||||
| ///////////////////////////////////////////////////////////////////////////// | ||||
| // tokenizer | ||||
|  | ||||
|   function tokenizer(stream,state) { | ||||
|     // in multi-line string | ||||
|     if (state.in_string) { | ||||
|       state.in_string = (!doubleQuote(stream)); | ||||
|       return rval(state,stream,"string"); | ||||
|     } | ||||
|  | ||||
|     // in multi-line atom | ||||
|     if (state.in_atom) { | ||||
|       state.in_atom = (!singleQuote(stream)); | ||||
|       return rval(state,stream,"atom"); | ||||
|     } | ||||
|  | ||||
|     // whitespace | ||||
|     if (stream.eatSpace()) { | ||||
|       return rval(state,stream,"whitespace"); | ||||
|     } | ||||
|  | ||||
|     // attributes and type specs | ||||
|     if (!peekToken(state) && | ||||
|         stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) { | ||||
|       if (is_member(stream.current(),typeWords)) { | ||||
|         return rval(state,stream,"type"); | ||||
|       }else{ | ||||
|         return rval(state,stream,"attribute"); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     var ch = stream.next(); | ||||
|  | ||||
|     // comment | ||||
|     if (ch == '%') { | ||||
|       stream.skipToEnd(); | ||||
|       return rval(state,stream,"comment"); | ||||
|     } | ||||
|  | ||||
|     // colon | ||||
|     if (ch == ":") { | ||||
|       return rval(state,stream,"colon"); | ||||
|     } | ||||
|  | ||||
|     // macro | ||||
|     if (ch == '?') { | ||||
|       stream.eatSpace(); | ||||
|       stream.eatWhile(anumRE); | ||||
|       return rval(state,stream,"macro"); | ||||
|     } | ||||
|  | ||||
|     // record | ||||
|     if (ch == "#") { | ||||
|       stream.eatSpace(); | ||||
|       stream.eatWhile(anumRE); | ||||
|       return rval(state,stream,"record"); | ||||
|     } | ||||
|  | ||||
|     // dollar escape | ||||
|     if (ch == "$") { | ||||
|       if (stream.next() == "\\" && !stream.match(escapesRE)) { | ||||
|         return rval(state,stream,"error"); | ||||
|       } | ||||
|       return rval(state,stream,"number"); | ||||
|     } | ||||
|  | ||||
|     // dot | ||||
|     if (ch == ".") { | ||||
|       return rval(state,stream,"dot"); | ||||
|     } | ||||
|  | ||||
|     // quoted atom | ||||
|     if (ch == '\'') { | ||||
|       if (!(state.in_atom = (!singleQuote(stream)))) { | ||||
|         if (stream.match(/\s*\/\s*[0-9]/,false)) { | ||||
|           stream.match(/\s*\/\s*[0-9]/,true); | ||||
|           return rval(state,stream,"fun");      // 'f'/0 style fun | ||||
|         } | ||||
|         if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) { | ||||
|           return rval(state,stream,"function"); | ||||
|         } | ||||
|       } | ||||
|       return rval(state,stream,"atom"); | ||||
|     } | ||||
|  | ||||
|     // string | ||||
|     if (ch == '"') { | ||||
|       state.in_string = (!doubleQuote(stream)); | ||||
|       return rval(state,stream,"string"); | ||||
|     } | ||||
|  | ||||
|     // variable | ||||
|     if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) { | ||||
|       stream.eatWhile(anumRE); | ||||
|       return rval(state,stream,"variable"); | ||||
|     } | ||||
|  | ||||
|     // atom/keyword/BIF/function | ||||
|     if (/[a-z_ß-öø-ÿ]/.test(ch)) { | ||||
|       stream.eatWhile(anumRE); | ||||
|  | ||||
|       if (stream.match(/\s*\/\s*[0-9]/,false)) { | ||||
|         stream.match(/\s*\/\s*[0-9]/,true); | ||||
|         return rval(state,stream,"fun");      // f/0 style fun | ||||
|       } | ||||
|  | ||||
|       var w = stream.current(); | ||||
|  | ||||
|       if (is_member(w,keywordWords)) { | ||||
|         return rval(state,stream,"keyword"); | ||||
|       }else if (is_member(w,operatorAtomWords)) { | ||||
|         return rval(state,stream,"operator"); | ||||
|       }else if (stream.match(/\s*\(/,false)) { | ||||
|         // 'put' and 'erlang:put' are bifs, 'foo:put' is not | ||||
|         if (is_member(w,bifWords) && | ||||
|             ((peekToken(state).token != ":") || | ||||
|              (peekToken(state,2).token == "erlang"))) { | ||||
|           return rval(state,stream,"builtin"); | ||||
|         }else if (is_member(w,guardWords)) { | ||||
|           return rval(state,stream,"guard"); | ||||
|         }else{ | ||||
|           return rval(state,stream,"function"); | ||||
|         } | ||||
|       }else if (lookahead(stream) == ":") { | ||||
|         if (w == "erlang") { | ||||
|           return rval(state,stream,"builtin"); | ||||
|         } else { | ||||
|           return rval(state,stream,"function"); | ||||
|         } | ||||
|       }else if (is_member(w,["true","false"])) { | ||||
|         return rval(state,stream,"boolean"); | ||||
|       }else{ | ||||
|         return rval(state,stream,"atom"); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // number | ||||
|     var digitRE      = /[0-9]/; | ||||
|     var radixRE      = /[0-9a-zA-Z]/;         // 36#zZ style int | ||||
|     if (digitRE.test(ch)) { | ||||
|       stream.eatWhile(digitRE); | ||||
|       if (stream.eat('#')) {                // 36#aZ  style integer | ||||
|         if (!stream.eatWhile(radixRE)) { | ||||
|           stream.backUp(1);                 //"36#" - syntax error | ||||
|         } | ||||
|       } else if (stream.eat('.')) {       // float | ||||
|         if (!stream.eatWhile(digitRE)) { | ||||
|           stream.backUp(1);        // "3." - probably end of function | ||||
|         } else { | ||||
|           if (stream.eat(/[eE]/)) {        // float with exponent | ||||
|             if (stream.eat(/[-+]/)) { | ||||
|               if (!stream.eatWhile(digitRE)) { | ||||
|                 stream.backUp(2);            // "2e-" - syntax error | ||||
|               } | ||||
|             } else { | ||||
|               if (!stream.eatWhile(digitRE)) { | ||||
|                 stream.backUp(1);            // "2e" - syntax error | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       return rval(state,stream,"number");   // normal integer | ||||
|     } | ||||
|  | ||||
|     // open parens | ||||
|     if (nongreedy(stream,openParenRE,openParenWords)) { | ||||
|       return rval(state,stream,"open_paren"); | ||||
|     } | ||||
|  | ||||
|     // close parens | ||||
|     if (nongreedy(stream,closeParenRE,closeParenWords)) { | ||||
|       return rval(state,stream,"close_paren"); | ||||
|     } | ||||
|  | ||||
|     // separators | ||||
|     if (greedy(stream,separatorRE,separatorWords)) { | ||||
|       return rval(state,stream,"separator"); | ||||
|     } | ||||
|  | ||||
|     // operators | ||||
|     if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) { | ||||
|       return rval(state,stream,"operator"); | ||||
|     } | ||||
|  | ||||
|     return rval(state,stream,null); | ||||
|   } | ||||
|  | ||||
| ///////////////////////////////////////////////////////////////////////////// | ||||
| // utilities | ||||
|   function nongreedy(stream,re,words) { | ||||
|     if (stream.current().length == 1 && re.test(stream.current())) { | ||||
|       stream.backUp(1); | ||||
|       while (re.test(stream.peek())) { | ||||
|         stream.next(); | ||||
|         if (is_member(stream.current(),words)) { | ||||
|           return true; | ||||
|         } | ||||
|       } | ||||
|       stream.backUp(stream.current().length-1); | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   function greedy(stream,re,words) { | ||||
|     if (stream.current().length == 1 && re.test(stream.current())) { | ||||
|       while (re.test(stream.peek())) { | ||||
|         stream.next(); | ||||
|       } | ||||
|       while (0 < stream.current().length) { | ||||
|         if (is_member(stream.current(),words)) { | ||||
|           return true; | ||||
|         }else{ | ||||
|           stream.backUp(1); | ||||
|         } | ||||
|       } | ||||
|       stream.next(); | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   function doubleQuote(stream) { | ||||
|     return quote(stream, '"', '\\'); | ||||
|   } | ||||
|  | ||||
|   function singleQuote(stream) { | ||||
|     return quote(stream,'\'','\\'); | ||||
|   } | ||||
|  | ||||
|   function quote(stream,quoteChar,escapeChar) { | ||||
|     while (!stream.eol()) { | ||||
|       var ch = stream.next(); | ||||
|       if (ch == quoteChar) { | ||||
|         return true; | ||||
|       }else if (ch == escapeChar) { | ||||
|         stream.next(); | ||||
|       } | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   function lookahead(stream) { | ||||
|     var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false); | ||||
|     return m ? m.pop() : ""; | ||||
|   } | ||||
|  | ||||
|   function is_member(element,list) { | ||||
|     return (-1 < list.indexOf(element)); | ||||
|   } | ||||
|  | ||||
|   function rval(state,stream,type) { | ||||
|  | ||||
|     // parse stack | ||||
|     pushToken(state,realToken(type,stream)); | ||||
|  | ||||
|     // map erlang token type to CodeMirror style class | ||||
|     //     erlang             -> CodeMirror tag | ||||
|     switch (type) { | ||||
|       case "atom":        return "atom"; | ||||
|       case "attribute":   return "attribute"; | ||||
|       case "boolean":     return "atom"; | ||||
|       case "builtin":     return "builtin"; | ||||
|       case "close_paren": return null; | ||||
|       case "colon":       return null; | ||||
|       case "comment":     return "comment"; | ||||
|       case "dot":         return null; | ||||
|       case "error":       return "error"; | ||||
|       case "fun":         return "meta"; | ||||
|       case "function":    return "tag"; | ||||
|       case "guard":       return "property"; | ||||
|       case "keyword":     return "keyword"; | ||||
|       case "macro":       return "variable-2"; | ||||
|       case "number":      return "number"; | ||||
|       case "open_paren":  return null; | ||||
|       case "operator":    return "operator"; | ||||
|       case "record":      return "bracket"; | ||||
|       case "separator":   return null; | ||||
|       case "string":      return "string"; | ||||
|       case "type":        return "def"; | ||||
|       case "variable":    return "variable"; | ||||
|       default:            return null; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function aToken(tok,col,ind,typ) { | ||||
|     return {token:  tok, | ||||
|             column: col, | ||||
|             indent: ind, | ||||
|             type:   typ}; | ||||
|   } | ||||
|  | ||||
|   function realToken(type,stream) { | ||||
|     return aToken(stream.current(), | ||||
|                  stream.column(), | ||||
|                  stream.indentation(), | ||||
|                  type); | ||||
|   } | ||||
|  | ||||
|   function fakeToken(type) { | ||||
|     return aToken(type,0,0,type); | ||||
|   } | ||||
|  | ||||
|   function peekToken(state,depth) { | ||||
|     var len = state.tokenStack.length; | ||||
|     var dep = (depth ? depth : 1); | ||||
|  | ||||
|     if (len < dep) { | ||||
|       return false; | ||||
|     }else{ | ||||
|       return state.tokenStack[len-dep]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function pushToken(state,token) { | ||||
|  | ||||
|     if (!(token.type == "comment" || token.type == "whitespace")) { | ||||
|       state.tokenStack = maybe_drop_pre(state.tokenStack,token); | ||||
|       state.tokenStack = maybe_drop_post(state.tokenStack); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function maybe_drop_pre(s,token) { | ||||
|     var last = s.length-1; | ||||
|  | ||||
|     if (0 < last && s[last].type === "record" && token.type === "dot") { | ||||
|       s.pop(); | ||||
|     }else if (0 < last && s[last].type === "group") { | ||||
|       s.pop(); | ||||
|       s.push(token); | ||||
|     }else{ | ||||
|       s.push(token); | ||||
|     } | ||||
|     return s; | ||||
|   } | ||||
|  | ||||
|   function maybe_drop_post(s) { | ||||
|     if (!s.length) return s | ||||
|     var last = s.length-1; | ||||
|  | ||||
|     if (s[last].type === "dot") { | ||||
|       return []; | ||||
|     } | ||||
|     if (last > 1 && s[last].type === "fun" && s[last-1].token === "fun") { | ||||
|       return s.slice(0,last-1); | ||||
|     } | ||||
|     switch (s[last].token) { | ||||
|       case "}":    return d(s,{g:["{"]}); | ||||
|       case "]":    return d(s,{i:["["]}); | ||||
|       case ")":    return d(s,{i:["("]}); | ||||
|       case ">>":   return d(s,{i:["<<"]}); | ||||
|       case "end":  return d(s,{i:["begin","case","fun","if","receive","try"]}); | ||||
|       case ",":    return d(s,{e:["begin","try","when","->", | ||||
|                                   ",","(","[","{","<<"]}); | ||||
|       case "->":   return d(s,{r:["when"], | ||||
|                                m:["try","if","case","receive"]}); | ||||
|       case ";":    return d(s,{E:["case","fun","if","receive","try","when"]}); | ||||
|       case "catch":return d(s,{e:["try"]}); | ||||
|       case "of":   return d(s,{e:["case"]}); | ||||
|       case "after":return d(s,{e:["receive","try"]}); | ||||
|       default:     return s; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function d(stack,tt) { | ||||
|     // stack is a stack of Token objects. | ||||
|     // tt is an object; {type:tokens} | ||||
|     // type is a char, tokens is a list of token strings. | ||||
|     // The function returns (possibly truncated) stack. | ||||
|     // It will descend the stack, looking for a Token such that Token.token | ||||
|     //  is a member of tokens. If it does not find that, it will normally (but | ||||
|     //  see "E" below) return stack. If it does find a match, it will remove | ||||
|     //  all the Tokens between the top and the matched Token. | ||||
|     // If type is "m", that is all it does. | ||||
|     // If type is "i", it will also remove the matched Token and the top Token. | ||||
|     // If type is "g", like "i", but add a fake "group" token at the top. | ||||
|     // If type is "r", it will remove the matched Token, but not the top Token. | ||||
|     // If type is "e", it will keep the matched Token but not the top Token. | ||||
|     // If type is "E", it behaves as for type "e", except if there is no match, | ||||
|     //  in which case it will return an empty stack. | ||||
|  | ||||
|     for (var type in tt) { | ||||
|       var len = stack.length-1; | ||||
|       var tokens = tt[type]; | ||||
|       for (var i = len-1; -1 < i ; i--) { | ||||
|         if (is_member(stack[i].token,tokens)) { | ||||
|           var ss = stack.slice(0,i); | ||||
|           switch (type) { | ||||
|               case "m": return ss.concat(stack[i]).concat(stack[len]); | ||||
|               case "r": return ss.concat(stack[len]); | ||||
|               case "i": return ss; | ||||
|               case "g": return ss.concat(fakeToken("group")); | ||||
|               case "E": return ss.concat(stack[i]); | ||||
|               case "e": return ss.concat(stack[i]); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return (type == "E" ? [] : stack); | ||||
|   } | ||||
|  | ||||
| ///////////////////////////////////////////////////////////////////////////// | ||||
| // indenter | ||||
|  | ||||
|   function indenter(state,textAfter) { | ||||
|     var t; | ||||
|     var unit = cmCfg.indentUnit; | ||||
|     var wordAfter = wordafter(textAfter); | ||||
|     var currT = peekToken(state,1); | ||||
|     var prevT = peekToken(state,2); | ||||
|  | ||||
|     if (state.in_string || state.in_atom) { | ||||
|       return CodeMirror.Pass; | ||||
|     }else if (!prevT) { | ||||
|       return 0; | ||||
|     }else if (currT.token == "when") { | ||||
|       return currT.column+unit; | ||||
|     }else if (wordAfter === "when" && prevT.type === "function") { | ||||
|       return prevT.indent+unit; | ||||
|     }else if (wordAfter === "(" && currT.token === "fun") { | ||||
|       return  currT.column+3; | ||||
|     }else if (wordAfter === "catch" && (t = getToken(state,["try"]))) { | ||||
|       return t.column; | ||||
|     }else if (is_member(wordAfter,["end","after","of"])) { | ||||
|       t = getToken(state,["begin","case","fun","if","receive","try"]); | ||||
|       return t ? t.column : CodeMirror.Pass; | ||||
|     }else if (is_member(wordAfter,closeParenWords)) { | ||||
|       t = getToken(state,openParenWords); | ||||
|       return t ? t.column : CodeMirror.Pass; | ||||
|     }else if (is_member(currT.token,[",","|","||"]) || | ||||
|               is_member(wordAfter,[",","|","||"])) { | ||||
|       t = postcommaToken(state); | ||||
|       return t ? t.column+t.token.length : unit; | ||||
|     }else if (currT.token == "->") { | ||||
|       if (is_member(prevT.token, ["receive","case","if","try"])) { | ||||
|         return prevT.column+unit+unit; | ||||
|       }else{ | ||||
|         return prevT.column+unit; | ||||
|       } | ||||
|     }else if (is_member(currT.token,openParenWords)) { | ||||
|       return currT.column+currT.token.length; | ||||
|     }else{ | ||||
|       t = defaultToken(state); | ||||
|       return truthy(t) ? t.column+unit : 0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function wordafter(str) { | ||||
|     var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/); | ||||
|  | ||||
|     return truthy(m) && (m.index === 0) ? m[0] : ""; | ||||
|   } | ||||
|  | ||||
|   function postcommaToken(state) { | ||||
|     var objs = state.tokenStack.slice(0,-1); | ||||
|     var i = getTokenIndex(objs,"type",["open_paren"]); | ||||
|  | ||||
|     return truthy(objs[i]) ? objs[i] : false; | ||||
|   } | ||||
|  | ||||
|   function defaultToken(state) { | ||||
|     var objs = state.tokenStack; | ||||
|     var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]); | ||||
|     var oper = getTokenIndex(objs,"type",["operator"]); | ||||
|  | ||||
|     if (truthy(stop) && truthy(oper) && stop < oper) { | ||||
|       return objs[stop+1]; | ||||
|     } else if (truthy(stop)) { | ||||
|       return objs[stop]; | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function getToken(state,tokens) { | ||||
|     var objs = state.tokenStack; | ||||
|     var i = getTokenIndex(objs,"token",tokens); | ||||
|  | ||||
|     return truthy(objs[i]) ? objs[i] : false; | ||||
|   } | ||||
|  | ||||
|   function getTokenIndex(objs,propname,propvals) { | ||||
|  | ||||
|     for (var i = objs.length-1; -1 < i ; i--) { | ||||
|       if (is_member(objs[i][propname],propvals)) { | ||||
|         return i; | ||||
|       } | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   function truthy(x) { | ||||
|     return (x !== false) && (x != null); | ||||
|   } | ||||
|  | ||||
| ///////////////////////////////////////////////////////////////////////////// | ||||
| // this object defines the mode | ||||
|  | ||||
|   return { | ||||
|     startState: | ||||
|       function() { | ||||
|         return {tokenStack: [], | ||||
|                 in_string:  false, | ||||
|                 in_atom:    false}; | ||||
|       }, | ||||
|  | ||||
|     token: | ||||
|       function(stream, state) { | ||||
|         return tokenizer(stream, state); | ||||
|       }, | ||||
|  | ||||
|     indent: | ||||
|       function(state, textAfter) { | ||||
|         return indenter(state,textAfter); | ||||
|       }, | ||||
|  | ||||
|     lineComment: "%" | ||||
|   }; | ||||
| }); | ||||
|  | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user