asterisk.js
220 lines
| 7.9 KiB
| application/javascript
|
JavascriptLexer
r1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others | |||
r4105 | // Distributed under an MIT license: https://codemirror.net/LICENSE | |||
r1 | ||||
/* | ||||
* ===================================================================================== | ||||
* | ||||
* Filename: mode/asterisk/asterisk.js | ||||
* | ||||
* Description: CodeMirror mode for Asterisk dialplan | ||||
* | ||||
* Created: 05/17/2012 09:20:25 PM | ||||
r4105 | * Revision: 08/05/2019 AstLinux Project: Support block-comments | |||
r1 | * | |||
* Author: Stas Kobzar (stas@modulis.ca), | ||||
* Company: Modulis.ca Inc. | ||||
* | ||||
* ===================================================================================== | ||||
*/ | ||||
(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("asterisk", function() { | ||||
var atoms = ["exten", "same", "include","ignorepat","switch"], | ||||
dpcmd = ["#include","#exec"], | ||||
apps = [ | ||||
"addqueuemember","adsiprog","aelsub","agentlogin","agentmonitoroutgoing","agi", | ||||
"alarmreceiver","amd","answer","authenticate","background","backgrounddetect", | ||||
"bridge","busy","callcompletioncancel","callcompletionrequest","celgenuserevent", | ||||
"changemonitor","chanisavail","channelredirect","chanspy","clearhash","confbridge", | ||||
"congestion","continuewhile","controlplayback","dahdiacceptr2call","dahdibarge", | ||||
"dahdiras","dahdiscan","dahdisendcallreroutingfacility","dahdisendkeypadfacility", | ||||
"datetime","dbdel","dbdeltree","deadagi","dial","dictate","directory","disa", | ||||
"dumpchan","eagi","echo","endwhile","exec","execif","execiftime","exitwhile","extenspy", | ||||
"externalivr","festival","flash","followme","forkcdr","getcpeid","gosub","gosubif", | ||||
"goto","gotoif","gotoiftime","hangup","iax2provision","ices","importvar","incomplete", | ||||
"ivrdemo","jabberjoin","jabberleave","jabbersend","jabbersendgroup","jabberstatus", | ||||
"jack","log","macro","macroexclusive","macroexit","macroif","mailboxexists","meetme", | ||||
"meetmeadmin","meetmechanneladmin","meetmecount","milliwatt","minivmaccmess","minivmdelete", | ||||
"minivmgreet","minivmmwi","minivmnotify","minivmrecord","mixmonitor","monitor","morsecode", | ||||
"mp3player","mset","musiconhold","nbscat","nocdr","noop","odbc","odbc","odbcfinish", | ||||
"originate","ospauth","ospfinish","osplookup","ospnext","page","park","parkandannounce", | ||||
"parkedcall","pausemonitor","pausequeuemember","pickup","pickupchan","playback","playtones", | ||||
"privacymanager","proceeding","progress","queue","queuelog","raiseexception","read","readexten", | ||||
"readfile","receivefax","receivefax","receivefax","record","removequeuemember", | ||||
"resetcdr","retrydial","return","ringing","sayalpha","saycountedadj","saycountednoun", | ||||
"saycountpl","saydigits","saynumber","sayphonetic","sayunixtime","senddtmf","sendfax", | ||||
"sendfax","sendfax","sendimage","sendtext","sendurl","set","setamaflags", | ||||
"setcallerpres","setmusiconhold","sipaddheader","sipdtmfmode","sipremoveheader","skel", | ||||
"slastation","slatrunk","sms","softhangup","speechactivategrammar","speechbackground", | ||||
"speechcreate","speechdeactivategrammar","speechdestroy","speechloadgrammar","speechprocessingsound", | ||||
"speechstart","speechunloadgrammar","stackpop","startmusiconhold","stopmixmonitor","stopmonitor", | ||||
"stopmusiconhold","stopplaytones","system","testclient","testserver","transfer","tryexec", | ||||
"trysystem","unpausemonitor","unpausequeuemember","userevent","verbose","vmauthenticate", | ||||
"vmsayname","voicemail","voicemailmain","wait","waitexten","waitfornoise","waitforring", | ||||
"waitforsilence","waitmusiconhold","waituntil","while","zapateller" | ||||
]; | ||||
function basicToken(stream,state){ | ||||
var cur = ''; | ||||
var ch = stream.next(); | ||||
// comment | ||||
r4105 | if (state.blockComment) { | |||
if (ch == "-" && stream.match("-;", true)) { | ||||
state.blockComment = false; | ||||
} else if (stream.skipTo("--;")) { | ||||
stream.next(); | ||||
stream.next(); | ||||
stream.next(); | ||||
state.blockComment = false; | ||||
} else { | ||||
stream.skipToEnd(); | ||||
} | ||||
return "comment"; | ||||
} | ||||
r1 | if(ch == ";") { | |||
r4105 | if (stream.match("--", true)) { | |||
if (!stream.match("-", false)) { // Except ;--- is not a block comment | ||||
state.blockComment = true; | ||||
return "comment"; | ||||
} | ||||
} | ||||
r1 | stream.skipToEnd(); | |||
return "comment"; | ||||
} | ||||
// context | ||||
if(ch == '[') { | ||||
stream.skipTo(']'); | ||||
stream.eat(']'); | ||||
return "header"; | ||||
} | ||||
// string | ||||
if(ch == '"') { | ||||
stream.skipTo('"'); | ||||
return "string"; | ||||
} | ||||
if(ch == "'") { | ||||
stream.skipTo("'"); | ||||
return "string-2"; | ||||
} | ||||
// dialplan commands | ||||
if(ch == '#') { | ||||
stream.eatWhile(/\w/); | ||||
cur = stream.current(); | ||||
if(dpcmd.indexOf(cur) !== -1) { | ||||
stream.skipToEnd(); | ||||
return "strong"; | ||||
} | ||||
} | ||||
// application args | ||||
if(ch == '$'){ | ||||
var ch1 = stream.peek(); | ||||
if(ch1 == '{'){ | ||||
stream.skipTo('}'); | ||||
stream.eat('}'); | ||||
return "variable-3"; | ||||
} | ||||
} | ||||
// extension | ||||
stream.eatWhile(/\w/); | ||||
cur = stream.current(); | ||||
if(atoms.indexOf(cur) !== -1) { | ||||
state.extenStart = true; | ||||
switch(cur) { | ||||
case 'same': state.extenSame = true; break; | ||||
case 'include': | ||||
case 'switch': | ||||
case 'ignorepat': | ||||
state.extenInclude = true;break; | ||||
default:break; | ||||
} | ||||
return "atom"; | ||||
} | ||||
} | ||||
return { | ||||
startState: function() { | ||||
return { | ||||
r4105 | blockComment: false, | |||
r1 | extenStart: false, | |||
extenSame: false, | ||||
extenInclude: false, | ||||
extenExten: false, | ||||
extenPriority: false, | ||||
extenApplication: false | ||||
}; | ||||
}, | ||||
token: function(stream, state) { | ||||
var cur = ''; | ||||
if(stream.eatSpace()) return null; | ||||
// extension started | ||||
if(state.extenStart){ | ||||
stream.eatWhile(/[^\s]/); | ||||
cur = stream.current(); | ||||
if(/^=>?$/.test(cur)){ | ||||
state.extenExten = true; | ||||
state.extenStart = false; | ||||
return "strong"; | ||||
} else { | ||||
state.extenStart = false; | ||||
stream.skipToEnd(); | ||||
return "error"; | ||||
} | ||||
} else if(state.extenExten) { | ||||
// set exten and priority | ||||
state.extenExten = false; | ||||
state.extenPriority = true; | ||||
stream.eatWhile(/[^,]/); | ||||
if(state.extenInclude) { | ||||
stream.skipToEnd(); | ||||
state.extenPriority = false; | ||||
state.extenInclude = false; | ||||
} | ||||
if(state.extenSame) { | ||||
state.extenPriority = false; | ||||
state.extenSame = false; | ||||
state.extenApplication = true; | ||||
} | ||||
return "tag"; | ||||
} else if(state.extenPriority) { | ||||
state.extenPriority = false; | ||||
state.extenApplication = true; | ||||
stream.next(); // get comma | ||||
if(state.extenSame) return null; | ||||
stream.eatWhile(/[^,]/); | ||||
return "number"; | ||||
} else if(state.extenApplication) { | ||||
stream.eatWhile(/,/); | ||||
cur = stream.current(); | ||||
if(cur === ',') return null; | ||||
stream.eatWhile(/\w/); | ||||
cur = stream.current().toLowerCase(); | ||||
state.extenApplication = false; | ||||
if(apps.indexOf(cur) !== -1){ | ||||
return "def strong"; | ||||
} | ||||
} else{ | ||||
return basicToken(stream,state); | ||||
} | ||||
return null; | ||||
r4105 | }, | |||
blockCommentStart: ";--", | ||||
blockCommentEnd: "--;", | ||||
lineComment: ";" | ||||
r1 | }; | |||
}); | ||||
CodeMirror.defineMIME("text/x-asterisk", "asterisk"); | ||||
}); | ||||