First step at a config file for CodeMirror: steal from Jan :)
This commit is contained in:
parent
443fe5af18
commit
9d0722bf2f
666
misc/editors/yap.js
Normal file
666
misc/editors/yap.js
Normal file
@ -0,0 +1,666 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(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("prolog", function(cmConfig, parserConfig) {
|
||||
|
||||
function chain(stream, state, f) {
|
||||
state.tokenize = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
/*******************************
|
||||
* CONFIG DATA *
|
||||
*******************************/
|
||||
|
||||
var config = { quasiQuotations: false, /* {|Syntax||Quotation|} */
|
||||
dicts: false, /* tag{k:v, ...} */
|
||||
unicodeEscape: true, /* \uXXXX and \UXXXXXXXX */
|
||||
multiLineQuoted: true, /* "...\n..." */
|
||||
groupedIntegers: false /* 10 000 or 10_000 */
|
||||
};
|
||||
|
||||
var quoteType = { '"': "string",
|
||||
"'": "qatom",
|
||||
"`": "bqstring"
|
||||
};
|
||||
|
||||
var isSingleEscChar = /[abref\\'"nrtsv]/;
|
||||
var isOctalDigit = /[0-7]/;
|
||||
var isHexDigit = /[0-9a-fA-F]/;
|
||||
|
||||
var isSymbolChar = /[-#$&*+./:<=>?@\\^~]/; /* Prolog glueing symbols chars */
|
||||
var isSoloChar = /[[\]{}(),;|!]/; /* Prolog solo chars */
|
||||
var isNeck = /^(:-|-->)$/;
|
||||
var isControlOp = /^(,|;|->|\*->|\\+|\|)$/;
|
||||
|
||||
|
||||
/*******************************
|
||||
* CHARACTER ESCAPES *
|
||||
*******************************/
|
||||
|
||||
function readDigits(stream, re, count) {
|
||||
if ( count > 0 ) {
|
||||
while( count-- > 0 ) {
|
||||
if ( !re.test(stream.next()) )
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
while ( re.test(stream.peek()) )
|
||||
stream.next();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function readEsc(stream) {
|
||||
var next = stream.next();
|
||||
if ( isSingleEscChar.test(next) )
|
||||
return true;
|
||||
switch( next )
|
||||
{ case "u":
|
||||
if ( config.unicodeEscape )
|
||||
return readDigits(stream, isHexDigit, 4); /* SWI */
|
||||
return false;
|
||||
case "U":
|
||||
if ( config.unicodeEscape )
|
||||
return readDigits(stream, isHexDigit, 8); /* SWI */
|
||||
return false;
|
||||
case null: return true; /* end of line */
|
||||
case "c": stream.eatSpace(); return true;
|
||||
case "x": return readDigits(stream, isHexDigit, 2);
|
||||
}
|
||||
if ( isOctalDigit.test(next) ) {
|
||||
if ( !readDigits(stream, isOctalDigit, -1) )
|
||||
return false;
|
||||
if ( stream.peek() == "\\" ) /* SWI: optional closing \ */
|
||||
stream.next();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function nextUntilUnescaped(stream, state, end) {
|
||||
var next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if ( next == end && end != stream.peek() )
|
||||
{ state.nesting.pop();
|
||||
return false;
|
||||
}
|
||||
if ( next == "\\" )
|
||||
{ if ( !readEsc(stream) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return config.multiLineQuoted;
|
||||
}
|
||||
|
||||
/*******************************
|
||||
* CONTEXT NESTING *
|
||||
*******************************/
|
||||
|
||||
function nesting(state) {
|
||||
return state.nesting.slice(-1)[0];
|
||||
}
|
||||
|
||||
/* Called on every non-comment token */
|
||||
function setArg1(state) {
|
||||
var nest = nesting(state);
|
||||
if ( nest ) {
|
||||
if ( nest.arg == 0 ) /* nested in a compound */
|
||||
nest.arg = 1;
|
||||
else if ( nest.type == "control" )
|
||||
state.goalStart = false;
|
||||
} else
|
||||
state.goalStart = false;
|
||||
}
|
||||
|
||||
function setArgAlignment(state) {
|
||||
var nest = nesting(state);
|
||||
if ( nest && !nest.alignment && nest.arg != undefined ) {
|
||||
if ( nest.arg == 0 )
|
||||
nest.alignment = nest.leftCol ? nest.leftCol+4 : nest.column+4;
|
||||
else
|
||||
nest.alignment = nest.column+1;
|
||||
}
|
||||
}
|
||||
|
||||
function nextArg(state) {
|
||||
var nest = nesting(state);
|
||||
if ( nest ) {
|
||||
if ( nest.arg ) /* nested in a compound */
|
||||
nest.arg++;
|
||||
else if ( nest.type == "control" )
|
||||
state.goalStart = true; /* FIXME: also needed for ; and -> */
|
||||
} else
|
||||
state.goalStart = true;
|
||||
}
|
||||
|
||||
function isControl(state) { /* our terms are goals */
|
||||
var nest = nesting(state);
|
||||
if ( nest ) {
|
||||
if ( nest.type == "control" ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else
|
||||
return state.inBody;
|
||||
}
|
||||
|
||||
// Used as scratch variables to communicate multiple values without
|
||||
// consing up tons of objects.
|
||||
var type, content;
|
||||
function ret(tp, style, cont) {
|
||||
type = tp; content = cont;
|
||||
return style;
|
||||
}
|
||||
|
||||
function peekSpace(stream) { /* TBD: handle block comment as space */
|
||||
if ( stream.eol() ||
|
||||
/[\s%]/.test(stream.peek()) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*******************************
|
||||
* SUB TOKENISERS *
|
||||
*******************************/
|
||||
|
||||
function plTokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
|
||||
if ( ch == "(" ) {
|
||||
if ( state.lastType == "functor" ) {
|
||||
state.nesting.push({ functor: state.functorName,
|
||||
column: stream.column(),
|
||||
leftCol: state.functorColumn,
|
||||
arg: 0
|
||||
});
|
||||
delete state.functorName;
|
||||
delete state.functorColumn;
|
||||
} else {
|
||||
state.nesting.push({ type: "control",
|
||||
closeColumn: stream.column(),
|
||||
alignment: stream.column()+4
|
||||
});
|
||||
}
|
||||
return ret("solo", null, "(");
|
||||
}
|
||||
|
||||
if ( ch == "{" && state.lastType == "tag" ) {
|
||||
state.nesting.push({ tag: state.tagName,
|
||||
column: stream.column(),
|
||||
leftCol: state.tagColumn,
|
||||
arg: 0
|
||||
});
|
||||
delete state.tagName;
|
||||
delete state.tagColumn;
|
||||
return ret("dict_open", null);
|
||||
}
|
||||
|
||||
if ( ch == "/" && stream.eat("*") )
|
||||
return chain(stream, state, plTokenComment);
|
||||
|
||||
if ( ch == "%" ) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
setArg1(state);
|
||||
|
||||
if ( isSoloChar.test(ch) ) {
|
||||
switch ( ch )
|
||||
{ case ")":
|
||||
state.nesting.pop();
|
||||
break;
|
||||
case "]":
|
||||
state.nesting.pop();
|
||||
return ret("list_close", null);
|
||||
case "}":
|
||||
{ var nest = nesting(state);
|
||||
var type = (nest && nest.tag) ? "dict_close" : "brace_term_close";
|
||||
|
||||
state.nesting.pop();
|
||||
return ret(type, null);
|
||||
}
|
||||
case ",":
|
||||
if ( stream.eol() )
|
||||
state.commaAtEOL = true;
|
||||
nextArg(state);
|
||||
/*FALLTHROUGH*/
|
||||
case ";":
|
||||
if ( isControl(state) )
|
||||
state.goalStart = true;
|
||||
break;
|
||||
case "[":
|
||||
state.nesting.push({ type: "list",
|
||||
closeColumn: stream.column(),
|
||||
alignment: stream.column()+2
|
||||
});
|
||||
return ret("list_open", null);
|
||||
break;
|
||||
case "{":
|
||||
if ( config.quasiQuotations && stream.eat("|") ) {
|
||||
state.nesting.push({ type: "quasi-quotation",
|
||||
alignment: stream.column()+1
|
||||
});
|
||||
return ret("qq_open", "qq_open");
|
||||
} else {
|
||||
state.nesting.push({ type: "curly",
|
||||
closeColumn: stream.column(),
|
||||
alignment: stream.column()+2
|
||||
});
|
||||
return ret("brace_term_open", null);
|
||||
}
|
||||
break;
|
||||
case "|":
|
||||
if ( config.quasiQuotations ) {
|
||||
if ( stream.eat("|") ) {
|
||||
state.tokenize = plTokenQuasiQuotation;
|
||||
return ret("qq_sep", "qq_sep");
|
||||
} else if ( stream.eat("}") ) {
|
||||
state.nesting.pop();
|
||||
return ret("qq_close", "qq_close");
|
||||
}
|
||||
}
|
||||
if ( isControl(state) )
|
||||
state.goalStart = true;
|
||||
break;
|
||||
}
|
||||
return ret("solo", null, ch);
|
||||
}
|
||||
|
||||
if (ch == '"' || ch == "'" || ch == "`")
|
||||
{ state.nesting.push({ type: "quoted",
|
||||
alignment: stream.column()+1
|
||||
});
|
||||
return chain(stream, state, plTokenString(ch));
|
||||
}
|
||||
|
||||
if ( ch == "0" ) {
|
||||
if ( stream.eat(/x/i)) {
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
if ( stream.eat(/o/i)) {
|
||||
stream.eatWhile(/[0-7]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
if ( stream.eat(/'/) ) { /* 0' */
|
||||
var next = stream.next();
|
||||
if ( next == "\\" ) {
|
||||
if ( !readEsc(stream) )
|
||||
return ret("error", "error");
|
||||
}
|
||||
return ret("code", "code");
|
||||
}
|
||||
}
|
||||
|
||||
if ( /\d/.test(ch) || /[+-]/.test(ch) && stream.eat(/\d/)) {
|
||||
if ( config.groupedIntegers )
|
||||
stream.match(/^\d*((_|\s+)\d+)*(?:\.\d+)?(?:[eE][+\-]?\d+)?/);
|
||||
else
|
||||
stream.match(/^\d*(?:\.\d+)?(?:[eE][+\-]?\d+)?/);
|
||||
return ret(ch == "-" ? "neg-number" :
|
||||
ch == "+" ? "pos-number" :
|
||||
"number");
|
||||
}
|
||||
|
||||
if ( isSymbolChar.test(ch) ) {
|
||||
stream.eatWhile(isSymbolChar);
|
||||
var atom = stream.current();
|
||||
if ( atom == "." && peekSpace(stream) ) {
|
||||
if ( nesting(state) ) {
|
||||
return ret("fullstop", "error", atom);
|
||||
} else {
|
||||
} return ret("fullstop", "fullstop", atom);
|
||||
} else if ( isNeck.test(atom) ) {
|
||||
return ret("neck", "neck", atom);
|
||||
} else if ( isControl(state) && isControlOp.test(atom) ) {
|
||||
state.goalStart = true;
|
||||
return ret("symbol", "operator", atom);
|
||||
} else
|
||||
return ret("symbol", "operator", atom);
|
||||
}
|
||||
|
||||
stream.eatWhile(/[\w_]/);
|
||||
var word = stream.current();
|
||||
if ( stream.peek() == "{" && config.dicts ) {
|
||||
state.tagName = word; /* tmp state extension */
|
||||
state.tagColumn = stream.column();
|
||||
return ret("tag", "tag", word);
|
||||
} else if ( ch == "_" ) {
|
||||
if ( word.length == 1 ) {
|
||||
return ret("var", "anon", word);
|
||||
} else {
|
||||
var sec = word.charAt(1);
|
||||
if ( sec == sec.toUpperCase() )
|
||||
return ret("var", "var-2", word);
|
||||
}
|
||||
return ret("var", "var", word);
|
||||
} else if ( ch == ch.toUpperCase() ) {
|
||||
return ret("var", "var", word);
|
||||
} else if ( stream.peek() == "(" ) {
|
||||
state.functorName = word; /* tmp state extension */
|
||||
state.functorColumn = stream.column();
|
||||
return ret("functor", "functor", word);
|
||||
} else
|
||||
return ret("atom", "atom", word);
|
||||
}
|
||||
|
||||
function plTokenString(quote) {
|
||||
return function(stream, state) {
|
||||
if (!nextUntilUnescaped(stream, state, quote)) {
|
||||
state.tokenize = plTokenBase;
|
||||
if ( stream.peek() == "(" ) { /* 'quoted functor'() */
|
||||
var word = stream.current();
|
||||
state.functorName = word; /* tmp state extension */
|
||||
return ret("functor", "functor", word);
|
||||
}
|
||||
if ( stream.peek() == "{" && config.dicts ) { /* 'quoted tag'{} */
|
||||
var word = stream.current();
|
||||
state.tagName = word; /* tmp state extension */
|
||||
return ret("tag", "tag", word);
|
||||
}
|
||||
}
|
||||
return ret(quoteType[quote], quoteType[quote]);
|
||||
};
|
||||
}
|
||||
|
||||
function plTokenQuasiQuotation(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "}" && maybeEnd) {
|
||||
state.tokenize = plTokenBase;
|
||||
stream.backUp(2);
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "|");
|
||||
}
|
||||
return ret("qq_content", "qq_content");
|
||||
}
|
||||
|
||||
function plTokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = plTokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
|
||||
/*******************************
|
||||
* ACTIVE KEYS *
|
||||
*******************************/
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Support if-then-else layout like this:
|
||||
|
||||
goal :-
|
||||
( Condition
|
||||
-> IfTrue
|
||||
; IfFalse
|
||||
).
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
CodeMirror.commands.prologStartIfThenElse = function(cm) {
|
||||
var start = cm.getCursor("start");
|
||||
var token = cm.getTokenAt(start, true);
|
||||
|
||||
if ( token.state.goalStart == true )
|
||||
{ cm.replaceSelection("( ", "end");
|
||||
return;
|
||||
}
|
||||
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
|
||||
CodeMirror.commands.prologStartThen = function(cm) {
|
||||
var start = cm.getCursor("start");
|
||||
var token = cm.getTokenAt(start, true);
|
||||
|
||||
/* FIXME: These functions are copied from prolog.js. How
|
||||
can we reuse these?
|
||||
*/
|
||||
function nesting(state) {
|
||||
var len = state.nesting.length;
|
||||
if ( len > 0 )
|
||||
return state.nesting[len-1];
|
||||
return null;
|
||||
}
|
||||
|
||||
function isControl(state) { /* our terms are goals */
|
||||
var nest = nesting(state);
|
||||
if ( nest ) {
|
||||
if ( nest.type == "control" ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else
|
||||
return state.inBody;
|
||||
}
|
||||
|
||||
if ( start.ch == token.end &&
|
||||
token.type == "operator" &&
|
||||
token.string == "-" &&
|
||||
isControl(token.state) )
|
||||
{ cm.replaceSelection("> ", "end");
|
||||
return;
|
||||
}
|
||||
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
|
||||
CodeMirror.commands.prologStartElse = function(cm) {
|
||||
var start = cm.getCursor("start");
|
||||
var token = cm.getTokenAt(start, true);
|
||||
|
||||
if ( token.start == 0 && start.ch == token.end &&
|
||||
!/\S/.test(token.string) )
|
||||
{ cm.replaceSelection("; ", "end");
|
||||
return;
|
||||
}
|
||||
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("prologKeys", null, function(cm, val, prev) {
|
||||
if (prev && prev != CodeMirror.Init)
|
||||
cm.removeKeyMap("prolog");
|
||||
if ( val ) {
|
||||
var map = { name: "prolog",
|
||||
"'('": "prologStartIfThenElse",
|
||||
"'>'": "prologStartThen",
|
||||
"';'": "prologStartElse",
|
||||
"Ctrl-L": "refreshHighlight"
|
||||
};
|
||||
cm.addKeyMap(map);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
//Default (SWI-)Prolog operator table. To be used later to enhance the
|
||||
//offline experience.
|
||||
|
||||
var ops = { "-->": { p:1200, t:"xfx" },
|
||||
":-": [ { p:1200, t:"xfx" },
|
||||
{ p:1200, t:"fx" }
|
||||
],
|
||||
"?-": { p:1200, t:"fx" },
|
||||
|
||||
"dynamic": { p:1150, t:"fx" },
|
||||
"discontiguous": { p:1150, t:"fx" },
|
||||
"initialization": { p:1150, t:"fx" },
|
||||
"meta_predicate": { p:1150, t:"fx" },
|
||||
"module_transparent": { p:1150, t:"fx" },
|
||||
"multifile": { p:1150, t:"fx" },
|
||||
"thread_local": { p:1150, t:"fx" },
|
||||
"volatile": { p:1150, t:"fx" },
|
||||
|
||||
";": { p:1100, t:"xfy" },
|
||||
"|": { p:1100, t:"xfy" },
|
||||
|
||||
"->": { p:1050, t:"xfy" },
|
||||
"*->": { p:1050, t:"xfy" },
|
||||
|
||||
",": { p:1000, t:"xfy" },
|
||||
|
||||
"\\+": { p:900, t:"fy" },
|
||||
|
||||
"~": { p:900, t:"fx" },
|
||||
|
||||
"<": { p:700, t:"xfx" },
|
||||
"=": { p:700, t:"xfx" },
|
||||
"=..": { p:700, t:"xfx" },
|
||||
"=@=": { p:700, t:"xfx" },
|
||||
"=:=": { p:700, t:"xfx" },
|
||||
"=<": { p:700, t:"xfx" },
|
||||
"==": { p:700, t:"xfx" },
|
||||
"=\\=": { p:700, t:"xfx" },
|
||||
">": { p:700, t:"xfx" },
|
||||
">=": { p:700, t:"xfx" },
|
||||
"@<": { p:700, t:"xfx" },
|
||||
"@=<": { p:700, t:"xfx" },
|
||||
"@>": { p:700, t:"xfx" },
|
||||
"@>=": { p:700, t:"xfx" },
|
||||
"\\=": { p:700, t:"xfx" },
|
||||
"\\==": { p:700, t:"xfx" },
|
||||
"is": { p:700, t:"xfx" },
|
||||
|
||||
":": { p:600, t:"xfy" },
|
||||
|
||||
"+": [ { p:500, t:"yfx" },
|
||||
{ p:200, t:"fy" }
|
||||
],
|
||||
"-": [ { p:500, t:"yfx" },
|
||||
{ p:200, t:"fy" }
|
||||
],
|
||||
"/\\": { p:500, t:"yfx" },
|
||||
"\\/": { p:500, t:"yfx" },
|
||||
"xor": { p:500, t:"yfx" },
|
||||
|
||||
"?": { p:500, t:"fx" },
|
||||
|
||||
"*": { p:400, t:"yfx" },
|
||||
"/": { p:400, t:"yfx" },
|
||||
"//": { p:400, t:"yfx" },
|
||||
"rdiv": { p:400, t:"yfx" },
|
||||
"<<": { p:400, t:"yfx" },
|
||||
">>": { p:400, t:"yfx" },
|
||||
"mod": { p:400, t:"yfx" },
|
||||
"rem": { p:400, t:"yfx" },
|
||||
|
||||
"**": { p:200, t:"xfx" },
|
||||
"^": { p:200, t:"xfy" },
|
||||
|
||||
"\\": { p:200, t:"fy" }
|
||||
};
|
||||
|
||||
|
||||
/*******************************
|
||||
* RETURN OBJECT *
|
||||
*******************************/
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
tokenize: plTokenBase,
|
||||
inBody: false,
|
||||
goalStart: false,
|
||||
lastType: null,
|
||||
nesting: new Array(), /* ([{}]) nesting FIXME: copy this */
|
||||
curTerm: null, /* term index in metainfo */
|
||||
curToken: null /* token in term */
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var nest;
|
||||
|
||||
if ( state.curTerm == null && parserConfig.metainfo ) {
|
||||
state.curTerm = 0;
|
||||
state.curToken = 0;
|
||||
}
|
||||
|
||||
if ( stream.sol() )
|
||||
delete state.commaAtEOL;
|
||||
|
||||
if ( state.tokenize == plTokenBase && stream.eatSpace() ) {
|
||||
if ( stream.eol() )
|
||||
setArgAlignment(state);
|
||||
return null;
|
||||
}
|
||||
|
||||
var style = state.tokenize(stream, state);
|
||||
|
||||
if ( stream.eol() )
|
||||
setArgAlignment(state);
|
||||
|
||||
if ( type == "neck" ) {
|
||||
state.inBody = true;
|
||||
state.goalStart = true;
|
||||
} else if ( type == "fullstop" ) {
|
||||
state.inBody = false;
|
||||
state.goalStart = false;
|
||||
}
|
||||
|
||||
state.lastType = type;
|
||||
|
||||
if ( typeof(parserConfig.enrich) == "function" )
|
||||
style = parserConfig.enrich(stream, state, type, content, style);
|
||||
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize == plTokenComment) return CodeMirror.Pass;
|
||||
|
||||
var nest;
|
||||
if ( (nest=nesting(state)) ) {
|
||||
if ( nest.closeColumn && !state.commaAtEOL )
|
||||
return nest.closeColumn;
|
||||
return nest.alignment;
|
||||
}
|
||||
if ( !state.inBody )
|
||||
return 0;
|
||||
|
||||
return 4;
|
||||
},
|
||||
|
||||
theme: "prolog",
|
||||
|
||||
blockCommentStart: "/*", /* continuecomment.js support */
|
||||
blockCommentEnd: "*/",
|
||||
blockCommentContinue: " * ",
|
||||
lineComment: "%",
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-prolog", "prolog");
|
||||
});
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(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";
|
Reference in New Issue
Block a user