forked from ZwiiCMS-Team/ZwiiCMS
nettoyage CodeMirror
This commit is contained in:
parent
2eafd25381
commit
065331b495
@ -9,6 +9,8 @@
|
||||
* @author Rémi Jean <remi.jean@outlook.com>
|
||||
* @copyright Copyright (C) 2008-2018, Rémi Jean
|
||||
* @license GNU General Public License, version 3
|
||||
* @author Frédéric Tempez <frederic.tempez@outlook.com>
|
||||
* @copyright Copyright (C) 2018-2019, Frédéric Tempez
|
||||
* @link http://zwiicms.com/
|
||||
*/
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
*.txt text
|
||||
*.js text
|
||||
*.html text
|
||||
*.md text
|
||||
*.json text
|
||||
*.yml text
|
||||
*.css text
|
||||
*.svg text
|
@ -1,78 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Active Line Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="../addon/selection/active-line.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Active Line</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Active Line Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
|
||||
xmlns:georss="http://www.georss.org/georss"
|
||||
xmlns:twitter="http://api.twitter.com">
|
||||
<channel>
|
||||
<title>Twitter / codemirror</title>
|
||||
<link>http://twitter.com/codemirror</link>
|
||||
<atom:link type="application/rss+xml"
|
||||
href="http://twitter.com/statuses/user_timeline/242283288.rss" rel="self"/>
|
||||
<description>Twitter updates from CodeMirror / codemirror.</description>
|
||||
<language>en-us</language>
|
||||
<ttl>40</ttl>
|
||||
<item>
|
||||
<title>codemirror: http://cloud-ide.com — they're springing up like mushrooms. This one
|
||||
uses CodeMirror as its editor.</title>
|
||||
<description>codemirror: http://cloud-ide.com — they're springing up like mushrooms. This
|
||||
one uses CodeMirror as its editor.</description>
|
||||
<pubDate>Thu, 17 Mar 2011 23:34:47 +0000</pubDate>
|
||||
<guid>http://twitter.com/codemirror/statuses/48527733722058752</guid>
|
||||
<link>http://twitter.com/codemirror/statuses/48527733722058752</link>
|
||||
<twitter:source>web</twitter:source>
|
||||
<twitter:place/>
|
||||
</item>
|
||||
<item>
|
||||
<title>codemirror: Posted a description of the CodeMirror 2 internals at
|
||||
http://codemirror.net/2/internals.html</title>
|
||||
<description>codemirror: Posted a description of the CodeMirror 2 internals at
|
||||
http://codemirror.net/2/internals.html</description>
|
||||
<pubDate>Wed, 02 Mar 2011 12:15:09 +0000</pubDate>
|
||||
<guid>http://twitter.com/codemirror/statuses/42920879788789760</guid>
|
||||
<link>http://twitter.com/codemirror/statuses/42920879788789760</link>
|
||||
<twitter:source>web</twitter:source>
|
||||
<twitter:place/>
|
||||
</item>
|
||||
</channel>
|
||||
</rss></textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "application/xml",
|
||||
styleActiveLine: true,
|
||||
lineNumbers: true,
|
||||
lineWrapping: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Styling the current cursor line.</p>
|
||||
|
||||
</article>
|
@ -1,79 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Any Word Completion Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/hint/show-hint.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/hint/show-hint.js"></script>
|
||||
<script src="../addon/hint/anyword-hint.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Any Word Completion</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Any Word Completion Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var WORD = /[\w$]+/g, RANGE = 500;
|
||||
|
||||
CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
|
||||
var word = options && options.word || WORD;
|
||||
var range = options && options.range || RANGE;
|
||||
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
|
||||
var start = cur.ch, end = start;
|
||||
while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
|
||||
while (start && word.test(curLine.charAt(start - 1))) --start;
|
||||
var curWord = start != end && curLine.slice(start, end);
|
||||
|
||||
var list = [], seen = {};
|
||||
function scan(dir) {
|
||||
var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
|
||||
for (; line != end; line += dir) {
|
||||
var text = editor.getLine(line), m;
|
||||
word.lastIndex = 0;
|
||||
while (m = word.exec(text)) {
|
||||
if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) {
|
||||
seen[m[0]] = true;
|
||||
list.push(m[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scan(-1);
|
||||
scan(1);
|
||||
return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
|
||||
});
|
||||
})();
|
||||
</textarea></form>
|
||||
|
||||
<p>Press <strong>ctrl-space</strong> to activate autocompletion. The
|
||||
completion uses
|
||||
the <a href="../doc/manual.html#addon_anyword-hint">anyword-hint.js</a>
|
||||
module, which simply looks at nearby words in the buffer and completes
|
||||
to those.</p>
|
||||
|
||||
<script>
|
||||
CodeMirror.commands.autocomplete = function(cm) {
|
||||
cm.showHint({hint: CodeMirror.hint.anyword});
|
||||
}
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"}
|
||||
});
|
||||
</script>
|
||||
</article>
|
@ -1,74 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Bi-directional Text Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Bi-directional Text</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Bi-directional Text Demo</h2>
|
||||
<form><textarea id="code" name="code"><!-- Piece of the CodeMirror manual, 'translated' into Arabic by
|
||||
Google Translate -->
|
||||
|
||||
<dl>
|
||||
<dt id=option_value><code>value (string or Doc)</code></dt>
|
||||
<dd>قيمة البداية المحرر. يمكن أن تكون سلسلة، أو. كائن مستند.</dd>
|
||||
<dt id=option_mode><code>mode (string or object)</code></dt>
|
||||
<dd>وضع الاستخدام. عندما لا تعطى، وهذا الافتراضي إلى الطريقة الاولى
|
||||
التي تم تحميلها. قد يكون من سلسلة، والتي إما أسماء أو ببساطة هو وضع
|
||||
MIME نوع المرتبطة اسطة. بدلا من ذلك، قد يكون من كائن يحتوي على
|
||||
خيارات التكوين لواسطة، مع <code>name</code> الخاصية التي وضع أسماء
|
||||
(على سبيل المثال <code>{name: "javascript", json: true}</code>).
|
||||
صفحات التجريبي لكل وضع تحتوي على معلومات حول ما معلمات تكوين وضع
|
||||
يدعمها. يمكنك أن تطلب CodeMirror التي تم تعريفها طرق وأنواع MIME
|
||||
الكشف على <code>CodeMirror.modes</code>
|
||||
و <code>CodeMirror.mimeModes</code> الكائنات. وضع خرائط الأسماء
|
||||
الأولى لمنشئات الخاصة بهم، وخرائط لأنواع MIME 2 المواصفات
|
||||
واسطة.</dd>
|
||||
<dt id=option_theme><code>theme (string)</code></dt>
|
||||
<dd>موضوع لنمط المحرر مع. يجب عليك التأكد من الملف CSS تحديد
|
||||
المقابلة <code>.cm-s-[name]</code> يتم تحميل أنماط (انظر
|
||||
<a href="../theme/"><code>theme</code></a> الدليل في التوزيع).
|
||||
الافتراضي هو <code>"default"</code> ، والتي تم تضمينها في
|
||||
الألوان <code>codemirror.css</code>. فمن الممكن استخدام فئات متعددة
|
||||
في تطبيق السمات مرة واحدة على سبيل المثال <code>"foo bar"</code>
|
||||
سيتم تعيين كل من <code>cm-s-foo</code> و <code>cm-s-bar</code>
|
||||
الطبقات إلى المحرر.</dd>
|
||||
</dl>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "text/html",
|
||||
lineNumbers: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Demonstration of bi-directional text support. See
|
||||
the <a href="http://marijnhaverbeke.nl/blog/cursor-in-bidi-text.html">related
|
||||
blog post</a> for more background.</p>
|
||||
|
||||
<p><strong>Note:</strong> There is
|
||||
a <a href="https://github.com/codemirror/CodeMirror/issues/1757">known
|
||||
bug</a> with cursor motion and mouse clicks in bi-directional lines
|
||||
that are line wrapped.</p>
|
||||
|
||||
</article>
|
@ -1,85 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: B-Tree visualization</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<style type="text/css">
|
||||
.lineblock { display: inline-block; margin: 1px; height: 5px; }
|
||||
.CodeMirror {border: 1px solid #aaa; height: 400px}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">B-Tree visualization</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>B-Tree visualization</h2>
|
||||
<form><textarea id="code" name="code">type here, see a summary of the document b-tree below</textarea></form>
|
||||
</div>
|
||||
<div style="display: inline-block; height: 402px; overflow-y: auto" id="output"></div>
|
||||
</div>
|
||||
|
||||
<script id="me">
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
lineWrapping: true
|
||||
});
|
||||
var updateTimeout;
|
||||
editor.on("change", function(cm) {
|
||||
clearTimeout(updateTimeout);
|
||||
updateTimeout = setTimeout(updateVisual, 200);
|
||||
});
|
||||
updateVisual();
|
||||
|
||||
function updateVisual() {
|
||||
var out = document.getElementById("output");
|
||||
out.innerHTML = "";
|
||||
|
||||
function drawTree(out, node) {
|
||||
if (node.lines) {
|
||||
out.appendChild(document.createElement("div")).innerHTML =
|
||||
"<b>leaf</b>: " + node.lines.length + " lines, " + Math.round(node.height) + " px";
|
||||
var lines = out.appendChild(document.createElement("div"));
|
||||
lines.style.lineHeight = "6px"; lines.style.marginLeft = "10px";
|
||||
for (var i = 0; i < node.lines.length; ++i) {
|
||||
var line = node.lines[i], lineElt = lines.appendChild(document.createElement("div"));
|
||||
lineElt.className = "lineblock";
|
||||
var gray = Math.min(line.text.length * 3, 230), col = gray.toString(16);
|
||||
if (col.length == 1) col = "0" + col;
|
||||
lineElt.style.background = "#" + col + col + col;
|
||||
lineElt.style.width = Math.max(Math.round(line.height / 3), 1) + "px";
|
||||
}
|
||||
} else {
|
||||
out.appendChild(document.createElement("div")).innerHTML =
|
||||
"<b>node</b>: " + node.size + " lines, " + Math.round(node.height) + " px";
|
||||
var sub = out.appendChild(document.createElement("div"));
|
||||
sub.style.paddingLeft = "20px";
|
||||
for (var i = 0; i < node.children.length; ++i)
|
||||
drawTree(sub, node.children[i]);
|
||||
}
|
||||
}
|
||||
drawTree(out, editor.getDoc());
|
||||
}
|
||||
|
||||
function fillEditor() {
|
||||
var sc = document.getElementById("me");
|
||||
var doc = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "") + "\n";
|
||||
doc += doc; doc += doc; doc += doc; doc += doc; doc += doc; doc += doc;
|
||||
editor.setValue(doc);
|
||||
}
|
||||
</script>
|
||||
|
||||
<p><button onclick="fillEditor()">Add a lot of content</button></p>
|
||||
|
||||
</article>
|
@ -1,109 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Multiple Buffer & Split View Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../mode/css/css.js"></script>
|
||||
<style type="text/css" id=style>
|
||||
.CodeMirror {border: 1px solid black; height: 250px;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Multiple Buffer & Split View</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Multiple Buffer & Split View Demo</h2>
|
||||
|
||||
|
||||
<div id=code_top></div>
|
||||
<div>
|
||||
Select buffer: <select id=buffers_top></select>
|
||||
<button onclick="newBuf('top')">New buffer</button>
|
||||
</div>
|
||||
<div id=code_bot></div>
|
||||
<div>
|
||||
Select buffer: <select id=buffers_bot></select>
|
||||
<button onclick="newBuf('bot')">New buffer</button>
|
||||
</div>
|
||||
|
||||
<script id=script>
|
||||
var sel_top = document.getElementById("buffers_top");
|
||||
CodeMirror.on(sel_top, "change", function() {
|
||||
selectBuffer(ed_top, sel_top.options[sel_top.selectedIndex].value);
|
||||
});
|
||||
|
||||
var sel_bot = document.getElementById("buffers_bot");
|
||||
CodeMirror.on(sel_bot, "change", function() {
|
||||
selectBuffer(ed_bot, sel_bot.options[sel_bot.selectedIndex].value);
|
||||
});
|
||||
|
||||
var buffers = {};
|
||||
|
||||
function openBuffer(name, text, mode) {
|
||||
buffers[name] = CodeMirror.Doc(text, mode);
|
||||
var opt = document.createElement("option");
|
||||
opt.appendChild(document.createTextNode(name));
|
||||
sel_top.appendChild(opt);
|
||||
sel_bot.appendChild(opt.cloneNode(true));
|
||||
}
|
||||
|
||||
function newBuf(where) {
|
||||
var name = prompt("Name for the buffer", "*scratch*");
|
||||
if (name == null) return;
|
||||
if (buffers.hasOwnProperty(name)) {
|
||||
alert("There's already a buffer by that name.");
|
||||
return;
|
||||
}
|
||||
openBuffer(name, "", "javascript");
|
||||
selectBuffer(where == "top" ? ed_top : ed_bot, name);
|
||||
var sel = where == "top" ? sel_top : sel_bot;
|
||||
sel.value = name;
|
||||
}
|
||||
|
||||
function selectBuffer(editor, name) {
|
||||
var buf = buffers[name];
|
||||
if (buf.getEditor()) buf = buf.linkedDoc({sharedHist: true});
|
||||
var old = editor.swapDoc(buf);
|
||||
var linked = old.iterLinkedDocs(function(doc) {linked = doc;});
|
||||
if (linked) {
|
||||
// Make sure the document in buffers is the one the other view is looking at
|
||||
for (var name in buffers) if (buffers[name] == old) buffers[name] = linked;
|
||||
old.unlinkDoc(linked);
|
||||
}
|
||||
editor.focus();
|
||||
}
|
||||
|
||||
function nodeContent(id) {
|
||||
var node = document.getElementById(id), val = node.textContent || node.innerText;
|
||||
val = val.slice(val.match(/^\s*/)[0].length, val.length - val.match(/\s*$/)[0].length) + "\n";
|
||||
return val;
|
||||
}
|
||||
openBuffer("js", nodeContent("script"), "javascript");
|
||||
openBuffer("css", nodeContent("style"), "css");
|
||||
|
||||
var ed_top = CodeMirror(document.getElementById("code_top"), {lineNumbers: true});
|
||||
selectBuffer(ed_top, "js");
|
||||
var ed_bot = CodeMirror(document.getElementById("code_bot"), {lineNumbers: true});
|
||||
selectBuffer(ed_bot, "js");
|
||||
</script>
|
||||
|
||||
<p>Demonstration of
|
||||
using <a href="../doc/manual.html#linkedDoc">linked documents</a>
|
||||
to provide a split view on a document, and
|
||||
using <a href="../doc/manual.html#swapDoc"><code>swapDoc</code></a>
|
||||
to use a single editor to display multiple documents.</p>
|
||||
|
||||
</article>
|
@ -1,58 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Mode-Changing Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../mode/scheme/scheme.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid black;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Mode-Changing</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Mode-Changing Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
;; If there is Scheme code in here, the editor will be in Scheme mode.
|
||||
;; If you put in JS instead, it'll switch to JS mode.
|
||||
|
||||
(define (double x)
|
||||
(* x x))
|
||||
</textarea></form>
|
||||
|
||||
<p>On changes to the content of the above editor, a (crude) script
|
||||
tries to auto-detect the language used, and switches the editor to
|
||||
either JavaScript or Scheme mode based on that.</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "scheme",
|
||||
lineNumbers: true
|
||||
});
|
||||
var pending;
|
||||
editor.on("change", function() {
|
||||
clearTimeout(pending);
|
||||
pending = setTimeout(update, 400);
|
||||
});
|
||||
function looksLikeScheme(code) {
|
||||
return !/^\s*\(\s*function\b/.test(code) && /^\s*[;\(]/.test(code);
|
||||
}
|
||||
function update() {
|
||||
editor.setOption("mode", looksLikeScheme(editor.getValue()) ? "scheme" : "javascript");
|
||||
}
|
||||
</script>
|
||||
</article>
|
@ -1,52 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Closebrackets Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/edit/closebrackets.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Closebrackets</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Closebrackets Demo</h2>
|
||||
<form><textarea id="code" name="code">function Grid(width, height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.cells = new Array(width * height);
|
||||
}
|
||||
Grid.prototype.valueAt = function(point) {
|
||||
return this.cells[point.y * this.width + point.x];
|
||||
};
|
||||
Grid.prototype.setValueAt = function(point, value) {
|
||||
this.cells[point.y * this.width + point.x] = value;
|
||||
};
|
||||
Grid.prototype.isInside = function(point) {
|
||||
return point.x >= 0 && point.y >= 0 &&
|
||||
point.x < this.width && point.y < this.height;
|
||||
};
|
||||
Grid.prototype.moveValue = function(from, to) {
|
||||
this.setValueAt(to, this.valueAt(from));
|
||||
this.setValueAt(from, undefined);
|
||||
};</textarea></form>
|
||||
|
||||
<script type="text/javascript">
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {autoCloseBrackets: true});
|
||||
</script>
|
||||
</article>
|
@ -1,41 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Close-Tag Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/edit/closetag.js"></script>
|
||||
<script src="../addon/fold/xml-fold.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../mode/css/css.js"></script>
|
||||
<script src="../mode/htmlmixed/htmlmixed.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Close-Tag</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Close-Tag Demo</h2>
|
||||
<form><textarea id="code" name="code"><html</textarea></form>
|
||||
|
||||
<script type="text/javascript">
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: 'text/html',
|
||||
autoCloseTags: true
|
||||
});
|
||||
</script>
|
||||
</article>
|
@ -1,79 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Autocomplete Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/hint/show-hint.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/hint/show-hint.js"></script>
|
||||
<script src="../addon/hint/javascript-hint.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Autocomplete</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Autocomplete Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
function getCompletions(token, context) {
|
||||
var found = [], start = token.string;
|
||||
function maybeAdd(str) {
|
||||
if (str.indexOf(start) == 0) found.push(str);
|
||||
}
|
||||
function gatherCompletions(obj) {
|
||||
if (typeof obj == "string") forEach(stringProps, maybeAdd);
|
||||
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
|
||||
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
|
||||
for (var name in obj) maybeAdd(name);
|
||||
}
|
||||
|
||||
if (context) {
|
||||
// If this is a property, see if it belongs to some object we can
|
||||
// find in the current environment.
|
||||
var obj = context.pop(), base;
|
||||
if (obj.className == "js-variable")
|
||||
base = window[obj.string];
|
||||
else if (obj.className == "js-string")
|
||||
base = "";
|
||||
else if (obj.className == "js-atom")
|
||||
base = 1;
|
||||
while (base != null && context.length)
|
||||
base = base[context.pop().string];
|
||||
if (base != null) gatherCompletions(base);
|
||||
}
|
||||
else {
|
||||
// If not, just look in the window object and any local scope
|
||||
// (reading into JS mode internals to get at the local variables)
|
||||
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
|
||||
gatherCompletions(window);
|
||||
forEach(keywords, maybeAdd);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
</textarea></form>
|
||||
|
||||
<p>Press <strong>ctrl-space</strong> to activate autocompletion. Built
|
||||
on top of the <a href="../doc/manual.html#addon_show-hint"><code>show-hint</code></a>
|
||||
and <a href="../doc/manual.html#addon_javascript-hint"><code>javascript-hint</code></a>
|
||||
addons.</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"},
|
||||
mode: {name: "javascript", globalVars: true}
|
||||
});
|
||||
</script>
|
||||
</article>
|
@ -1,75 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Emacs bindings demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/dialog/dialog.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/clike/clike.js"></script>
|
||||
<script src="../keymap/emacs.js"></script>
|
||||
<script src="../addon/edit/matchbrackets.js"></script>
|
||||
<script src="../addon/comment/comment.js"></script>
|
||||
<script src="../addon/dialog/dialog.js"></script>
|
||||
<script src="../addon/search/searchcursor.js"></script>
|
||||
<script src="../addon/search/search.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Emacs bindings</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Emacs bindings demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
#include "syscalls.h"
|
||||
/* getchar: simple buffered version */
|
||||
int getchar(void)
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
static char *bufp = buf;
|
||||
static int n = 0;
|
||||
if (n == 0) { /* buffer is empty */
|
||||
n = read(0, buf, sizeof buf);
|
||||
bufp = buf;
|
||||
}
|
||||
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
|
||||
}
|
||||
</textarea></form>
|
||||
|
||||
<p>The emacs keybindings are enabled by
|
||||
including <a href="../keymap/emacs.js">keymap/emacs.js</a> and setting
|
||||
the <code>keyMap</code> option to <code>"emacs"</code>. Because
|
||||
CodeMirror's internal API is quite different from Emacs, they are only
|
||||
a loose approximation of actual emacs bindings, though.</p>
|
||||
|
||||
<p>Also note that a lot of browsers disallow certain keys from being
|
||||
captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the
|
||||
result that idiomatic use of Emacs keys will constantly close your tab
|
||||
or open a new window.</p>
|
||||
|
||||
<script>
|
||||
CodeMirror.commands.save = function() {
|
||||
var elt = editor.getWrapperElement();
|
||||
elt.style.background = "#def";
|
||||
setTimeout(function() { elt.style.background = ""; }, 300);
|
||||
};
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "text/x-csrc",
|
||||
keyMap: "emacs"
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,95 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<head>
|
||||
<title>CodeMirror: Code Folding Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/fold/foldgutter.css" />
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/fold/foldcode.js"></script>
|
||||
<script src="../addon/fold/foldgutter.js"></script>
|
||||
<script src="../addon/fold/brace-fold.js"></script>
|
||||
<script src="../addon/fold/xml-fold.js"></script>
|
||||
<script src="../addon/fold/markdown-fold.js"></script>
|
||||
<script src="../addon/fold/comment-fold.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="../mode/markdown/markdown.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Code Folding</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Code Folding Demo</h2>
|
||||
<form>
|
||||
<div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br>
|
||||
<textarea id="code" name="code"></textarea></div>
|
||||
<div style="max-width: 50em; margin-bottom: 1em">HTML:<br>
|
||||
<textarea id="code-html" name="code-html"></textarea></div>
|
||||
<div style="max-width: 50em">Markdown:<br>
|
||||
<textarea id="code-markdown" name="code"></textarea></div>
|
||||
</form>
|
||||
<script id="script">
|
||||
/*
|
||||
* Demonstration of code folding
|
||||
*/
|
||||
window.onload = function() {
|
||||
var te = document.getElementById("code");
|
||||
var sc = document.getElementById("script");
|
||||
te.value = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "");
|
||||
sc.innerHTML = "";
|
||||
var te_html = document.getElementById("code-html");
|
||||
te_html.value = document.documentElement.innerHTML;
|
||||
var te_markdown = document.getElementById("code-markdown");
|
||||
te_markdown.value = "# Foo\n## Bar\n\nblah blah\n\n## Baz\n\nblah blah\n\n# Quux\n\nblah blah\n"
|
||||
|
||||
window.editor = CodeMirror.fromTextArea(te, {
|
||||
mode: "javascript",
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
|
||||
});
|
||||
editor.foldCode(CodeMirror.Pos(13, 0));
|
||||
|
||||
window.editor_html = CodeMirror.fromTextArea(te_html, {
|
||||
mode: "text/html",
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
|
||||
});
|
||||
editor_html.foldCode(CodeMirror.Pos(0, 0));
|
||||
editor_html.foldCode(CodeMirror.Pos(21, 0));
|
||||
|
||||
window.editor_markdown = CodeMirror.fromTextArea(te_markdown, {
|
||||
mode: "markdown",
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</article>
|
||||
</body>
|
@ -1,83 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Full Screen Editing</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/display/fullscreen.css">
|
||||
<link rel="stylesheet" href="../theme/night.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="../addon/display/fullscreen.js"></script>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Full Screen Editing</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Full Screen Editing</h2>
|
||||
<form><textarea id="code" name="code" rows="5">
|
||||
<dl>
|
||||
<dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt>
|
||||
<dd>Whether, when indenting, the first N*<code>tabSize</code>
|
||||
spaces should be replaced by N tabs. Default is false.</dd>
|
||||
|
||||
<dt id="option_electricChars"><code><strong>electricChars</strong>: boolean</code></dt>
|
||||
<dd>Configures whether the editor should re-indent the current
|
||||
line when a character is typed that might change its proper
|
||||
indentation (only works if the mode supports indentation).
|
||||
Default is true.</dd>
|
||||
|
||||
<dt id="option_specialChars"><code><strong>specialChars</strong>: RegExp</code></dt>
|
||||
<dd>A regular expression used to determine which characters
|
||||
should be replaced by a
|
||||
special <a href="#option_specialCharPlaceholder">placeholder</a>.
|
||||
Mostly useful for non-printing special characters. The default
|
||||
is <code>/[\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/</code>.</dd>
|
||||
<dt id="option_specialCharPlaceholder"><code><strong>specialCharPlaceholder</strong>: function(char) → Element</code></dt>
|
||||
<dd>A function that, given a special character identified by
|
||||
the <a href="#option_specialChars"><code>specialChars</code></a>
|
||||
option, produces a DOM node that is used to represent the
|
||||
character. By default, a red dot (<span style="color: red">•</span>)
|
||||
is shown, with a title tooltip to indicate the character code.</dd>
|
||||
|
||||
<dt id="option_rtlMoveVisually"><code><strong>rtlMoveVisually</strong>: boolean</code></dt>
|
||||
<dd>Determines whether horizontal cursor movement through
|
||||
right-to-left (Arabic, Hebrew) text is visual (pressing the left
|
||||
arrow moves the cursor left) or logical (pressing the left arrow
|
||||
moves to the next lower index in the string, which is visually
|
||||
right in right-to-left text). The default is <code>false</code>
|
||||
on Windows, and <code>true</code> on other platforms.</dd>
|
||||
</dl>
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
theme: "night",
|
||||
extraKeys: {
|
||||
"F11": function(cm) {
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
"Esc": function(cm) {
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Demonstration of
|
||||
the <a href="../doc/manual.html#addon_fullscreen">fullscreen</a>
|
||||
addon. Press <strong>F11</strong> when cursor is in the editor to
|
||||
toggle full screen editing. <strong>Esc</strong> can also be used
|
||||
to <i>exit</i> full screen editing.</p>
|
||||
</article>
|
@ -1,72 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Hard-wrapping Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/markdown/markdown.js"></script>
|
||||
<script src="../addon/wrap/hardwrap.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Hard-wrapping</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Hard-wrapping Demo</h2>
|
||||
<form><textarea id="code" name="code">Lorem ipsum dolor sit amet, vim augue dictas constituto ex,
|
||||
sit falli simul viderer te. Graeco scaevola maluisset sit
|
||||
ut, in idque viris praesent sea. Ea sea eirmod indoctum
|
||||
repudiare. Vel noluisse suscipit pericula ut. In ius nulla
|
||||
alienum molestie. Mei essent discere democritum id.
|
||||
|
||||
Equidem ponderum expetendis ius in, mea an erroribus
|
||||
constituto, congue timeam perfecto ad est. Ius ut primis
|
||||
timeam, per in ullum mediocrem. An case vero labitur pri,
|
||||
vel dicit laoreet et. An qui prompta conclusionemque, eam
|
||||
timeam sapientem in, cum dictas epicurei eu.
|
||||
|
||||
Usu cu vide dictas deseruisse, eum choro graece adipiscing
|
||||
ut. Cibo qualisque ius ad, et dicat scripta mea, eam nihil
|
||||
mentitum aliquando cu. Debet aperiam splendide at quo, ad
|
||||
paulo nostro commodo duo. Sea adhuc utinam conclusionemque
|
||||
id, quas doming malorum nec ad. Tollit eruditi vivendum ad
|
||||
ius, eos soleat ignota ad.
|
||||
</textarea></form>
|
||||
|
||||
<p>Demonstration of
|
||||
the <a href="../doc/manual.html#addon_hardwrap">hardwrap</a> addon.
|
||||
The above editor has its change event hooked up to
|
||||
the <code>wrapParagraphsInRange</code> method, so that the paragraphs
|
||||
are reflown as you are typing.</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "markdown",
|
||||
lineNumbers: true,
|
||||
extraKeys: {
|
||||
"Ctrl-Q": function(cm) { cm.wrapParagraph(cm.getCursor(), options); }
|
||||
}
|
||||
});
|
||||
var wait, options = {column: 60};
|
||||
editor.on("change", function(cm, change) {
|
||||
clearTimeout(wait);
|
||||
wait = setTimeout(function() {
|
||||
console.log(cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options));
|
||||
}, 200);
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,56 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<head>
|
||||
<title>CodeMirror: HTML completion demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/hint/show-hint.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/hint/show-hint.js"></script>
|
||||
<script src="../addon/hint/xml-hint.js"></script>
|
||||
<script src="../addon/hint/html-hint.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../mode/css/css.js"></script>
|
||||
<script src="../mode/htmlmixed/htmlmixed.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">HTML completion</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>HTML completion demo</h2>
|
||||
|
||||
<p>Shows the <a href="xmlcomplete.html">XML completer</a>
|
||||
parameterized with information about the tags in HTML.
|
||||
Press <strong>ctrl-space</strong> to activate completion.</p>
|
||||
|
||||
<div id="code"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
editor = CodeMirror(document.getElementById("code"), {
|
||||
mode: "text/html",
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"},
|
||||
value: document.documentElement.innerHTML
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</article>
|
||||
</body>
|
@ -1,59 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Indented wrapped line demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
.CodeMirror pre > * { text-indent: 0px; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Indented wrapped line</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Indented wrapped line demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<!doctype html>
|
||||
<body>
|
||||
<h2 id="overview">Overview</h2>
|
||||
|
||||
<p>CodeMirror is a code-editor component that can be embedded in Web pages. The core library provides <em>only</em> the editor component, no accompanying buttons, auto-completion, or other IDE functionality. It does provide a rich API on top of which such functionality can be straightforwardly implemented. See the <a href="#addons">add-ons</a> included in the distribution, and the <a href="https://github.com/jagthedrummer/codemirror-ui">CodeMirror UI</a> project, for reusable implementations of extra features.</p>
|
||||
|
||||
<p>CodeMirror works with language-specific modes. Modes are JavaScript programs that help color (and optionally indent) text written in a given language. The distribution comes with a number of modes (see the <a href="../mode/"><code>mode/</code></a> directory), and it isn't hard to <a href="#modeapi">write new ones</a> for other languages.</p>
|
||||
</body>
|
||||
</textarea></form>
|
||||
|
||||
<p>This page uses a hack on top of the <code>"renderLine"</code>
|
||||
event to make wrapped text line up with the base indentation of
|
||||
the line.</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
mode: "text/html"
|
||||
});
|
||||
var charWidth = editor.defaultCharWidth(), basePadding = 4;
|
||||
editor.on("renderLine", function(cm, line, elt) {
|
||||
var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth;
|
||||
elt.style.textIndent = "-" + off + "px";
|
||||
elt.style.paddingLeft = (basePadding + off) + "px";
|
||||
});
|
||||
editor.refresh();
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,171 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Linter Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/lint/lint.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../mode/css/css.js"></script>
|
||||
<script src="//ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script>
|
||||
<script src="https://rawgithub.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script>
|
||||
<script src="https://rawgithub.com/stubbornella/csslint/master/release/csslint.js"></script>
|
||||
<script src="../addon/lint/lint.js"></script>
|
||||
<script src="../addon/lint/javascript-lint.js"></script>
|
||||
<script src="../addon/lint/json-lint.js"></script>
|
||||
<script src="../addon/lint/css-lint.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid black;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Linter</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Linter Demo</h2>
|
||||
|
||||
|
||||
<p><textarea id="code-js">var widgets = []
|
||||
function updateHints() {
|
||||
editor.operation(function(){
|
||||
for (var i = 0; i < widgets.length; ++i)
|
||||
editor.removeLineWidget(widgets[i]);
|
||||
widgets.length = 0;
|
||||
|
||||
JSHINT(editor.getValue());
|
||||
for (var i = 0; i < JSHINT.errors.length; ++i) {
|
||||
var err = JSHINT.errors[i];
|
||||
if (!err) continue;
|
||||
var msg = document.createElement("div");
|
||||
var icon = msg.appendChild(document.createElement("span"));
|
||||
icon.innerHTML = "!!";
|
||||
icon.className = "lint-error-icon";
|
||||
msg.appendChild(document.createTextNode(err.reason));
|
||||
msg.className = "lint-error";
|
||||
widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true}));
|
||||
}
|
||||
});
|
||||
var info = editor.getScrollInfo();
|
||||
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
|
||||
if (info.top + info.clientHeight < after)
|
||||
editor.scrollTo(null, after - info.clientHeight + 3);
|
||||
}
|
||||
</textarea></p>
|
||||
|
||||
<p><textarea id="code-json">[
|
||||
{
|
||||
_id: "post 1",
|
||||
"author": "Bob",
|
||||
"content": "...",
|
||||
"page_views": 5
|
||||
},
|
||||
{
|
||||
"_id": "post 2",
|
||||
"author": "Bob",
|
||||
"content": "...",
|
||||
"page_views": 9
|
||||
},
|
||||
{
|
||||
"_id": "post 3",
|
||||
"author": "Bob",
|
||||
"content": "...",
|
||||
"page_views": 8
|
||||
}
|
||||
]
|
||||
</textarea></p>
|
||||
|
||||
<p><textarea id="code-css">@charset "UTF-8";
|
||||
|
||||
@import url("booya.css") print, screen;
|
||||
@import "whatup.css" screen;
|
||||
@import "wicked.css";
|
||||
|
||||
/*Error*/
|
||||
@charset "UTF-8";
|
||||
|
||||
|
||||
@namespace "http://www.w3.org/1999/xhtml";
|
||||
@namespace svg "http://www.w3.org/2000/svg";
|
||||
|
||||
/*Warning: empty ruleset */
|
||||
.foo {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*Warning: qualified heading */
|
||||
.foo h1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*Warning: adjoining classes */
|
||||
.foo.bar {
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
li.inline {
|
||||
width: 100%; /*Warning: 100% can be problematic*/
|
||||
}
|
||||
|
||||
li.last {
|
||||
display: inline;
|
||||
padding-left: 3px !important;
|
||||
padding-right: 3px;
|
||||
border-right: 0px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
li.inline {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
@page {
|
||||
margin: 10%;
|
||||
counter-increment: page;
|
||||
|
||||
@top-center {
|
||||
font-family: sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
content: counter(page);
|
||||
}
|
||||
}
|
||||
</textarea></p>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code-js"), {
|
||||
lineNumbers: true,
|
||||
mode: "javascript",
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
lint: true
|
||||
});
|
||||
|
||||
var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), {
|
||||
lineNumbers: true,
|
||||
mode: "application/json",
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
lint: true
|
||||
});
|
||||
|
||||
var editor_css = CodeMirror.fromTextArea(document.getElementById("code-css"), {
|
||||
lineNumbers: true,
|
||||
mode: "css",
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
lint: true
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,72 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Lazy Mode Loading Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/mode/loadmode.js"></script>
|
||||
<script src="../mode/meta.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Lazy Mode Loading</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Lazy Mode Loading Demo</h2>
|
||||
<p style="color: gray">Current mode: <span id="modeinfo">text/plain</span></p>
|
||||
<form><textarea id="code" name="code">This is the editor.
|
||||
// It starts out in plain text mode,
|
||||
# use the control below to load and apply a mode
|
||||
"you'll see the highlighting of" this text /*change*/.
|
||||
</textarea></form>
|
||||
<p>Filename, mime, or mode name: <input type=text value=foo.js id=mode> <button type=button onclick="change()">change mode</button></p>
|
||||
|
||||
<script>
|
||||
CodeMirror.modeURL = "../mode/%N/%N.js";
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true
|
||||
});
|
||||
var modeInput = document.getElementById("mode");
|
||||
CodeMirror.on(modeInput, "keypress", function(e) {
|
||||
if (e.keyCode == 13) change();
|
||||
});
|
||||
function change() {
|
||||
var val = modeInput.value, m, mode, spec;
|
||||
if (m = /.+\.([^.]+)$/.exec(val)) {
|
||||
var info = CodeMirror.findModeByExtension(m[1]);
|
||||
if (info) {
|
||||
mode = info.mode;
|
||||
spec = info.mime;
|
||||
}
|
||||
} else if (/\//.test(val)) {
|
||||
var info = CodeMirror.findModeByMIME(val);
|
||||
if (info) {
|
||||
mode = info.mode;
|
||||
spec = val;
|
||||
}
|
||||
} else {
|
||||
mode = spec = val;
|
||||
}
|
||||
if (mode) {
|
||||
editor.setOption("mode", spec);
|
||||
CodeMirror.autoLoadMode(editor, mode);
|
||||
document.getElementById("modeinfo").textContent = spec;
|
||||
} else {
|
||||
alert("Could not find a mode corresponding to " + val);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</article>
|
@ -1,52 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Breakpoint Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<style type="text/css">
|
||||
.breakpoints {width: .8em;}
|
||||
.breakpoint { color: #822; }
|
||||
.CodeMirror {border: 1px solid #aaa;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Breakpoint</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Breakpoint Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
gutters: ["CodeMirror-linenumbers", "breakpoints"]
|
||||
});
|
||||
editor.on("gutterClick", function(cm, n) {
|
||||
var info = cm.lineInfo(n);
|
||||
cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker());
|
||||
});
|
||||
|
||||
function makeMarker() {
|
||||
var marker = document.createElement("div");
|
||||
marker.style.color = "#822";
|
||||
marker.innerHTML = "●";
|
||||
return marker;
|
||||
}
|
||||
</textarea></form>
|
||||
|
||||
<p>Click the line-number gutter to add or remove 'breakpoints'.</p>
|
||||
|
||||
<script>eval(document.getElementById("code").value);</script>
|
||||
|
||||
</article>
|
@ -1,52 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Selection Marking Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/search/searchcursor.js"></script>
|
||||
<script src="../addon/selection/mark-selection.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
.CodeMirror-selected { background-color: blue !important; }
|
||||
.CodeMirror-selectedtext { color: white; }
|
||||
.styled-background { background-color: #ff7; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Selection Marking</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Selection Marking Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
Select something from here. You'll see that the selection's foreground
|
||||
color changes to white! Since, by default, CodeMirror only puts an
|
||||
independent "marker" layer behind the text, you'll need something like
|
||||
this to change its colour.
|
||||
|
||||
Also notice that turning this addon on (with the default style) allows
|
||||
you to safely give text a background color without screwing up the
|
||||
visibility of the selection.</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
styleSelectedText: true
|
||||
});
|
||||
editor.markText({line: 6, ch: 26}, {line: 6, ch: 42}, {className: "styled-background"});
|
||||
</script>
|
||||
|
||||
<p>Simple addon to easily mark (and style) selected text. <a href="../doc/manual.html#addon_mark-selection">Docs</a>.</p>
|
||||
|
||||
</article>
|
@ -1,47 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Match Highlighter Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/search/searchcursor.js"></script>
|
||||
<script src="../addon/search/match-highlighter.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
.CodeMirror-focused .cm-matchhighlight {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Match Highlighter</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Match Highlighter Demo</h2>
|
||||
<form><textarea id="code" name="code">Select this text: hardToSpotVar
|
||||
And everywhere else in your code where hardToSpotVar appears will automatically illuminate.
|
||||
Give it a try! No more hardToSpotVars.</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
highlightSelectionMatches: {showToken: /\w/}
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Search and highlight occurences of the selected text.</p>
|
||||
|
||||
</article>
|
@ -1,48 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Tag Matcher Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/fold/xml-fold.js"></script>
|
||||
<script src="../addon/edit/matchtags.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Tag Matcher</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Tag Matcher Demo</h2>
|
||||
|
||||
|
||||
<div id="editor"></div>
|
||||
|
||||
<script>
|
||||
window.onload = function() {
|
||||
editor = CodeMirror(document.getElementById("editor"), {
|
||||
value: "<html>\n " + document.documentElement.innerHTML + "\n</html>",
|
||||
mode: "text/html",
|
||||
matchTags: {bothTags: true},
|
||||
extraKeys: {"Ctrl-J": "toMatchingTag"}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<p>Put the cursor on or inside a pair of tags to highlight them.
|
||||
Press Ctrl-J to jump to the tag that matches the one under the
|
||||
cursor.</p>
|
||||
</article>
|
@ -1,107 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: merge view demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel=stylesheet href="../lib/codemirror.css">
|
||||
<link rel=stylesheet href="../addon/merge/merge.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js"></script>
|
||||
<script src="../addon/merge/merge.js"></script>
|
||||
<style>
|
||||
.CodeMirror { line-height: 1.2; }
|
||||
span.clicky {
|
||||
cursor: pointer;
|
||||
background: #d70;
|
||||
color: white;
|
||||
padding: 0 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">merge view</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>merge view demo</h2>
|
||||
|
||||
|
||||
<div id=view></div>
|
||||
|
||||
<p>The <a href="../doc/manual.html#addon_merge"><code>merge</code></a>
|
||||
addon provides an interface for displaying and merging diffs,
|
||||
either <span class=clicky onclick="initUI(2)">two-way</span>
|
||||
or <span class=clicky onclick="initUI(3)">three-way</span>. The left
|
||||
(or center) pane is editable, and the differences with the other
|
||||
pane(s) are <span class=clicky onclick="toggleDifferences()">optionally</span> shown live as you edit it.</p>
|
||||
|
||||
<p>This addon depends on
|
||||
the <a href="https://code.google.com/p/google-diff-match-patch/">google-diff-match-patch</a>
|
||||
library to compute the diffs.</p>
|
||||
|
||||
<script>
|
||||
var value, orig1, orig2, dv, hilight= true;
|
||||
function initUI(panes) {
|
||||
if (value == null) return;
|
||||
var target = document.getElementById("view");
|
||||
target.innerHTML = "";
|
||||
dv = CodeMirror.MergeView(target, {
|
||||
value: value,
|
||||
origLeft: panes == 3 ? orig1 : null,
|
||||
orig: orig2,
|
||||
lineNumbers: true,
|
||||
mode: "text/html",
|
||||
highlightDifferences: hilight
|
||||
});
|
||||
}
|
||||
|
||||
function toggleDifferences() {
|
||||
dv.setShowDifferences(hilight = !hilight);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
value = document.documentElement.innerHTML;
|
||||
orig1 = value.replace(/\.\.\//g, "codemirror/").replace("yellow", "orange");
|
||||
orig2 = value.replace(/\u003cscript/g, "\u003cscript type=text/javascript ")
|
||||
.replace("white", "purple;\n font: comic sans;\n text-decoration: underline;\n height: 15em");
|
||||
initUI(2);
|
||||
};
|
||||
|
||||
function mergeViewHeight(mergeView) {
|
||||
function editorHeight(editor) {
|
||||
if (!editor) return 0;
|
||||
return editor.getScrollInfo().height;
|
||||
}
|
||||
return Math.max(editorHeight(mergeView.leftOriginal()),
|
||||
editorHeight(mergeView.editor()),
|
||||
editorHeight(mergeView.rightOriginal()));
|
||||
}
|
||||
|
||||
function resize(mergeView) {
|
||||
var height = mergeViewHeight(mergeView);
|
||||
for(;;) {
|
||||
if (mergeView.leftOriginal())
|
||||
mergeView.leftOriginal().setSize(null, height);
|
||||
mergeView.editor().setSize(null, height);
|
||||
if (mergeView.rightOriginal())
|
||||
mergeView.rightOriginal().setSize(null, height);
|
||||
|
||||
var newHeight = mergeViewHeight(mergeView);
|
||||
if (newHeight >= height) break;
|
||||
else height = newHeight;
|
||||
}
|
||||
mergeView.wrap.style.height = height + "px";
|
||||
}
|
||||
</script>
|
||||
</article>
|
@ -1,75 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Multiplexing Parser Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/mode/multiplex.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid black;}
|
||||
.cm-delimit {color: #fa4;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Multiplexing Parser</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Multiplexing Parser Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<html>
|
||||
<body style="<<magic>>">
|
||||
<h1><< this is not <html >></h1>
|
||||
<<
|
||||
multiline
|
||||
not html
|
||||
at all : &amp; <link/>
|
||||
>>
|
||||
<p>this is html again</p>
|
||||
</body>
|
||||
</html>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
CodeMirror.defineMode("demo", function(config) {
|
||||
return CodeMirror.multiplexingMode(
|
||||
CodeMirror.getMode(config, "text/html"),
|
||||
{open: "<<", close: ">>",
|
||||
mode: CodeMirror.getMode(config, "text/plain"),
|
||||
delimStyle: "delimit"}
|
||||
// .. more multiplexed styles can follow here
|
||||
);
|
||||
});
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "demo",
|
||||
lineNumbers: true,
|
||||
lineWrapping: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Demonstration of a multiplexing mode, which, at certain
|
||||
boundary strings, switches to one or more inner modes. The out
|
||||
(HTML) mode does not get fed the content of the <code><<
|
||||
>></code> blocks. See
|
||||
the <a href="../doc/manual.html#addon_multiplex">manual</a> and
|
||||
the <a href="../addon/mode/multiplex.js">source</a> for more
|
||||
information.</p>
|
||||
|
||||
<p>
|
||||
<strong>Parsing/Highlighting Tests:</strong>
|
||||
<a href="../test/index.html#multiplexing_*">normal</a>,
|
||||
<a href="../test/index.html#verbose,multiplexing_*">verbose</a>.
|
||||
</p>
|
||||
|
||||
</article>
|
@ -1,69 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Overlay Parser Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/mode/overlay.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid black;}
|
||||
.cm-mustache {color: #0ca;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Overlay Parser</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Overlay Parser Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<html>
|
||||
<body>
|
||||
<h1>{{title}}</h1>
|
||||
<p>These are links to {{things}}:</p>
|
||||
<ul>{{#links}}
|
||||
<li><a href="{{url}}">{{text}}</a></li>
|
||||
{{/links}}</ul>
|
||||
</body>
|
||||
</html>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
CodeMirror.defineMode("mustache", function(config, parserConfig) {
|
||||
var mustacheOverlay = {
|
||||
token: function(stream, state) {
|
||||
var ch;
|
||||
if (stream.match("{{")) {
|
||||
while ((ch = stream.next()) != null)
|
||||
if (ch == "}" && stream.next() == "}") {
|
||||
stream.eat("}");
|
||||
return "mustache";
|
||||
}
|
||||
}
|
||||
while (stream.next() != null && !stream.match("{{", false)) {}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
|
||||
});
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "mustache"});
|
||||
</script>
|
||||
|
||||
<p>Demonstration of a mode that parses HTML, highlighting
|
||||
the <a href="http://mustache.github.com/">Mustache</a> templating
|
||||
directives inside of it by using the code
|
||||
in <a href="../addon/mode/overlay.js"><code>overlay.js</code></a>. View
|
||||
source to see the 15 lines of code needed to accomplish this.</p>
|
||||
|
||||
</article>
|
@ -1,45 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Placeholder demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/display/placeholder.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror { border: 1px solid silver; }
|
||||
.CodeMirror-empty { outline: 1px solid #c22; }
|
||||
.CodeMirror-empty.CodeMirror-focused { outline: none; }
|
||||
.CodeMirror pre.CodeMirror-placeholder { color: #999; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Placeholder</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Placeholder demo</h2>
|
||||
<form><textarea id="code" name="code" placeholder="Code goes here..."></textarea></form>
|
||||
|
||||
<p>The <a href="../doc/manual.html#addon_placeholder">placeholder</a>
|
||||
plug-in adds an option <code>placeholder</code> that can be set to
|
||||
make text appear in the editor when it is empty and not focused.
|
||||
If the source textarea has a <code>placeholder</code> attribute,
|
||||
it will automatically be inherited.</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,87 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: HTML5 preview</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel=stylesheet href=../lib/codemirror.css>
|
||||
<script src=../lib/codemirror.js></script>
|
||||
<script src=../mode/xml/xml.js></script>
|
||||
<script src=../mode/javascript/javascript.js></script>
|
||||
<script src=../mode/css/css.js></script>
|
||||
<script src=../mode/htmlmixed/htmlmixed.js></script>
|
||||
<style type=text/css>
|
||||
.CodeMirror {
|
||||
float: left;
|
||||
width: 50%;
|
||||
border: 1px solid black;
|
||||
}
|
||||
iframe {
|
||||
width: 49%;
|
||||
float: left;
|
||||
height: 300px;
|
||||
border: 1px solid black;
|
||||
border-left: 0px;
|
||||
}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">HTML5 preview</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>HTML5 preview</h2>
|
||||
|
||||
<textarea id=code name=code>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<title>HTML5 canvas demo</title>
|
||||
<style>p {font-family: monospace;}</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>Canvas pane goes here:</p>
|
||||
<canvas id=pane width=300 height=200></canvas>
|
||||
<script>
|
||||
var canvas = document.getElementById('pane');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
context.fillStyle = 'rgb(250,0,0)';
|
||||
context.fillRect(10, 10, 55, 50);
|
||||
|
||||
context.fillStyle = 'rgba(0, 0, 250, 0.5)';
|
||||
context.fillRect(30, 30, 55, 50);
|
||||
</script>
|
||||
</body>
|
||||
</html></textarea>
|
||||
<iframe id=preview></iframe>
|
||||
<script>
|
||||
var delay;
|
||||
// Initialize CodeMirror editor with a nice html5 canvas demo.
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
|
||||
mode: 'text/html'
|
||||
});
|
||||
editor.on("change", function() {
|
||||
clearTimeout(delay);
|
||||
delay = setTimeout(updatePreview, 300);
|
||||
});
|
||||
|
||||
function updatePreview() {
|
||||
var previewFrame = document.getElementById('preview');
|
||||
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
|
||||
preview.open();
|
||||
preview.write(editor.getValue());
|
||||
preview.close();
|
||||
}
|
||||
setTimeout(updatePreview, 300);
|
||||
</script>
|
||||
</article>
|
@ -1,52 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<head>
|
||||
<title>CodeMirror: HTML completion demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/hint/show-hint.css">
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.min.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">HTML completion</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>RequireJS module loading demo</h2>
|
||||
|
||||
<p>This demo does the same thing as
|
||||
the <a href="html5complete.html">HTML5 completion demo</a>, but
|
||||
loads its dependencies
|
||||
with <a href="http://requirejs.org/">Require.js</a>, rather than
|
||||
explicitly. Press <strong>ctrl-space</strong> to activate
|
||||
completion.</p>
|
||||
|
||||
<div id="code"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
require(["../lib/codemirror", "../mode/htmlmixed/htmlmixed",
|
||||
"../addon/hint/show-hint", "../addon/hint/html-hint"], function(CodeMirror) {
|
||||
editor = CodeMirror(document.getElementById("code"), {
|
||||
mode: "text/html",
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"},
|
||||
value: document.documentElement.innerHTML
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</article>
|
||||
</body>
|
@ -1,58 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Autoresize Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/css/css.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {
|
||||
border: 1px solid #eee;
|
||||
height: auto;
|
||||
}
|
||||
.CodeMirror-scroll {
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Autoresize</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Autoresize Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
.CodeMirror {
|
||||
border: 1px solid #eee;
|
||||
height: auto;
|
||||
}
|
||||
.CodeMirror-scroll {
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</textarea></form>
|
||||
|
||||
<p>By setting a few CSS properties, and giving
|
||||
the <a href="../doc/manual.html#option_viewportMargin"><code>viewportMargin</code></a>
|
||||
a value of <code>Infinity</code>, CodeMirror can be made to
|
||||
automatically resize to fit its content.</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
viewportMargin: Infinity
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,49 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Ruler Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/display/rulers.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Ruler demo</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Ruler Demo</h2>
|
||||
|
||||
<script type="text/javascript">
|
||||
var nums = "0123456789", space = " ";
|
||||
var colors = ["#fcc", "#f5f577", "#cfc", "#aff", "#ccf", "#fcf"];
|
||||
var rulers = [], value = "";
|
||||
for (var i = 1; i <= 6; i++) {
|
||||
rulers.push({color: colors[i], column: i * 10, lineStyle: "dashed"});
|
||||
for (var j = 1; j < i; j++) value += space;
|
||||
value += nums + "\n";
|
||||
}
|
||||
var editor = CodeMirror(document.body.lastChild, {
|
||||
rulers: rulers,
|
||||
value: value + value + value,
|
||||
lineNumbers: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Demonstration of
|
||||
the <a href="../doc/manual.html#addon_rulers">rulers</a> addon, which
|
||||
displays vertical lines at given column offsets.</p>
|
||||
|
||||
</article>
|
@ -1,62 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Mode Runner Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/runmode/runmode.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Mode Runner</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Mode Runner Demo</h2>
|
||||
|
||||
|
||||
<textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;">
|
||||
<foobar>
|
||||
<blah>Enter your xml here and press the button below to display
|
||||
it as highlighted by the CodeMirror XML mode</blah>
|
||||
<tag2 foo="2" bar="&quot;bar&quot;"/>
|
||||
</foobar></textarea><br>
|
||||
<button onclick="doHighlight();">Highlight!</button>
|
||||
<pre id="output" class="cm-s-default"></pre>
|
||||
|
||||
<script>
|
||||
function doHighlight() {
|
||||
CodeMirror.runMode(document.getElementById("code").value, "application/xml",
|
||||
document.getElementById("output"));
|
||||
}
|
||||
</script>
|
||||
|
||||
<p>Running a CodeMirror mode outside of the editor.
|
||||
The <code>CodeMirror.runMode</code> function, defined
|
||||
in <code><a href="../addon/runmode/runmode.js">lib/runmode.js</a></code> takes the following arguments:</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>text (string)</code></dt>
|
||||
<dd>The document to run through the highlighter.</dd>
|
||||
<dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt>
|
||||
<dd>The mode to use (must be loaded as normal).</dd>
|
||||
<dt><code>output (function or DOM node)</code></dt>
|
||||
<dd>If this is a function, it will be called for each token with
|
||||
two arguments, the token's text and the token's style class (may
|
||||
be <code>null</code> for unstyled tokens). If it is a DOM node,
|
||||
the tokens will be converted to <code>span</code> elements as in
|
||||
an editor, and inserted into the node
|
||||
(through <code>innerHTML</code>).</dd>
|
||||
</dl>
|
||||
|
||||
</article>
|
@ -1,87 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Search/Replace Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/dialog/dialog.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="../addon/dialog/dialog.js"></script>
|
||||
<script src="../addon/search/searchcursor.js"></script>
|
||||
<script src="../addon/search/search.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
dt {font-family: monospace; color: #666;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Search/Replace</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Search/Replace Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<dl>
|
||||
<dt id="option_indentWithTabs"><code><strong>indentWithTabs</strong>: boolean</code></dt>
|
||||
<dd>Whether, when indenting, the first N*<code>tabSize</code>
|
||||
spaces should be replaced by N tabs. Default is false.</dd>
|
||||
|
||||
<dt id="option_electricChars"><code><strong>electricChars</strong>: boolean</code></dt>
|
||||
<dd>Configures whether the editor should re-indent the current
|
||||
line when a character is typed that might change its proper
|
||||
indentation (only works if the mode supports indentation).
|
||||
Default is true.</dd>
|
||||
|
||||
<dt id="option_specialChars"><code><strong>specialChars</strong>: RegExp</code></dt>
|
||||
<dd>A regular expression used to determine which characters
|
||||
should be replaced by a
|
||||
special <a href="#option_specialCharPlaceholder">placeholder</a>.
|
||||
Mostly useful for non-printing special characters. The default
|
||||
is <code>/[\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/</code>.</dd>
|
||||
<dt id="option_specialCharPlaceholder"><code><strong>specialCharPlaceholder</strong>: function(char) → Element</code></dt>
|
||||
<dd>A function that, given a special character identified by
|
||||
the <a href="#option_specialChars"><code>specialChars</code></a>
|
||||
option, produces a DOM node that is used to represent the
|
||||
character. By default, a red dot (<span style="color: red">•</span>)
|
||||
is shown, with a title tooltip to indicate the character code.</dd>
|
||||
|
||||
<dt id="option_rtlMoveVisually"><code><strong>rtlMoveVisually</strong>: boolean</code></dt>
|
||||
<dd>Determines whether horizontal cursor movement through
|
||||
right-to-left (Arabic, Hebrew) text is visual (pressing the left
|
||||
arrow moves the cursor left) or logical (pressing the left arrow
|
||||
moves to the next lower index in the string, which is visually
|
||||
right in right-to-left text). The default is <code>false</code>
|
||||
on Windows, and <code>true</code> on other platforms.</dd>
|
||||
</dl>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "text/html", lineNumbers: true});
|
||||
</script>
|
||||
|
||||
<p>Demonstration of primitive search/replace functionality. The
|
||||
keybindings (which can be overridden by custom keymaps) are:</p>
|
||||
<dl>
|
||||
<dt>Ctrl-F / Cmd-F</dt><dd>Start searching</dd>
|
||||
<dt>Ctrl-G / Cmd-G</dt><dd>Find next</dd>
|
||||
<dt>Shift-Ctrl-G / Shift-Cmd-G</dt><dd>Find previous</dd>
|
||||
<dt>Shift-Ctrl-F / Cmd-Option-F</dt><dd>Replace</dd>
|
||||
<dt>Shift-Ctrl-R / Shift-Cmd-Option-F</dt><dd>Replace all</dd>
|
||||
</dl>
|
||||
<p>Searching is enabled by
|
||||
including <a href="../addon/search/search.js">addon/search/search.js</a>
|
||||
and <a href="../addon/search/searchcursor.js">addon/search/searchcursor.js</a>.
|
||||
For good-looking input dialogs, you also want to include
|
||||
<a href="../addon/dialog/dialog.js">addon/dialog/dialog.js</a>
|
||||
and <a href="../addon/dialog/dialog.css">addon/dialog/dialog.css</a>.</p>
|
||||
</article>
|
@ -1,181 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Simple Mode Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/mode/simple.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid silver; margin-bottom: 1em; }
|
||||
dt { text-indent: -2em; padding-left: 2em; margin-top: 1em; }
|
||||
dd { margin-left: 1.5em; margin-bottom: 1em; }
|
||||
dt {margin-top: 1em;}
|
||||
</style>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Simple Mode</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Simple Mode Demo</h2>
|
||||
|
||||
<p>The <a href="../addon/mode/simple.js"><code>mode/simple</code></a>
|
||||
addon allows CodeMirror modes to be specified using a relatively simple
|
||||
declarative format. This format is not as powerful as writing code
|
||||
directly against the <a href="../doc/manual.html#modeapi">mode
|
||||
interface</a>, but is a lot easier to get started with, and
|
||||
sufficiently expressive for many simple language modes.</p>
|
||||
|
||||
<p>This interface is still in flux. It is unlikely to be scrapped or
|
||||
overhauled completely, so do start writing code against it, but
|
||||
details might change as it stabilizes, and you might have to tweak
|
||||
your code when upgrading.</p>
|
||||
|
||||
<p>Simple modes (loosely based on
|
||||
the <a href="https://github.com/mozilla/skywriter/wiki/Common-JavaScript-Syntax-Highlighting-Specification">Common
|
||||
JavaScript Syntax Highlighting Specification</a>, which never took
|
||||
off), are state machines, where each state has a number of rules that
|
||||
match tokens. A rule describes a type of token that may occur in the
|
||||
current state, and possibly a transition to another state caused by
|
||||
that token.</p>
|
||||
|
||||
<p>The <code>CodeMirror.defineSimpleMode(name, states)</code> method
|
||||
takes a mode name and an object that describes the mode's states. The
|
||||
editor below shows an example of such a mode (and is itself
|
||||
highlighted by the mode shown in it).</p>
|
||||
|
||||
<div id="code"></div>
|
||||
|
||||
<p>Each state is an array of rules. A rule may have the following properties:</p>
|
||||
|
||||
<dl>
|
||||
<dt><code><strong>regex</strong>: string | RegExp</code></dt>
|
||||
<dd>The regular expression that matches the token. May be a string
|
||||
or a regex object. When a regex, the <code>ignoreCase</code> flag
|
||||
will be taken into account when matching the token. This regex
|
||||
should only capture groups when the <code>token</code> property is
|
||||
an array.</dd>
|
||||
<dt><code><strong>token</strong></code>: string | null</dt>
|
||||
<dd>An optional token style. Multiple styles can be specified by
|
||||
separating them with dots or spaces. When the <code>regex</code> for
|
||||
this rule captures groups, it must capture <em>all</em> of the
|
||||
string (since JS provides no way to find out where a group matched),
|
||||
and this property must hold an array of token styles that has one
|
||||
style for each matched group.</dd>
|
||||
<dt><code><strong>next</strong>: string</code></dt>
|
||||
<dd>When a <code>next</code> property is present, the mode will
|
||||
transfer to the state named by the property when the token is
|
||||
encountered.</dd>
|
||||
<dt><code><strong>push</strong>: string</code></dt>
|
||||
<dd>Like <code>next</code>, but instead replacing the current state
|
||||
by the new state, the current state is kept on a stack, and can be
|
||||
returned to with the <code>pop</code> directive.</dd>
|
||||
<dt><code><strong>pop</strong>: bool</code></dt>
|
||||
<dd>When true, and there is another state on the state stack, will
|
||||
cause the mode to pop that state off the stack and transition to
|
||||
it.</dd>
|
||||
<dt><code><strong>mode</strong>: {spec, end, persistent}</code></dt>
|
||||
<dd>Can be used to embed another mode inside a mode. When present,
|
||||
must hold an object with a <code>spec</code> property that describes
|
||||
the embedded mode, and an optional <code>end</code> end property
|
||||
that specifies the regexp that will end the extent of the mode. When
|
||||
a <code>persistent</code> property is set (and true), the nested
|
||||
mode's state will be preserved between occurrences of the mode.</dd>
|
||||
<dt><code><strong>indent</strong>: bool</code></dt>
|
||||
<dd>When true, this token changes the indentation to be one unit
|
||||
more than the current line's indentation.</dd>
|
||||
<dt><code><strong>dedent</strong>: bool</code></dt>
|
||||
<dd>When true, this token will pop one scope off the indentation
|
||||
stack.</dd>
|
||||
<dt><code><strong>dedentIfLineStart</strong>: bool</code></dt>
|
||||
<dd>If a token has its <code>dedent</code> property set, it will, by
|
||||
default, cause lines where it appears at the start to be dedented.
|
||||
Set this property to false to prevent that behavior.</dd>
|
||||
</dl>
|
||||
|
||||
<p>The <code>meta</code> property of the states object is special, and
|
||||
will not be interpreted as a state. Instead, properties set on it will
|
||||
be set on the mode, which is useful for properties
|
||||
like <a href="../doc/manual.html#addon_comment"><code>lineComment</code></a>,
|
||||
which sets the comment style for a mode. The simple mode addon also
|
||||
recognizes a few such properties:</p>
|
||||
|
||||
<dl>
|
||||
<dt><code><strong>dontIndentStates</strong>: array<string></code></dt>
|
||||
<dd>An array of states in which the mode's auto-indentation should
|
||||
not take effect. Usually used for multi-line comment and string
|
||||
states.</dd>
|
||||
</dl>
|
||||
|
||||
<script id="modecode">/* Example definition of a simple mode that understands a subset of
|
||||
* JavaScript:
|
||||
*/
|
||||
|
||||
CodeMirror.defineSimpleMode("simplemode", {
|
||||
// The start state contains the rules that are intially used
|
||||
start: [
|
||||
// The regex matches the token, the token property contains the type
|
||||
{regex: /"(?:[^\\]|\\.)*?"/, token: "string"},
|
||||
// You can match multiple tokens at once. Note that the captured
|
||||
// groups must span the whole string in this case
|
||||
{regex: /(function)(\s+)([a-z$][\w$]*)/,
|
||||
token: ["keyword", null, "variable-2"]},
|
||||
// Rules are matched in the order in which they appear, so there is
|
||||
// no ambiguity between this one and the one above
|
||||
{regex: /(?:function|var|return|if|for|while|else|do|this)\b/,
|
||||
token: "keyword"},
|
||||
{regex: /true|false|null|undefined/, token: "atom"},
|
||||
{regex: /0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i,
|
||||
token: "number"},
|
||||
{regex: /\/\/.*/, token: "comment"},
|
||||
{regex: /\/(?:[^\\]|\\.)*?\//, token: "variable-3"},
|
||||
// A next property will cause the mode to move to a different state
|
||||
{regex: /\/\*/, token: "comment", next: "comment"},
|
||||
{regex: /[-+\/*=<>!]+/, token: "operator"},
|
||||
// indent and dedent properties guide autoindentation
|
||||
{regex: /[\{\[\(]/, indent: true},
|
||||
{regex: /[\}\]\)]/, dedent: true},
|
||||
{regex: /[a-z$][\w$]*/, token: "variable"},
|
||||
// You can embed other modes with the mode property. This rule
|
||||
// causes all code between << and >> to be highlighted with the XML
|
||||
// mode.
|
||||
{regex: /<</, token: "meta", mode: {spec: "xml", end: />>/}}
|
||||
],
|
||||
// The multi-line comment state.
|
||||
comment: [
|
||||
{regex: /.*?\*\//, token: "comment", next: "start"},
|
||||
{regex: /.*/, token: "comment"}
|
||||
],
|
||||
// The meta property contains global information about the mode. It
|
||||
// can contain properties like lineComment, which are supported by
|
||||
// all modes, and also directives like dontIndentStates, which are
|
||||
// specific to simple modes.
|
||||
meta: {
|
||||
dontIndentStates: ["comment"],
|
||||
lineComment: "//"
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var sc = document.getElementById("modecode");
|
||||
var code = document.getElementById("code");
|
||||
var editor = CodeMirror(code, {
|
||||
value: (sc.textContent || sc.innerText || sc.innerHTML),
|
||||
mode: "simplemode"
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,85 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Automatically derive odd wrapping behavior for your browser</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Automatically derive odd wrapping behavior for your browser</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Automatically derive odd wrapping behavior for your browser</h2>
|
||||
|
||||
|
||||
<p>This is a hack to automatically derive
|
||||
a <code>spanAffectsWrapping</code> regexp for a browser. See the
|
||||
comments above that variable
|
||||
in <a href="../lib/codemirror.js"><code>lib/codemirror.js</code></a>
|
||||
for some more details.</p>
|
||||
|
||||
<div style="white-space: pre-wrap; width: 50px;" id="area"></div>
|
||||
<pre id="output"></pre>
|
||||
|
||||
<script id="script">
|
||||
var a = document.getElementById("area"), bad = Object.create(null);
|
||||
var chars = "a~`!@#$%^&*()-_=+}{[]\\|'\"/?.>,<:;", l = chars.length;
|
||||
for (var x = 0; x < l; ++x) for (var y = 0; y < l; ++y) {
|
||||
var s1 = "foooo" + chars.charAt(x), s2 = chars.charAt(y) + "br";
|
||||
a.appendChild(document.createTextNode(s1 + s2));
|
||||
var h1 = a.offsetHeight;
|
||||
a.innerHTML = "";
|
||||
a.appendChild(document.createElement("span")).appendChild(document.createTextNode(s1));
|
||||
a.appendChild(document.createElement("span")).appendChild(document.createTextNode(s2));
|
||||
if (a.offsetHeight != h1)
|
||||
bad[chars.charAt(x)] = (bad[chars.charAt(x)] || "") + chars.charAt(y);
|
||||
a.innerHTML = "";
|
||||
}
|
||||
|
||||
var re = "";
|
||||
function toREElt(str) {
|
||||
if (str.length > 1) {
|
||||
var invert = false;
|
||||
if (str.length > chars.length * .6) {
|
||||
invert = true;
|
||||
var newStr = "";
|
||||
for (var i = 0; i < l; ++i) if (str.indexOf(chars.charAt(i)) == -1) newStr += chars.charAt(i);
|
||||
str = newStr;
|
||||
}
|
||||
str = str.replace(/[\-\.\]\"\'\\\/\^a]/g, function(orig) { return orig == "a" ? "\\w" : "\\" + orig; });
|
||||
return "[" + (invert ? "^" : "") + str + "]";
|
||||
} else if (str == "a") {
|
||||
return "\\w";
|
||||
} else if (/[?$*()+{}[\]\.|/\'\"]/.test(str)) {
|
||||
return "\\" + str;
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
var newRE = "";
|
||||
for (;;) {
|
||||
var left = null;
|
||||
for (var left in bad) break;
|
||||
if (left == null) break;
|
||||
var right = bad[left];
|
||||
delete bad[left];
|
||||
for (var other in bad) if (bad[other] == right) {
|
||||
left += other;
|
||||
delete bad[other];
|
||||
}
|
||||
newRE += (newRE ? "|" : "") + toREElt(left) + toREElt(right);
|
||||
}
|
||||
|
||||
document.getElementById("output").appendChild(document.createTextNode("Your regexp is: " + (newRE || "^$")));
|
||||
</script>
|
||||
</article>
|
@ -1,76 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Sublime Text bindings demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/fold/foldgutter.css">
|
||||
<link rel="stylesheet" href="../addon/dialog/dialog.css">
|
||||
<link rel="stylesheet" href="../theme/monokai.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/search/searchcursor.js"></script>
|
||||
<script src="../addon/search/search.js"></script>
|
||||
<script src="../addon/dialog/dialog.js"></script>
|
||||
<script src="../addon/edit/matchbrackets.js"></script>
|
||||
<script src="../addon/edit/closebrackets.js"></script>
|
||||
<script src="../addon/comment/comment.js"></script>
|
||||
<script src="../addon/wrap/hardwrap.js"></script>
|
||||
<script src="../addon/fold/foldcode.js"></script>
|
||||
<script src="../addon/fold/brace-fold.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../keymap/sublime.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee; line-height: 1.3; height: 500px}
|
||||
.CodeMirror-linenumbers { padding: 0 8px; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Sublime bindings</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Sublime Text bindings demo</h2>
|
||||
|
||||
<p>The <code>sublime</code> keymap defines many Sublime Text-specific
|
||||
bindings for CodeMirror. See the code below for an overview.</p>
|
||||
|
||||
<p>Enable the keymap by
|
||||
loading <a href="../keymap/sublime.js"><code>keymap/sublime.js</code></a>
|
||||
and setting
|
||||
the <a href="../doc/manual.html#option_keyMap"><code>keyMap</code></a>
|
||||
option to <code>"sublime"</code>.</p>
|
||||
|
||||
<p>(A lot of the search functionality is still missing.)
|
||||
|
||||
<script>
|
||||
var value = "// The bindings defined specifically in the Sublime Text mode\nvar bindings = {\n";
|
||||
var map = CodeMirror.keyMap.sublime;
|
||||
for (var key in map) {
|
||||
var val = map[key];
|
||||
if (key != "fallthrough" && val != "..." && (!/find/.test(val) || /findUnder/.test(val)))
|
||||
value += " \"" + key + "\": \"" + val + "\",\n";
|
||||
}
|
||||
value += "}\n\n// The implementation of joinLines\n";
|
||||
value += CodeMirror.commands.joinLines.toString().replace(/^function\s*\(/, "function joinLines(").replace(/\n /g, "\n") + "\n";
|
||||
var editor = CodeMirror(document.body.getElementsByTagName("article")[0], {
|
||||
value: value,
|
||||
lineNumbers: true,
|
||||
mode: "javascript",
|
||||
keyMap: "sublime",
|
||||
autoCloseBrackets: true,
|
||||
matchBrackets: true,
|
||||
showCursorWhenSelecting: true,
|
||||
theme: "monokai"
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,131 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Tern Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/dialog/dialog.css">
|
||||
<link rel="stylesheet" href="../addon/hint/show-hint.css">
|
||||
<link rel="stylesheet" href="../addon/tern/tern.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../addon/dialog/dialog.js"></script>
|
||||
<script src="../addon/hint/show-hint.js"></script>
|
||||
<script src="../addon/tern/tern.js"></script>
|
||||
<script src="http://marijnhaverbeke.nl/acorn/acorn.js"></script>
|
||||
<script src="http://marijnhaverbeke.nl/acorn/acorn_loose.js"></script>
|
||||
<script src="http://marijnhaverbeke.nl/acorn/util/walk.js"></script>
|
||||
<script src="http://ternjs.net/doc/demo/polyfill.js"></script>
|
||||
<script src="http://ternjs.net/lib/signal.js"></script>
|
||||
<script src="http://ternjs.net/lib/tern.js"></script>
|
||||
<script src="http://ternjs.net/lib/def.js"></script>
|
||||
<script src="http://ternjs.net/lib/comment.js"></script>
|
||||
<script src="http://ternjs.net/lib/infer.js"></script>
|
||||
<script src="http://ternjs.net/plugin/doc_comment.js"></script>
|
||||
<style>
|
||||
.CodeMirror {border: 1px solid #ddd;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Tern</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Tern Demo</h2>
|
||||
<form><textarea id="code" name="code">// Use ctrl-space to complete something
|
||||
// Put the cursor in or after an expression, press ctrl-i to
|
||||
// find its type
|
||||
|
||||
var foo = ["array", "of", "strings"];
|
||||
var bar = foo.slice(0, 2).join("").split("a")[0];
|
||||
|
||||
// Works for locally defined types too.
|
||||
|
||||
function CTor() { this.size = 10; }
|
||||
CTor.prototype.hallo = "hallo";
|
||||
|
||||
var baz = new CTor;
|
||||
baz.
|
||||
|
||||
// You can press ctrl-q when the cursor is on a variable name to
|
||||
// rename it. Try it with CTor...
|
||||
|
||||
// When the cursor is in an argument list, the arguments are
|
||||
// shown below the editor.
|
||||
|
||||
[1].reduce( );
|
||||
|
||||
// And a little more advanced code...
|
||||
|
||||
(function(exports) {
|
||||
exports.randomElt = function(arr) {
|
||||
return arr[Math.floor(arr.length * Math.random())];
|
||||
};
|
||||
exports.strList = "foo".split("");
|
||||
exports.intList = exports.strList.map(function(s) { return s.charCodeAt(0); });
|
||||
})(window.myMod = {});
|
||||
|
||||
var randomStr = myMod.randomElt(myMod.strList);
|
||||
var randomInt = myMod.randomElt(myMod.intList);
|
||||
</textarea></p>
|
||||
|
||||
<p>Demonstrates integration of <a href="http://ternjs.net/">Tern</a>
|
||||
and CodeMirror. The following keys are bound:</p>
|
||||
|
||||
<dl>
|
||||
<dt>Ctrl-Space</dt><dd>Autocomplete</dd>
|
||||
<dt>Ctrl-I</dt><dd>Find type at cursor</dd>
|
||||
<dt>Alt-.</dt><dd>Jump to definition (Alt-, to jump back)</dd>
|
||||
<dt>Ctrl-Q</dt><dd>Rename variable</dd>
|
||||
<dt>Ctrl-.</dt><dd>Select all occurrences of a variable</dd>
|
||||
</dl>
|
||||
|
||||
<p>Documentation is sparse for now. See the top of
|
||||
the <a href="../addon/tern/tern.js">script</a> for a rough API
|
||||
overview.</p>
|
||||
|
||||
<script>
|
||||
function getURL(url, c) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("get", url, true);
|
||||
xhr.send();
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState != 4) return;
|
||||
if (xhr.status < 400) return c(null, xhr.responseText);
|
||||
var e = new Error(xhr.responseText || "No response");
|
||||
e.status = xhr.status;
|
||||
c(e);
|
||||
};
|
||||
}
|
||||
|
||||
var server;
|
||||
getURL("http://ternjs.net/defs/ecma5.json", function(err, code) {
|
||||
if (err) throw new Error("Request for ecma5.json: " + err);
|
||||
server = new CodeMirror.TernServer({defs: [JSON.parse(code)]});
|
||||
editor.setOption("extraKeys", {
|
||||
"Ctrl-Space": function(cm) { server.complete(cm); },
|
||||
"Ctrl-I": function(cm) { server.showType(cm); },
|
||||
"Alt-.": function(cm) { server.jumpToDef(cm); },
|
||||
"Alt-,": function(cm) { server.jumpBack(cm); },
|
||||
"Ctrl-Q": function(cm) { server.rename(cm); },
|
||||
"Ctrl-.": function(cm) { server.selectName(cm); }
|
||||
})
|
||||
editor.on("cursorActivity", function(cm) { server.updateArgHints(cm); });
|
||||
});
|
||||
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "javascript"
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,126 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Theme Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../theme/3024-day.css">
|
||||
<link rel="stylesheet" href="../theme/3024-night.css">
|
||||
<link rel="stylesheet" href="../theme/ambiance.css">
|
||||
<link rel="stylesheet" href="../theme/base16-dark.css">
|
||||
<link rel="stylesheet" href="../theme/base16-light.css">
|
||||
<link rel="stylesheet" href="../theme/blackboard.css">
|
||||
<link rel="stylesheet" href="../theme/cobalt.css">
|
||||
<link rel="stylesheet" href="../theme/eclipse.css">
|
||||
<link rel="stylesheet" href="../theme/elegant.css">
|
||||
<link rel="stylesheet" href="../theme/erlang-dark.css">
|
||||
<link rel="stylesheet" href="../theme/lesser-dark.css">
|
||||
<link rel="stylesheet" href="../theme/mbo.css">
|
||||
<link rel="stylesheet" href="../theme/mdn-like.css">
|
||||
<link rel="stylesheet" href="../theme/midnight.css">
|
||||
<link rel="stylesheet" href="../theme/monokai.css">
|
||||
<link rel="stylesheet" href="../theme/neat.css">
|
||||
<link rel="stylesheet" href="../theme/neo.css">
|
||||
<link rel="stylesheet" href="../theme/night.css">
|
||||
<link rel="stylesheet" href="../theme/paraiso-dark.css">
|
||||
<link rel="stylesheet" href="../theme/paraiso-light.css">
|
||||
<link rel="stylesheet" href="../theme/pastel-on-dark.css">
|
||||
<link rel="stylesheet" href="../theme/rubyblue.css">
|
||||
<link rel="stylesheet" href="../theme/solarized.css">
|
||||
<link rel="stylesheet" href="../theme/the-matrix.css">
|
||||
<link rel="stylesheet" href="../theme/tomorrow-night-eighties.css">
|
||||
<link rel="stylesheet" href="../theme/twilight.css">
|
||||
<link rel="stylesheet" href="../theme/vibrant-ink.css">
|
||||
<link rel="stylesheet" href="../theme/xq-dark.css">
|
||||
<link rel="stylesheet" href="../theme/xq-light.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../addon/selection/active-line.js"></script>
|
||||
<script src="../addon/edit/matchbrackets.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid black; font-size:13px}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Theme</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Theme Demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
function findSequence(goal) {
|
||||
function find(start, history) {
|
||||
if (start == goal)
|
||||
return history;
|
||||
else if (start > goal)
|
||||
return null;
|
||||
else
|
||||
return find(start + 5, "(" + history + " + 5)") ||
|
||||
find(start * 3, "(" + history + " * 3)");
|
||||
}
|
||||
return find(1, "1");
|
||||
}</textarea></form>
|
||||
|
||||
<p>Select a theme: <select onchange="selectTheme()" id=select>
|
||||
<option selected>default</option>
|
||||
<option>3024-day</option>
|
||||
<option>3024-night</option>
|
||||
<option>ambiance</option>
|
||||
<option>base16-dark</option>
|
||||
<option>base16-light</option>
|
||||
<option>blackboard</option>
|
||||
<option>cobalt</option>
|
||||
<option>eclipse</option>
|
||||
<option>elegant</option>
|
||||
<option>erlang-dark</option>
|
||||
<option>lesser-dark</option>
|
||||
<option>mbo</option>
|
||||
<option>mdn-like</option>
|
||||
<option>midnight</option>
|
||||
<option>monokai</option>
|
||||
<option>neat</option>
|
||||
<option>neo</option>
|
||||
<option>night</option>
|
||||
<option>paraiso-dark</option>
|
||||
<option>paraiso-light</option>
|
||||
<option>pastel-on-dark</option>
|
||||
<option>rubyblue</option>
|
||||
<option>solarized dark</option>
|
||||
<option>solarized light</option>
|
||||
<option>the-matrix</option>
|
||||
<option>tomorrow-night-eighties</option>
|
||||
<option>twilight</option>
|
||||
<option>vibrant-ink</option>
|
||||
<option>xq-dark</option>
|
||||
<option>xq-light</option>
|
||||
</select>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
styleActiveLine: true,
|
||||
matchBrackets: true
|
||||
});
|
||||
var input = document.getElementById("select");
|
||||
function selectTheme() {
|
||||
var theme = input.options[input.selectedIndex].innerHTML;
|
||||
editor.setOption("theme", theme);
|
||||
}
|
||||
var choice = document.location.search &&
|
||||
decodeURIComponent(document.location.search.slice(1));
|
||||
if (choice) {
|
||||
input.value = choice;
|
||||
editor.setOption("theme", choice);
|
||||
}
|
||||
</script>
|
||||
</article>
|
@ -1,48 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Trailing Whitespace Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/edit/trailingspace.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
.cm-trailingspace {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom left;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Trailing Whitespace</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Trailing Whitespace Demo</h2>
|
||||
<form><textarea id="code" name="code">This text
|
||||
has some
|
||||
trailing whitespace!</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
showTrailingSpace: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Uses
|
||||
the <a href="../doc/manual.html#addon_trailingspace">trailingspace</a>
|
||||
addon to highlight trailing whitespace.</p>
|
||||
|
||||
</article>
|
@ -1,67 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Variable Height Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/markdown/markdown.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid silver; border-width: 1px 2px; }
|
||||
.cm-header { font-family: arial; }
|
||||
.cm-header-1 { font-size: 150%; }
|
||||
.cm-header-2 { font-size: 130%; }
|
||||
.cm-header-3 { font-size: 120%; }
|
||||
.cm-header-4 { font-size: 110%; }
|
||||
.cm-header-5 { font-size: 100%; }
|
||||
.cm-header-6 { font-size: 90%; }
|
||||
.cm-strong { font-size: 140%; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Variable Height</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Variable Height Demo</h2>
|
||||
<form><textarea id="code" name="code"># A First Level Header
|
||||
|
||||
**Bold** text in a normal-size paragraph.
|
||||
|
||||
And a very long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long, wrapped line with a piece of **big** text inside of it.
|
||||
|
||||
## A Second Level Header
|
||||
|
||||
Now is the time for all good men to come to
|
||||
the aid of their country. This is just a
|
||||
regular paragraph.
|
||||
|
||||
The quick brown fox jumped over the lazy
|
||||
dog's back.
|
||||
|
||||
### Header 3
|
||||
|
||||
> This is a blockquote.
|
||||
>
|
||||
> This is the second paragraph in the blockquote.
|
||||
>
|
||||
> ## This is an H2 in a blockquote
|
||||
</textarea></form>
|
||||
<script id="script">
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
mode: "markdown"
|
||||
});
|
||||
</script>
|
||||
</article>
|
@ -1,99 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Vim bindings demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/dialog/dialog.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/dialog/dialog.js"></script>
|
||||
<script src="../addon/search/searchcursor.js"></script>
|
||||
<script src="../mode/clike/clike.js"></script>
|
||||
<script src="../addon/edit/matchbrackets.js"></script>
|
||||
<script src="../keymap/vim.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Vim bindings</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Vim bindings demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
#include "syscalls.h"
|
||||
/* getchar: simple buffered version */
|
||||
int getchar(void)
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
static char *bufp = buf;
|
||||
static int n = 0;
|
||||
if (n == 0) { /* buffer is empty */
|
||||
n = read(0, buf, sizeof buf);
|
||||
bufp = buf;
|
||||
}
|
||||
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
|
||||
}
|
||||
</textarea></form>
|
||||
<div style="font-size: 13px; width: 300px; height: 30px;">Key buffer: <span id="command-display"></span></div>
|
||||
|
||||
<p>The vim keybindings are enabled by
|
||||
including <a href="../keymap/vim.js">keymap/vim.js</a> and setting
|
||||
the <code>vimMode</code> option to <code>true</code>. This will also
|
||||
automatically change the <code>keyMap</code> option to <code>"vim"</code>.</p>
|
||||
|
||||
<p><strong>Features</strong></p>
|
||||
|
||||
<ul>
|
||||
<li>All common motions and operators, including text objects</li>
|
||||
<li>Operator motion orthogonality</li>
|
||||
<li>Visual mode - characterwise, linewise, partial support for blockwise</li>
|
||||
<li>Full macro support (q, @)</li>
|
||||
<li>Incremental highlighted search (/, ?, #, *, g#, g*)</li>
|
||||
<li>Search/replace with confirm (:substitute, :%s)</li>
|
||||
<li>Search history</li>
|
||||
<li>Jump lists (Ctrl-o, Ctrl-i)</li>
|
||||
<li>Key/command mapping with API (:map, :nmap, :vmap)</li>
|
||||
<li>Sort (:sort)</li>
|
||||
<li>Marks (`, ')</li>
|
||||
<li>:global</li>
|
||||
<li>Insert mode behaves identical to base CodeMirror</li>
|
||||
<li>Cross-buffer yank/paste</li>
|
||||
</ul>
|
||||
|
||||
<p>Note that while the vim mode tries to emulate the most useful features of
|
||||
vim as faithfully as possible, it does not strive to become a complete vim
|
||||
implementation</p>
|
||||
|
||||
<script>
|
||||
CodeMirror.commands.save = function(){ alert("Saving"); };
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "text/x-csrc",
|
||||
keyMap: "vim",
|
||||
matchBrackets: true,
|
||||
showCursorWhenSelecting: true
|
||||
});
|
||||
var commandDisplay = document.getElementById('command-display');
|
||||
var keys = '';
|
||||
CodeMirror.on(editor, 'vim-keypress', function(key) {
|
||||
keys = keys + key;
|
||||
commandDisplay.innerHTML = keys;
|
||||
});
|
||||
CodeMirror.on(editor, 'vim-command-done', function(e) {
|
||||
keys = '';
|
||||
commandDisplay.innerHTML = keys;
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,62 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Visible tabs demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/clike/clike.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
|
||||
.cm-tab {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
|
||||
background-position: right;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Visible tabs</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Visible tabs demo</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
#include "syscalls.h"
|
||||
/* getchar: simple buffered version */
|
||||
int getchar(void)
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
static char *bufp = buf;
|
||||
static int n = 0;
|
||||
if (n == 0) { /* buffer is empty */
|
||||
n = read(0, buf, sizeof buf);
|
||||
bufp = buf;
|
||||
}
|
||||
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
|
||||
}
|
||||
</textarea></form>
|
||||
|
||||
<p>Tabs inside the editor are spans with the
|
||||
class <code>cm-tab</code>, and can be styled.</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
tabSize: 4,
|
||||
indentUnit: 4,
|
||||
indentWithTabs: true,
|
||||
mode: "text/x-csrc"
|
||||
});
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,85 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Inline Widget Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="//ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror {border: 1px solid black;}
|
||||
.lint-error {font-family: arial; font-size: 70%; background: #ffa; color: #a00; padding: 2px 5px 3px; }
|
||||
.lint-error-icon {color: white; background-color: red; font-weight: bold; border-radius: 50%; padding: 0 3px; margin-right: 7px;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Inline Widget</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Inline Widget Demo</h2>
|
||||
|
||||
|
||||
<div id=code></div>
|
||||
<script id="script">var widgets = []
|
||||
function updateHints() {
|
||||
editor.operation(function(){
|
||||
for (var i = 0; i < widgets.length; ++i)
|
||||
editor.removeLineWidget(widgets[i]);
|
||||
widgets.length = 0;
|
||||
|
||||
JSHINT(editor.getValue());
|
||||
for (var i = 0; i < JSHINT.errors.length; ++i) {
|
||||
var err = JSHINT.errors[i];
|
||||
if (!err) continue;
|
||||
var msg = document.createElement("div");
|
||||
var icon = msg.appendChild(document.createElement("span"));
|
||||
icon.innerHTML = "!!";
|
||||
icon.className = "lint-error-icon";
|
||||
msg.appendChild(document.createTextNode(err.reason));
|
||||
msg.className = "lint-error";
|
||||
widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true}));
|
||||
}
|
||||
});
|
||||
var info = editor.getScrollInfo();
|
||||
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
|
||||
if (info.top + info.clientHeight < after)
|
||||
editor.scrollTo(null, after - info.clientHeight + 3);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
var sc = document.getElementById("script");
|
||||
var content = sc.textContent || sc.innerText || sc.innerHTML;
|
||||
|
||||
window.editor = CodeMirror(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "javascript",
|
||||
value: content
|
||||
});
|
||||
|
||||
var waiting;
|
||||
editor.on("change", function() {
|
||||
clearTimeout(waiting);
|
||||
waiting = setTimeout(updateHints, 500);
|
||||
});
|
||||
|
||||
setTimeout(updateHints, 100);
|
||||
};
|
||||
|
||||
"long line to create a horizontal scrollbar, in order to test whether the (non-inline) widgets stay in place when scrolling to the right";
|
||||
</script>
|
||||
<p>This demo runs <a href="http://jshint.com">JSHint</a> over the code
|
||||
in the editor (which is the script used on this page), and
|
||||
inserts <a href="../doc/manual.html#addLineWidget">line widgets</a> to
|
||||
display the warnings that JSHint comes up with.</p>
|
||||
</article>
|
@ -1,119 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: XML Autocomplete Demo</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../addon/hint/show-hint.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../addon/hint/show-hint.js"></script>
|
||||
<script src="../addon/hint/xml-hint.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<style type="text/css">
|
||||
.CodeMirror { border: 1px solid #eee; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">XML Autocomplete</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>XML Autocomplete Demo</h2>
|
||||
<form><textarea id="code" name="code"><!-- write some xml below -->
|
||||
</textarea></form>
|
||||
|
||||
<p>Press <strong>ctrl-space</strong>, or type a '<' character to
|
||||
activate autocompletion. This demo defines a simple schema that
|
||||
guides completion. The schema can be customized—see
|
||||
the <a href="../doc/manual.html#addon_xml-hint">manual</a>.</p>
|
||||
|
||||
<p>Development of the <code>xml-hint</code> addon was kindly
|
||||
sponsored
|
||||
by <a href="http://www.xperiment.mobi">www.xperiment.mobi</a>.</p>
|
||||
|
||||
<script>
|
||||
var dummy = {
|
||||
attrs: {
|
||||
color: ["red", "green", "blue", "purple", "white", "black", "yellow"],
|
||||
size: ["large", "medium", "small"],
|
||||
description: null
|
||||
},
|
||||
children: []
|
||||
};
|
||||
|
||||
var tags = {
|
||||
"!top": ["top"],
|
||||
"!attrs": {
|
||||
id: null,
|
||||
class: ["A", "B", "C"]
|
||||
},
|
||||
top: {
|
||||
attrs: {
|
||||
lang: ["en", "de", "fr", "nl"],
|
||||
freeform: null
|
||||
},
|
||||
children: ["animal", "plant"]
|
||||
},
|
||||
animal: {
|
||||
attrs: {
|
||||
name: null,
|
||||
isduck: ["yes", "no"]
|
||||
},
|
||||
children: ["wings", "feet", "body", "head", "tail"]
|
||||
},
|
||||
plant: {
|
||||
attrs: {name: null},
|
||||
children: ["leaves", "stem", "flowers"]
|
||||
},
|
||||
wings: dummy, feet: dummy, body: dummy, head: dummy, tail: dummy,
|
||||
leaves: dummy, stem: dummy, flowers: dummy
|
||||
};
|
||||
|
||||
function completeAfter(cm, pred) {
|
||||
var cur = cm.getCursor();
|
||||
if (!pred || pred()) setTimeout(function() {
|
||||
if (!cm.state.completionActive)
|
||||
cm.showHint({completeSingle: false});
|
||||
}, 100);
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
|
||||
function completeIfAfterLt(cm) {
|
||||
return completeAfter(cm, function() {
|
||||
var cur = cm.getCursor();
|
||||
return cm.getRange(CodeMirror.Pos(cur.line, cur.ch - 1), cur) == "<";
|
||||
});
|
||||
}
|
||||
|
||||
function completeIfInTag(cm) {
|
||||
return completeAfter(cm, function() {
|
||||
var tok = cm.getTokenAt(cm.getCursor());
|
||||
if (tok.type == "string" && (!/['"]/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1)) return false;
|
||||
var inner = CodeMirror.innerMode(cm.getMode(), tok.state).state;
|
||||
return inner.tagName;
|
||||
});
|
||||
}
|
||||
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "xml",
|
||||
lineNumbers: true,
|
||||
extraKeys: {
|
||||
"'<'": completeAfter,
|
||||
"'/'": completeIfAfterLt,
|
||||
"' '": completeIfInTag,
|
||||
"'='": completeIfInTag,
|
||||
"Ctrl-Space": "autocomplete"
|
||||
},
|
||||
hintOptions: {schemaInfo: tags}
|
||||
});
|
||||
</script>
|
||||
</article>
|
@ -1,57 +0,0 @@
|
||||
// Kludge in HTML5 tag recognition in IE8
|
||||
document.createElement("section");
|
||||
document.createElement("article");
|
||||
|
||||
(function() {
|
||||
if (!window.addEventListener) return;
|
||||
var pending = false, prevVal = null;
|
||||
|
||||
function updateSoon() {
|
||||
if (!pending) {
|
||||
pending = true;
|
||||
setTimeout(update, 250);
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
pending = false;
|
||||
var marks = document.getElementById("nav").getElementsByTagName("a"), found;
|
||||
for (var i = 0; i < marks.length; ++i) {
|
||||
var mark = marks[i], m;
|
||||
if (mark.getAttribute("data-default")) {
|
||||
if (found == null) found = i;
|
||||
} else if (m = mark.href.match(/#(.*)/)) {
|
||||
var ref = document.getElementById(m[1]);
|
||||
if (ref && ref.getBoundingClientRect().top < 50)
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
if (found != null && found != prevVal) {
|
||||
prevVal = found;
|
||||
var lis = document.getElementById("nav").getElementsByTagName("li");
|
||||
for (var i = 0; i < lis.length; ++i) lis[i].className = "";
|
||||
for (var i = 0; i < marks.length; ++i) {
|
||||
if (found == i) {
|
||||
marks[i].className = "active";
|
||||
for (var n = marks[i]; n; n = n.parentNode)
|
||||
if (n.nodeName == "LI") n.className = "active";
|
||||
} else {
|
||||
marks[i].className = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", updateSoon);
|
||||
window.addEventListener("load", updateSoon);
|
||||
window.addEventListener("hashchange", function() {
|
||||
setTimeout(function() {
|
||||
var hash = document.location.hash, found = null, m;
|
||||
var marks = document.getElementById("nav").getElementsByTagName("a");
|
||||
for (var i = 0; i < marks.length; i++)
|
||||
if ((m = marks[i].href.match(/(#.*)/)) && m[1] == hash) { found = i; break; }
|
||||
if (found != null) for (var i = 0; i < marks.length; i++)
|
||||
marks[i].className = i == found ? "active" : "";
|
||||
}, 300);
|
||||
});
|
||||
})();
|
@ -1,296 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Compression Helper</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<link rel=stylesheet href="../lib/codemirror.css">
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Compression helper</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2>Script compression helper</h2>
|
||||
|
||||
<p>To optimize loading CodeMirror, especially when including a
|
||||
bunch of different modes, it is recommended that you combine and
|
||||
minify (and preferably also gzip) the scripts. This page makes
|
||||
those first two steps very easy. Simply select the version and
|
||||
scripts you need in the form below, and
|
||||
click <strong>Compress</strong> to download the minified script
|
||||
file.</p>
|
||||
|
||||
<form id="form" action="http://marijnhaverbeke.nl/uglifyjs" method="post" onsubmit="generateHeader();">
|
||||
<input type="hidden" id="download" name="download" value="codemirror-compressed.js"/>
|
||||
<p>Version: <select id="version" onchange="setVersion(this);" style="padding: 1px;">
|
||||
<option value="http://codemirror.net/">HEAD</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.8.0;f=">4.8</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.7.0;f=">4.7</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.6.0;f=">4.6</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.5.0;f=">4.5</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.4.0;f=">4.4</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.3.0;f=">4.3</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.2.1;f=">4.2</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.2.0;f=">4.2</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.1.0;f=">4.1</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.0.3;f=">4.0</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.23.0;f=">3.23</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.22.0;f=">3.22</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.21.0;f=">3.21</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.20.0;f=">3.20</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.19.0;f=">3.19</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.18.0;f=">3.18</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.16.0;f=">3.16</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.15.0;f=">3.15</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.14.0;f=">3.14</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.13.0;f=">3.13</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.12;f=">3.12</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.11;f=">3.11</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.1;f=">3.1</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.02;f=">3.02</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.01;f=">3.01</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.0;f=">3.0</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.38;f=">2.38</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.37;f=">2.37</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.36;f=">2.36</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.35;f=">2.35</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.34;f=">2.34</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.33;f=">2.33</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.32;f=">2.32</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.31;f=">2.31</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.3;f=">2.3</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.25;f=">2.25</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.24;f=">2.24</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.23;f=">2.23</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.22;f=">2.22</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.21;f=">2.21</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.2;f=">2.2</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.18;f=">2.18</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.16;f=">2.16</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.15;f=">2.15</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.13;f=">2.13</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.12;f=">2.12</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.11;f=">2.11</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.1;f=">2.1</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.02;f=">2.02</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.01;f=">2.01</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.0;f=">2.0</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=beta2;f=">beta2</option>
|
||||
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=beta1;f=">beta1</option>
|
||||
</select></p>
|
||||
|
||||
<select multiple="multiple" size="20" name="code_url" style="width: 40em;" class="field" id="files">
|
||||
<optgroup label="CodeMirror Library">
|
||||
<option value="http://codemirror.net/lib/codemirror.js" selected>codemirror.js</option>
|
||||
</optgroup>
|
||||
<optgroup label="Modes">
|
||||
<option value="http://codemirror.net/mode/apl/apl.js">apl.js</option>
|
||||
<option value="http://codemirror.net/mode/clike/clike.js">clike.js</option>
|
||||
<option value="http://codemirror.net/mode/clojure/clojure.js">clojure.js</option>
|
||||
<option value="http://codemirror.net/mode/cobol/cobol.js">cobol.js</option>
|
||||
<option value="http://codemirror.net/mode/coffeescript/coffeescript.js">coffeescript.js</option>
|
||||
<option value="http://codemirror.net/mode/commonlisp/commonlisp.js">commonlisp.js</option>
|
||||
<option value="http://codemirror.net/mode/css/css.js">css.js</option>
|
||||
<option value="http://codemirror.net/mode/cypher/cypher.js">cypher.js</option>
|
||||
<option value="http://codemirror.net/mode/d/d.js">d.js</option>
|
||||
<option value="http://codemirror.net/mode/diff/diff.js">diff.js</option>
|
||||
<option value="http://codemirror.net/mode/django/django.js">django.js</option>
|
||||
<option value="http://codemirror.net/mode/dockerfile/dockerfile.js">dockerfile.js</option>
|
||||
<option value="http://codemirror.net/mode/dtd/dtd.js">dtd.js</option>
|
||||
<option value="http://codemirror.net/mode/dylan/dylan.js">dylan.js</option>
|
||||
<option value="http://codemirror.net/mode/ecl/ecl.js">ecl.js</option>
|
||||
<option value="http://codemirror.net/mode/eiffel/eiffel.js">eiffel.js</option>
|
||||
<option value="http://codemirror.net/mode/erlang/erlang.js">erlang.js</option>
|
||||
<option value="http://codemirror.net/mode/fortran/fortran.js">fortran.js</option>
|
||||
<option value="http://codemirror.net/mode/gfm/gfm.js">gfm.js</option>
|
||||
<option value="http://codemirror.net/mode/gas/gas.js">gas.js</option>
|
||||
<option value="http://codemirror.net/mode/gherkin/gherkin.js">gherkin.js</option>
|
||||
<option value="http://codemirror.net/mode/go/go.js">go.js</option>
|
||||
<option value="http://codemirror.net/mode/groovy/groovy.js">groovy.js</option>
|
||||
<option value="http://codemirror.net/mode/haml/haml.js">haml.js</option>
|
||||
<option value="http://codemirror.net/mode/haskell/haskell.js">haskell.js</option>
|
||||
<option value="http://codemirror.net/mode/haxe/haxe.js">haxe.js</option>
|
||||
<option value="http://codemirror.net/mode/htmlembedded/htmlembedded.js">htmlembedded.js</option>
|
||||
<option value="http://codemirror.net/mode/htmlmixed/htmlmixed.js">htmlmixed.js</option>
|
||||
<option value="http://codemirror.net/mode/http/http.js">http.js</option>
|
||||
<option value="http://codemirror.net/mode/idl/idl.js">idl.js</option>
|
||||
<option value="http://codemirror.net/mode/jade/jade.js">jade.js</option>
|
||||
<option value="http://codemirror.net/mode/javascript/javascript.js">javascript.js</option>
|
||||
<option value="http://codemirror.net/mode/jinja2/jinja2.js">jinja2.js</option>
|
||||
<option value="http://codemirror.net/mode/julia/julia.js">julia.js</option>
|
||||
<option value="http://codemirror.net/mode/kotlin/kotlin.js">kotlin.js</option>
|
||||
<option value="http://codemirror.net/mode/livescript/livescript.js">livescript.js</option>
|
||||
<option value="http://codemirror.net/mode/lua/lua.js">lua.js</option>
|
||||
<option value="http://codemirror.net/mode/markdown/markdown.js">markdown.js</option>
|
||||
<option value="http://codemirror.net/mode/mirc/mirc.js">mirc.js</option>
|
||||
<option value="http://codemirror.net/mode/mllike/mllike.js">mllike.js</option>
|
||||
<option value="http://codemirror.net/mode/modelica/modelica.js">modelica.js</option>
|
||||
<option value="http://codemirror.net/mode/nginx/nginx.js">nginx.js</option>
|
||||
<option value="http://codemirror.net/mode/ntriples/ntriples.js">ntriples.js</option>
|
||||
<option value="http://codemirror.net/mode/octave/octave.js">octave.js</option>
|
||||
<option value="http://codemirror.net/mode/pascal/pascal.js">pascal.js</option>
|
||||
<option value="http://codemirror.net/mode/pegjs/pegjs.js">pegjs.js</option>
|
||||
<option value="http://codemirror.net/mode/perl/perl.js">perl.js</option>
|
||||
<option value="http://codemirror.net/mode/php/php.js">php.js</option>
|
||||
<option value="http://codemirror.net/mode/pig/pig.js">pig.js</option>
|
||||
<option value="http://codemirror.net/mode/properties/properties.js">properties.js</option>
|
||||
<option value="http://codemirror.net/mode/python/python.js">python.js</option>
|
||||
<option value="http://codemirror.net/mode/puppet/puppet.js">puppet.js</option>
|
||||
<option value="http://codemirror.net/mode/q/q.js">q.js</option>
|
||||
<option value="http://codemirror.net/mode/r/r.js">r.js</option>
|
||||
<option value="http://codemirror.net/mode/rpm/rpm.js">rpm.js</option>
|
||||
<option value="http://codemirror.net/mode/rst/rst.js">rst.js</option>
|
||||
<option value="http://codemirror.net/mode/ruby/ruby.js">ruby.js</option>
|
||||
<option value="http://codemirror.net/mode/rust/rust.js">rust.js</option>
|
||||
<option value="http://codemirror.net/mode/sass/sass.js">sass.js</option>
|
||||
<option value="http://codemirror.net/mode/scala/scala.js">scala.js</option>
|
||||
<option value="http://codemirror.net/mode/scheme/scheme.js">scheme.js</option>
|
||||
<option value="http://codemirror.net/mode/shell/shell.js">shell.js</option>
|
||||
<option value="http://codemirror.net/mode/sieve/sieve.js">sieve.js</option>
|
||||
<option value="http://codemirror.net/mode/slim/slim.js">slim.js</option>
|
||||
<option value="http://codemirror.net/mode/smalltalk/smalltalk.js">smalltalk.js</option>
|
||||
<option value="http://codemirror.net/mode/smarty/smarty.js">smarty.js</option>
|
||||
<option value="http://codemirror.net/mode/smartymixed/smartymixed.js">smartymixed.js</option>
|
||||
<option value="http://codemirror.net/mode/sql/sql.js">sql.js</option>
|
||||
<option value="http://codemirror.net/mode/sparql/sparql.js">sparql.js</option>
|
||||
<option value="http://codemirror.net/mode/stex/stex.js">stex.js</option>
|
||||
<option value="http://codemirror.net/mode/tcl/tcl.js">tcl.js</option>
|
||||
<option value="http://codemirror.net/mode/textile/textile.js">textile.js</option>
|
||||
<option value="http://codemirror.net/mode/tiddlywiki/tiddlywiki.js">tiddlywiki.js</option>
|
||||
<option value="http://codemirror.net/mode/tiki/tiki.js">tiki.js</option>
|
||||
<option value="http://codemirror.net/mode/toml/toml.js">toml.js</option>
|
||||
<option value="http://codemirror.net/mode/tornado/tornado.js">tornado.js</option>
|
||||
<option value="http://codemirror.net/mode/turtle/turtle.js">turtle.js</option>
|
||||
<option value="http://codemirror.net/mode/vb/vb.js">vb.js</option>
|
||||
<option value="http://codemirror.net/mode/vbscript/vbscript.js">vbscript.js</option>
|
||||
<option value="http://codemirror.net/mode/velocity/velocity.js">velocity.js</option>
|
||||
<option value="http://codemirror.net/mode/verilog/verilog.js">verilog.js</option>
|
||||
<option value="http://codemirror.net/mode/xml/xml.js">xml.js</option>
|
||||
<option value="http://codemirror.net/mode/xquery/xquery.js">xquery.js</option>
|
||||
<option value="http://codemirror.net/mode/yaml/yaml.js">yaml.js</option>
|
||||
<option value="http://codemirror.net/mode/z80/z80.js">z80.js</option>
|
||||
</optgroup>
|
||||
<optgroup label="Add-ons">
|
||||
<option value="http://codemirror.net/addon/selection/active-line.js">active-line.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/anyword-hint.js">anyword-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/fold/brace-fold.js">brace-fold.js</option>
|
||||
<option value="http://codemirror.net/addon/edit/closebrackets.js">closebrackets.js</option>
|
||||
<option value="http://codemirror.net/addon/edit/closetag.js">closetag.js</option>
|
||||
<option value="http://codemirror.net/addon/runmode/colorize.js">colorize.js</option>
|
||||
<option value="http://codemirror.net/addon/comment/comment.js">comment.js</option>
|
||||
<option value="http://codemirror.net/addon/fold/comment-fold.js">comment-fold.js</option>
|
||||
<option value="http://codemirror.net/addon/comment/continuecomment.js">continuecomment.js</option>
|
||||
<option value="http://codemirror.net/addon/edit/continuelist.js">continuelist.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/css-hint.js">css-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/dialog/dialog.js">dialog.js</option>
|
||||
<option value="http://codemirror.net/addon/fold/foldcode.js">foldcode.js</option>
|
||||
<option value="http://codemirror.net/addon/fold/foldgutter.js">foldgutter.js</option>
|
||||
<option value="http://codemirror.net/addon/display/fullscreen.js">fullscreen.js</option>
|
||||
<option value="http://codemirror.net/addon/wrap/hardwrap.js">hardwrap.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/html-hint.js">html-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/fold/indent-fold.js">indent-fold.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/javascript-hint.js">javascript-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/lint/javascript-lint.js">javascript-lint.js</option>
|
||||
<option value="http://codemirror.net/addon/lint/json-lint.js">json-lint.js</option>
|
||||
<option value="http://codemirror.net/addon/lint/lint.js">lint.js</option>
|
||||
<option value="http://codemirror.net/addon/mode/loadmode.js">loadmode.js</option>
|
||||
<option value="http://codemirror.net/addon/fold/markdown-fold.js">markdown-fold.js</option>
|
||||
<option value="http://codemirror.net/addon/selection/mark-selection.js">mark-selection.js</option>
|
||||
<option value="http://codemirror.net/addon/search/match-highlighter.js">match-highlighter.js</option>
|
||||
<option value="http://codemirror.net/addon/edit/matchbrackets.js">matchbrackets.js</option>
|
||||
<option value="http://codemirror.net/addon/edit/matchtags.js">matchtags.js</option>
|
||||
<option value="http://codemirror.net/addon/merge/merge.js">merge.js</option>
|
||||
<option value="http://codemirror.net/addon/mode/multiplex.js">multiplex.js</option>
|
||||
<option value="http://codemirror.net/addon/mode/overlay.js">overlay.js</option>
|
||||
<option value="http://codemirror.net/addon/display/placeholder.js">placeholder.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/python-hint.js">python-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/display/rulers.js">rulers.js</option>
|
||||
<option value="http://codemirror.net/addon/runmode/runmode.js">runmode.js</option>
|
||||
<option value="http://codemirror.net/addon/runmode/runmode.node.js">runmode.node.js</option>
|
||||
<option value="http://codemirror.net/addon/runmode/runmode-standalone.js">runmode-standalone.js</option>
|
||||
<option value="http://codemirror.net/addon/search/search.js">search.js</option>
|
||||
<option value="http://codemirror.net/addon/search/searchcursor.js">searchcursor.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/show-hint.js">show-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/mode/simple.js">simple.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/sql-hint.js">sql-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/edit/trailingspace.js">trailingspace.js</option>
|
||||
<option value="http://codemirror.net/addon/tern/tern.js">tern.js</option>
|
||||
<option value="http://codemirror.net/addon/fold/xml-fold.js">xml-fold.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/xml-hint.js">xml-hint.js</option>
|
||||
<option value="http://codemirror.net/addon/hint/yaml-lint.js">yaml-lint.js</option>
|
||||
</optgroup>
|
||||
<optgroup label="Keymaps">
|
||||
<option value="http://codemirror.net/keymap/emacs.js">emacs.js</option>
|
||||
<option value="http://codemirror.net/keymap/sublime.js">sublime.js</option>
|
||||
<option value="http://codemirror.net/keymap/vim.js">vim.js</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
|
||||
<p>
|
||||
<button type="submit">Compress</button> with <a href="http://github.com/mishoo/UglifyJS/">UglifyJS</a>
|
||||
</p>
|
||||
<input type="hidden" id="header" name="header">
|
||||
<p>Custom code to add to the compressed file:<textarea name="js_code" style="width: 100%; height: 15em;" class="field" id="js_code"></textarea></p>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
CodeMirror.fromTextArea(document.getElementById("js_code")).getWrapperElement().className += " field";
|
||||
|
||||
function setVersion(ver) {
|
||||
var urlprefix = ver.options[ver.selectedIndex].value;
|
||||
var select = document.getElementById("files"), m;
|
||||
for (var optgr = select.firstChild; optgr; optgr = optgr.nextSibling)
|
||||
for (var opt = optgr.firstChild; opt; opt = opt.nextSibling) {
|
||||
if (opt.nodeName != "OPTION")
|
||||
continue;
|
||||
else if (m = opt.value.match(/^http:\/\/codemirror.net\/(.*)$/))
|
||||
opt.value = urlprefix + m[1];
|
||||
else if (m = opt.value.match(/http:\/\/marijnhaverbeke.nl\/git\/codemirror\?a=blob_plain;hb=[^;]+;f=(.*)$/))
|
||||
opt.value = urlprefix + m[1];
|
||||
}
|
||||
}
|
||||
|
||||
function generateHeader() {
|
||||
var versionNode = document.getElementById("version");
|
||||
var version = versionNode.options[versionNode.selectedIndex].label
|
||||
var filesNode = document.getElementById("files");
|
||||
var optGroupHeaderIncluded;
|
||||
|
||||
// Generate the comment
|
||||
var str = "/* CodeMirror - Minified & Bundled\n";
|
||||
str += " Generated on " + new Date().toLocaleDateString() + " with http://codemirror.net/doc/compress.html\n";
|
||||
str += " Version: " + version + "\n\n";
|
||||
|
||||
for (var group = filesNode.firstChild; group; group = group.nextSibling) {
|
||||
optGroupHeaderIncluded = false;
|
||||
for (var option = group.firstChild; option; option = option.nextSibling) {
|
||||
if (option.nodeName !== "OPTION") {
|
||||
continue;
|
||||
} else if (option.selected) {
|
||||
if (!optGroupHeaderIncluded) {
|
||||
str += " " + group.label + ":\n";
|
||||
optGroupHeaderIncluded = true;
|
||||
}
|
||||
str += " - " + option.label + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
str += " */\n\n";
|
||||
|
||||
document.getElementById("header").value = str;
|
||||
}
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,241 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(//themes.googleusercontent.com/static/fonts/sourcesanspro/v5/ODelI1aHBYDBqgeIAH2zlBM0YzuT7MdOe03otPbuUS0.woff) format('woff');
|
||||
}
|
||||
|
||||
body, html { margin: 0; padding: 0; height: 100%; }
|
||||
section, article { display: block; padding: 0; }
|
||||
|
||||
body {
|
||||
background: #f8f8f8;
|
||||
font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
p { margin-top: 0; }
|
||||
|
||||
h2, h3, h1 {
|
||||
font-weight: normal;
|
||||
margin-bottom: .7em;
|
||||
}
|
||||
h1 { font-size: 140%; }
|
||||
h2 { font-size: 120%; }
|
||||
h3 { font-size: 110%; }
|
||||
article > h2:first-child, section:first-child > h2 { margin-top: 0; }
|
||||
|
||||
#nav h1 {
|
||||
margin-right: 12px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 2px;
|
||||
color: #d30707;
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
|
||||
a, a:visited, a:link, .quasilink {
|
||||
color: #A21313;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
em {
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.quasilink {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
article {
|
||||
max-width: 700px;
|
||||
margin: 0 0 0 160px;
|
||||
border-left: 2px solid #E30808;
|
||||
border-right: 1px solid #ddd;
|
||||
padding: 30px 50px 100px 50px;
|
||||
background: white;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
#nav {
|
||||
position: fixed;
|
||||
padding-top: 30px;
|
||||
max-height: 100%;
|
||||
box-sizing: -moz-border-box;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
left: 0; right: none;
|
||||
width: 160px;
|
||||
text-align: right;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1000px) {
|
||||
article {
|
||||
margin: 0 auto;
|
||||
}
|
||||
#nav {
|
||||
right: 50%;
|
||||
width: auto;
|
||||
border-right: 349px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
#nav ul {
|
||||
display: block;
|
||||
margin: 0; padding: 0;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
#nav li {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
#nav li ul {
|
||||
font-size: 80%;
|
||||
margin-bottom: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav li.active ul {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#nav li li a {
|
||||
padding-right: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#nav ul a {
|
||||
color: black;
|
||||
padding: 0 7px 1px 11px;
|
||||
}
|
||||
|
||||
#nav ul a.active, #nav ul a:hover {
|
||||
border-bottom: 1px solid #E30808;
|
||||
margin-bottom: -1px;
|
||||
color: #E30808;
|
||||
}
|
||||
|
||||
#logo {
|
||||
border: 0;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
section {
|
||||
border-top: 1px solid #E30808;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
|
||||
section.first {
|
||||
border: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#demo {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#demolist {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
z-index: 25;
|
||||
}
|
||||
|
||||
.bankinfo {
|
||||
text-align: left;
|
||||
display: none;
|
||||
padding: 0 .5em;
|
||||
position: absolute;
|
||||
border: 2px solid #aaa;
|
||||
border-radius: 5px;
|
||||
background: #eee;
|
||||
top: 10px;
|
||||
left: 30px;
|
||||
}
|
||||
|
||||
.bankinfo_close {
|
||||
position: absolute;
|
||||
top: 0; right: 6px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bigbutton {
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
padding: 0 1em;
|
||||
display: inline-block;
|
||||
color: white;
|
||||
position: relative;
|
||||
line-height: 1.9;
|
||||
color: white !important;
|
||||
background: #A21313;
|
||||
}
|
||||
|
||||
.bigbutton.right {
|
||||
border-bottom-left-radius: 100px;
|
||||
border-top-left-radius: 100px;
|
||||
}
|
||||
|
||||
.bigbutton.left {
|
||||
border-bottom-right-radius: 100px;
|
||||
border-top-right-radius: 100px;
|
||||
}
|
||||
|
||||
.bigbutton:hover {
|
||||
background: #E30808;
|
||||
}
|
||||
|
||||
th {
|
||||
text-decoration: underline;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#features ul {
|
||||
list-style: none;
|
||||
margin: 0 0 1em;
|
||||
padding: 0 0 0 1.2em;
|
||||
}
|
||||
|
||||
#features li:before {
|
||||
content: "-";
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-left: -1em;
|
||||
}
|
||||
|
||||
.rel {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.rel-note {
|
||||
margin-top: 0;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding-left: 15px;
|
||||
border-left: 2px solid #ddd;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
strong {
|
||||
text-decoration: underline;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.field {
|
||||
border: 1px solid #A21313;
|
||||
}
|
@ -1,503 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Internals</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
<style>dl dl {margin: 0;} .update {color: #d40 !important}</style>
|
||||
<script src="activebookmark.js"></script>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="#top">Introduction</a></li>
|
||||
<li><a href="#approach">General Approach</a></li>
|
||||
<li><a href="#input">Input</a></li>
|
||||
<li><a href="#selection">Selection</a></li>
|
||||
<li><a href="#update">Intelligent Updating</a></li>
|
||||
<li><a href="#parse">Parsing</a></li>
|
||||
<li><a href="#summary">What Gives?</a></li>
|
||||
<li><a href="#btree">Content Representation</a></li>
|
||||
<li><a href="#keymap">Key Maps</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2 id=top>(Re-) Implementing A Syntax-Highlighting Editor in JavaScript</h2>
|
||||
|
||||
<p style="font-size: 85%" id="intro">
|
||||
<strong>Topic:</strong> JavaScript, code editor implementation<br>
|
||||
<strong>Author:</strong> Marijn Haverbeke<br>
|
||||
<strong>Date:</strong> March 2nd 2011 (updated November 13th 2011)
|
||||
</p>
|
||||
|
||||
<p style="padding: 0 3em 0 2em"><strong>Caution</strong>: this text was written briefly after
|
||||
version 2 was initially written. It no longer (even including the
|
||||
update at the bottom) fully represents the current implementation. I'm
|
||||
leaving it here as a historic document. For more up-to-date
|
||||
information, look at the entries
|
||||
tagged <a href="http://marijnhaverbeke.nl/blog/#cm-internals">cm-internals</a>
|
||||
on my blog.</p>
|
||||
|
||||
<p>This is a followup to
|
||||
my <a href="http://codemirror.net/story.html">Brutal Odyssey to the
|
||||
Dark Side of the DOM Tree</a> story. That one describes the
|
||||
mind-bending process of implementing (what would become) CodeMirror 1.
|
||||
This one describes the internals of CodeMirror 2, a complete rewrite
|
||||
and rethink of the old code base. I wanted to give this piece another
|
||||
Hunter Thompson copycat subtitle, but somehow that would be out of
|
||||
place—the process this time around was one of straightforward
|
||||
engineering, requiring no serious mind-bending whatsoever.</p>
|
||||
|
||||
<p>So, what is wrong with CodeMirror 1? I'd estimate, by mailing list
|
||||
activity and general search-engine presence, that it has been
|
||||
integrated into about a thousand systems by now. The most prominent
|
||||
one, since a few weeks,
|
||||
being <a href="http://googlecode.blogspot.com/2011/01/make-quick-fixes-quicker-on-google.html">Google
|
||||
code's project hosting</a>. It works, and it's being used widely.</p>
|
||||
|
||||
<p>Still, I did not start replacing it because I was bored. CodeMirror
|
||||
1 was heavily reliant on <code>designMode</code>
|
||||
or <code>contentEditable</code> (depending on the browser). Neither of
|
||||
these are well specified (HTML5 tries
|
||||
to <a href="http://www.w3.org/TR/html5/editing.html#contenteditable">specify</a>
|
||||
their basics), and, more importantly, they tend to be one of the more
|
||||
obscure and buggy areas of browser functionality—CodeMirror, by using
|
||||
this functionality in a non-typical way, was constantly running up
|
||||
against browser bugs. WebKit wouldn't show an empty line at the end of
|
||||
the document, and in some releases would suddenly get unbearably slow.
|
||||
Firefox would show the cursor in the wrong place. Internet Explorer
|
||||
would insist on linkifying everything that looked like a URL or email
|
||||
address, a behaviour that can't be turned off. Some bugs I managed to
|
||||
work around (which was often a frustrating, painful process), others,
|
||||
such as the Firefox cursor placement, I gave up on, and had to tell
|
||||
user after user that they were known problems, but not something I
|
||||
could help.</p>
|
||||
|
||||
<p>Also, there is the fact that <code>designMode</code> (which seemed
|
||||
to be less buggy than <code>contentEditable</code> in Webkit and
|
||||
Firefox, and was thus used by CodeMirror 1 in those browsers) requires
|
||||
a frame. Frames are another tricky area. It takes some effort to
|
||||
prevent getting tripped up by domain restrictions, they don't
|
||||
initialize synchronously, behave strangely in response to the back
|
||||
button, and, on several browsers, can't be moved around the DOM
|
||||
without having them re-initialize. They did provide a very nice way to
|
||||
namespace the library, though—CodeMirror 1 could freely pollute the
|
||||
namespace inside the frame.</p>
|
||||
|
||||
<p>Finally, working with an editable document means working with
|
||||
selection in arbitrary DOM structures. Internet Explorer (8 and
|
||||
before) has an utterly different (and awkward) selection API than all
|
||||
of the other browsers, and even among the different implementations of
|
||||
<code>document.selection</code>, details about how exactly a selection
|
||||
is represented vary quite a bit. Add to that the fact that Opera's
|
||||
selection support tended to be very buggy until recently, and you can
|
||||
imagine why CodeMirror 1 contains 700 lines of selection-handling
|
||||
code.</p>
|
||||
|
||||
<p>And that brings us to the main issue with the CodeMirror 1
|
||||
code base: The proportion of browser-bug-workarounds to real
|
||||
application code was getting dangerously high. By building on top of a
|
||||
few dodgy features, I put the system in a vulnerable position—any
|
||||
incompatibility and bugginess in these features, I had to paper over
|
||||
with my own code. Not only did I have to do some serious stunt-work to
|
||||
get it to work on older browsers (as detailed in the
|
||||
previous <a href="http://codemirror.net/story.html">story</a>), things
|
||||
also kept breaking in newly released versions, requiring me to come up
|
||||
with <em>new</em> scary hacks in order to keep up. This was starting
|
||||
to lose its appeal.</p>
|
||||
|
||||
<section id=approach>
|
||||
<h2>General Approach</h2>
|
||||
|
||||
<p>What CodeMirror 2 does is try to sidestep most of the hairy hacks
|
||||
that came up in version 1. I owe a lot to the
|
||||
<a href="http://ace.ajax.org">ACE</a> editor for inspiration on how to
|
||||
approach this.</p>
|
||||
|
||||
<p>I absolutely did not want to be completely reliant on key events to
|
||||
generate my input. Every JavaScript programmer knows that key event
|
||||
information is horrible and incomplete. Some people (most awesomely
|
||||
Mihai Bazon with <a href="http://ymacs.org">Ymacs</a>) have been able
|
||||
to build more or less functioning editors by directly reading key
|
||||
events, but it takes a lot of work (the kind of never-ending, fragile
|
||||
work I described earlier), and will never be able to properly support
|
||||
things like multi-keystoke international character
|
||||
input. <a href="#keymap" class="update">[see below for caveat]</a></p>
|
||||
|
||||
<p>So what I do is focus a hidden textarea, and let the browser
|
||||
believe that the user is typing into that. What we show to the user is
|
||||
a DOM structure we built to represent his document. If this is updated
|
||||
quickly enough, and shows some kind of believable cursor, it feels
|
||||
like a real text-input control.</p>
|
||||
|
||||
<p>Another big win is that this DOM representation does not have to
|
||||
span the whole document. Some CodeMirror 1 users insisted that they
|
||||
needed to put a 30 thousand line XML document into CodeMirror. Putting
|
||||
all that into the DOM takes a while, especially since, for some
|
||||
reason, an editable DOM tree is slower than a normal one on most
|
||||
browsers. If we have full control over what we show, we must only
|
||||
ensure that the visible part of the document has been added, and can
|
||||
do the rest only when needed. (Fortunately, the <code>onscroll</code>
|
||||
event works almost the same on all browsers, and lends itself well to
|
||||
displaying things only as they are scrolled into view.)</p>
|
||||
</section>
|
||||
<section id="input">
|
||||
<h2>Input</h2>
|
||||
|
||||
<p>ACE uses its hidden textarea only as a text input shim, and does
|
||||
all cursor movement and things like text deletion itself by directly
|
||||
handling key events. CodeMirror's way is to let the browser do its
|
||||
thing as much as possible, and not, for example, define its own set of
|
||||
key bindings. One way to do this would have been to have the whole
|
||||
document inside the hidden textarea, and after each key event update
|
||||
the display DOM to reflect what's in that textarea.</p>
|
||||
|
||||
<p>That'd be simple, but it is not realistic. For even medium-sized
|
||||
document the editor would be constantly munging huge strings, and get
|
||||
terribly slow. What CodeMirror 2 does is put the current selection,
|
||||
along with an extra line on the top and on the bottom, into the
|
||||
textarea.</p>
|
||||
|
||||
<p>This means that the arrow keys (and their ctrl-variations), home,
|
||||
end, etcetera, do not have to be handled specially. We just read the
|
||||
cursor position in the textarea, and update our cursor to match it.
|
||||
Also, copy and paste work pretty much for free, and people get their
|
||||
native key bindings, without any special work on my part. For example,
|
||||
I have emacs key bindings configured for Chrome and Firefox. There is
|
||||
no way for a script to detect this. <a class="update"
|
||||
href="#keymap">[no longer the case]</a></p>
|
||||
|
||||
<p>Of course, since only a small part of the document sits in the
|
||||
textarea, keys like page up and ctrl-end won't do the right thing.
|
||||
CodeMirror is catching those events and handling them itself.</p>
|
||||
</section>
|
||||
<section id="selection">
|
||||
<h2>Selection</h2>
|
||||
|
||||
<p>Getting and setting the selection range of a textarea in modern
|
||||
browsers is trivial—you just use the <code>selectionStart</code>
|
||||
and <code>selectionEnd</code> properties. On IE you have to do some
|
||||
insane stuff with temporary ranges and compensating for the fact that
|
||||
moving the selection by a 'character' will treat \r\n as a single
|
||||
character, but even there it is possible to build functions that
|
||||
reliably set and get the selection range.</p>
|
||||
|
||||
<p>But consider this typical case: When I'm somewhere in my document,
|
||||
press shift, and press the up arrow, something gets selected. Then, if
|
||||
I, still holding shift, press the up arrow again, the top of my
|
||||
selection is adjusted. The selection remembers where its <em>head</em>
|
||||
and its <em>anchor</em> are, and moves the head when we shift-move.
|
||||
This is a generally accepted property of selections, and done right by
|
||||
every editing component built in the past twenty years.</p>
|
||||
|
||||
<p>But not something that the browser selection APIs expose.</p>
|
||||
|
||||
<p>Great. So when someone creates an 'upside-down' selection, the next
|
||||
time CodeMirror has to update the textarea, it'll re-create the
|
||||
selection as an 'upside-up' selection, with the anchor at the top, and
|
||||
the next cursor motion will behave in an unexpected way—our second
|
||||
up-arrow press in the example above will not do anything, since it is
|
||||
interpreted in exactly the same way as the first.</p>
|
||||
|
||||
<p>No problem. We'll just, ehm, detect that the selection is
|
||||
upside-down (you can tell by the way it was created), and then, when
|
||||
an upside-down selection is present, and a cursor-moving key is
|
||||
pressed in combination with shift, we quickly collapse the selection
|
||||
in the textarea to its start, allow the key to take effect, and then
|
||||
combine its new head with its old anchor to get the <em>real</em>
|
||||
selection.</p>
|
||||
|
||||
<p>In short, scary hacks could not be avoided entirely in CodeMirror
|
||||
2.</p>
|
||||
|
||||
<p>And, the observant reader might ask, how do you even know that a
|
||||
key combo is a cursor-moving combo, if you claim you support any
|
||||
native key bindings? Well, we don't, but we can learn. The editor
|
||||
keeps a set known cursor-movement combos (initialized to the
|
||||
predictable defaults), and updates this set when it observes that
|
||||
pressing a certain key had (only) the effect of moving the cursor.
|
||||
This, of course, doesn't work if the first time the key is used was
|
||||
for extending an inverted selection, but it works most of the
|
||||
time.</p>
|
||||
</section>
|
||||
<section id="update">
|
||||
<h2>Intelligent Updating</h2>
|
||||
|
||||
<p>One thing that always comes up when you have a complicated internal
|
||||
state that's reflected in some user-visible external representation
|
||||
(in this case, the displayed code and the textarea's content) is
|
||||
keeping the two in sync. The naive way is to just update the display
|
||||
every time you change your state, but this is not only error prone
|
||||
(you'll forget), it also easily leads to duplicate work on big,
|
||||
composite operations. Then you start passing around flags indicating
|
||||
whether the display should be updated in an attempt to be efficient
|
||||
again and, well, at that point you might as well give up completely.</p>
|
||||
|
||||
<p>I did go down that road, but then switched to a much simpler model:
|
||||
simply keep track of all the things that have been changed during an
|
||||
action, and then, only at the end, use this information to update the
|
||||
user-visible display.</p>
|
||||
|
||||
<p>CodeMirror uses a concept of <em>operations</em>, which start by
|
||||
calling a specific set-up function that clears the state and end by
|
||||
calling another function that reads this state and does the required
|
||||
updating. Most event handlers, and all the user-visible methods that
|
||||
change state are wrapped like this. There's a method
|
||||
called <code>operation</code> that accepts a function, and returns
|
||||
another function that wraps the given function as an operation.</p>
|
||||
|
||||
<p>It's trivial to extend this (as CodeMirror does) to detect nesting,
|
||||
and, when an operation is started inside an operation, simply
|
||||
increment the nesting count, and only do the updating when this count
|
||||
reaches zero again.</p>
|
||||
|
||||
<p>If we have a set of changed ranges and know the currently shown
|
||||
range, we can (with some awkward code to deal with the fact that
|
||||
changes can add and remove lines, so we're dealing with a changing
|
||||
coordinate system) construct a map of the ranges that were left
|
||||
intact. We can then compare this map with the part of the document
|
||||
that's currently visible (based on scroll offset and editor height) to
|
||||
determine whether something needs to be updated.</p>
|
||||
|
||||
<p>CodeMirror uses two update algorithms—a full refresh, where it just
|
||||
discards the whole part of the DOM that contains the edited text and
|
||||
rebuilds it, and a patch algorithm, where it uses the information
|
||||
about changed and intact ranges to update only the out-of-date parts
|
||||
of the DOM. When more than 30 percent (which is the current heuristic,
|
||||
might change) of the lines need to be updated, the full refresh is
|
||||
chosen (since it's faster to do than painstakingly finding and
|
||||
updating all the changed lines), in the other case it does the
|
||||
patching (so that, if you scroll a line or select another character,
|
||||
the whole screen doesn't have to be
|
||||
re-rendered). <span class="update">[the full-refresh
|
||||
algorithm was dropped, it wasn't really faster than the patching
|
||||
one]</span></p>
|
||||
|
||||
<p>All updating uses <code>innerHTML</code> rather than direct DOM
|
||||
manipulation, since that still seems to be by far the fastest way to
|
||||
build documents. There's a per-line function that combines the
|
||||
highlighting, <a href="manual.html#markText">marking</a>, and
|
||||
selection info for that line into a snippet of HTML. The patch updater
|
||||
uses this to reset individual lines, the refresh updater builds an
|
||||
HTML chunk for the whole visible document at once, and then uses a
|
||||
single <code>innerHTML</code> update to do the refresh.</p>
|
||||
</section>
|
||||
<section id="parse">
|
||||
<h2>Parsers can be Simple</h2>
|
||||
|
||||
<p>When I wrote CodeMirror 1, I
|
||||
thought <a href="http://codemirror.net/story.html#parser">interruptable
|
||||
parsers</a> were a hugely scary and complicated thing, and I used a
|
||||
bunch of heavyweight abstractions to keep this supposed complexity
|
||||
under control: parsers
|
||||
were <a href="http://bob.pythonmac.org/archives/2005/07/06/iteration-in-javascript/">iterators</a>
|
||||
that consumed input from another iterator, and used funny
|
||||
closure-resetting tricks to copy and resume themselves.</p>
|
||||
|
||||
<p>This made for a rather nice system, in that parsers formed strictly
|
||||
separate modules, and could be composed in predictable ways.
|
||||
Unfortunately, it was quite slow (stacking three or four iterators on
|
||||
top of each other), and extremely intimidating to people not used to a
|
||||
functional programming style.</p>
|
||||
|
||||
<p>With a few small changes, however, we can keep all those
|
||||
advantages, but simplify the API and make the whole thing less
|
||||
indirect and inefficient. CodeMirror
|
||||
2's <a href="manual.html#modeapi">mode API</a> uses explicit state
|
||||
objects, and makes the parser/tokenizer a function that simply takes a
|
||||
state and a character stream abstraction, advances the stream one
|
||||
token, and returns the way the token should be styled. This state may
|
||||
be copied, optionally in a mode-defined way, in order to be able to
|
||||
continue a parse at a given point. Even someone who's never touched a
|
||||
lambda in his life can understand this approach. Additionally, far
|
||||
fewer objects are allocated in the course of parsing now.</p>
|
||||
|
||||
<p>The biggest speedup comes from the fact that the parsing no longer
|
||||
has to touch the DOM though. In CodeMirror 1, on an older browser, you
|
||||
could <em>see</em> the parser work its way through the document,
|
||||
managing some twenty lines in each 50-millisecond time slice it got. It
|
||||
was reading its input from the DOM, and updating the DOM as it went
|
||||
along, which any experienced JavaScript programmer will immediately
|
||||
spot as a recipe for slowness. In CodeMirror 2, the parser usually
|
||||
finishes the whole document in a single 100-millisecond time slice—it
|
||||
manages some 1500 lines during that time on Chrome. All it has to do
|
||||
is munge strings, so there is no real reason for it to be slow
|
||||
anymore.</p>
|
||||
</section>
|
||||
<section id="summary">
|
||||
<h2>What Gives?</h2>
|
||||
|
||||
<p>Given all this, what can you expect from CodeMirror 2?</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><strong>Small.</strong> the base library is
|
||||
some <span class="update">45k</span> when minified
|
||||
now, <span class="update">17k</span> when gzipped. It's smaller than
|
||||
its own logo.</li>
|
||||
|
||||
<li><strong>Lightweight.</strong> CodeMirror 2 initializes very
|
||||
quickly, and does almost no work when it is not focused. This means
|
||||
you can treat it almost like a textarea, have multiple instances on a
|
||||
page without trouble.</li>
|
||||
|
||||
<li><strong>Huge document support.</strong> Since highlighting is
|
||||
really fast, and no DOM structure is being built for non-visible
|
||||
content, you don't have to worry about locking up your browser when a
|
||||
user enters a megabyte-sized document.</li>
|
||||
|
||||
<li><strong>Extended API.</strong> Some things kept coming up in the
|
||||
mailing list, such as marking pieces of text or lines, which were
|
||||
extremely hard to do with CodeMirror 1. The new version has proper
|
||||
support for these built in.</li>
|
||||
|
||||
<li><strong>Tab support.</strong> Tabs inside editable documents were,
|
||||
for some reason, a no-go. At least six different people announced they
|
||||
were going to add tab support to CodeMirror 1, none survived (I mean,
|
||||
none delivered a working version). CodeMirror 2 no longer removes tabs
|
||||
from your document.</li>
|
||||
|
||||
<li><strong>Sane styling.</strong> <code>iframe</code> nodes aren't
|
||||
really known for respecting document flow. Now that an editor instance
|
||||
is a plain <code>div</code> element, it is much easier to size it to
|
||||
fit the surrounding elements. You don't even have to make it scroll if
|
||||
you do not <a href="../demo/resize.html">want to</a>.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>On the downside, a CodeMirror 2 instance is <em>not</em> a native
|
||||
editable component. Though it does its best to emulate such a
|
||||
component as much as possible, there is functionality that browsers
|
||||
just do not allow us to hook into. Doing select-all from the context
|
||||
menu, for example, is not currently detected by CodeMirror.</p>
|
||||
|
||||
<p id="changes" style="margin-top: 2em;"><span style="font-weight:
|
||||
bold">[Updates from November 13th 2011]</span> Recently, I've made
|
||||
some changes to the codebase that cause some of the text above to no
|
||||
longer be current. I've left the text intact, but added markers at the
|
||||
passages that are now inaccurate. The new situation is described
|
||||
below.</p>
|
||||
</section>
|
||||
<section id="btree">
|
||||
<h2>Content Representation</h2>
|
||||
|
||||
<p>The original implementation of CodeMirror 2 represented the
|
||||
document as a flat array of line objects. This worked well—splicing
|
||||
arrays will require the part of the array after the splice to be
|
||||
moved, but this is basically just a simple <code>memmove</code> of a
|
||||
bunch of pointers, so it is cheap even for huge documents.</p>
|
||||
|
||||
<p>However, I recently added line wrapping and code folding (line
|
||||
collapsing, basically). Once lines start taking up a non-constant
|
||||
amount of vertical space, looking up a line by vertical position
|
||||
(which is needed when someone clicks the document, and to determine
|
||||
the visible part of the document during scrolling) can only be done
|
||||
with a linear scan through the whole array, summing up line heights as
|
||||
you go. Seeing how I've been going out of my way to make big documents
|
||||
fast, this is not acceptable.</p>
|
||||
|
||||
<p>The new representation is based on a B-tree. The leaves of the tree
|
||||
contain arrays of line objects, with a fixed minimum and maximum size,
|
||||
and the non-leaf nodes simply hold arrays of child nodes. Each node
|
||||
stores both the amount of lines that live below them and the vertical
|
||||
space taken up by these lines. This allows the tree to be indexed both
|
||||
by line number and by vertical position, and all access has
|
||||
logarithmic complexity in relation to the document size.</p>
|
||||
|
||||
<p>I gave line objects and tree nodes parent pointers, to the node
|
||||
above them. When a line has to update its height, it can simply walk
|
||||
these pointers to the top of the tree, adding or subtracting the
|
||||
difference in height from each node it encounters. The parent pointers
|
||||
also make it cheaper (in complexity terms, the difference is probably
|
||||
tiny in normal-sized documents) to find the current line number when
|
||||
given a line object. In the old approach, the whole document array had
|
||||
to be searched. Now, we can just walk up the tree and count the sizes
|
||||
of the nodes coming before us at each level.</p>
|
||||
|
||||
<p>I chose B-trees, not regular binary trees, mostly because they
|
||||
allow for very fast bulk insertions and deletions. When there is a big
|
||||
change to a document, it typically involves adding, deleting, or
|
||||
replacing a chunk of subsequent lines. In a regular balanced tree, all
|
||||
these inserts or deletes would have to be done separately, which could
|
||||
be really expensive. In a B-tree, to insert a chunk, you just walk
|
||||
down the tree once to find where it should go, insert them all in one
|
||||
shot, and then break up the node if needed. This breaking up might
|
||||
involve breaking up nodes further up, but only requires a single pass
|
||||
back up the tree. For deletion, I'm somewhat lax in keeping things
|
||||
balanced—I just collapse nodes into a leaf when their child count goes
|
||||
below a given number. This means that there are some weird editing
|
||||
patterns that may result in a seriously unbalanced tree, but even such
|
||||
an unbalanced tree will perform well, unless you spend a day making
|
||||
strangely repeating edits to a really big document.</p>
|
||||
</section>
|
||||
<section id="keymap">
|
||||
<h2>Keymaps</h2>
|
||||
|
||||
<p><a href="#approach">Above</a>, I claimed that directly catching key
|
||||
events for things like cursor movement is impractical because it
|
||||
requires some browser-specific kludges. I then proceeded to explain
|
||||
some awful <a href="#selection">hacks</a> that were needed to make it
|
||||
possible for the selection changes to be detected through the
|
||||
textarea. In fact, the second hack is about as bad as the first.</p>
|
||||
|
||||
<p>On top of that, in the presence of user-configurable tab sizes and
|
||||
collapsed and wrapped lines, lining up cursor movement in the textarea
|
||||
with what's visible on the screen becomes a nightmare. Thus, I've
|
||||
decided to move to a model where the textarea's selection is no longer
|
||||
depended on.</p>
|
||||
|
||||
<p>So I moved to a model where all cursor movement is handled by my
|
||||
own code. This adds support for a goal column, proper interaction of
|
||||
cursor movement with collapsed lines, and makes it possible for
|
||||
vertical movement to move through wrapped lines properly, instead of
|
||||
just treating them like non-wrapped lines.</p>
|
||||
|
||||
<p>The key event handlers now translate the key event into a string,
|
||||
something like <code>Ctrl-Home</code> or <code>Shift-Cmd-R</code>, and
|
||||
use that string to look up an action to perform. To make keybinding
|
||||
customizable, this lookup goes through
|
||||
a <a href="manual.html#option_keyMap">table</a>, using a scheme that
|
||||
allows such tables to be chained together (for example, the default
|
||||
Mac bindings fall through to a table named 'emacsy', which defines
|
||||
basic Emacs-style bindings like <code>Ctrl-F</code>, and which is also
|
||||
used by the custom Emacs bindings).</p>
|
||||
|
||||
<p>A new
|
||||
option <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
|
||||
allows ad-hoc keybindings to be defined in a much nicer way than what
|
||||
was possible with the
|
||||
old <a href="manual.html#option_onKeyEvent"><code>onKeyEvent</code></a>
|
||||
callback. You simply provide an object mapping key identifiers to
|
||||
functions, instead of painstakingly looking at raw key events.</p>
|
||||
|
||||
<p>Built-in commands map to strings, rather than functions, for
|
||||
example <code>"goLineUp"</code> is the default action bound to the up
|
||||
arrow key. This allows new keymaps to refer to them without
|
||||
duplicating any code. New commands can be defined by assigning to
|
||||
the <code>CodeMirror.commands</code> object, which maps such commands
|
||||
to functions.</p>
|
||||
|
||||
<p>The hidden textarea now only holds the current selection, with no
|
||||
extra characters around it. This has a nice advantage: polling for
|
||||
input becomes much, much faster. If there's a big selection, this text
|
||||
does not have to be read from the textarea every time—when we poll,
|
||||
just noticing that something is still selected is enough to tell us
|
||||
that no new text was typed.</p>
|
||||
|
||||
<p>The reason that cheap polling is important is that many browsers do
|
||||
not fire useful events on IME (input method engine) input, which is
|
||||
the thing where people inputting a language like Japanese or Chinese
|
||||
use multiple keystrokes to create a character or sequence of
|
||||
characters. Most modern browsers fire <code>input</code> when the
|
||||
composing is finished, but many don't fire anything when the character
|
||||
is updated <em>during</em> composition. So we poll, whenever the
|
||||
editor is focused, to provide immediate updates of the display.</p>
|
||||
|
||||
</article>
|
Binary file not shown.
Before Width: | Height: | Size: 9.1 KiB |
@ -1,181 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
width="640"
|
||||
height="640"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:export-filename="/home/marijn/src/js/codemirror/doc/logo.png"
|
||||
inkscape:export-xdpi="16.601332"
|
||||
inkscape:export-ydpi="16.601332"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath16"><path
|
||||
d="M 0,512 512,512 512,0 0,0 0,512 z"
|
||||
id="path18" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath40"><path
|
||||
d="m 435.607,369.899 31.242,0 0,-64.782 -31.242,0 0,64.782 z"
|
||||
id="path42" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath56"><path
|
||||
d="m 421.796,349.477 39.074,0 0,-88.423 -39.074,0 0,88.423 z"
|
||||
id="path58" /></clipPath></defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="875"
|
||||
id="namedview4"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:zoom="0.52149125"
|
||||
inkscape:cx="303.572"
|
||||
inkscape:cy="574.48012"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="g10" /><g
|
||||
id="g10"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="2014-10_codeMirror_logo_vectors"
|
||||
transform="matrix(1.25,0,0,-1.25,0,640)"><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path22"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 233.97976,469.37438 c 0,0 7.01353,-14.94848 -2.94916,-31.42373 -4.97925,-8.23417 -130.50847,-34.94915 -179.50847,-102.94915 -30,-47 -76,-183 71,-273 66,-34 94,-33 94,-33 0,0 -44,31 -16,52 28,21 69,31 80,60 13,-10 34,-31 54,-29 -2,13 -7,18 9,20 16,2 24,2 24,2 0,0 -15,12 -32,13 -17,1 -49,34 -48,48 21,12 48,32 64,26 16,-6 32,-16 35,-25 0,-6 -3,-16 10,-8 13,8 10,13 15,24 5,11 6,13 -5,22 -11,9 -37,30 -58,24 -21,-6 -65,-23 -87,-2 9,20 23,52 16,74 13,10 28,21 30,39 15,2 47,11 41,27 -6,16 -48.59322,87.16949 -113.59322,73.16949"
|
||||
sodipodi:nodetypes="cscccsccscscscsssscccsc" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path26"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 441.52213,306.0015 c 11,29 29,78 12,80 -17,2 -36,-44 -41,-56 -5,-12 -25,-72 -14,-80 11,-8 43,56 43,56" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path30"
|
||||
style="fill:#da687d;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 348.52213,384.0015 c 3.13,4.919 5.82086,0.64508 -7.67914,-0.35492 -13.5,-1 -29.62196,-5.18461 -32.38899,-11.04836 -5.19174,-11.00208 -6.93187,-38.09672 -26.43187,-44.09672 -1,-7 0,-23 27.5,-26 27.5,-3 28.5,15 44.5,14.5 16,-0.5 14.5,5.5 9,10 -5.5,4.5 -24.5,35 -24.5,45 0,10 6.5,6.5 10,12"
|
||||
sodipodi:nodetypes="csscssssc" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path34"
|
||||
style="fill:#da687d;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 103.02213,82.502 c 0,0 -8.5,22.5 16.5,34.5 25,12 47.5,2.5 52,-6 4.5,-8.5 -7.5,-42.5 -50.5,-43 -10.5,8.5 -18,14.5 -18,14.5" /><g
|
||||
id="g38"
|
||||
transform="translate(-21.47687,0)" /><g
|
||||
id="g44"
|
||||
transform="translate(-21.47687,0)"><g
|
||||
style="opacity:0.69999701"
|
||||
id="g46"
|
||||
clip-path="url(#clipPath40)"><g
|
||||
id="g48"
|
||||
transform="translate(466.2583,369.8384)"><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path50"
|
||||
style="fill:#da687d;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="M 0,0 C 0.423,-1.569 0.298,-3.199 0.255,-4.838 0.213,-6.452 0.062,-8.15 -0.349,-9.801 c 0.106,-0.377 -0.082,-0.814 -0.018,-1.201 -0.41,-0.515 -0.194,-0.903 -0.284,-1.354 0.661,-0.674 1.522,-1.313 1.152,-2.162 -0.259,-0.596 -0.874,-0.706 -1.464,-0.995 -0.389,-1.403 -0.709,-3.099 -1.028,-4.649 -0.097,-0.476 -0.044,-1.051 -0.187,-1.485 -0.334,-1.01 -0.691,-1.978 -0.971,-3.09 -0.237,-0.945 0.034,-2.689 -1.063,-2.811 -0.423,-1.049 -0.663,-1.841 -1.165,-2.83 -0.286,-0.163 -0.452,0.106 -0.692,0.009 -0.305,-0.348 -0.294,-0.823 -0.577,-1.114 -0.222,-0.229 -0.503,-0.163 -0.665,-0.385 -0.363,-0.5 -0.266,-1.24 -0.523,-1.902 -0.468,-0.4 -0.862,-0.905 -1.147,-1.478 -0.588,-1.179 -0.698,-2.681 -1.591,-3.593 -0.28,-0.286 -0.761,-0.365 -1.011,-0.647 -0.238,-0.269 -0.455,-0.665 -0.689,-0.98 -0.338,-0.452 -0.669,-1.045 -0.972,-1.583 -1.004,-1.787 -2.383,-3.71 -3.301,-5.664 -0.173,-0.369 -0.199,-0.805 -0.364,-1.165 -0.381,-0.827 -0.943,-1.579 -1.257,-2.333 -0.516,-1.239 -1.31,-3.339 -2.538,-4.42 -0.149,-0.131 -0.473,-0.254 -0.606,-0.414 -0.179,-0.215 -0.136,-0.568 -0.32,-0.808 -0.086,-0.113 -0.4,-0.164 -0.537,-0.302 -0.208,-0.211 -0.306,-0.481 -0.479,-0.639 -0.426,-0.388 -1.015,-0.555 -1.381,-0.959 -0.277,-0.306 -0.397,-0.743 -0.692,-1.127 -0.318,-0.413 -0.761,-0.784 -1.09,-1.202 -0.994,-1.264 -1.38,-2.8 -2.702,-3.396 -0.393,-0.178 -0.88,-0.12 -1.291,-0.241 -0.374,0.344 -0.078,0.818 -0.163,1.164 -0.055,0.222 -0.285,0.382 -0.346,0.583 -0.143,0.474 -0.347,1.336 -0.34,1.878 0.007,0.538 0.305,0.971 0.375,1.612 0.061,0.549 -0.137,1.246 -0.177,1.856 -0.021,0.306 0.064,0.624 0.059,0.956 -0.008,0.533 -0.066,0.801 0.008,1.442 0.086,0.743 -0.074,1.462 -0.171,2.152 0.342,1.705 0.531,3.008 1.09,4.919 0.258,0.881 0.721,2.367 1.18,3.346 0.886,1.895 1.64,3.964 2.6,5.945 0.319,0.656 0.825,1.196 1.139,1.852 0.182,0.381 0.211,0.828 0.395,1.215 1.617,3.398 3.877,6.233 5.565,9.731 1.399,2.859 2.88,5.418 4.745,8.545 0.842,1.415 1.568,2.917 2.434,4.086 0.66,0.891 1.632,2.413 2.334,3.916 0.278,0.596 0.269,1.073 1.005,1.102 0.758,0.948 1.326,2.018 2.119,2.824 0.2,0.202 0.51,0.303 0.733,0.498 0.26,0.228 0.383,0.57 0.638,0.778 0.541,0.441 1.432,0.832 2.035,1.659 0.16,0.22 0.229,0.451 0.406,0.682 0.414,0.539 1.191,1.866 1.81,2.013 C -0.241,0.085 -0.126,0.061 0,0" /></g></g></g><g
|
||||
id="g54"
|
||||
transform="translate(-21.47687,0)" /><g
|
||||
id="g60"
|
||||
transform="translate(-21.47687,0)"><g
|
||||
style="opacity:0.69999701"
|
||||
id="g62"
|
||||
clip-path="url(#clipPath56)"><g
|
||||
id="g64"
|
||||
transform="translate(459.8965,349.4487)"><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path66"
|
||||
style="fill:#da687d;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="m 0,0 c 0.688,-1.936 0.765,-4.106 0.935,-6.266 -0.019,-2.14 -0.168,-4.579 -0.715,-6.943 0.098,-0.492 -0.155,-1.108 -0.109,-1.623 -0.519,-0.752 -0.295,-1.25 -0.438,-1.876 0.718,-0.835 1.666,-1.609 1.155,-2.836 -0.37,-0.846 -1.118,-1.037 -1.845,-1.479 -0.64,-1.905 -1.226,-4.263 -1.846,-6.305 -0.187,-0.635 -0.212,-1.395 -0.447,-1.977 -0.547,-1.362 -1.111,-2.656 -1.597,-4.101 -0.416,-1.238 -0.356,-3.498 -1.652,-3.689 -0.61,-1.355 -0.978,-2.373 -1.674,-3.651 -0.35,-0.217 -0.512,0.119 -0.801,-0.013 -0.392,-0.456 -0.442,-1.063 -0.795,-1.445 -0.269,-0.298 -0.585,-0.226 -0.785,-0.514 -0.449,-0.651 -0.386,-1.58 -0.723,-2.425 -0.282,-0.266 -0.546,-0.564 -0.784,-0.888 -0.119,-0.162 -0.233,-0.33 -0.337,-0.505 l -0.153,-0.266 -0.072,-0.136 -0.034,-0.069 -0.003,-0.004 0,-10e-4 c 0.099,0.238 0.028,0.066 0.05,0.119 l -10e-4,-0.002 -0.001,-10e-4 -0.004,-0.01 -0.008,-0.019 -0.016,-0.037 c -0.697,-1.635 -0.851,-3.63 -1.895,-4.955 -0.335,-0.421 -0.872,-0.577 -1.142,-0.971 -0.259,-0.375 -0.491,-0.912 -0.746,-1.347 -0.366,-0.625 -0.722,-1.432 -1.046,-2.164 -1.085,-2.456 -2.571,-5.274 -3.572,-8.03 -0.188,-0.523 -0.205,-1.106 -0.385,-1.617 -0.422,-1.173 -1.022,-2.273 -1.394,-3.342 -0.626,-1.753 -1.474,-4.727 -3.01,-6.377 -0.182,-0.2 -0.567,-0.415 -0.732,-0.65 -0.22,-0.315 -0.191,-0.786 -0.42,-1.137 -0.106,-0.164 -0.475,-0.275 -0.642,-0.48 -0.254,-0.313 -0.383,-0.69 -0.594,-0.926 -0.503,-0.581 -1.23,-0.865 -1.714,-1.438 -0.365,-0.435 -0.562,-1.029 -0.958,-1.568 -0.426,-0.578 -0.991,-1.104 -1.428,-1.683 -0.65,-0.928 -1.251,-1.786 -1.828,-2.608 -0.592,-0.813 -1.215,-1.514 -2.047,-1.884 -0.495,-0.219 -1.042,-0.12 -1.539,-0.256 -0.353,0.473 0.086,1.071 0.061,1.524 -0.018,0.288 -0.25,0.504 -0.28,0.766 -0.07,0.615 -0.141,1.712 -0.035,2.387 0.099,0.676 0.548,1.191 0.712,2.005 0.125,0.708 -0.034,1.591 -0.025,2.359 0.004,0.387 0.13,0.791 0.153,1.206 0.038,0.668 -0.008,0.999 0.13,1.795 0.163,0.922 -0.034,1.854 -0.121,2.709 0.426,2.191 0.686,3.806 1.265,6.362 0.273,1.176 0.786,3.104 1.265,4.488 0.472,1.315 0.904,2.681 1.347,4.063 0.445,1.4 0.906,2.841 1.424,4.249 0.347,0.939 0.896,1.734 1.274,2.728 0.213,0.565 0.249,1.192 0.465,1.767 0.475,1.25 0.99,2.514 1.541,3.656 0.553,1.123 1.13,2.228 1.711,3.336 l 0.938,1.807 c 0.326,0.58 0.653,1.161 0.981,1.745 0.649,1.172 1.283,2.367 1.886,3.609 1.027,1.966 2.073,3.828 3.188,5.725 1.116,1.844 2.324,3.757 3.629,5.817 1.158,1.853 2.248,3.825 3.357,5.355 0.827,1.167 2.173,3.163 3.042,5.126 0.342,0.78 0.349,1.38 1.197,1.482 0.907,1.274 1.649,2.697 2.452,3.773 0.214,0.276 0.563,0.445 0.808,0.722 0.286,0.323 0.408,0.762 0.693,1.065 0.582,0.653 1.672,1.277 2.21,2.569 0.151,0.332 0.198,0.653 0.368,1.006 0.397,0.822 1.098,2.779 1.78,3.145 C -0.284,0.044 -0.151,0.044 0,0" /></g></g></g><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path70"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 416.68863,327.0015 c 0,0 -8,-30.667 -4.667,-56 0.667,8 4.667,56 4.667,56" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path74"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 426.18913,347.7256 c -0.61,2.147 -4.597,-59.478 -3.432,-61.636 1.166,-2.159 7.147,48.575 3.432,61.636" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path78"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 235.24913,465.60369 c 0,0 4.667,-26.6198 -38.667,-40.6198 -43.333,-14 -103.0605,-25.98239 -147.0605,-78.64939 -44.0000004,-52.666 -52.0000004,-139.999 -22,-197.333 30,-57.333 103.333,-128.667 235.333,-128.667 132,0 236.85312,101.50582 236.85312,171.50582 0,36.667 -20.1469,28.4918 -27.11433,-5.90828 C 466.30468,154.88286 408.18863,39.0015 262.18863,39.0015 c -146,0 -220.667,88.667 -230,164.667 -9.334,76 11.898969,141.46925 88.56597,180.80225 76.667,39.334 125.32039,23.66435 114.65339,80.99735"
|
||||
sodipodi:nodetypes="cssssssscsc" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path82"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 198.85713,260.335 c 0,0 -8.667,-40.001 -50.667,-59.333 -42,-19.334 -60,-30 -66,-63.334 16,26.666 62.667,32 88.667,58 26,26 28,64.667 28,64.667" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path86"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 210.19013,353.0015 c 0,0 36,-46.667 78.667,-24 42.666,22.667 20.667,75.333 20,78.667 -0.667,3.333 4.666,-58.667 -27.334,-69.334 -32,-10.666 -71.333,14.667 -71.333,14.667" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path90"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 116.18913,74.3359 c 0,0 22.666,-1.334 39.333,17.332 16.667,18.668 7.334,48 34.667,58.668 27.333,10.666 46,4 46,4 0,0 -48.667,-6.668 -52.667,-34.668 -4,-28 -10.666,-40.666 -21.333,-49.332 -10.667,-8.668 -24.667,-10 -24.667,-10 l -21.333,14 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path94"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 219.02213,219.502 c 0,0 40.523,6.783 59,48 15.167,33.833 5,63 5,63 l -20.5,-3 c 0,0 8.5,-24.5 2,-46.5 -6.5,-22 -21.5,-47.5 -45.5,-61.5" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path98"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 437.13303,313.1621 c -14.461,-36.13 -35.773,-62.068 -38.265,-60.674 -4.494,2.513 -0.358,34.036 14.104,70.166 14.46,36.13 32.432,63.635 39.104,61.014 6.672,-2.621 -0.483,-34.376 -14.943,-70.506 m 20.999,72.506 c -16.442,8.934 -36.644,-24.449 -53.276,-63.334 -16.633,-38.885 -18.542,-70.229 -5.759,-75.836 17.092,-7.496 33.127,22.285 49.759,61.17 16.632,38.885 24,70 9.276,78" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path102"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 159.52163,189.668 c 0,0 10.331,-31.037 62,-24.666 48.667,6 69.59,24.744 99.333,43.334 21.334,13.332 20,7.332 22.667,6.666 2.667,-0.666 14.667,-8 27.333,-6.666 0.667,-6.668 -5.999,-1.334 -8.666,-7.334 -1.333,-4 10.12,-22.824 26.666,-20 27.334,4.666 19.667,16 25.001,28.666 5.333,12.666 9,19.334 -17.667,37.334 -20.667,18.666 -32,13.999 -42,13.999 -10,0 -36,-13.999 -54,-10.666 -18,3.333 -29.334,10 -29.334,10 l -11.999,-13.333 c 0,0 21.999,-16.666 47.333,-10.666 25.333,6 44.001,25.332 66.001,15.332 22,-10 26.282,-16.701 32.999,-21.666 7.667,-5.668 8.333,-11.666 3,-17 -5.334,-5.334 0.001,-9.334 -3.332,-15.334 -3.334,-6 -20,-8.666 -20,-8.666 0,0 18.273,23.477 -4,25.332 -16,1.334 -26,22.668 -48.667,11.334 -32.55,-16.277 -78.668,-44 -110.668,-47.332 -31.193,-3.248 -42.667,6.666 -50.667,25.332 -9.333,-8 -11.333,-14 -11.333,-14" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path106"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 274.18863,183.002 c 0,0 22.667,-12 16,-38 -6.667,-26 -36.667,-44 -56,-52.668 -19.333,-8.666 -33.743,-20.127 -19.333,-27.332 12,-6 18.667,9.334 36,12 17.333,2.666 32.667,-4 34,-14 -7.334,4 -12.667,4 -12.667,4 0,0 6,-4 6.667,-10.668 0.666,-6.666 -0.667,-3.332 -4.667,-3.332 -10,0 -11.333,8.666 -20,7.332 -22,-2 -23.333,-11.334 -35.333,-12.666 -12,-1.334 -32,5.334 -29.334,20.666 2.667,15.334 23.334,26 42.667,34 19.333,8 48.667,33.334 44.667,56 -4,22.668 -21.334,18 -21.334,18 l 18.667,6.668 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path110"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 331.02213,371.7515 c 0,0 9.5,-4.75 15.5,-28.75 4,-8.667 9.333,-15.667 14,-17.667 4.667,-2 -2,-4 -5.333,-3.333 -3.334,0.667 -10.334,3.667 -15,-0.333 -4.667,-4 -16,-14.667 -32,-12 -16,2.666 -29.667,12.833 -29.667,12.833 0,0 6,-26.5 41.667,-24.833 24.721,1.155 19.333,14 36,16.666 16.666,2.667 14.893,11.089 11.333,18 -5.667,11 -23.333,13.667 -25.333,45.834 -2,3.333 -14.5,-0.417 -11.167,-6.417" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path114"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 388.01383,204.4707 c 1.506,-1.477 -11.825,-31.469 -11.825,-31.469 0,0 -2.667,-7.334 -9.814,-4.75 -7.311,2.645 -5.413,7.948 -5.413,7.948 l 17.026,30.837 c 0,0 9.353,-1.906 10.026,-2.566" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path118"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 406.74623,247.168 c -0.667,-2 -3.333,-10 -3.333,-10 l -10.891,8.334 2.891,6.332 11.333,-4.666 z" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path122"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 284.85563,189.002 c -2,-7.334 23.333,-50.002 40.667,-47.334 17.333,2.666 19.999,-2.668 14.666,-6 -5.333,-3.334 -14.666,-4.668 -13.333,-9.334 1.333,-4.666 5,-9.334 -3.667,-8 -8.666,1.334 -26.333,10.668 -37,28.668 -3.333,-10.668 -4.666,-14 -4.666,-14 0,0 34,-35.334 68.666,-20.668 -6,4.668 -22.666,3.334 -8.666,11.334 14,8 24.666,10.666 31.333,-2 3.333,0.666 3.333,30 -40.667,28 -15.333,2 -36,32 -36,47.334 -4,-4 -9.333,-0.666 -11.333,-8" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path126"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 420.44553,336.5015 c 0,0 -8.75,-26.286 -5.104,-48 0.729,6.857 5.104,48 5.104,48" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path130"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 429.40543,352.0503 c -0.444,1.66 -4.07,-45.761 -3.203,-47.435 0.868,-1.673 5.909,37.339 3.203,47.435" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path134"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 312.85513,378.335 c 0,0 37.667,3.333 31,18.333 -20.105,45.239 -58.333,71.667 -129,69 40,16 74.00021,14.00025 106.667,-14 16.33311,-13.99988 23.89324,-31.04069 29.74979,-44.08296 9.34044,-20.80074 6.58914,-22.74696 -3.74979,-28.58304 -12.56847,-7.0946 -34.191,-2.57 -34.667,-0.667"
|
||||
sodipodi:nodetypes="cccsssc" /><path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path138"
|
||||
style="fill:#2d2b2c;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 316.7084,372.58242 c 0,0 10.36415,-7.13802 18.50215,-1.32602 3.74086,3.84884 6.23323,5.95026 -4.37137,5.51213 l -12.90479,0.52875 c -8.94116,1.82452 -8.7647,-0.93753 -1.22599,-4.71486 z"
|
||||
sodipodi:nodetypes="ccccc" /></g></svg>
|
Before Width: | Height: | Size: 17 KiB |
File diff suppressed because it is too large
Load Diff
@ -1,168 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Real-world Uses</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Real-world uses</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2>CodeMirror real-world uses</h2>
|
||||
|
||||
<p>Create a <a href="https://github.com/codemirror/codemirror">pull
|
||||
request</a> or <a href="mailto:marijnh@gmail.com">email me</a> if
|
||||
you'd like your project to be added to this list.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://brackets.io">Adobe Brackets</a> (code editor)</li>
|
||||
<li><a href="http://amber-lang.net/">Amber</a> (JavaScript-based Smalltalk system)</li>
|
||||
<li><a href="http://apachegui.ca/">Apache GUI</a></li>
|
||||
<li><a href="http://apeye.org/">APEye</a> (tool for testing & documenting APIs)</li>
|
||||
<li><a href="https://chrome.google.com/webstore/detail/better-text-viewer/lcaidopdffhfemoefoaadecppnjdknkc">Better Text Viewer</a> (plain text reader app for Chrome)</li>
|
||||
<li><a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a> (code hosting)</li>
|
||||
<li><a href="http://buzz.blogger.com/2013/04/improvements-to-blogger-template-html.html">Blogger's template editor</a></li>
|
||||
<li><a href="http://bluegriffon.org/">BlueGriffon</a> (HTML editor)</li>
|
||||
<li><a href="http://cargocollective.com/">Cargo Collective</a> (creative publishing platform)</li>
|
||||
<li><a href="https://developers.google.com/chrome-developer-tools/">Chrome DevTools</a></li>
|
||||
<li><a href="http://clickhelp.co/">ClickHelp</a> (technical writing tool)</li>
|
||||
<li><a href="http://codeworld.info/">CodeWorld</a> (Haskell playground)</li>
|
||||
<li><a href="http://complete-ly.appspot.com/playground/code.playground.html">Complete.ly playground</a></li>
|
||||
<li><a href="https://codeanywhere.com/">Codeanywhere</a> (multi-platform cloud editor)</li>
|
||||
<li><a href="http://drupal.org/project/cpn">Code per Node</a> (Drupal module)</li>
|
||||
<li><a href="http://www.codebugapp.com/">Codebug</a> (PHP Xdebug front-end)</li>
|
||||
<li><a href="https://github.com/angelozerr/CodeMirror-Eclipse">CodeMirror Eclipse</a> (embed CM in Eclipse)</li>
|
||||
<li><a href="http://emmet.io/blog/codemirror-movie/">CodeMirror movie</a> (scripted editing demos)</li>
|
||||
<li><a href="http://code.google.com/p/codemirror2-gwt/">CodeMirror2-GWT</a> (Google Web Toolkit wrapper)</li>
|
||||
<li><a href="http://www.crunchzilla.com/code-monster">Code Monster</a> & <a href="http://www.crunchzilla.com/code-maven">Code Maven</a> (learning environment)</li>
|
||||
<li><a href="http://codepen.io">Codepen</a> (gallery of animations)</li>
|
||||
<li><a href="https://coderpad.io/">Coderpad</a> (interviewing tool)</li>
|
||||
<li><a href="http://sasstwo.codeschool.com/levels/1/challenges/1">Code School</a> (online tech learning environment)</li>
|
||||
<li><a href="http://code-snippets.bungeshea.com/">Code Snippets</a> (WordPress snippet management plugin)</li>
|
||||
<li><a href="http://antonmi.github.io/code_together/">Code together</a> (collaborative editing)</li>
|
||||
<li><a href="http://codev.it/">Codev</a> (collaborative IDE)</li>
|
||||
<li><a href="http://www.codezample.com">CodeZample</a> (code snippet sharing)</li>
|
||||
<li><a href="http://codio.com">Codio</a> (Web IDE)</li>
|
||||
<li><a href="http://ot.substance.io/demo/">Collaborative CodeMirror demo</a> (CodeMirror + operational transforms)</li>
|
||||
<li><a href="http://www.communitycodecamp.com/">Community Code Camp</a> (code snippet sharing)</li>
|
||||
<li><a href="http://www.compilejava.net/">compilejava.net</a> (online Java sandbox)</li>
|
||||
<li><a href="http://www.ckwnc.com/">CKWNC</a> (UML editor)</li>
|
||||
<li><a href="http://www.crossui.com/">CrossUI</a> (cross-platform UI builder)</li>
|
||||
<li><a href="http://rsnous.com/cruncher/">Cruncher</a> (notepad with calculation features)</li>
|
||||
<li><a href="http://www.crudzilla.com/">Crudzilla</a> (self-hosted web IDE)</li>
|
||||
<li><a href="http://cssdeck.com/">CSSDeck</a> (CSS showcase)</li>
|
||||
<li><a href="http://ireneros.com/deck/deck.js-codemirror/introduction/#textarea-code">Deck.js integration</a> (slides with editors)</li>
|
||||
<li><a href="http://www.dbninja.com">DbNinja</a> (MySQL access interface)</li>
|
||||
<li><a href="https://chat.echoplex.us/">Echoplexus</a> (chat and collaborative coding)</li>
|
||||
<li><a href="http://www.ecsspert.com/">eCSSpert</a> (CSS demos and experiments)</li>
|
||||
<li><a href="http://elm-lang.org/Examples.elm">Elm language examples</a></li>
|
||||
<li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</li>
|
||||
<li><a href="http://emmet.io">Emmet</a> (fast XML editing)</li>
|
||||
<li><a href="https://github.com/espruino/EspruinoWebIDE">Espruino Web IDE</a> (Chrome App for writing code on Espruino devices)</li>
|
||||
<li><a href="http://www.fastfig.com/">Fastfig</a> (online computation/math tool)</li>
|
||||
<li><a href="https://metacpan.org/module/Farabi">Farabi</a> (modern Perl IDE)</li>
|
||||
<li><a href="http://blog.pamelafox.org/2012/02/interactive-html5-slides-with-fathomjs.html">FathomJS integration</a> (slides with editors, again)</li>
|
||||
<li><a href="https://phantomus.com/">Phantomus</a> (blogging platform)</li>
|
||||
<li><a href="http://fiddlesalad.com/">Fiddle Salad</a> (web development environment)</li>
|
||||
<li><a href="https://github.com/simogeo/Filemanager">Filemanager</a></li>
|
||||
<li><a href="https://hacks.mozilla.org/2013/11/firefox-developer-tools-episode-27-edit-as-html-codemirror-more/">Firefox Developer Tools</a></li>
|
||||
<li><a href="http://www.firepad.io">Firepad</a> (collaborative text editor)</li>
|
||||
<li><a href="https://code.google.com/p/gerrit/">Gerrit</a>'s diff view</li>
|
||||
<li><a href="https://github.com/maks/git-crx">Git Crx</a> (Chrome App for browsing local git repos)</li>
|
||||
<li><a href="http://tour.golang.org">Go language tour</a></li>
|
||||
<li><a href="https://github.com/github/android">GitHub's Android app</a></li>
|
||||
<li><a href="https://script.google.com/">Google Apps Script</a></li>
|
||||
<li><a href="http://web.uvic.ca/~siefkenj/graphit/graphit.html">Graphit</a> (function graphing)</li>
|
||||
<li><a href="http://www.handcraft.com/">Handcraft</a> (HTML prototyping)</li>
|
||||
<li><a href="http://hawkee.com/">Hawkee</a></li>
|
||||
<li><a href="http://try.haxe.org">Haxe</a> (Haxe Playground) </li>
|
||||
<li><a href="http://haxpad.com/">HaxPad</a> (editor for Win RT)</li>
|
||||
<li><a href="http://megafonweblab.github.com/histone-javascript/">Histone template engine playground</a></li>
|
||||
<li><a href="http://icecoder.net">ICEcoder</a> (web IDE)</li>
|
||||
<li><a href="http://ipython.org/">IPython</a> (interactive computing shell)</li>
|
||||
<li><a href="http://i-mos.org/imos/">i-MOS</a> (modeling and simulation platform)</li>
|
||||
<li><a href="http://www.janvas.com/">Janvas</a> (vector graphics editor)</li>
|
||||
<li><a href="http://extensions.joomla.org/extensions/edition/editors/8723">Joomla plugin</a></li>
|
||||
<li><a href="http://jqfundamentals.com/">jQuery fundamentals</a> (interactive tutorial)</li>
|
||||
<li><a href="http://jsbin.com">jsbin.com</a> (JS playground)</li>
|
||||
<li><a href="https://github.com/kucherenko/jscpd">jscpd</a> (code duplication detector)</li>
|
||||
<li><a href="http://jsfiddle.com">jsfiddle.com</a> (another JS playground)</li>
|
||||
<li><a href="http://www.jshint.com/">JSHint</a> (JS linter)</li>
|
||||
<li><a href="http://jumpseller.com/">Jumpseller</a> (online store builder)</li>
|
||||
<li><a href="http://kl1p.com/cmtest/1">kl1p</a> (paste service)</li>
|
||||
<li><a href="http://kodtest.com/">Kodtest</a> (HTML/JS/CSS playground)</li>
|
||||
<li><a href="https://laborate.io/">Laborate</a> (collaborative coding)</li>
|
||||
<li><a href="http://lighttable.com/">Light Table</a> (experimental IDE)</li>
|
||||
<li><a href="http://liveweave.com/">Liveweave</a> (HTML/CSS/JS scratchpad)</li>
|
||||
<li><a href="http://marklighteditor.com/">Marklight editor</a> (lightweight markup editor)</li>
|
||||
<li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
|
||||
<li><a href="http://www.iunbug.com/mihtool">MIHTool</a> (iOS web-app debugging tool)</li>
|
||||
<li><a href="http://mongo-mapreduce-webbrowser.opensagres.cloudbees.net/">Mongo MapReduce WebBrowser</a></li>
|
||||
<li><a href="http://montagestudio.com/">Montage Studio</a> (web app creator suite)</li>
|
||||
<li><a href="http://mvcplayground.apphb.com/">MVC Playground</a></li>
|
||||
<li><a href="https://www.my2ndgeneration.com/">My2ndGeneration</a> (social coding)</li>
|
||||
<li><a href="http://www.navigatecms.com">Navigate CMS</a></li>
|
||||
<li><a href="https://github.com/soliton4/nodeMirror">nodeMirror</a> (IDE project)</li>
|
||||
<li><a href="https://notex.ch">NoTex</a> (rST authoring)</li>
|
||||
<li><a href="http://oakoutliner.com">Oak</a> (online outliner)</li>
|
||||
<li><a href="http://clrhome.org/asm/">ORG</a> (z80 assembly IDE)</li>
|
||||
<li><a href="https://github.com/mamacdon/orion-codemirror">Orion-CodeMirror integration</a> (running CodeMirror modes in Orion)</li>
|
||||
<li><a href="http://paperjs.org/">Paper.js</a> (graphics scripting)</li>
|
||||
<li><a href="http://prinbit.com/">PrinBit</a> (collaborative coding tool)</li>
|
||||
<li><a href="http://prose.io/">Prose.io</a> (github content editor)</li>
|
||||
<li><a href="https://pypi.python.org/pypi/PubliForge/">PubliForge</a> (online publishing system)</li>
|
||||
<li><a href="http://www.puzzlescript.net/">Puzzlescript</a> (puzzle game engine)</li>
|
||||
<li><a href="http://ql.io/">ql.io</a> (http API query helper)</li>
|
||||
<li><a href="http://qyapp.com">QiYun web app platform</a></li>
|
||||
<li><a href="http://ariya.ofilabs.com/2011/09/hybrid-webnative-desktop-codemirror.html">Qt+Webkit integration</a> (building a desktop CodeMirror app)</li>
|
||||
<li><a href="http://www.quivive-file-manager.com">Quivive File Manager</a></li>
|
||||
<li><a href="http://rascalmicro.com/docs/basic-tutorial-getting-started.html">Rascal</a> (tiny computer)</li>
|
||||
<li><a href="https://www.realtime.io/">RealTime.io</a> (Internet-of-Things infrastructure)</li>
|
||||
<li><a href="https://cloud.sagemath.com/">SageMathCloud</a> (interactive mathematical software environment)</li>
|
||||
<li><a href="https://chrome.google.com/webstore/detail/servephp/mnpikomdchjhkhbhmbboehfdjkobbfpo">ServePHP</a> (PHP code testing in Chrome dev tools)</li>
|
||||
<li><a href="https://www.shadertoy.com/">Shadertoy</a> (shader sharing)</li>
|
||||
<li><a href="http://www.sketchpatch.net/labs/livecodelabIntro.html">sketchPatch Livecodelab</a></li>
|
||||
<li><a href="http://www.skulpt.org/">Skulpt</a> (in-browser Python environment)</li>
|
||||
<li><a href="http://snaptomato.appspot.com/editor.html">Snap Tomato</a> (HTML editing/testing page)</li>
|
||||
<li><a href="http://snippets.pro/">Snippets.pro</a> (code snippet sharing)</li>
|
||||
<li><a href="http://www.solidshops.com/">SolidShops</a> (hosted e-commerce platform)</li>
|
||||
<li><a href="http://sqlfiddle.com">SQLFiddle</a> (SQL playground)</li>
|
||||
<li><a href="http://xuanji.appspot.com/isicp/">Structure and Interpretation of Computer Programs</a>, Interactive Version</li>
|
||||
<li><a href="http://syframework.alwaysdata.net">SyBox</a> (PHP playground)</li>
|
||||
<li><a href="http://www.tagspaces.org/">TagSpaces</a> (personal data manager)</li>
|
||||
<li><a href="https://thefiletree.com">The File Tree</a> (collab editor)</li>
|
||||
<li><a href="http://www.mapbox.com/tilemill/">TileMill</a> (map design tool)</li>
|
||||
<li><a href="http://www.toolsverse.com/products/data-explorer/">Toolsverse Data Explorer</a> (database management)</li>
|
||||
<li><a href="http://enjalot.com/tributary/2636296/sinwaves.js">Tributary</a> (augmented editing)</li>
|
||||
<li><a href="http://blog.englard.net/post/39608000629/codeintumblr">Tumblr code highlighting shim</a></li>
|
||||
<li><a href="http://turbopy.com/">TurboPY</a> (web publishing framework)</li>
|
||||
<li><a href="http://uicod.com/">uiCod</a> (animation demo gallery and sharing)</li>
|
||||
<li><a href="http://cruise.eecs.uottawa.ca/umpleonline/">UmpleOnline</a> (model-oriented programming tool)</li>
|
||||
<li><a href="https://upsource.jetbrains.com/#idea/view/923f30395f2603cd9f42a32bcafd13b6c28de0ff/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java">Upsource</a> (code viewer)</li>
|
||||
<li><a href="http://wamer.net/">Wamer</a> (web application builder)</li>
|
||||
<li><a href="https://github.com/brettz9/webappfind">webappfind</a> (windows file bindings for webapps)</li>
|
||||
<li><a href="http://www.webglacademy.com/">WebGL academy</a> (learning WebGL)</li>
|
||||
<li><a href="http://webglplayground.net/">WebGL playground</a></li>
|
||||
<li><a href="https://www.webkit.org/blog/2518/state-of-web-inspector/#source-code">WebKit Web inspector</a></li>
|
||||
<li><a href="http://www.wescheme.org/">WeScheme</a> (learning tool)</li>
|
||||
<li><a href="https://github.com/b3log/wide">Wide</a> (golang web IDE)</li>
|
||||
<li><a href="http://wordpress.org/extend/plugins/codemirror-for-codeeditor/">WordPress plugin</a></li>
|
||||
<li><a href="https://www.writelatex.com">writeLaTeX</a> (Collaborative LaTeX Editor)</li>
|
||||
<li><a href="http://www.xosystem.org/home/applications_websites/xosystem_website/xoside_EN.php">XOSide</a> (online editor)</li>
|
||||
<li><a href="http://videlibri.sourceforge.net/cgi-bin/xidelcgi">XQuery tester</a></li>
|
||||
<li><a href="http://q42jaap.github.io/xsd2codemirror/">xsd2codemirror</a> (convert XSD to CM XML completion info)</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
@ -1,974 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Release History</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
<script src="activebookmark.js"></script>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active data-default="true" href="#v4">Version 4.x</a>
|
||||
<li><a href="#v3">Version 3.x</a>
|
||||
<li><a href="#v2">Version 2.x</a>
|
||||
<li><a href="#v1">Version 0.x</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2>Release notes and version history</h2>
|
||||
|
||||
<section id=v4 class=first>
|
||||
|
||||
<h2>Version 4.x</h2>
|
||||
|
||||
<p class="rel">22-11-2014: <a href="http://codemirror.net/codemirror-4.8.zip">Version 4.8</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Built-in support for <a href="manual.html#normalizeKeyMap">multi-stroke key bindings</a>.</li>
|
||||
<li>New method: <a href="manual.html#getLineTokens"><code>getLineTokens</code></a>.</li>
|
||||
<li>New modes: <a href="../mode/dockerfile/index.html">dockerfile</a>, <a href="../mode/idl/index.html">IDL</a>, <a href="../mode/clike/index.html">Objective C</a> (crude).</li>
|
||||
<li>Support styling of gutter backgrounds, allow <code>"gutter"</code> styles in <a href="manual.html#addLineClass"><code>addLineClass</code></a>.</li>
|
||||
<li>Many improvements to the <a href="../demo/vim.html">Vim mode</a>, rewritten visual mode.</li>
|
||||
<li>Improvements to modes: <a href="../mode/gfm/index.html">gfm</a> (strikethrough), <a href="../mode/sparql/index.html">SPARQL</a> (version 1.1 support), and <a href="../mode/stex/index.html">sTeX</a> (no more runaway math mode).
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.7.0...4.8.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-10-2014: <a href="http://codemirror.net/codemirror-4.7.zip">Version 4.7</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li><strong>Incompatible</strong>:
|
||||
The <a href="../demo/lint.html">lint addon</a> now passes the
|
||||
editor's value as first argument to asynchronous lint functions,
|
||||
for consistency. The editor is still passed, as fourth
|
||||
argument.</li>
|
||||
<li>Improved handling of unicode identifiers in modes for
|
||||
languages that support them.</li>
|
||||
<li>More mode
|
||||
improvements: <a href="../mode/coffeescript/index.html">CoffeeScript</a>
|
||||
(indentation), <a href="../mode/verilog/index.html">Verilog</a>
|
||||
(indentation), <a href="../mode/clike/index.html">Scala</a>
|
||||
(indentation, triple-quoted strings),
|
||||
and <a href="../mode/php/index.html">PHP</a> (interpolated
|
||||
variables in heredoc strings).</li>
|
||||
<li>New modes: <a href="../mode/textile/index.html">Textile</a> and <a href="../mode/tornado/index.html">Tornado templates</a>.</li>
|
||||
<li>Experimental new <a href="../demo/simplemode.html">way to define modes</a>.</li>
|
||||
<li>Improvements to the <a href="../demo/vim.html">Vim
|
||||
bindings</a>: Arbitrary insert mode key mappings are now possible,
|
||||
and text objects are supported in visual mode.</li>
|
||||
<li>The mode <a href="../mode/meta.js">meta-information file</a>
|
||||
now includes information about file extensions,
|
||||
and <a href="manual.html#addon_meta">helper
|
||||
functions</a> <code>findModeByMIME</code>
|
||||
and <code>findModeByExtension</code>.</li>
|
||||
<li>New logo!</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.6.0...4.7.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">19-09-2014: <a href="http://codemirror.net/codemirror-4.6.zip">Version 4.6</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/modelica/index.html">Modelica</a></li>
|
||||
<li>New method: <a href="manual.html#findWordAt"><code>findWordAt</code></a></li>
|
||||
<li>Make it easier to <a href="../demo/markselection.html">use text background styling</a></li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.5.0...4.6.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-08-2014: <a href="http://codemirror.net/codemirror-4.5.zip">Version 4.5</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Fix several serious bugs with horizontal scrolling</li>
|
||||
<li>New mode: <a href="../mode/slim/index.html">Slim</a></li>
|
||||
<li>New command: <a href="manual.html#command_goLineLeftSmart"><code>goLineLeftSmart</code></a></li>
|
||||
<li>More fixes and extensions for the <a href="../demo/vim.html">Vim</a> visual block mode</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.4.0...4.5.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-07-2014: <a href="http://codemirror.net/codemirror-4.4.zip">Version 4.4</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li><strong>Note:</strong> Some events might now fire in slightly
|
||||
different order (<code>"change"</code> is still guaranteed to fire
|
||||
before <code>"cursorActivity"</code>)</li>
|
||||
<li>Nested operations in multiple editors are now synced (complete
|
||||
at same time, reducing DOM reflows)</li>
|
||||
<li>Visual block mode for <a href="../demo/vim.html">vim</a> (<C-v>) is nearly complete</li>
|
||||
<li>New mode: <a href="../mode/kotlin/index.html">Kotlin</a></li>
|
||||
<li>Better multi-selection paste for text copied from multiple CodeMirror selections</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.3.0...4.4.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">23-06-2014: <a href="http://codemirror.net/codemirror-4.3.zip">Version 4.3</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Several <a href="../demo/vim.html">vim bindings</a>
|
||||
improvements: search and exCommand history, global flag
|
||||
for <code>:substitute</code>, <code>:global</code> command.
|
||||
<li>Allow hiding the cursor by
|
||||
setting <a href="manual.html#option_cursorBlinkRate"><code>cursorBlinkRate</code></a>
|
||||
to a negative value.</li>
|
||||
<li>Make gutter markers themeable, use this in foldgutter.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.2.0...4.3.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">19-05-2014: <a href="http://codemirror.net/codemirror-4.2.zip">Version 4.2</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Fix problem where some modes were broken by the fact that empty tokens were forbidden.</li>
|
||||
<li>Several fixes to context menu handling.</li>
|
||||
<li>On undo, scroll <em>change</em>, not cursor, into view.</li>
|
||||
<li>Rewritten <a href="../mode/jade/index.html">Jade</a> mode.</li>
|
||||
<li>Various improvements to <a href="../mode/shell/index.html">Shell</a> (support for more syntax) and <a href="../mode/python/index.html">Python</a> (better indentation) modes.</li>
|
||||
<li>New mode: <a href="../mode/cypher/index.html">Cypher</a>.</li>
|
||||
<li>New theme: <a href="../demo/theme.html?neo">Neo</a>.</li>
|
||||
<li>Support direct styling options (color, line style, width) in the <a href="manual.html#addon_rulers">rulers</a> addon.</li>
|
||||
<li>Recognize per-editor configuration for the <a href="manual.html#addon_show-hint">show-hint</a> and <a href="manual.html#addon_foldcode">foldcode</a> addons.</li>
|
||||
<li>More intelligent scanning for existing close tags in <a href="manual.html#addon_closetag">closetag</a> addon.</li>
|
||||
<li>In the <a href="../demo/vim.html">Vim bindings</a>: Fix bracket matching, support case conversion in visual mode, visual paste, append action.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.1.0...4.2.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">22-04-2014: <a href="http://codemirror.net/codemirror-4.1.zip">Version 4.1</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li><em>Slightly incompatible</em>:
|
||||
The <a href="manual.html#event_cursorActivity"><code>"cursorActivity"</code></a>
|
||||
event now fires after all other events for the operation (and only
|
||||
for handlers that were actually registered at the time the
|
||||
activity happened).</li>
|
||||
<li>New command: <a href="manual.html#command_insertSoftTab"><code>insertSoftTab</code></a>.</li>
|
||||
<li>New mode: <a href="../mode/django/index.html">Django</a>.</li>
|
||||
<li>Improved modes: <a href="../mode/verilog/index.html">Verilog</a> (rewritten), <a href="../mode/jinja2/index.html">Jinja2</a>, <a href="../mode/haxe/index.html">Haxe</a>, <a href="../mode/php/index.html">PHP</a> (string interpolation highlighted), <a href="../mode/javascript/index.html">JavaScript</a> (indentation of trailing else, template strings), <a href="../mode/livescript/index.html">LiveScript</a> (multi-line strings).</li>
|
||||
<li>Many small issues from the 3.x→4.x transition were found and fixed.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.0.3...4.1.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-03-2014: <a href="http://codemirror.net/codemirror-4.0.zip">Version 4.0</a>:</p>
|
||||
|
||||
<p class="rel-note">This is a new major version of CodeMirror. There
|
||||
are a few <strong>incompatible</strong> changes in the API. Upgrade
|
||||
with care, and read the <a href="upgrade_v4.html">upgrading
|
||||
guide</a>.</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Multiple selections (ctrl-click, alt-drag, <a href="manual.html#setSelections">API</a>).</li>
|
||||
<li>Sublime Text <a href="../demo/sublime.html">bindings</a>.</li>
|
||||
<li><a href="manual.html#modloader">Module loader shims</a> wrapped around all modules.</li>
|
||||
<li>Selection <a href="manual.html#command_undoSelection">undo</a>/<a href="manual.html#command_redoSelection">redo</a>.</li>
|
||||
<li>Improved character measuring (faster, handles wrapped lines more robustly).</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.23.0...4.0.3">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=v3>
|
||||
|
||||
<h2>Version 3.x</h2>
|
||||
|
||||
<p class="rel">22-04-2014: <a href="http://codemirror.net/codemirror-3.24.zip">Version 3.24</a>:</p>
|
||||
|
||||
<p class="rel-note">Merges the improvements from 4.1 that could
|
||||
easily be applied to the 3.x code. Also improves the way the editor
|
||||
size is updated when line widgets change.</p>
|
||||
|
||||
<p class="rel">20-03-2014: <a href="http://codemirror.net/codemirror-3.23.zip">Version 3.23</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>In the <a href="../mode/xml/index.html">XML mode</a>,
|
||||
add <code>brackets</code> style to angle brackets, fix
|
||||
case-sensitivity of tags for HTML.</li>
|
||||
<li>New mode: <a href="../mode/dylan/index.html">Dylan</a>.</li>
|
||||
<li>Many improvements to the <a href="../demo/vim.html">Vim bindings</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-02-2014: <a href="http://codemirror.net/codemirror-3.22.zip">Version 3.22</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Adds the <a href="manual.html#findMarks"><code>findMarks</code></a> method.</li>
|
||||
<li>New addons: <a href="manual.html#addon_rulers">rulers</a>, markdown-fold, yaml-lint.</li>
|
||||
<li>New theme: <a href="../demo/theme.html?mdn-like">mdn-like</a>.</li>
|
||||
<li>New mode: <a href="../mode/solr/index.html">Solr</a>.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.21.0...3.22.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">16-01-2014: <a href="http://codemirror.net/codemirror-3.21.zip">Version 3.21</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Auto-indenting a block will no longer add trailing whitespace to blank lines.</a>
|
||||
<li>Marking text has a new option <a href="manual.html#markText"><code>clearWhenEmpty</code></a> to control auto-removal.</li>
|
||||
<li>Several bugfixes in the handling of bidirectional text.</li>
|
||||
<li>The <a href="../mode/xml/index.html">XML</a> and <a href="../mode/css/index.html">CSS</a> modes were largely rewritten. <a href="../mode/css/less.html">LESS</a> support was added to the CSS mode.</li>
|
||||
<li>The OCaml mode was moved to an <a href="../mode/mllike/index.html">mllike</a> mode, F# support added.</li>
|
||||
<li>Make it possible to fetch multiple applicable helper values with <a href="manual.html#getHelpers"><code>getHelpers</code></a>, and to register helpers matched on predicates with <a href="manual.html#registerGlobalHelper"><code>registerGlobalHelper</code></a>.</li>
|
||||
<li>New theme <a href="../demo/theme.html?pastel-on-dark">pastel-on-dark</a>.</li>
|
||||
<li>Better ECMAScript 6 support in <a href="../mode/javascript/index.html">JavaScript</a> mode.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.20.0...3.21.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-11-2013: <a href="http://codemirror.net/codemirror-3.20.zip">Version 3.20</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New modes: <a href="../mode/julia/index.html">Julia</a> and <a href="../mode/pegjs/index.html">PEG.js</a>.</li>
|
||||
<li>Support ECMAScript 6 in the <a href="../mode/javascript/index.html">JavaScript mode</a>.</li>
|
||||
<li>Improved indentation for the <a href="../mode/coffeescript/index.html">CoffeeScript mode</a>.</li>
|
||||
<li>Make non-printable-character representation <a href="manual.html#option_specialChars">configurable</a>.</li>
|
||||
<li>Add ‘notification’ functionality to <a href="manual.html#addon_dialog">dialog</a> addon.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.19.0...3.20.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-10-2013: <a href="http://codemirror.net/codemirror-3.19.zip">Version 3.19</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New modes: <a href="../mode/eiffel/index.html">Eiffel</a>, <a href="../mode/gherkin/index.html">Gherkin</a>, <a href="../mode/sql/?mime=text/x-mssql">MSSQL dialect</a>.</li>
|
||||
<li>New addons: <a href="manual.html#addon_hardwrap">hardwrap</a>, <a href="manual.html#addon_sql-hint">sql-hint</a>.</li>
|
||||
<li>New theme: <a href="../demo/theme.html?mbo">MBO</a>.</li>
|
||||
<li>Add <a href="manual.html#token_style_line">support</a> for line-level styling from mode tokenizers.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.18.0...3.19.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">23-09-2013: <a href="http://codemirror.net/codemirror-3.18.zip">Version 3.18</a>:</p>
|
||||
|
||||
<p class="rel-note">Emergency release to fix a problem in 3.17
|
||||
where <code>.setOption("lineNumbers", false)</code> would raise an
|
||||
error.</p>
|
||||
|
||||
<p class="rel">23-09-2013: <a href="http://codemirror.net/codemirror-3.17.zip">Version 3.17</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New modes: <a href="../mode/fortran/index.html">Fortran</a>, <a href="../mode/octave/index.html">Octave</a> (Matlab), <a href="../mode/toml/index.html">TOML</a>, and <a href="../mode/dtd/index.html">DTD</a>.</li>
|
||||
<li>New addons: <a href="../addon/lint/css-lint.js"><code>css-lint</code></a>, <a href="manual.html#addon_css-hint"><code>css-hint</code></a>.</li>
|
||||
<li>Improve resilience to CSS 'frameworks' that globally mess up <code>box-sizing</code>.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.16.0...3.17.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-08-2013: <a href="http://codemirror.net/codemirror-3.16.zip">Version 3.16</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>The whole codebase is now under a single <a href="../LICENSE">license</a> file.</li>
|
||||
<li>The project page was overhauled and redesigned.</li>
|
||||
<li>New themes: <a href="../demo/theme.html?paraiso-dark">Paraiso</a> (<a href="../demo/theme.html?paraiso-light">light</a>), <a href="../demo/theme.html?the-matrix">The Matrix</a>.</li>
|
||||
<li>Improved interaction between themes and <a href="manual.html#addon_active-line">active-line</a>/<a href="manual.html#addon_matchbrackets">matchbrackets</a> addons.</li>
|
||||
<li>New <a href="manual.html#addon_foldcode">folding</a> function <code>CodeMirror.fold.comment</code>.</li>
|
||||
<li>Added <a href="manual.html#addon_fullscreen">fullscreen</a> addon.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.15.0...3.16.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">29-07-2013: <a href="http://codemirror.net/codemirror-3.15.zip">Version 3.15</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New modes: <a href="../mode/jade/index.html">Jade</a>, <a href="../mode/nginx/index.html">Nginx</a>.</li>
|
||||
<li>New addons: <a href="../demo/tern.html">Tern</a>, <a href="manual.html#addon_matchtags">matchtags</a>, and <a href="manual.html#addon_foldgutter">foldgutter</a>.</li>
|
||||
<li>Introduced <a href="manual.html#getHelper"><em>helper</em></a> concept (<a href="https://groups.google.com/forum/#!msg/codemirror/cOc0xvUUEUU/nLrX1-qnidgJ">context</a>).</li>
|
||||
<li>New method: <a href="manual.html#getModeAt"><code>getModeAt</code></a>.</li>
|
||||
<li>New themes: base16 <a href="../demo/theme.html?base16-dark">dark</a>/<a href="../demo/theme.html?base16-light">light</a>, 3024 <a href="../demo/theme.html?3024-night">dark</a>/<a href="../demo/theme.html?3024-day">light</a>, <a href="../demo/theme.html?tomorrow-night-eighties">tomorrow-night</a>.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.14.0...3.15.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-06-2013: <a href="http://codemirror.net/codemirror-3.14.zip">Version 3.14</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New
|
||||
addons: <a href="manual.html#addon_trailingspace">trailing
|
||||
space highlight</a>, <a href="manual.html#addon_xml-hint">XML
|
||||
completion</a> (rewritten),
|
||||
and <a href="manual.html#addon_merge">diff merging</a>.</li>
|
||||
<li><a href="manual.html#markText"><code>markText</code></a>
|
||||
and <a href="manual.html#addLineWidget"><code>addLineWidget</code></a>
|
||||
now take a <code>handleMouseEvents</code> option.</li>
|
||||
<li>New methods: <a href="manual.html#lineAtHeight"><code>lineAtHeight</code></a>,
|
||||
<a href="manual.html#getTokenTypeAt"><code>getTokenTypeAt</code></a>.</li>
|
||||
<li>More precise cleanness-tracking
|
||||
using <a href="manual.html#changeGeneration"><code>changeGeneration</code></a>
|
||||
and <a href="manual.html#isClean"><code>isClean</code></a>.</li>
|
||||
<li>Many extensions to <a href="../demo/emacs.html">Emacs</a> mode
|
||||
(prefixes, more navigation units, and more).</li>
|
||||
<li>New
|
||||
events <a href="manual.html#event_keyHandled"><code>"keyHandled"</code></a>
|
||||
and <a href="manual.html#event_inputRead"><code>"inputRead"</code></a>.</li>
|
||||
<li>Various improvements to <a href="../mode/ruby/index.html">Ruby</a>,
|
||||
<a href="../mode/smarty/index.html">Smarty</a>, <a href="../mode/sql/index.html">SQL</a>,
|
||||
and <a href="../demo/vim.html">Vim</a> modes.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/3.13.0...3.14.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-05-2013: <a href="http://codemirror.net/codemirror-3.13.zip">Version 3.13</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New modes: <a href="../mode/cobol/index.html">COBOL</a> and <a href="../mode/haml/index.html">HAML</a>.</li>
|
||||
<li>New options: <a href="manual.html#option_cursorScrollMargin"><code>cursorScrollMargin</code></a> and <a href="manual.html#option_coverGutterNextToScrollbar"><code>coverGutterNextToScrollbar</code></a>.</li>
|
||||
<li>New addon: <a href="manual.html#addon_comment">commenting</a>.</li>
|
||||
<li>More features added to the <a href="../demo/vim.html">Vim keymap</a>.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.12...3.13.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">19-04-2013: <a href="http://codemirror.net/codemirror-3.12.zip">Version 3.12</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/gas/index.html">GNU assembler</a>.</li>
|
||||
<li>New
|
||||
options: <a href="manual.html#option_maxHighlightLength"><code>maxHighlightLength</code></a>
|
||||
and <a href="manual.html#option_historyEventDelay"><code>historyEventDelay</code></a>.</li>
|
||||
<li>Added <a href="manual.html#mark_addToHistory"><code>addToHistory</code></a>
|
||||
option for <code>markText</code>.</li>
|
||||
<li>Various fixes to JavaScript tokenization and indentation corner cases.</li>
|
||||
<li>Further improvements to the vim mode.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.11...v3.12">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-03-2013: <a href="http://codemirror.net/codemirror-3.11.zip">Version 3.11</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li><strong>Removed code:</strong> <code>collapserange</code>,
|
||||
<code>formatting</code>, and <code>simple-hint</code>
|
||||
addons. <code>plsql</code> and <code>mysql</code> modes
|
||||
(use <a href="../mode/sql/index.html"><code>sql</code></a> mode).</li>
|
||||
<li><strong>Moved code:</strong> the range-finding functions for folding now have <a href="../addon/fold/">their own files</a>.</li>
|
||||
<li><strong>Changed interface:</strong>
|
||||
the <a href="manual.html#addon_continuecomment"><code>continuecomment</code></a>
|
||||
addon now exposes an option, rather than a command.</li>
|
||||
<li>New
|
||||
modes: <a href="../mode/css/scss.html">SCSS</a>, <a href="../mode/tcl/index.html">Tcl</a>, <a href="../mode/livescript/index.html">LiveScript</a>,
|
||||
and <a href="../mode/mirc/index.html">mIRC</a>.</li>
|
||||
<li>New addons: <a href="../demo/placeholder.html"><code>placeholder</code></a>, <a href="../demo/html5complete.html">HTML completion</a>.</li>
|
||||
<li>New
|
||||
methods: <a href="manual.html#hasFocus"><code>hasFocus</code></a>, <a href="manual.html#defaultCharWidth"><code>defaultCharWidth</code></a>.</li>
|
||||
<li>New events: <a href="manual.html#event_beforeCursorEnter"><code>beforeCursorEnter</code></a>, <a href="manual.html#event_renderLine"><code>renderLine</code></a>.</li>
|
||||
<li>Many improvements to the <a href="manual.html#addon_show-hint"><code>show-hint</code></a> completion
|
||||
dialog addon.</li>
|
||||
<li>Tweak behavior of by-word cursor motion.</li>
|
||||
<li>Further improvements to the <a href="../demo/vim.html">vim mode</a>.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.1...v3.11">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-02-2013: <a href="http://codemirror.net/codemirror-3.1.zip">Version 3.1</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li><strong>Incompatible:</strong> key handlers may
|
||||
now <em>return</em>, rather
|
||||
than <em>throw</em> <code>CodeMirror.Pass</code> to signal they
|
||||
didn't handle the key.</li>
|
||||
<li>Make documents a <a href="manual.html#api_doc">first-class
|
||||
construct</a>, support split views and subviews.</li>
|
||||
<li>Add a <a href="manual.html#addon_show-hint">new module</a>
|
||||
for showing completion hints.
|
||||
Deprecate <code>simple-hint.js</code>.</li>
|
||||
<li>Extend <a href="../mode/htmlmixed/index.html">htmlmixed mode</a>
|
||||
to allow custom handling of script types.</li>
|
||||
<li>Support an <code>insertLeft</code> option
|
||||
to <a href="manual.html#setBookmark"><code>setBookmark</code></a>.</li>
|
||||
<li>Add an <a href="manual.html#eachLine"><code>eachLine</code></a>
|
||||
method to iterate over a document.</li>
|
||||
<li>New addon modules: <a href="../demo/markselection.html">selection
|
||||
marking</a>, <a href="../demo/lint.html">linting</a>,
|
||||
and <a href="../demo/closebrackets.html">automatic bracket
|
||||
closing</a>.</li>
|
||||
<li>Add <a href="manual.html#event_beforeChange"><code>"beforeChange"</code></a>
|
||||
and <a href="manual.html#event_beforeSelectionChange"><code>"beforeSelectionChange"</code></a>
|
||||
events.</li>
|
||||
<li>Add <a href="manual.html#event_hide"><code>"hide"</code></a>
|
||||
and <a href="manual.html#event_unhide"><code>"unhide"</code></a>
|
||||
events to marked ranges.</li>
|
||||
<li>Fix <a href="manual.html#coordsChar"><code>coordsChar</code></a>'s
|
||||
interpretation of its argument to match the documentation.</li>
|
||||
<li>New modes: <a href="../mode/turtle/index.html">Turtle</a>
|
||||
and <a href="../mode/q/index.html">Q</a>.</li>
|
||||
<li>Further improvements to the <a href="../demo/vim.html">vim mode</a>.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.01...v3.1">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p class="rel">25-01-2013: <a href="http://codemirror.net/codemirror-3.02.zip">Version 3.02</a>:</p>
|
||||
|
||||
<p class="rel-note">Single-bugfix release. Fixes a problem that
|
||||
prevents CodeMirror instances from being garbage-collected after
|
||||
they become unused.</p>
|
||||
|
||||
<p class="rel">21-01-2013: <a href="http://codemirror.net/codemirror-3.01.zip">Version 3.01</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Move all add-ons into an organized directory structure
|
||||
under <a href="../addon/"><code>/addon</code></a>. <strong>You might have to adjust your
|
||||
paths.</strong></li>
|
||||
<li>New
|
||||
modes: <a href="../mode/d/index.html">D</a>, <a href="../mode/sass/index.html">Sass</a>, <a href="../mode/apl/index.html">APL</a>, <a href="../mode/sql/index.html">SQL</a>
|
||||
(configurable), and <a href="../mode/asterisk/index.html">Asterisk</a>.</li>
|
||||
<li>Several bugfixes in right-to-left text support.</li>
|
||||
<li>Add <a href="manual.html#option_rtlMoveVisually"><code>rtlMoveVisually</code></a> option.</li>
|
||||
<li>Improvements to vim keymap.</li>
|
||||
<li>Add built-in (lightweight) <a href="manual.html#addOverlay">overlay mode</a> support.</li>
|
||||
<li>Support <code>showIfHidden</code> option for <a href="manual.html#addLineWidget">line widgets</a>.</li>
|
||||
<li>Add simple <a href="manual.html#addon_python-hint">Python hinter</a>.</li>
|
||||
<li>Bring back the <a href="manual.html#option_fixedGutter"><code>fixedGutter</code></a> option.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.0...v3.01">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">10-12-2012: <a href="http://codemirror.net/codemirror-3.0.zip">Version 3.0</a>:</p>
|
||||
|
||||
<p class="rel-note"><strong>New major version</strong>. Only
|
||||
partially backwards-compatible. See
|
||||
the <a href="upgrade_v3.html">upgrading guide</a> for more
|
||||
information. Changes since release candidate 2:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Rewritten VIM mode.</li>
|
||||
<li>Fix a few minor scrolling and sizing issues.</li>
|
||||
<li>Work around Safari segfault when dragging.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.0rc2...v3.0">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc2.zip">Version 3.0, release candidate 2</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/http/index.html">HTTP</a>.</li>
|
||||
<li>Improved handling of selection anchor position.</li>
|
||||
<li>Improve IE performance on longer lines.</li>
|
||||
<li>Reduce gutter glitches during horiz. scrolling.</li>
|
||||
<li>Add <a href="manual.html#addKeyMap"><code>addKeyMap</code></a> and <a href="manual.html#removeKeyMap"><code>removeKeyMap</code></a> methods.</li>
|
||||
<li>Rewrite <code>formatting</code> and <code>closetag</code> add-ons.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.0rc1...v3.0rc2">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc1.zip">Version 3.0, release candidate 1</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New theme: <a href="../demo/theme.html?solarized%20light">Solarized</a>.</li>
|
||||
<li>Introduce <a href="manual.html#addLineClass"><code>addLineClass</code></a>
|
||||
and <a href="manual.html#removeLineClass"><code>removeLineClass</code></a>,
|
||||
drop <code>setLineClass</code>.</li>
|
||||
<li>Add a <em>lot</em> of
|
||||
new <a href="manual.html#markText">options for marked text</a>
|
||||
(read-only, atomic, collapsed, widget replacement).</li>
|
||||
<li>Remove the old code folding interface in favour of these new ranges.</li>
|
||||
<li>Add <a href="manual.html#isClean"><code>isClean</code></a>/<a href="manual.html#markClean"><code>markClean</code></a> methods.</li>
|
||||
<li>Remove <code>compoundChange</code> method, use better undo-event-combining heuristic.</li>
|
||||
<li>Improve scrolling performance smoothness.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.0beta2...v3.0rc1">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">22-10-2012: <a href="http://codemirror.net/codemirror-3.0beta2.zip">Version 3.0, beta 2</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Fix page-based coordinate computation.</li>
|
||||
<li>Fix firing of <a href="manual.html#event_gutterClick"><code>gutterClick</code></a> event.</li>
|
||||
<li>Add <a href="manual.html#option_cursorHeight"><code>cursorHeight</code></a> option.</li>
|
||||
<li>Fix bi-directional text regression.</li>
|
||||
<li>Add <a href="manual.html#option_viewportMargin"><code>viewportMargin</code></a> option.</li>
|
||||
<li>Directly handle mousewheel events (again, hopefully better).</li>
|
||||
<li>Make vertical cursor movement more robust (through widgets, big line gaps).</li>
|
||||
<li>Add <a href="manual.html#option_flattenSpans"><code>flattenSpans</code></a> option.</li>
|
||||
<li>Many optimizations. Poor responsiveness should be fixed.</li>
|
||||
<li>Initialization in hidden state works again.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v3.0beta1...v3.0beta2">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-3.0beta1.zip">Version 3.0, beta 1</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Bi-directional text support.</li>
|
||||
<li>More powerful gutter model.</li>
|
||||
<li>Support for arbitrary text/widget height.</li>
|
||||
<li>In-line widgets.</li>
|
||||
<li>Generalized event handling.</li>
|
||||
</ul>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=v2>
|
||||
|
||||
<h2>Version 2.x</h2>
|
||||
|
||||
<p class="rel">21-01-2013: <a href="http://codemirror.net/codemirror-2.38.zip">Version 2.38</a>:</p>
|
||||
|
||||
<p class="rel-note">Integrate some bugfixes, enhancements to the vim keymap, and new
|
||||
modes
|
||||
(<a href="../mode/d/index.html">D</a>, <a href="../mode/sass/index.html">Sass</a>, <a href="../mode/apl/index.html">APL</a>)
|
||||
from the v3 branch.</p>
|
||||
|
||||
<p class="rel">20-12-2012: <a href="http://codemirror.net/codemirror-2.37.zip">Version 2.37</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/sql/index.html">SQL</a> (will replace <a href="../mode/plsql/index.html">plsql</a> and <a href="../mode/mysql/index.html">mysql</a> modes).</li>
|
||||
<li>Further work on the new VIM mode.</li>
|
||||
<li>Fix Cmd/Ctrl keys on recent Operas on OS X.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v2.36...v2.37">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-2.36.zip">Version 2.36</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/z80/index.html">Z80 assembly</a>.</li>
|
||||
<li>New theme: <a href="../demo/theme.html?twilight">Twilight</a>.</li>
|
||||
<li>Add command-line compression helper.</li>
|
||||
<li>Make <a href="manual.html#scrollIntoView"><code>scrollIntoView</code></a> public.</li>
|
||||
<li>Add <a href="manual.html#defaultTextHeight"><code>defaultTextHeight</code></a> method.</li>
|
||||
<li>Various extensions to the vim keymap.</li>
|
||||
<li>Make <a href="../mode/php/index.html">PHP mode</a> build on <a href="../mode/htmlmixed/index.html">mixed HTML mode</a>.</li>
|
||||
<li>Add <a href="manual.html#addon_continuecomment">comment-continuing</a> add-on.</li>
|
||||
<li>Full <a href="../https://github.com/codemirror/CodeMirror/compare/v2.35...v2.36">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">22-10-2012: <a href="http://codemirror.net/codemirror-2.35.zip">Version 2.35</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New (sub) mode: <a href="../mode/javascript/typescript.html">TypeScript</a>.</li>
|
||||
<li>Don't overwrite (insert key) when pasting.</li>
|
||||
<li>Fix several bugs in <a href="manual.html#markText"><code>markText</code></a>/undo interaction.</li>
|
||||
<li>Better indentation of JavaScript code without semicolons.</li>
|
||||
<li>Add <a href="manual.html#defineInitHook"><code>defineInitHook</code></a> function.</li>
|
||||
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/v2.34...v2.35">list of patches</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-2.34.zip">Version 2.34</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/commonlisp/index.html">Common Lisp</a>.</li>
|
||||
<li>Fix right-click select-all on most browsers.</li>
|
||||
<li>Change the way highlighting happens:<br> Saves memory and CPU cycles.<br> <code>compareStates</code> is no longer needed.<br> <code>onHighlightComplete</code> no longer works.</li>
|
||||
<li>Integrate mode (Markdown, XQuery, CSS, sTex) tests in central testsuite.</li>
|
||||
<li>Add a <a href="manual.html#version"><code>CodeMirror.version</code></a> property.</li>
|
||||
<li>More robust handling of nested modes in <a href="../demo/formatting.html">formatting</a> and <a href="../demo/closetag.html">closetag</a> plug-ins.</li>
|
||||
<li>Un/redo now preserves <a href="manual.html#markText">marked text</a> and bookmarks.</li>
|
||||
<li><a href="https://github.com/codemirror/CodeMirror/compare/v2.33...v2.34">Full list</a> of patches.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">23-08-2012: <a href="http://codemirror.net/codemirror-2.33.zip">Version 2.33</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/sieve/index.html">Sieve</a>.</li>
|
||||
<li>New <a href="manual.html#getViewport"><code>getViewPort</code></a> and <a href="manual.html#option_onViewportChange"><code>onViewportChange</code></a> API.</li>
|
||||
<li><a href="manual.html#option_cursorBlinkRate">Configurable</a> cursor blink rate.</li>
|
||||
<li>Make binding a key to <code>false</code> disabling handling (again).</li>
|
||||
<li>Show non-printing characters as red dots.</li>
|
||||
<li>More tweaks to the scrolling model.</li>
|
||||
<li>Expanded testsuite. Basic linter added.</li>
|
||||
<li>Remove most uses of <code>innerHTML</code>. Remove <code>CodeMirror.htmlEscape</code>.</li>
|
||||
<li><a href="https://github.com/codemirror/CodeMirror/compare/v2.32...v2.33">Full list</a> of patches.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">23-07-2012: <a href="http://codemirror.net/codemirror-2.32.zip">Version 2.32</a>:</p>
|
||||
|
||||
<p class="rel-note">Emergency fix for a bug where an editor with
|
||||
line wrapping on IE will break when there is <em>no</em>
|
||||
scrollbar.</p>
|
||||
|
||||
<p class="rel">20-07-2012: <a href="http://codemirror.net/codemirror-2.31.zip">Version 2.31</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New modes: <a href="../mode/ocaml/index.html">OCaml</a>, <a href="../mode/haxe/index.html">Haxe</a>, and <a href="../mode/vb/index.html">VB.NET</a>.</li>
|
||||
<li>Several fixes to the new scrolling model.</li>
|
||||
<li>Add a <a href="manual.html#setSize"><code>setSize</code></a> method for programmatic resizing.</li>
|
||||
<li>Add <a href="manual.html#getHistory"><code>getHistory</code></a> and <a href="manual.html#setHistory"><code>setHistory</code></a> methods.</li>
|
||||
<li>Allow custom line separator string in <a href="manual.html#getValue"><code>getValue</code></a> and <a href="manual.html#getRange"><code>getRange</code></a>.</li>
|
||||
<li>Support double- and triple-click drag, double-clicking whitespace.</li>
|
||||
<li>And more... <a href="https://github.com/codemirror/CodeMirror/compare/v2.3...v2.31">(all patches)</a></li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">22-06-2012: <a href="http://codemirror.net/codemirror-2.3.zip">Version 2.3</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li><strong>New scrollbar implementation</strong>. Should flicker less. Changes DOM structure of the editor.</li>
|
||||
<li>New theme: <a href="../demo/theme.html?vibrant-ink">vibrant-ink</a>.</li>
|
||||
<li>Many extensions to the VIM keymap (including text objects).</li>
|
||||
<li>Add <a href="../demo/multiplex.html">mode-multiplexing</a> utility script.</li>
|
||||
<li>Fix bug where right-click paste works in read-only mode.</li>
|
||||
<li>Add a <a href="manual.html#getScrollInfo"><code>getScrollInfo</code></a> method.</li>
|
||||
<li>Lots of other <a href="https://github.com/codemirror/CodeMirror/compare/v2.25...v2.3">fixes</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">23-05-2012: <a href="http://codemirror.net/codemirror-2.25.zip">Version 2.25</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>New mode: <a href="../mode/erlang/index.html">Erlang</a>.</li>
|
||||
<li><strong>Remove xmlpure mode</strong> (use <a href="../mode/xml/index.html">xml.js</a>).</li>
|
||||
<li>Fix line-wrapping in Opera.</li>
|
||||
<li>Fix X Windows middle-click paste in Chrome.</li>
|
||||
<li>Fix bug that broke pasting of huge documents.</li>
|
||||
<li>Fix backspace and tab key repeat in Opera.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">23-04-2012: <a href="http://codemirror.net/codemirror-2.24.zip">Version 2.24</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li><strong>Drop support for Internet Explorer 6</strong>.</li>
|
||||
<li>New
|
||||
modes: <a href="../mode/shell/index.html">Shell</a>, <a href="../mode/tiki/index.html">Tiki
|
||||
wiki</a>, <a href="../mode/pig/index.html">Pig Latin</a>.</li>
|
||||
<li>New themes: <a href="../demo/theme.html?ambiance">Ambiance</a>, <a href="../demo/theme.html?blackboard">Blackboard</a>.</li>
|
||||
<li>More control over drag/drop
|
||||
with <a href="manual.html#option_dragDrop"><code>dragDrop</code></a>
|
||||
and <a href="manual.html#option_onDragEvent"><code>onDragEvent</code></a>
|
||||
options.</li>
|
||||
<li>Make HTML mode a bit less pedantic.</li>
|
||||
<li>Add <a href="manual.html#compoundChange"><code>compoundChange</code></a> API method.</li>
|
||||
<li>Several fixes in undo history and line hiding.</li>
|
||||
<li>Remove (broken) support for <code>catchall</code> in key maps,
|
||||
add <code>nofallthrough</code> boolean field instead.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">26-03-2012: <a href="http://codemirror.net/codemirror-2.23.zip">Version 2.23</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Change <strong>default binding for tab</strong> <a href="javascript:void(document.getElementById('tabbinding').style.display='')">[more]</a>
|
||||
<div style="display: none" id=tabbinding>
|
||||
Starting in 2.23, these bindings are default:
|
||||
<ul><li>Tab: Insert tab character</li>
|
||||
<li>Shift-tab: Reset line indentation to default</li>
|
||||
<li>Ctrl/Cmd-[: Reduce line indentation (old tab behaviour)</li>
|
||||
<li>Ctrl/Cmd-]: Increase line indentation (old shift-tab behaviour)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li>New modes: <a href="../mode/xquery/index.html">XQuery</a> and <a href="../mode/vbscript/index.html">VBScript</a>.</li>
|
||||
<li>Two new themes: <a href="../mode/less/index.html">lesser-dark</a> and <a href="../mode/xquery/index.html">xq-dark</a>.</li>
|
||||
<li>Differentiate between background and text styles in <a href="manual.html#setLineClass"><code>setLineClass</code></a>.</li>
|
||||
<li>Fix drag-and-drop in IE9+.</li>
|
||||
<li>Extend <a href="manual.html#charCoords"><code>charCoords</code></a>
|
||||
and <a href="manual.html#cursorCoords"><code>cursorCoords</code></a> with a <code>mode</code> argument.</li>
|
||||
<li>Add <a href="manual.html#option_autofocus"><code>autofocus</code></a> option.</li>
|
||||
<li>Add <a href="manual.html#findMarksAt"><code>findMarksAt</code></a> method.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">27-02-2012: <a href="http://codemirror.net/codemirror-2.22.zip">Version 2.22</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Allow <a href="manual.html#keymaps">key handlers</a> to pass up events, allow binding characters.</li>
|
||||
<li>Add <a href="manual.html#option_autoClearEmptyLines"><code>autoClearEmptyLines</code></a> option.</li>
|
||||
<li>Properly use tab stops when rendering tabs.</li>
|
||||
<li>Make PHP mode more robust.</li>
|
||||
<li>Support indentation blocks in <a href="manual.html#addon_foldcode">code folder</a>.</li>
|
||||
<li>Add a script for <a href="manual.html#addon_match-highlighter">highlighting instances of the selection</a>.</li>
|
||||
<li>New <a href="../mode/properties/index.html">.properties</a> mode.</li>
|
||||
<li>Fix many bugs.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">27-01-2012: <a href="http://codemirror.net/codemirror-2.21.zip">Version 2.21</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Added <a href="../mode/less/index.html">LESS</a>, <a href="../mode/mysql/index.html">MySQL</a>,
|
||||
<a href="../mode/go/index.html">Go</a>, and <a href="../mode/verilog/index.html">Verilog</a> modes.</li>
|
||||
<li>Add <a href="manual.html#option_smartIndent"><code>smartIndent</code></a>
|
||||
option.</li>
|
||||
<li>Support a cursor in <a href="manual.html#option_readOnly"><code>readOnly</code></a>-mode.</li>
|
||||
<li>Support assigning multiple styles to a token.</li>
|
||||
<li>Use a new approach to drawing the selection.</li>
|
||||
<li>Add <a href="manual.html#scrollTo"><code>scrollTo</code></a> method.</li>
|
||||
<li>Allow undo/redo events to span non-adjacent lines.</li>
|
||||
<li>Lots and lots of bugfixes.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">20-12-2011: <a href="http://codemirror.net/codemirror-2.2.zip">Version 2.2</a>:</p>
|
||||
|
||||
<ul class="rel-note">
|
||||
<li>Slightly incompatible API changes. Read <a href="upgrade_v2.2.html">this</a>.</li>
|
||||
<li>New approach
|
||||
to <a href="manual.html#option_extraKeys">binding</a> keys,
|
||||
support for <a href="manual.html#option_keyMap">custom
|
||||
bindings</a>.</li>
|
||||
<li>Support for overwrite (insert).</li>
|
||||
<li><a href="manual.html#option_tabSize">Custom-width</a>
|
||||
and <a href="../demo/visibletabs.html">stylable</a> tabs.</li>
|
||||
<li>Moved more code into <a href="manual.html#addons">add-on scripts</a>.</li>
|
||||
<li>Support for sane vertical cursor movement in wrapped lines.</li>
|
||||
<li>More reliable handling of
|
||||
editing <a href="manual.html#markText">marked text</a>.</li>
|
||||
<li>Add minimal <a href="../demo/emacs.html">emacs</a>
|
||||
and <a href="../demo/vim.html">vim</a> bindings.</li>
|
||||
<li>Rename <code>coordsFromIndex</code>
|
||||
to <a href="manual.html#posFromIndex"><code>posFromIndex</code></a>,
|
||||
add <a href="manual.html#indexFromPos"><code>indexFromPos</code></a>
|
||||
method.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.18.zip">Version 2.18</a>:</p>
|
||||
<p class="rel-note">Fixes <code>TextMarker.clear</code>, which is broken in 2.17.</p>
|
||||
|
||||
<p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.17.zip">Version 2.17</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add support for <a href="manual.html#option_lineWrapping">line
|
||||
wrapping</a> and <a href="manual.html#hideLine">code
|
||||
folding</a>.</li>
|
||||
<li>Add <a href="../mode/gfm/index.html">Github-style Markdown</a> mode.</li>
|
||||
<li>Add <a href="../theme/monokai.css">Monokai</a>
|
||||
and <a href="../theme/rubyblue.css">Rubyblue</a> themes.</li>
|
||||
<li>Add <a href="manual.html#setBookmark"><code>setBookmark</code></a> method.</li>
|
||||
<li>Move some of the demo code into reusable components
|
||||
under <a href="../addon/"><code>lib/util</code></a>.</li>
|
||||
<li>Make screen-coord-finding code faster and more reliable.</li>
|
||||
<li>Fix drag-and-drop in Firefox.</li>
|
||||
<li>Improve support for IME.</li>
|
||||
<li>Speed up content rendering.</li>
|
||||
<li>Fix browser's built-in search in Webkit.</li>
|
||||
<li>Make double- and triple-click work in IE.</li>
|
||||
<li>Various fixes to modes.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">27-10-2011: <a href="http://codemirror.net/codemirror-2.16.zip">Version 2.16</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add <a href="../mode/perl/index.html">Perl</a>, <a href="../mode/rust/index.html">Rust</a>, <a href="../mode/tiddlywiki/index.html">TiddlyWiki</a>, and <a href="../mode/groovy/index.html">Groovy</a> modes.</li>
|
||||
<li>Dragging text inside the editor now moves, rather than copies.</li>
|
||||
<li>Add a <a href="manual.html#coordsFromIndex"><code>coordsFromIndex</code></a> method.</li>
|
||||
<li><strong>API change</strong>: <code>setValue</code> now no longer clears history. Use <a href="manual.html#clearHistory"><code>clearHistory</code></a> for that.</li>
|
||||
<li><strong>API change</strong>: <a href="manual.html#markText"><code>markText</code></a> now
|
||||
returns an object with <code>clear</code> and <code>find</code>
|
||||
methods. Marked text is now more robust when edited.</li>
|
||||
<li>Fix editing code with tabs in Internet Explorer.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.15.zip">Version 2.15</a>:</p>
|
||||
<p class="rel-note">Fix bug that snuck into 2.14: Clicking the
|
||||
character that currently has the cursor didn't re-focus the
|
||||
editor.</p>
|
||||
|
||||
<p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.14.zip">Version 2.14</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add <a href="../mode/clojure/index.html">Clojure</a>, <a href="../mode/pascal/index.html">Pascal</a>, <a href="../mode/ntriples/index.html">NTriples</a>, <a href="../mode/jinja2/index.html">Jinja2</a>, and <a href="../mode/markdown/index.html">Markdown</a> modes.</li>
|
||||
<li>Add <a href="../theme/cobalt.css">Cobalt</a> and <a href="../theme/eclipse.css">Eclipse</a> themes.</li>
|
||||
<li>Add a <a href="manual.html#option_fixedGutter"><code>fixedGutter</code></a> option.</li>
|
||||
<li>Fix bug with <code>setValue</code> breaking cursor movement.</li>
|
||||
<li>Make gutter updates much more efficient.</li>
|
||||
<li>Allow dragging of text out of the editor (on modern browsers).</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p class="rel">23-08-2011: <a href="http://codemirror.net/codemirror-2.13.zip">Version 2.13</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add <a href="../mode/ruby/index.html">Ruby</a>, <a href="../mode/r/index.html">R</a>, <a href="../mode/coffeescript/index.html">CoffeeScript</a>, and <a href="../mode/velocity/index.html">Velocity</a> modes.</li>
|
||||
<li>Add <a href="manual.html#getGutterElement"><code>getGutterElement</code></a> to API.</li>
|
||||
<li>Several fixes to scrolling and positioning.</li>
|
||||
<li>Add <a href="manual.html#option_smartHome"><code>smartHome</code></a> option.</li>
|
||||
<li>Add an experimental <a href="../mode/xmlpure/index.html">pure XML</a> mode.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">25-07-2011: <a href="http://codemirror.net/codemirror-2.12.zip">Version 2.12</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add a <a href="../mode/sparql/index.html">SPARQL</a> mode.</li>
|
||||
<li>Fix bug with cursor jumping around in an unfocused editor in IE.</li>
|
||||
<li>Allow key and mouse events to bubble out of the editor. Ignore widget clicks.</li>
|
||||
<li>Solve cursor flakiness after undo/redo.</li>
|
||||
<li>Fix block-reindent ignoring the last few lines.</li>
|
||||
<li>Fix parsing of multi-line attrs in XML mode.</li>
|
||||
<li>Use <code>innerHTML</code> for HTML-escaping.</li>
|
||||
<li>Some fixes to indentation in C-like mode.</li>
|
||||
<li>Shrink horiz scrollbars when long lines removed.</li>
|
||||
<li>Fix width feedback loop bug that caused the width of an inner DIV to shrink.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">04-07-2011: <a href="http://codemirror.net/codemirror-2.11.zip">Version 2.11</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add a <a href="../mode/scheme/index.html">Scheme mode</a>.</li>
|
||||
<li>Add a <code>replace</code> method to search cursors, for cursor-preserving replacements.</li>
|
||||
<li>Make the <a href="../mode/clike/index.html">C-like mode</a> mode more customizable.</li>
|
||||
<li>Update XML mode to spot mismatched tags.</li>
|
||||
<li>Add <code>getStateAfter</code> API and <code>compareState</code> mode API methods for finer-grained mode magic.</li>
|
||||
<li>Add a <code>getScrollerElement</code> API method to manipulate the scrolling DIV.</li>
|
||||
<li>Fix drag-and-drop for Firefox.</li>
|
||||
<li>Add a C# configuration for the <a href="../mode/clike/index.html">C-like mode</a>.</li>
|
||||
<li>Add <a href="../demo/fullscreen.html">full-screen editing</a> and <a href="../demo/changemode.html">mode-changing</a> demos.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">07-06-2011: <a href="http://codemirror.net/codemirror-2.1.zip">Version 2.1</a>:</p>
|
||||
<p class="rel-note">Add
|
||||
a <a href="manual.html#option_theme">theme</a> system
|
||||
(<a href="../demo/theme.html">demo</a>). Note that this is not
|
||||
backwards-compatible—you'll have to update your styles and
|
||||
modes!</p>
|
||||
|
||||
<p class="rel">07-06-2011: <a href="http://codemirror.net/codemirror-2.02.zip">Version 2.02</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add a <a href="../mode/lua/index.html">Lua mode</a>.</li>
|
||||
<li>Fix reverse-searching for a regexp.</li>
|
||||
<li>Empty lines can no longer break highlighting.</li>
|
||||
<li>Rework scrolling model (the outer wrapper no longer does the scrolling).</li>
|
||||
<li>Solve horizontal jittering on long lines.</li>
|
||||
<li>Add <a href="../demo/runmode.html">runmode.js</a>.</li>
|
||||
<li>Immediately re-highlight text when typing.</li>
|
||||
<li>Fix problem with 'sticking' horizontal scrollbar.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">26-05-2011: <a href="http://codemirror.net/codemirror-2.01.zip">Version 2.01</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add a <a href="../mode/smalltalk/index.html">Smalltalk mode</a>.</li>
|
||||
<li>Add a <a href="../mode/rst/index.html">reStructuredText mode</a>.</li>
|
||||
<li>Add a <a href="../mode/python/index.html">Python mode</a>.</li>
|
||||
<li>Add a <a href="../mode/plsql/index.html">PL/SQL mode</a>.</li>
|
||||
<li><code>coordsChar</code> now works</li>
|
||||
<li>Fix a problem where <code>onCursorActivity</code> interfered with <code>onChange</code>.</li>
|
||||
<li>Fix a number of scrolling and mouse-click-position glitches.</li>
|
||||
<li>Pass information about the changed lines to <code>onChange</code>.</li>
|
||||
<li>Support cmd-up/down on OS X.</li>
|
||||
<li>Add triple-click line selection.</li>
|
||||
<li>Don't handle shift when changing the selection through the API.</li>
|
||||
<li>Support <code>"nocursor"</code> mode for <code>readOnly</code> option.</li>
|
||||
<li>Add an <code>onHighlightComplete</code> option.</li>
|
||||
<li>Fix the context menu for Firefox.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">28-03-2011: <a href="http://codemirror.net/codemirror-2.0.zip">Version 2.0</a>:</p>
|
||||
<p class="rel-note">CodeMirror 2 is a complete rewrite that's
|
||||
faster, smaller, simpler to use, and less dependent on browser
|
||||
quirks. See <a href="internals.html">this</a>
|
||||
and <a href="http://groups.google.com/group/codemirror/browse_thread/thread/5a8e894024a9f580">this</a>
|
||||
for more information.</p>
|
||||
|
||||
<p class="rel">22-02-2011: <a href="https://github.com/codemirror/codemirror/tree/beta2">Version 2.0 beta 2</a>:</p>
|
||||
<p class="rel-note">Somewhat more mature API, lots of bugs shaken out.</p>
|
||||
|
||||
<p class="rel">17-02-2011: <a href="http://codemirror.net/codemirror-0.94.zip">Version 0.94</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li><code>tabMode: "spaces"</code> was modified slightly (now indents when something is selected).</li>
|
||||
<li>Fixes a bug that would cause the selection code to break on some IE versions.</li>
|
||||
<li>Disabling spell-check on WebKit browsers now works.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">08-02-2011: <a href="http://codemirror.net/">Version 2.0 beta 1</a>:</p>
|
||||
<p class="rel-note">CodeMirror 2 is a complete rewrite of
|
||||
CodeMirror, no longer depending on an editable frame.</p>
|
||||
|
||||
<p class="rel">19-01-2011: <a href="http://codemirror.net/codemirror-0.93.zip">Version 0.93</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Added a <a href="contrib/regex/index.html">Regular Expression</a> parser.</li>
|
||||
<li>Fixes to the PHP parser.</li>
|
||||
<li>Support for regular expression in search/replace.</li>
|
||||
<li>Add <code>save</code> method to instances created with <code>fromTextArea</code>.</li>
|
||||
<li>Add support for MS T-SQL in the SQL parser.</li>
|
||||
<li>Support use of CSS classes for highlighting brackets.</li>
|
||||
<li>Fix yet another hang with line-numbering in hidden editors.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id=v1>
|
||||
|
||||
<h2>Version 0.x</h2>
|
||||
|
||||
<p class="rel">28-03-2011: <a href="http://codemirror.net/codemirror-1.0.zip">Version 1.0</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Fix error when debug history overflows.</li>
|
||||
<li>Refine handling of C# verbatim strings.</li>
|
||||
<li>Fix some issues with JavaScript indentation.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">17-12-2010: <a href="http://codemirror.net/codemirror-0.92.zip">Version 0.92</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Make CodeMirror work in XHTML documents.</li>
|
||||
<li>Fix bug in handling of backslashes in Python strings.</li>
|
||||
<li>The <code>styleNumbers</code> option is now officially
|
||||
supported and documented.</li>
|
||||
<li><code>onLineNumberClick</code> option added.</li>
|
||||
<li>More consistent names <code>onLoad</code> and
|
||||
<code>onCursorActivity</code> callbacks. Old names still work, but
|
||||
are deprecated.</li>
|
||||
<li>Add a <a href="contrib/freemarker/index.html">Freemarker</a> mode.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">11-11-2010: <a
|
||||
href="http://codemirror.net/codemirror-0.91.zip">Version 0.91</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Adds support for <a href="contrib/java">Java</a>.</li>
|
||||
<li>Small additions to the <a href="contrib/php">PHP</a> and <a href="contrib/sql">SQL</a> parsers.</li>
|
||||
<li>Work around various <a href="https://bugs.webkit.org/show_bug.cgi?id=47806">Webkit</a> <a href="https://bugs.webkit.org/show_bug.cgi?id=23474">issues</a>.</li>
|
||||
<li>Fix <code>toTextArea</code> to update the code in the textarea.</li>
|
||||
<li>Add a <code>noScriptCaching</code> option (hack to ease development).</li>
|
||||
<li>Make sub-modes of <a href="mixedtest.html">HTML mixed</a> mode configurable.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">02-10-2010: <a
|
||||
href="http://codemirror.net/codemirror-0.9.zip">Version 0.9</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add support for searching backwards.</li>
|
||||
<li>There are now parsers for <a href="contrib/scheme/index.html">Scheme</a>, <a href="contrib/xquery/index.html">XQuery</a>, and <a href="contrib/ometa/index.html">OmetaJS</a>.</li>
|
||||
<li>Makes <code>height: "dynamic"</code> more robust.</li>
|
||||
<li>Fixes bug where paste did not work on OS X.</li>
|
||||
<li>Add a <code>enterMode</code> and <code>electricChars</code> options to make indentation even more customizable.</li>
|
||||
<li>Add <code>firstLineNumber</code> option.</li>
|
||||
<li>Fix bad handling of <code>@media</code> rules by the CSS parser.</li>
|
||||
<li>Take a new, more robust approach to working around the invisible-last-line bug in WebKit.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">22-07-2010: <a
|
||||
href="http://codemirror.net/codemirror-0.8.zip">Version 0.8</a>:</p>
|
||||
<ul class="rel-note">
|
||||
<li>Add a <code>cursorCoords</code> method to find the screen
|
||||
coordinates of the cursor.</li>
|
||||
<li>A number of fixes and support for more syntax in the PHP parser.</li>
|
||||
<li>Fix indentation problem with JSON-mode JS parser in Webkit.</li>
|
||||
<li>Add a <a href="compress.html">minification</a> UI.</li>
|
||||
<li>Support a <code>height: dynamic</code> mode, where the editor's
|
||||
height will adjust to the size of its content.</li>
|
||||
<li>Better support for IME input mode.</li>
|
||||
<li>Fix JavaScript parser getting confused when seeing a no-argument
|
||||
function call.</li>
|
||||
<li>Have CSS parser see the difference between selectors and other
|
||||
identifiers.</li>
|
||||
<li>Fix scrolling bug when pasting in a horizontally-scrolled
|
||||
editor.</li>
|
||||
<li>Support <code>toTextArea</code> method in instances created with
|
||||
<code>fromTextArea</code>.</li>
|
||||
<li>Work around new Opera cursor bug that causes the cursor to jump
|
||||
when pressing backspace at the end of a line.</li>
|
||||
</ul>
|
||||
|
||||
<p class="rel">27-04-2010: <a
|
||||
href="http://codemirror.net/codemirror-0.67.zip">Version
|
||||
0.67</a>:</p>
|
||||
<p class="rel-note">More consistent page-up/page-down behaviour
|
||||
across browsers. Fix some issues with hidden editors looping forever
|
||||
when line-numbers were enabled. Make PHP parser parse
|
||||
<code>"\\"</code> correctly. Have <code>jumpToLine</code> work on
|
||||
line handles, and add <code>cursorLine</code> function to fetch the
|
||||
line handle where the cursor currently is. Add new
|
||||
<code>setStylesheet</code> function to switch style-sheets in a
|
||||
running editor.</p>
|
||||
|
||||
<p class="rel">01-03-2010: <a
|
||||
href="http://codemirror.net/codemirror-0.66.zip">Version
|
||||
0.66</a>:</p>
|
||||
<p class="rel-note">Adds <code>removeLine</code> method to API.
|
||||
Introduces the <a href="contrib/plsql/index.html">PLSQL parser</a>.
|
||||
Marks XML errors by adding (rather than replacing) a CSS class, so
|
||||
that they can be disabled by modifying their style. Fixes several
|
||||
selection bugs, and a number of small glitches.</p>
|
||||
|
||||
<p class="rel">12-11-2009: <a
|
||||
href="http://codemirror.net/codemirror-0.65.zip">Version
|
||||
0.65</a>:</p>
|
||||
<p class="rel-note">Add support for having both line-wrapping and
|
||||
line-numbers turned on, make paren-highlighting style customisable
|
||||
(<code>markParen</code> and <code>unmarkParen</code> config
|
||||
options), work around a selection bug that Opera
|
||||
<em>re</em>introduced in version 10.</p>
|
||||
|
||||
<p class="rel">23-10-2009: <a
|
||||
href="http://codemirror.net/codemirror-0.64.zip">Version
|
||||
0.64</a>:</p>
|
||||
<p class="rel-note">Solves some issues introduced by the
|
||||
paste-handling changes from the previous release. Adds
|
||||
<code>setSpellcheck</code>, <code>setTextWrapping</code>,
|
||||
<code>setIndentUnit</code>, <code>setUndoDepth</code>,
|
||||
<code>setTabMode</code>, and <code>setLineNumbers</code> to
|
||||
customise a running editor. Introduces an <a
|
||||
href="contrib/sql/index.html">SQL</a> parser. Fixes a few small
|
||||
problems in the <a href="contrib/python/index.html">Python</a>
|
||||
parser. And, as usual, add workarounds for various newly discovered
|
||||
browser incompatibilities.</p>
|
||||
|
||||
<p class="rel"><em>31-08-2009</em>: <a href="http://codemirror.net/codemirror-0.63.zip">Version 0.63</a>:</p>
|
||||
<p class="rel-note"> Overhaul of paste-handling (less fragile), fixes for several
|
||||
serious IE8 issues (cursor jumping, end-of-document bugs) and a number
|
||||
of small problems.</p>
|
||||
|
||||
<p class="rel"><em>30-05-2009</em>: <a href="http://codemirror.net/codemirror-0.62.zip">Version 0.62</a>:</p>
|
||||
<p class="rel-note">Introduces <a href="contrib/python/index.html">Python</a>
|
||||
and <a href="contrib/lua/index.html">Lua</a> parsers. Add
|
||||
<code>setParser</code> (on-the-fly mode changing) and
|
||||
<code>clearHistory</code> methods. Make parsing passes time-based
|
||||
instead of lines-based (see the <code>passTime</code> option).</p>
|
||||
|
||||
</section>
|
||||
</article>
|
@ -1,61 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Reporting Bugs</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">Reporting bugs</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2>Reporting bugs effectively</h2>
|
||||
|
||||
<div class="left">
|
||||
|
||||
<p>So you found a problem in CodeMirror. By all means, report it! Bug
|
||||
reports from users are the main drive behind improvements to
|
||||
CodeMirror. But first, please read over these points:</p>
|
||||
|
||||
<ol>
|
||||
<li>CodeMirror is maintained by volunteers. They don't owe you
|
||||
anything, so be polite. Reports with an indignant or belligerent
|
||||
tone tend to be moved to the bottom of the pile.</li>
|
||||
|
||||
<li>Include information about <strong>the browser in which the
|
||||
problem occurred</strong>. Even if you tested several browsers, and
|
||||
the problem occurred in all of them, mention this fact in the bug
|
||||
report. Also include browser version numbers and the operating
|
||||
system that you're on.</li>
|
||||
|
||||
<li>Mention which release of CodeMirror you're using. Preferably,
|
||||
try also with the current development snapshot, to ensure the
|
||||
problem has not already been fixed.</li>
|
||||
|
||||
<li>Mention very precisely what went wrong. "X is broken" is not a
|
||||
good bug report. What did you expect to happen? What happened
|
||||
instead? Describe the exact steps a maintainer has to take to make
|
||||
the problem occur. We can not fix something that we can not
|
||||
observe.</li>
|
||||
|
||||
<li>If the problem can not be reproduced in any of the demos
|
||||
included in the CodeMirror distribution, please provide an HTML
|
||||
document that demonstrates the problem. The best way to do this is
|
||||
to go to <a href="http://jsbin.com/ihunin/1/edit">jsbin.com</a>, enter
|
||||
it there, press save, and include the resulting link in your bug
|
||||
report.</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
|
||||
</article>
|
@ -1,96 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Version 2.2 upgrade guide</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#">2.2 upgrade guide</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2>Upgrading to v2.2</h2>
|
||||
|
||||
<p>There are a few things in the 2.2 release that require some care
|
||||
when upgrading.</p>
|
||||
|
||||
<h3>No more default.css</h3>
|
||||
|
||||
<p>The default theme is now included
|
||||
in <a href="../lib/codemirror.css"><code>codemirror.css</code></a>, so
|
||||
you do not have to included it separately anymore. (It was tiny, so
|
||||
even if you're not using it, the extra data overhead is negligible.)
|
||||
|
||||
<h3>Different key customization</h3>
|
||||
|
||||
<p>CodeMirror has moved to a system
|
||||
where <a href="manual.html#option_keyMap">keymaps</a> are used to
|
||||
bind behavior to keys. This means <a href="../demo/emacs.html">custom
|
||||
bindings</a> are now possible.</p>
|
||||
|
||||
<p>Three options that influenced key
|
||||
behavior, <code>tabMode</code>, <code>enterMode</code>,
|
||||
and <code>smartHome</code>, are no longer supported. Instead, you can
|
||||
provide custom bindings to influence the way these keys act. This is
|
||||
done through the
|
||||
new <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
|
||||
option, which can hold an object mapping key names to functionality. A
|
||||
simple example would be:</p>
|
||||
|
||||
<pre> extraKeys: {
|
||||
"Ctrl-S": function(instance) { saveText(instance.getValue()); },
|
||||
"Ctrl-/": "undo"
|
||||
}</pre>
|
||||
|
||||
<p>Keys can be mapped either to functions, which will be given the
|
||||
editor instance as argument, or to strings, which are mapped through
|
||||
functions through the <code>CodeMirror.commands</code> table, which
|
||||
contains all the built-in editing commands, and can be inspected and
|
||||
extended by external code.</p>
|
||||
|
||||
<p>By default, the <code>Home</code> key is bound to
|
||||
the <code>"goLineStartSmart"</code> command, which moves the cursor to
|
||||
the first non-whitespace character on the line. You can set do this to
|
||||
make it always go to the very start instead:</p>
|
||||
|
||||
<pre> extraKeys: {"Home": "goLineStart"}</pre>
|
||||
|
||||
<p>Similarly, <code>Enter</code> is bound
|
||||
to <code>"newlineAndIndent"</code> by default. You can bind it to
|
||||
something else to get different behavior. To disable special handling
|
||||
completely and only get a newline character inserted, you can bind it
|
||||
to <code>false</code>:</p>
|
||||
|
||||
<pre> extraKeys: {"Enter": false}</pre>
|
||||
|
||||
<p>The same works for <code>Tab</code>. If you don't want CodeMirror
|
||||
to handle it, bind it to <code>false</code>. The default behaviour is
|
||||
to indent the current line more (<code>"indentMore"</code> command),
|
||||
and indent it less when shift is held (<code>"indentLess"</code>).
|
||||
There are also <code>"indentAuto"</code> (smart indent)
|
||||
and <code>"insertTab"</code> commands provided for alternate
|
||||
behaviors. Or you can write your own handler function to do something
|
||||
different altogether.</p>
|
||||
|
||||
<h3>Tabs</h3>
|
||||
|
||||
<p>Handling of tabs changed completely. The display width of tabs can
|
||||
now be set with the <code>tabSize</code> option, and tabs can
|
||||
be <a href="../demo/visibletabs.html">styled</a> by setting CSS rules
|
||||
for the <code>cm-tab</code> class.</p>
|
||||
|
||||
<p>The default width for tabs is now 4, as opposed to the 8 that is
|
||||
hard-wired into browsers. If you are relying on 8-space tabs, make
|
||||
sure you explicitly set <code>tabSize: 8</code> in your options.</p>
|
||||
|
||||
</article>
|
@ -1,230 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Version 3 upgrade guide</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
<script src="../lib/codemirror.js"></script>
|
||||
<link rel="stylesheet" href="../lib/codemirror.css">
|
||||
<script src="../addon/runmode/runmode.js"></script>
|
||||
<script src="../addon/runmode/colorize.js"></script>
|
||||
<script src="../mode/javascript/javascript.js"></script>
|
||||
<script src="../mode/xml/xml.js"></script>
|
||||
<script src="../mode/css/css.js"></script>
|
||||
<script src="../mode/htmlmixed/htmlmixed.js"></script>
|
||||
<script src="activebookmark.js"></script>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#upgrade">Upgrade guide</a>
|
||||
<li><a href="#dom">DOM structure</a></li>
|
||||
<li><a href="#gutters">Gutter model</a></li>
|
||||
<li><a href="#events">Event handling</a></li>
|
||||
<li><a href="#marktext">markText method arguments</a></li>
|
||||
<li><a href="#folding">Line folding</a></li>
|
||||
<li><a href="#lineclass">Line CSS classes</a></li>
|
||||
<li><a href="#positions">Position properties</a></li>
|
||||
<li><a href="#matchbrackets">Bracket matching</a></li>
|
||||
<li><a href="#modes">Mode management</a></li>
|
||||
<li><a href="#new">New features</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2 id=upgrade>Upgrading to version 3</h2>
|
||||
|
||||
<p>Version 3 does not depart too much from 2.x API, and sites that use
|
||||
CodeMirror in a very simple way might be able to upgrade without
|
||||
trouble. But it does introduce a number of incompatibilities. Please
|
||||
at least skim this text before upgrading.</p>
|
||||
|
||||
<p>Note that <strong>version 3 drops full support for Internet
|
||||
Explorer 7</strong>. The editor will mostly work on that browser, but
|
||||
it'll be significantly glitchy.</p>
|
||||
|
||||
<section id=dom>
|
||||
<h2>DOM structure</h2>
|
||||
|
||||
<p>This one is the most likely to cause problems. The internal
|
||||
structure of the editor has changed quite a lot, mostly to implement a
|
||||
new scrolling model.</p>
|
||||
|
||||
<p>Editor height is now set on the outer wrapper element (CSS
|
||||
class <code>CodeMirror</code>), not on the scroller element
|
||||
(<code>CodeMirror-scroll</code>).</p>
|
||||
|
||||
<p>Other nodes were moved, dropped, and added. If you have any code
|
||||
that makes assumptions about the internal DOM structure of the editor,
|
||||
you'll have to re-test it and probably update it to work with v3.</p>
|
||||
|
||||
<p>See the <a href="manual.html#styling">styling section</a> of the
|
||||
manual for more information.</p>
|
||||
</section>
|
||||
<section id=gutters>
|
||||
<h2>Gutter model</h2>
|
||||
|
||||
<p>In CodeMirror 2.x, there was a single gutter, and line markers
|
||||
created with <code>setMarker</code> would have to somehow coexist with
|
||||
the line numbers (if present). Version 3 allows you to specify an
|
||||
array of gutters, <a href="manual.html#option_gutters">by class
|
||||
name</a>,
|
||||
use <a href="manual.html#setGutterMarker"><code>setGutterMarker</code></a>
|
||||
to add or remove markers in individual gutters, and clear whole
|
||||
gutters
|
||||
with <a href="manual.html#clearGutter"><code>clearGutter</code></a>.
|
||||
Gutter markers are now specified as DOM nodes, rather than HTML
|
||||
snippets.</p>
|
||||
|
||||
<p>The gutters no longer horizontally scrolls along with the content.
|
||||
The <code>fixedGutter</code> option was removed (since it is now the
|
||||
only behavior).</p>
|
||||
|
||||
<pre data-lang="text/html">
|
||||
<style>
|
||||
/* Define a gutter style */
|
||||
.note-gutter { width: 3em; background: cyan; }
|
||||
</style>
|
||||
<script>
|
||||
// Create an instance with two gutters -- line numbers and notes
|
||||
var cm = new CodeMirror(document.body, {
|
||||
gutters: ["note-gutter", "CodeMirror-linenumbers"],
|
||||
lineNumbers: true
|
||||
});
|
||||
// Add a note to line 0
|
||||
cm.setGutterMarker(0, "note-gutter", document.createTextNode("hi"));
|
||||
</script>
|
||||
</pre>
|
||||
</section>
|
||||
<section id=events>
|
||||
<h2>Event handling</h2>
|
||||
|
||||
<p>Most of the <code>onXYZ</code> options have been removed. The same
|
||||
effect is now obtained by calling
|
||||
the <a href="manual.html#on"><code>on</code></a> method with a string
|
||||
identifying the event type. Multiple handlers can now be registered
|
||||
(and individually unregistered) for an event, and objects such as line
|
||||
handlers now also expose events. See <a href="manual.html#events">the
|
||||
full list here</a>.</p>
|
||||
|
||||
<p>(The <code>onKeyEvent</code> and <code>onDragEvent</code> options,
|
||||
which act more as hooks than as event handlers, are still there in
|
||||
their old form.)</p>
|
||||
|
||||
<pre data-lang="javascript">
|
||||
cm.on("change", function(cm, change) {
|
||||
console.log("something changed! (" + change.origin + ")");
|
||||
});
|
||||
</pre>
|
||||
</section>
|
||||
<section id=marktext>
|
||||
<h2>markText method arguments</h2>
|
||||
|
||||
<p>The <a href="manual.html#markText"><code>markText</code></a> method
|
||||
(which has gained some interesting new features, such as creating
|
||||
atomic and read-only spans, or replacing spans with widgets) no longer
|
||||
takes the CSS class name as a separate argument, but makes it an
|
||||
optional field in the options object instead.</p>
|
||||
|
||||
<pre data-lang="javascript">
|
||||
// Style first ten lines, and forbid the cursor from entering them
|
||||
cm.markText({line: 0, ch: 0}, {line: 10, ch: 0}, {
|
||||
className: "magic-text",
|
||||
inclusiveLeft: true,
|
||||
atomic: true
|
||||
});
|
||||
</pre>
|
||||
</section>
|
||||
<section id=folding>
|
||||
<h2>Line folding</h2>
|
||||
|
||||
<p>The interface for hiding lines has been
|
||||
removed. <a href="manual.html#markText"><code>markText</code></a> can
|
||||
now be used to do the same in a more flexible and powerful way.</p>
|
||||
|
||||
<p>The <a href="../demo/folding.html">folding script</a> has been
|
||||
updated to use the new interface, and should now be more robust.</p>
|
||||
|
||||
<pre data-lang="javascript">
|
||||
// Fold a range, replacing it with the text "??"
|
||||
var range = cm.markText({line: 4, ch: 2}, {line: 8, ch: 1}, {
|
||||
replacedWith: document.createTextNode("??"),
|
||||
// Auto-unfold when cursor moves into the range
|
||||
clearOnEnter: true
|
||||
});
|
||||
// Get notified when auto-unfolding
|
||||
CodeMirror.on(range, "clear", function() {
|
||||
console.log("boom");
|
||||
});
|
||||
</pre>
|
||||
</section>
|
||||
<section id=lineclass>
|
||||
<h2>Line CSS classes</h2>
|
||||
|
||||
<p>The <code>setLineClass</code> method has been replaced
|
||||
by <a href="manual.html#addLineClass"><code>addLineClass</code></a>
|
||||
and <a href="manual.html#removeLineClass"><code>removeLineClass</code></a>,
|
||||
which allow more modular control over the classes attached to a line.</p>
|
||||
|
||||
<pre data-lang="javascript">
|
||||
var marked = cm.addLineClass(10, "background", "highlighted-line");
|
||||
setTimeout(function() {
|
||||
cm.removeLineClass(marked, "background", "highlighted-line");
|
||||
});
|
||||
</pre>
|
||||
</section>
|
||||
<section id=positions>
|
||||
<h2>Position properties</h2>
|
||||
|
||||
<p>All methods that take or return objects that represent screen
|
||||
positions now use <code>{left, top, bottom, right}</code> properties
|
||||
(not always all of them) instead of the <code>{x, y, yBot}</code> used
|
||||
by some methods in v2.x.</p>
|
||||
|
||||
<p>Affected methods
|
||||
are <a href="manual.html#cursorCoords"><code>cursorCoords</code></a>, <a href="manual.html#charCoords"><code>charCoords</code></a>, <a href="manual.html#coordsChar"><code>coordsChar</code></a>,
|
||||
and <a href="manual.html#getScrollInfo"><code>getScrollInfo</code></a>.</p>
|
||||
</section>
|
||||
<section id=matchbrackets>
|
||||
<h2>Bracket matching no longer in core</h2>
|
||||
|
||||
<p>The <a href="manual.html#addon_matchbrackets"><code>matchBrackets</code></a>
|
||||
option is no longer defined in the core editor.
|
||||
Load <code>addon/edit/matchbrackets.js</code> to enable it.</p>
|
||||
</section>
|
||||
<section id=modes>
|
||||
<h2>Mode management</h2>
|
||||
|
||||
<p>The <code>CodeMirror.listModes</code>
|
||||
and <code>CodeMirror.listMIMEs</code> functions, used for listing
|
||||
defined modes, are gone. You are now encouraged to simply
|
||||
inspect <code>CodeMirror.modes</code> (mapping mode names to mode
|
||||
constructors) and <code>CodeMirror.mimeModes</code> (mapping MIME
|
||||
strings to mode specs).</p>
|
||||
</section>
|
||||
<section id=new>
|
||||
<h2>New features</h2>
|
||||
|
||||
<p>Some more reasons to upgrade to version 3.</p>
|
||||
|
||||
<ul>
|
||||
<li>Bi-directional text support. CodeMirror will now mostly do the
|
||||
right thing when editing Arabic or Hebrew text.</li>
|
||||
<li>Arbitrary line heights. Using fonts with different heights
|
||||
inside the editor (whether off by one pixel or fifty) is now
|
||||
supported and handled gracefully.</li>
|
||||
<li>In-line widgets. See <a href="../demo/widget.html">the demo</a>
|
||||
and <a href="manual.html#addLineWidget">the docs</a>.</li>
|
||||
<li>Defining custom options
|
||||
with <a href="manual.html#defineOption"><code>CodeMirror.defineOption</code></a>.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
<script>setTimeout(function(){CodeMirror.colorize();}, 20);</script>
|
@ -1,144 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Version 4 upgrade guide</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="docs.css">
|
||||
<script src="activebookmark.js"></script>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Home</a>
|
||||
<li><a href="manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a class=active href="#upgrade">Upgrade guide</a>
|
||||
<li><a href="#multisel">Multiple selections</a>
|
||||
<li><a href="#beforeSelectionChange">The beforeSelectionChange event</a>
|
||||
<li><a href="#replaceSelection">replaceSelection and collapsing</a>
|
||||
<li><a href="#changeEvent">change event data</a>
|
||||
<li><a href="#showIfHidden">showIfHidden option to line widgets</a>
|
||||
<li><a href="#module">Module loaders</a>
|
||||
<li><a href="#shareddata">Mutating shared data structures</a></li>
|
||||
<li><a href="#deprecated">Deprecated interfaces dropped</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
|
||||
<h2 id=upgrade>Upgrading to version 4</h2>
|
||||
|
||||
<p>CodeMirror 4's interface is <em>very</em> close version 3, but it
|
||||
does fix a few awkward details in a backwards-incompatible ways. At
|
||||
least skim the text below before upgrading.</p>
|
||||
|
||||
<section id=multisel><h2>Multiple selections</h2>
|
||||
|
||||
<p>The main new feature in version 4 is multiple selections. The
|
||||
single-selection variants of methods are still there, but now
|
||||
typically act only on the <em>primary</em> selection (usually the last
|
||||
one added).</p>
|
||||
|
||||
<p>The exception to this
|
||||
is <a href="manual.html#getSelection"><strong><code>getSelection</code></strong></a>,
|
||||
which will now return the content of <em>all</em> selections
|
||||
(separated by newlines, or whatever <code>lineSep</code> parameter you passed
|
||||
it).</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=beforeSelectionChange><h2>The beforeSelectionChange event</h2>
|
||||
|
||||
<p>This event still exists, but the object it is passed has
|
||||
a <a href="manual.html#event_beforeSelectionChange">completely new
|
||||
interface</a>, because such changes now concern multiple
|
||||
selections.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=replaceSelection><h2>replaceSelection's collapsing behavior</h2>
|
||||
|
||||
<p>By
|
||||
default, <a href="manual.html#replaceSelection"><code>replaceSelection</code></a>
|
||||
would leave the newly inserted text selected. This is only rarely what
|
||||
you want, and also (slightly) more expensive in the new model, so the
|
||||
default was changed to <code>"end"</code>, meaning the old behavior
|
||||
must be explicitly specified by passing a second argument
|
||||
of <code>"around"</code>.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=changeEvent><h2>change event data</h2>
|
||||
|
||||
<p>Rather than forcing client code to follow <code>next</code>
|
||||
pointers from one change object to the next, the library will now
|
||||
simply fire
|
||||
multiple <a href="manual.html#event_change"><code>"change"</code></a>
|
||||
events. Existing code will probably continue to work unmodified.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=showIfHidden><h2>showIfHidden option to line widgets</h2>
|
||||
|
||||
<p>This option, which conceptually caused line widgets to be visible
|
||||
even if their line was hidden, was never really well-defined, and was
|
||||
buggy from the start. It would be a rather expensive feature, both in
|
||||
code complexity and run-time performance, to implement properly. It
|
||||
has been dropped entirely in 4.0.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=module><h2>Module loaders</h2>
|
||||
|
||||
<p>All modules in the CodeMirror distribution are now wrapped in a
|
||||
shim function to make them compatible with both AMD
|
||||
(<a href="http://requirejs.org">requirejs</a>) and CommonJS (as used
|
||||
by <a href="http://nodejs.org/">node</a>
|
||||
and <a href="http://browserify.org/">browserify</a>) module loaders.
|
||||
When neither of these is present, they fall back to simply using the
|
||||
global <code>CodeMirror</code> variable.</p>
|
||||
|
||||
<p>If you have a module loader present in your environment, CodeMirror
|
||||
will attempt to use it, and you might need to change the way you load
|
||||
CodeMirror modules.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=shareddata><h2>Mutating shared data structures</h2>
|
||||
|
||||
<p>Data structures produced by the library should not be mutated
|
||||
unless explicitly allowed, in general. This is slightly more strict in
|
||||
4.0 than it was in earlier versions, which copied the position objects
|
||||
returned by <a href="manual.html#getCursor"><code>getCursor</code></a>
|
||||
for nebulous, historic reasons. In 4.0, mutating these
|
||||
objects <em>will</em> corrupt your editor's selection.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section id=deprecated><h2>Deprecated interfaces dropped</h2>
|
||||
|
||||
<p>A few properties and methods that have been deprecated for a while
|
||||
are now gone. Most notably, the <code>onKeyEvent</code>
|
||||
and <code>onDragEvent</code> options (use the
|
||||
corresponding <a href="manual.html#event_dom">events</a> instead).</p>
|
||||
|
||||
<p>Two silly methods, which were mostly there to stay close to the 0.x
|
||||
API, <code>setLine</code> and <code>removeLine</code> are now gone.
|
||||
Use the more
|
||||
flexible <a href="manual.html#replaceRange"><code>replaceRange</code></a>
|
||||
method instead.</p>
|
||||
|
||||
<p>The long names for folding and completing functions
|
||||
(<code>CodeMirror.braceRangeFinder</code>, <code>CodeMirror.javascriptHint</code>,
|
||||
etc) are also gone
|
||||
(use <code>CodeMirror.fold.brace</code>, <code>CodeMirror.hint.javascript</code>).</p>
|
||||
|
||||
<p>The <code>className</code> property in the return value
|
||||
of <a href="manual.html#getTokenAt"><code>getTokenAt</code></a>, which
|
||||
has been superseded by the <code>type</code> property, is also no
|
||||
longer present.</p>
|
||||
|
||||
</section>
|
||||
</article>
|
@ -1,175 +0,0 @@
|
||||
// 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("apl", function() {
|
||||
var builtInOps = {
|
||||
".": "innerProduct",
|
||||
"\\": "scan",
|
||||
"/": "reduce",
|
||||
"⌿": "reduce1Axis",
|
||||
"⍀": "scan1Axis",
|
||||
"¨": "each",
|
||||
"⍣": "power"
|
||||
};
|
||||
var builtInFuncs = {
|
||||
"+": ["conjugate", "add"],
|
||||
"−": ["negate", "subtract"],
|
||||
"×": ["signOf", "multiply"],
|
||||
"÷": ["reciprocal", "divide"],
|
||||
"⌈": ["ceiling", "greaterOf"],
|
||||
"⌊": ["floor", "lesserOf"],
|
||||
"∣": ["absolute", "residue"],
|
||||
"⍳": ["indexGenerate", "indexOf"],
|
||||
"?": ["roll", "deal"],
|
||||
"⋆": ["exponentiate", "toThePowerOf"],
|
||||
"⍟": ["naturalLog", "logToTheBase"],
|
||||
"○": ["piTimes", "circularFuncs"],
|
||||
"!": ["factorial", "binomial"],
|
||||
"⌹": ["matrixInverse", "matrixDivide"],
|
||||
"<": [null, "lessThan"],
|
||||
"≤": [null, "lessThanOrEqual"],
|
||||
"=": [null, "equals"],
|
||||
">": [null, "greaterThan"],
|
||||
"≥": [null, "greaterThanOrEqual"],
|
||||
"≠": [null, "notEqual"],
|
||||
"≡": ["depth", "match"],
|
||||
"≢": [null, "notMatch"],
|
||||
"∈": ["enlist", "membership"],
|
||||
"⍷": [null, "find"],
|
||||
"∪": ["unique", "union"],
|
||||
"∩": [null, "intersection"],
|
||||
"∼": ["not", "without"],
|
||||
"∨": [null, "or"],
|
||||
"∧": [null, "and"],
|
||||
"⍱": [null, "nor"],
|
||||
"⍲": [null, "nand"],
|
||||
"⍴": ["shapeOf", "reshape"],
|
||||
",": ["ravel", "catenate"],
|
||||
"⍪": [null, "firstAxisCatenate"],
|
||||
"⌽": ["reverse", "rotate"],
|
||||
"⊖": ["axis1Reverse", "axis1Rotate"],
|
||||
"⍉": ["transpose", null],
|
||||
"↑": ["first", "take"],
|
||||
"↓": [null, "drop"],
|
||||
"⊂": ["enclose", "partitionWithAxis"],
|
||||
"⊃": ["diclose", "pick"],
|
||||
"⌷": [null, "index"],
|
||||
"⍋": ["gradeUp", null],
|
||||
"⍒": ["gradeDown", null],
|
||||
"⊤": ["encode", null],
|
||||
"⊥": ["decode", null],
|
||||
"⍕": ["format", "formatByExample"],
|
||||
"⍎": ["execute", null],
|
||||
"⊣": ["stop", "left"],
|
||||
"⊢": ["pass", "right"]
|
||||
};
|
||||
|
||||
var isOperator = /[\.\/⌿⍀¨⍣]/;
|
||||
var isNiladic = /⍬/;
|
||||
var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/;
|
||||
var isArrow = /←/;
|
||||
var isComment = /[⍝#].*$/;
|
||||
|
||||
var stringEater = function(type) {
|
||||
var prev;
|
||||
prev = false;
|
||||
return function(c) {
|
||||
prev = c;
|
||||
if (c === type) {
|
||||
return prev === "\\";
|
||||
}
|
||||
return true;
|
||||
};
|
||||
};
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
prev: false,
|
||||
func: false,
|
||||
op: false,
|
||||
string: false,
|
||||
escape: false
|
||||
};
|
||||
},
|
||||
token: function(stream, state) {
|
||||
var ch, funcName, word;
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
ch = stream.next();
|
||||
if (ch === '"' || ch === "'") {
|
||||
stream.eatWhile(stringEater(ch));
|
||||
stream.next();
|
||||
state.prev = true;
|
||||
return "string";
|
||||
}
|
||||
if (/[\[{\(]/.test(ch)) {
|
||||
state.prev = false;
|
||||
return null;
|
||||
}
|
||||
if (/[\]}\)]/.test(ch)) {
|
||||
state.prev = true;
|
||||
return null;
|
||||
}
|
||||
if (isNiladic.test(ch)) {
|
||||
state.prev = false;
|
||||
return "niladic";
|
||||
}
|
||||
if (/[¯\d]/.test(ch)) {
|
||||
if (state.func) {
|
||||
state.func = false;
|
||||
state.prev = false;
|
||||
} else {
|
||||
state.prev = true;
|
||||
}
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
return "number";
|
||||
}
|
||||
if (isOperator.test(ch)) {
|
||||
return "operator apl-" + builtInOps[ch];
|
||||
}
|
||||
if (isArrow.test(ch)) {
|
||||
return "apl-arrow";
|
||||
}
|
||||
if (isFunction.test(ch)) {
|
||||
funcName = "apl-";
|
||||
if (builtInFuncs[ch] != null) {
|
||||
if (state.prev) {
|
||||
funcName += builtInFuncs[ch][1];
|
||||
} else {
|
||||
funcName += builtInFuncs[ch][0];
|
||||
}
|
||||
}
|
||||
state.func = true;
|
||||
state.prev = false;
|
||||
return "function " + funcName;
|
||||
}
|
||||
if (isComment.test(ch)) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
if (ch === "∘" && stream.peek() === ".") {
|
||||
stream.next();
|
||||
return "function jot-dot";
|
||||
}
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
word = stream.current();
|
||||
state.prev = true;
|
||||
return "keyword";
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/apl", "apl");
|
||||
|
||||
});
|
@ -1,72 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: APL mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="./apl.js"></script>
|
||||
<style>
|
||||
.CodeMirror { border: 2px inset #dee; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">APL</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>APL mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
⍝ Conway's game of life
|
||||
|
||||
⍝ This example was inspired by the impressive demo at
|
||||
⍝ http://www.youtube.com/watch?v=a9xAKttWgP4
|
||||
|
||||
⍝ Create a matrix:
|
||||
⍝ 0 1 1
|
||||
⍝ 1 1 0
|
||||
⍝ 0 1 0
|
||||
creature ← (3 3 ⍴ ⍳ 9) ∈ 1 2 3 4 7 ⍝ Original creature from demo
|
||||
creature ← (3 3 ⍴ ⍳ 9) ∈ 1 3 6 7 8 ⍝ Glider
|
||||
|
||||
⍝ Place the creature on a larger board, near the centre
|
||||
board ← ¯1 ⊖ ¯2 ⌽ 5 7 ↑ creature
|
||||
|
||||
⍝ A function to move from one generation to the next
|
||||
life ← {∨/ 1 ⍵ ∧ 3 4 = ⊂+/ +⌿ 1 0 ¯1 ∘.⊖ 1 0 ¯1 ⌽¨ ⊂⍵}
|
||||
|
||||
⍝ Compute n-th generation and format it as a
|
||||
⍝ character matrix
|
||||
gen ← {' #'[(life ⍣ ⍵) board]}
|
||||
|
||||
⍝ Show first three generations
|
||||
(gen 1) (gen 2) (gen 3)
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/apl"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Simple mode that tries to handle APL as well as it can.</p>
|
||||
<p>It attempts to label functions/operators based upon
|
||||
monadic/dyadic usage (but this is far from fully fleshed out).
|
||||
This means there are meaningful classnames so hover states can
|
||||
have popups etc.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/apl</code> (APL code)</p>
|
||||
</article>
|
@ -1,198 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: mode/asterisk/asterisk.js
|
||||
*
|
||||
* Description: CodeMirror mode for Asterisk dialplan
|
||||
*
|
||||
* Created: 05/17/2012 09:20:25 PM
|
||||
* Revision: none
|
||||
*
|
||||
* 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 = '';
|
||||
ch = stream.next();
|
||||
// comment
|
||||
if(ch == ";") {
|
||||
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 {
|
||||
extenStart: false,
|
||||
extenSame: false,
|
||||
extenInclude: false,
|
||||
extenExten: false,
|
||||
extenPriority: false,
|
||||
extenApplication: false
|
||||
};
|
||||
},
|
||||
token: function(stream, state) {
|
||||
|
||||
var cur = '';
|
||||
var ch = '';
|
||||
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;
|
||||
ch = 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;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-asterisk", "asterisk");
|
||||
|
||||
});
|
@ -1,154 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Asterisk dialplan mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="asterisk.js"></script>
|
||||
<style>
|
||||
.CodeMirror {border: 1px solid #999;}
|
||||
.cm-s-default span.cm-arrow { color: red; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Asterisk dialplan</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Asterisk dialplan mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
; extensions.conf - the Asterisk dial plan
|
||||
;
|
||||
|
||||
[general]
|
||||
;
|
||||
; If static is set to no, or omitted, then the pbx_config will rewrite
|
||||
; this file when extensions are modified. Remember that all comments
|
||||
; made in the file will be lost when that happens.
|
||||
static=yes
|
||||
|
||||
#include "/etc/asterisk/additional_general.conf
|
||||
|
||||
[iaxprovider]
|
||||
switch => IAX2/user:[key]@myserver/mycontext
|
||||
|
||||
[dynamic]
|
||||
#exec /usr/bin/dynamic-peers.pl
|
||||
|
||||
[trunkint]
|
||||
;
|
||||
; International long distance through trunk
|
||||
;
|
||||
exten => _9011.,1,Macro(dundi-e164,${EXTEN:4})
|
||||
exten => _9011.,n,Dial(${GLOBAL(TRUNK)}/${FILTER(0-9,${EXTEN:${GLOBAL(TRUNKMSD)}})})
|
||||
|
||||
[local]
|
||||
;
|
||||
; Master context for local, toll-free, and iaxtel calls only
|
||||
;
|
||||
ignorepat => 9
|
||||
include => default
|
||||
|
||||
[demo]
|
||||
include => stdexten
|
||||
;
|
||||
; We start with what to do when a call first comes in.
|
||||
;
|
||||
exten => s,1,Wait(1) ; Wait a second, just for fun
|
||||
same => n,Answer ; Answer the line
|
||||
same => n,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
||||
same => n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
same => n(restart),BackGround(demo-congrats) ; Play a congratulatory message
|
||||
same => n(instruct),BackGround(demo-instruct) ; Play some instructions
|
||||
same => n,WaitExten ; Wait for an extension to be dialed.
|
||||
|
||||
exten => 2,1,BackGround(demo-moreinfo) ; Give some more information.
|
||||
exten => 2,n,Goto(s,instruct)
|
||||
|
||||
exten => 3,1,Set(LANGUAGE()=fr) ; Set language to french
|
||||
exten => 3,n,Goto(s,restart) ; Start with the congratulations
|
||||
|
||||
exten => 1000,1,Goto(default,s,1)
|
||||
;
|
||||
; We also create an example user, 1234, who is on the console and has
|
||||
; voicemail, etc.
|
||||
;
|
||||
exten => 1234,1,Playback(transfer,skip) ; "Please hold while..."
|
||||
; (but skip if channel is not up)
|
||||
exten => 1234,n,Gosub(${EXTEN},stdexten(${GLOBAL(CONSOLE)}))
|
||||
exten => 1234,n,Goto(default,s,1) ; exited Voicemail
|
||||
|
||||
exten => 1235,1,Voicemail(1234,u) ; Right to voicemail
|
||||
|
||||
exten => 1236,1,Dial(Console/dsp) ; Ring forever
|
||||
exten => 1236,n,Voicemail(1234,b) ; Unless busy
|
||||
|
||||
;
|
||||
; # for when they're done with the demo
|
||||
;
|
||||
exten => #,1,Playback(demo-thanks) ; "Thanks for trying the demo"
|
||||
exten => #,n,Hangup ; Hang them up.
|
||||
|
||||
;
|
||||
; A timeout and "invalid extension rule"
|
||||
;
|
||||
exten => t,1,Goto(#,1) ; If they take too long, give up
|
||||
exten => i,1,Playback(invalid) ; "That's not valid, try again"
|
||||
|
||||
;
|
||||
; Create an extension, 500, for dialing the
|
||||
; Asterisk demo.
|
||||
;
|
||||
exten => 500,1,Playback(demo-abouttotry); Let them know what's going on
|
||||
exten => 500,n,Dial(IAX2/guest@pbx.digium.com/s@default) ; Call the Asterisk demo
|
||||
exten => 500,n,Playback(demo-nogo) ; Couldn't connect to the demo site
|
||||
exten => 500,n,Goto(s,6) ; Return to the start over message.
|
||||
|
||||
;
|
||||
; Create an extension, 600, for evaluating echo latency.
|
||||
;
|
||||
exten => 600,1,Playback(demo-echotest) ; Let them know what's going on
|
||||
exten => 600,n,Echo ; Do the echo test
|
||||
exten => 600,n,Playback(demo-echodone) ; Let them know it's over
|
||||
exten => 600,n,Goto(s,6) ; Start over
|
||||
|
||||
;
|
||||
; You can use the Macro Page to intercom a individual user
|
||||
exten => 76245,1,Macro(page,SIP/Grandstream1)
|
||||
; or if your peernames are the same as extensions
|
||||
exten => _7XXX,1,Macro(page,SIP/${EXTEN})
|
||||
;
|
||||
;
|
||||
; System Wide Page at extension 7999
|
||||
;
|
||||
exten => 7999,1,Set(TIMEOUT(absolute)=60)
|
||||
exten => 7999,2,Page(Local/Grandstream1@page&Local/Xlite1@page&Local/1234@page/n,d)
|
||||
|
||||
; Give voicemail at extension 8500
|
||||
;
|
||||
exten => 8500,1,VoicemailMain
|
||||
exten => 8500,n,Goto(s,6)
|
||||
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "text/x-asterisk",
|
||||
matchBrackets: true,
|
||||
lineNumber: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-asterisk</code>.</p>
|
||||
|
||||
</article>
|
@ -1,489 +0,0 @@
|
||||
// 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("clike", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit,
|
||||
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
|
||||
dontAlignCalls = parserConfig.dontAlignCalls,
|
||||
keywords = parserConfig.keywords || {},
|
||||
builtin = parserConfig.builtin || {},
|
||||
blockKeywords = parserConfig.blockKeywords || {},
|
||||
atoms = parserConfig.atoms || {},
|
||||
hooks = parserConfig.hooks || {},
|
||||
multiLineStrings = parserConfig.multiLineStrings,
|
||||
indentStatements = parserConfig.indentStatements !== false;
|
||||
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
|
||||
|
||||
var curPunc;
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (hooks[ch]) {
|
||||
var result = hooks[ch](stream, state);
|
||||
if (result !== false) return result;
|
||||
}
|
||||
if (ch == '"' || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
||||
curPunc = ch;
|
||||
return null;
|
||||
}
|
||||
if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
return "number";
|
||||
}
|
||||
if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
state.tokenize = tokenComment;
|
||||
return tokenComment(stream, state);
|
||||
}
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
}
|
||||
if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return "operator";
|
||||
}
|
||||
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
|
||||
var cur = stream.current();
|
||||
if (keywords.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "keyword";
|
||||
}
|
||||
if (builtin.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "builtin";
|
||||
}
|
||||
if (atoms.propertyIsEnumerable(cur)) return "atom";
|
||||
return "variable";
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, next, end = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote && !escaped) {end = true; break;}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
if (end || !(escaped || multiLineStrings))
|
||||
state.tokenize = null;
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function Context(indented, column, type, align, prev) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.align = align;
|
||||
this.prev = prev;
|
||||
}
|
||||
function pushContext(state, col, type) {
|
||||
var indent = state.indented;
|
||||
if (state.context && state.context.type == "statement")
|
||||
indent = state.context.indented;
|
||||
return state.context = new Context(indent, col, type, null, state.context);
|
||||
}
|
||||
function popContext(state) {
|
||||
var t = state.context.type;
|
||||
if (t == ")" || t == "]" || t == "}")
|
||||
state.indented = state.context.indented;
|
||||
return state.context = state.context.prev;
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: null,
|
||||
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
|
||||
indented: 0,
|
||||
startOfLine: true
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var ctx = state.context;
|
||||
if (stream.sol()) {
|
||||
if (ctx.align == null) ctx.align = false;
|
||||
state.indented = stream.indentation();
|
||||
state.startOfLine = true;
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
curPunc = null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style == "comment" || style == "meta") return style;
|
||||
if (ctx.align == null) ctx.align = true;
|
||||
|
||||
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
|
||||
else if (curPunc == "{") pushContext(state, stream.column(), "}");
|
||||
else if (curPunc == "[") pushContext(state, stream.column(), "]");
|
||||
else if (curPunc == "(") pushContext(state, stream.column(), ")");
|
||||
else if (curPunc == "}") {
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
if (ctx.type == "}") ctx = popContext(state);
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
}
|
||||
else if (curPunc == ctx.type) popContext(state);
|
||||
else if (indentStatements &&
|
||||
(((ctx.type == "}" || ctx.type == "top") && curPunc != ';') ||
|
||||
(ctx.type == "statement" && curPunc == "newstatement")))
|
||||
pushContext(state, stream.column(), "statement");
|
||||
state.startOfLine = false;
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
|
||||
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
||||
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
||||
var closing = firstChar == ctx.type;
|
||||
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
|
||||
else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
|
||||
else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
|
||||
else return ctx.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: "{}",
|
||||
blockCommentStart: "/*",
|
||||
blockCommentEnd: "*/",
|
||||
lineComment: "//",
|
||||
fold: "brace"
|
||||
};
|
||||
});
|
||||
|
||||
function words(str) {
|
||||
var obj = {}, words = str.split(" ");
|
||||
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
|
||||
"double static else struct entry switch extern typedef float union for unsigned " +
|
||||
"goto while enum void const signed volatile";
|
||||
|
||||
function cppHook(stream, state) {
|
||||
if (!state.startOfLine) return false;
|
||||
for (;;) {
|
||||
if (stream.skipTo("\\")) {
|
||||
stream.next();
|
||||
if (stream.eol()) {
|
||||
state.tokenize = cppHook;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
stream.skipToEnd();
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "meta";
|
||||
}
|
||||
|
||||
function cpp11StringHook(stream, state) {
|
||||
stream.backUp(1);
|
||||
// Raw strings.
|
||||
if (stream.match(/(R|u8R|uR|UR|LR)/)) {
|
||||
var match = stream.match(/"([^\s\\()]{0,16})\(/);
|
||||
if (!match) {
|
||||
return false;
|
||||
}
|
||||
state.cpp11RawStringDelim = match[1];
|
||||
state.tokenize = tokenRawString;
|
||||
return tokenRawString(stream, state);
|
||||
}
|
||||
// Unicode strings/chars.
|
||||
if (stream.match(/(u8|u|U|L)/)) {
|
||||
if (stream.match(/["']/, /* eat */ false)) {
|
||||
return "string";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Ignore this hook.
|
||||
stream.next();
|
||||
return false;
|
||||
}
|
||||
|
||||
// C#-style strings where "" escapes a quote.
|
||||
function tokenAtString(stream, state) {
|
||||
var next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == '"' && !stream.eat('"')) {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "string";
|
||||
}
|
||||
|
||||
// C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
|
||||
// <delim> can be a string up to 16 characters long.
|
||||
function tokenRawString(stream, state) {
|
||||
// Escape characters that have special regex meanings.
|
||||
var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
|
||||
var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
|
||||
if (match)
|
||||
state.tokenize = null;
|
||||
else
|
||||
stream.skipToEnd();
|
||||
return "string";
|
||||
}
|
||||
|
||||
function def(mimes, mode) {
|
||||
if (typeof mimes == "string") mimes = [mimes];
|
||||
var words = [];
|
||||
function add(obj) {
|
||||
if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
|
||||
words.push(prop);
|
||||
}
|
||||
add(mode.keywords);
|
||||
add(mode.builtin);
|
||||
add(mode.atoms);
|
||||
if (words.length) {
|
||||
mode.helperType = mimes[0];
|
||||
CodeMirror.registerHelper("hintWords", mimes[0], words);
|
||||
}
|
||||
|
||||
for (var i = 0; i < mimes.length; ++i)
|
||||
CodeMirror.defineMIME(mimes[i], mode);
|
||||
}
|
||||
|
||||
def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
|
||||
name: "clike",
|
||||
keywords: words(cKeywords),
|
||||
blockKeywords: words("case do else for if switch while struct"),
|
||||
atoms: words("null"),
|
||||
hooks: {"#": cppHook},
|
||||
modeProps: {fold: ["brace", "include"]}
|
||||
});
|
||||
|
||||
def(["text/x-c++src", "text/x-c++hdr"], {
|
||||
name: "clike",
|
||||
keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
|
||||
"static_cast typeid catch operator template typename class friend private " +
|
||||
"this using const_cast inline public throw virtual delete mutable protected " +
|
||||
"wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final " +
|
||||
"static_assert override"),
|
||||
blockKeywords: words("catch class do else finally for if struct switch try while"),
|
||||
atoms: words("true false null"),
|
||||
hooks: {
|
||||
"#": cppHook,
|
||||
"u": cpp11StringHook,
|
||||
"U": cpp11StringHook,
|
||||
"L": cpp11StringHook,
|
||||
"R": cpp11StringHook
|
||||
},
|
||||
modeProps: {fold: ["brace", "include"]}
|
||||
});
|
||||
|
||||
def("text/x-java", {
|
||||
name: "clike",
|
||||
keywords: words("abstract assert boolean break byte case catch char class const continue default " +
|
||||
"do double else enum extends final finally float for goto if implements import " +
|
||||
"instanceof int interface long native new package private protected public " +
|
||||
"return short static strictfp super switch synchronized this throw throws transient " +
|
||||
"try void volatile while"),
|
||||
blockKeywords: words("catch class do else finally for if switch try while"),
|
||||
atoms: words("true false null"),
|
||||
hooks: {
|
||||
"@": function(stream) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
}
|
||||
},
|
||||
modeProps: {fold: ["brace", "import"]}
|
||||
});
|
||||
|
||||
def("text/x-csharp", {
|
||||
name: "clike",
|
||||
keywords: words("abstract as base break case catch checked class const continue" +
|
||||
" default delegate do else enum event explicit extern finally fixed for" +
|
||||
" foreach goto if implicit in interface internal is lock namespace new" +
|
||||
" operator out override params private protected public readonly ref return sealed" +
|
||||
" sizeof stackalloc static struct switch this throw try typeof unchecked" +
|
||||
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
|
||||
" global group into join let orderby partial remove select set value var yield"),
|
||||
blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
|
||||
builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
|
||||
" Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
|
||||
" UInt64 bool byte char decimal double short int long object" +
|
||||
" sbyte float string ushort uint ulong"),
|
||||
atoms: words("true false null"),
|
||||
hooks: {
|
||||
"@": function(stream, state) {
|
||||
if (stream.eat('"')) {
|
||||
state.tokenize = tokenAtString;
|
||||
return tokenAtString(stream, state);
|
||||
}
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function tokenTripleString(stream, state) {
|
||||
var escaped = false;
|
||||
while (!stream.eol()) {
|
||||
if (!escaped && stream.match('"""')) {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
escaped = stream.next() != "\\" && !escaped;
|
||||
}
|
||||
return "string";
|
||||
}
|
||||
|
||||
def("text/x-scala", {
|
||||
name: "clike",
|
||||
keywords: words(
|
||||
|
||||
/* scala */
|
||||
"abstract case catch class def do else extends false final finally for forSome if " +
|
||||
"implicit import lazy match new null object override package private protected return " +
|
||||
"sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
|
||||
"<% >: # @ " +
|
||||
|
||||
/* package scala */
|
||||
"assert assume require print println printf readLine readBoolean readByte readShort " +
|
||||
"readChar readInt readLong readFloat readDouble " +
|
||||
|
||||
"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
|
||||
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
|
||||
"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
|
||||
"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
|
||||
"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
|
||||
|
||||
/* package java.lang */
|
||||
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
|
||||
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
|
||||
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
|
||||
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
|
||||
),
|
||||
multiLineStrings: true,
|
||||
blockKeywords: words("catch class do else finally for forSome if match switch try while"),
|
||||
atoms: words("true false null"),
|
||||
indentStatements: false,
|
||||
hooks: {
|
||||
"@": function(stream) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
},
|
||||
'"': function(stream, state) {
|
||||
if (!stream.match('""')) return false;
|
||||
state.tokenize = tokenTripleString;
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
|
||||
name: "clike",
|
||||
keywords: words("float int bool void " +
|
||||
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
|
||||
"mat2 mat3 mat4 " +
|
||||
"sampler1D sampler2D sampler3D samplerCube " +
|
||||
"sampler1DShadow sampler2DShadow" +
|
||||
"const attribute uniform varying " +
|
||||
"break continue discard return " +
|
||||
"for while do if else struct " +
|
||||
"in out inout"),
|
||||
blockKeywords: words("for while do if else struct"),
|
||||
builtin: words("radians degrees sin cos tan asin acos atan " +
|
||||
"pow exp log exp2 sqrt inversesqrt " +
|
||||
"abs sign floor ceil fract mod min max clamp mix step smootstep " +
|
||||
"length distance dot cross normalize ftransform faceforward " +
|
||||
"reflect refract matrixCompMult " +
|
||||
"lessThan lessThanEqual greaterThan greaterThanEqual " +
|
||||
"equal notEqual any all not " +
|
||||
"texture1D texture1DProj texture1DLod texture1DProjLod " +
|
||||
"texture2D texture2DProj texture2DLod texture2DProjLod " +
|
||||
"texture3D texture3DProj texture3DLod texture3DProjLod " +
|
||||
"textureCube textureCubeLod " +
|
||||
"shadow1D shadow2D shadow1DProj shadow2DProj " +
|
||||
"shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
|
||||
"dFdx dFdy fwidth " +
|
||||
"noise1 noise2 noise3 noise4"),
|
||||
atoms: words("true false " +
|
||||
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
|
||||
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
|
||||
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
|
||||
"gl_FogCoord " +
|
||||
"gl_Position gl_PointSize gl_ClipVertex " +
|
||||
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
|
||||
"gl_TexCoord gl_FogFragCoord " +
|
||||
"gl_FragCoord gl_FrontFacing " +
|
||||
"gl_FragColor gl_FragData gl_FragDepth " +
|
||||
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
|
||||
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
|
||||
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
|
||||
"gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
|
||||
"gl_ProjectionMatrixInverseTranspose " +
|
||||
"gl_ModelViewProjectionMatrixInverseTranspose " +
|
||||
"gl_TextureMatrixInverseTranspose " +
|
||||
"gl_NormalScale gl_DepthRange gl_ClipPlane " +
|
||||
"gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
|
||||
"gl_FrontLightModelProduct gl_BackLightModelProduct " +
|
||||
"gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
|
||||
"gl_FogParameters " +
|
||||
"gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
|
||||
"gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
|
||||
"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
|
||||
"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
|
||||
"gl_MaxDrawBuffers"),
|
||||
hooks: {"#": cppHook},
|
||||
modeProps: {fold: ["brace", "include"]}
|
||||
});
|
||||
|
||||
def("text/x-nesc", {
|
||||
name: "clike",
|
||||
keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
|
||||
"implementation includes interface module new norace nx_struct nx_union post provides " +
|
||||
"signal task uses abstract extends"),
|
||||
blockKeywords: words("case do else for if switch while struct"),
|
||||
atoms: words("null"),
|
||||
hooks: {"#": cppHook},
|
||||
modeProps: {fold: ["brace", "include"]}
|
||||
});
|
||||
|
||||
def("text/x-objectivec", {
|
||||
name: "clike",
|
||||
keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
|
||||
"inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
|
||||
atoms: words("YES NO NULL NILL ON OFF"),
|
||||
hooks: {
|
||||
"@": function(stream) {
|
||||
stream.eatWhile(/[\w\$]/);
|
||||
return "keyword";
|
||||
},
|
||||
"#": cppHook
|
||||
},
|
||||
modeProps: {fold: "brace"}
|
||||
});
|
||||
|
||||
});
|
@ -1,251 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: C-like mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
|
||||
<script src="../../addon/hint/show-hint.js"></script>
|
||||
<script src="clike.js"></script>
|
||||
<style>.CodeMirror {border: 2px inset #dee;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">C-like</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>C-like mode</h2>
|
||||
|
||||
<div><textarea id="c-code">
|
||||
/* C demo code */
|
||||
|
||||
#include <zmq.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <malloc.h>
|
||||
|
||||
typedef struct {
|
||||
void* arg_socket;
|
||||
zmq_msg_t* arg_msg;
|
||||
char* arg_string;
|
||||
unsigned long arg_len;
|
||||
int arg_int, arg_command;
|
||||
|
||||
int signal_fd;
|
||||
int pad;
|
||||
void* context;
|
||||
sem_t sem;
|
||||
} acl_zmq_context;
|
||||
|
||||
#define p(X) (context->arg_##X)
|
||||
|
||||
void* zmq_thread(void* context_pointer) {
|
||||
acl_zmq_context* context = (acl_zmq_context*)context_pointer;
|
||||
char ok = 'K', err = 'X';
|
||||
int res;
|
||||
|
||||
while (1) {
|
||||
while ((res = sem_wait(&context->sem)) == EINTR);
|
||||
if (res) {write(context->signal_fd, &err, 1); goto cleanup;}
|
||||
switch(p(command)) {
|
||||
case 0: goto cleanup;
|
||||
case 1: p(socket) = zmq_socket(context->context, p(int)); break;
|
||||
case 2: p(int) = zmq_close(p(socket)); break;
|
||||
case 3: p(int) = zmq_bind(p(socket), p(string)); break;
|
||||
case 4: p(int) = zmq_connect(p(socket), p(string)); break;
|
||||
case 5: p(int) = zmq_getsockopt(p(socket), p(int), (void*)p(string), &p(len)); break;
|
||||
case 6: p(int) = zmq_setsockopt(p(socket), p(int), (void*)p(string), p(len)); break;
|
||||
case 7: p(int) = zmq_send(p(socket), p(msg), p(int)); break;
|
||||
case 8: p(int) = zmq_recv(p(socket), p(msg), p(int)); break;
|
||||
case 9: p(int) = zmq_poll(p(socket), p(int), p(len)); break;
|
||||
}
|
||||
p(command) = errno;
|
||||
write(context->signal_fd, &ok, 1);
|
||||
}
|
||||
cleanup:
|
||||
close(context->signal_fd);
|
||||
free(context_pointer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* zmq_thread_init(void* zmq_context, int signal_fd) {
|
||||
acl_zmq_context* context = malloc(sizeof(acl_zmq_context));
|
||||
pthread_t thread;
|
||||
|
||||
context->context = zmq_context;
|
||||
context->signal_fd = signal_fd;
|
||||
sem_init(&context->sem, 1, 0);
|
||||
pthread_create(&thread, 0, &zmq_thread, context);
|
||||
pthread_detach(thread);
|
||||
return context;
|
||||
}
|
||||
</textarea></div>
|
||||
|
||||
<h2>C++ example</h2>
|
||||
|
||||
<div><textarea id="cpp-code">
|
||||
#include <iostream>
|
||||
#include "mystuff/util.h"
|
||||
|
||||
namespace {
|
||||
enum Enum {
|
||||
VAL1, VAL2, VAL3
|
||||
};
|
||||
|
||||
char32_t unicode_string = U"\U0010FFFF";
|
||||
string raw_string = R"delim(anything
|
||||
you
|
||||
want)delim";
|
||||
|
||||
int Helper(const MyType& param) {
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class ForwardDec;
|
||||
|
||||
template <class T, class V>
|
||||
class Class : public BaseClass {
|
||||
const MyType<T, V> member_;
|
||||
|
||||
public:
|
||||
const MyType<T, V>& Method() const {
|
||||
return member_;
|
||||
}
|
||||
|
||||
void Method2(MyType<T, V>* value);
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
void Class::Method2(MyType<T, V>* value) {
|
||||
std::out << 1 >> method();
|
||||
value->Method3(member_);
|
||||
member_ = value;
|
||||
}
|
||||
</textarea></div>
|
||||
|
||||
<h2>Objective-C example</h2>
|
||||
|
||||
<div><textarea id="objectivec-code">
|
||||
/*
|
||||
This is a longer comment
|
||||
That spans two lines
|
||||
*/
|
||||
|
||||
#import <Test/Test.h>
|
||||
@implementation YourAppDelegate
|
||||
|
||||
// This is a one-line comment
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
|
||||
char myString[] = "This is a C character array";
|
||||
int test = 5;
|
||||
return YES;
|
||||
}
|
||||
</textarea></div>
|
||||
|
||||
<h2>Java example</h2>
|
||||
|
||||
<div><textarea id="java-code">
|
||||
import com.demo.util.MyType;
|
||||
import com.demo.util.MyInterface;
|
||||
|
||||
public enum Enum {
|
||||
VAL1, VAL2, VAL3
|
||||
}
|
||||
|
||||
public class Class<T, V> implements MyInterface {
|
||||
public static final MyType<T, V> member;
|
||||
|
||||
private class InnerClass {
|
||||
public int zero() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyType method() {
|
||||
return member;
|
||||
}
|
||||
|
||||
public void method2(MyType<T, V> value) {
|
||||
method();
|
||||
value.method3();
|
||||
member = value;
|
||||
}
|
||||
}
|
||||
</textarea></div>
|
||||
|
||||
<h2>Scala example</h2>
|
||||
|
||||
<div><textarea id="scala-code">
|
||||
object FilterTest extends App {
|
||||
def filter(xs: List[Int], threshold: Int) = {
|
||||
def process(ys: List[Int]): List[Int] =
|
||||
if (ys.isEmpty) ys
|
||||
else if (ys.head < threshold) ys.head :: process(ys.tail)
|
||||
else process(ys.tail)
|
||||
process(xs)
|
||||
}
|
||||
println(filter(List(1, 9, 2, 8, 3, 7, 4), 5))
|
||||
}
|
||||
</textarea></div>
|
||||
|
||||
<script>
|
||||
var cEditor = CodeMirror.fromTextArea(document.getElementById("c-code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-csrc"
|
||||
});
|
||||
var cppEditor = CodeMirror.fromTextArea(document.getElementById("cpp-code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-c++src"
|
||||
});
|
||||
var javaEditor = CodeMirror.fromTextArea(document.getElementById("java-code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-java"
|
||||
});
|
||||
var objectivecEditor = CodeMirror.fromTextArea(document.getElementById("objectivec-code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-objectivec"
|
||||
});
|
||||
var scalaEditor = CodeMirror.fromTextArea(document.getElementById("scala-code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-scala"
|
||||
});
|
||||
var mac = CodeMirror.keyMap.default == CodeMirror.keyMap.macDefault;
|
||||
CodeMirror.keyMap.default[(mac ? "Cmd" : "Ctrl") + "-Space"] = "autocomplete";
|
||||
</script>
|
||||
|
||||
<p>Simple mode that tries to handle C-like languages as well as it
|
||||
can. Takes two configuration parameters: <code>keywords</code>, an
|
||||
object whose property names are the keywords in the language,
|
||||
and <code>useCPP</code>, which determines whether C preprocessor
|
||||
directives are recognized.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-csrc</code>
|
||||
(C), <code>text/x-c++src</code> (C++), <code>text/x-java</code>
|
||||
(Java), <code>text/x-csharp</code> (C#),
|
||||
<code>text/x-objectivec</code> (Objective-C),
|
||||
<code>text/x-scala</code> (Scala), <code>text/x-vertex</code>
|
||||
and <code>x-shader/x-fragment</code> (shader programs).</p>
|
||||
</article>
|
@ -1,767 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Scala mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../../theme/ambiance.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="clike.js"></script>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Scala</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Scala mode</h2>
|
||||
<form>
|
||||
<textarea id="code" name="code">
|
||||
|
||||
/* __ *\
|
||||
** ________ ___ / / ___ Scala API **
|
||||
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
|
||||
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
|
||||
** /____/\___/_/ |_/____/_/ | | **
|
||||
** |/ **
|
||||
\* */
|
||||
|
||||
package scala.collection
|
||||
|
||||
import generic._
|
||||
import mutable.{ Builder, ListBuffer }
|
||||
import annotation.{tailrec, migration, bridge}
|
||||
import annotation.unchecked.{ uncheckedVariance => uV }
|
||||
import parallel.ParIterable
|
||||
|
||||
/** A template trait for traversable collections of type `Traversable[A]`.
|
||||
*
|
||||
* $traversableInfo
|
||||
* @define mutability
|
||||
* @define traversableInfo
|
||||
* This is a base trait of all kinds of $mutability Scala collections. It
|
||||
* implements the behavior common to all collections, in terms of a method
|
||||
* `foreach` with signature:
|
||||
* {{{
|
||||
* def foreach[U](f: Elem => U): Unit
|
||||
* }}}
|
||||
* Collection classes mixing in this trait provide a concrete
|
||||
* `foreach` method which traverses all the
|
||||
* elements contained in the collection, applying a given function to each.
|
||||
* They also need to provide a method `newBuilder`
|
||||
* which creates a builder for collections of the same kind.
|
||||
*
|
||||
* A traversable class might or might not have two properties: strictness
|
||||
* and orderedness. Neither is represented as a type.
|
||||
*
|
||||
* The instances of a strict collection class have all their elements
|
||||
* computed before they can be used as values. By contrast, instances of
|
||||
* a non-strict collection class may defer computation of some of their
|
||||
* elements until after the instance is available as a value.
|
||||
* A typical example of a non-strict collection class is a
|
||||
* <a href="../immutable/Stream.html" target="ContentFrame">
|
||||
* `scala.collection.immutable.Stream`</a>.
|
||||
* A more general class of examples are `TraversableViews`.
|
||||
*
|
||||
* If a collection is an instance of an ordered collection class, traversing
|
||||
* its elements with `foreach` will always visit elements in the
|
||||
* same order, even for different runs of the program. If the class is not
|
||||
* ordered, `foreach` can visit elements in different orders for
|
||||
* different runs (but it will keep the same order in the same run).'
|
||||
*
|
||||
* A typical example of a collection class which is not ordered is a
|
||||
* `HashMap` of objects. The traversal order for hash maps will
|
||||
* depend on the hash codes of its elements, and these hash codes might
|
||||
* differ from one run to the next. By contrast, a `LinkedHashMap`
|
||||
* is ordered because it's `foreach` method visits elements in the
|
||||
* order they were inserted into the `HashMap`.
|
||||
*
|
||||
* @author Martin Odersky
|
||||
* @version 2.8
|
||||
* @since 2.8
|
||||
* @tparam A the element type of the collection
|
||||
* @tparam Repr the type of the actual collection containing the elements.
|
||||
*
|
||||
* @define Coll Traversable
|
||||
* @define coll traversable collection
|
||||
*/
|
||||
trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
|
||||
with FilterMonadic[A, Repr]
|
||||
with TraversableOnce[A]
|
||||
with GenTraversableLike[A, Repr]
|
||||
with Parallelizable[A, ParIterable[A]]
|
||||
{
|
||||
self =>
|
||||
|
||||
import Traversable.breaks._
|
||||
|
||||
/** The type implementing this traversable */
|
||||
protected type Self = Repr
|
||||
|
||||
/** The collection of type $coll underlying this `TraversableLike` object.
|
||||
* By default this is implemented as the `TraversableLike` object itself,
|
||||
* but this can be overridden.
|
||||
*/
|
||||
def repr: Repr = this.asInstanceOf[Repr]
|
||||
|
||||
/** The underlying collection seen as an instance of `$Coll`.
|
||||
* By default this is implemented as the current collection object itself,
|
||||
* but this can be overridden.
|
||||
*/
|
||||
protected[this] def thisCollection: Traversable[A] = this.asInstanceOf[Traversable[A]]
|
||||
|
||||
/** A conversion from collections of type `Repr` to `$Coll` objects.
|
||||
* By default this is implemented as just a cast, but this can be overridden.
|
||||
*/
|
||||
protected[this] def toCollection(repr: Repr): Traversable[A] = repr.asInstanceOf[Traversable[A]]
|
||||
|
||||
/** Creates a new builder for this collection type.
|
||||
*/
|
||||
protected[this] def newBuilder: Builder[A, Repr]
|
||||
|
||||
protected[this] def parCombiner = ParIterable.newCombiner[A]
|
||||
|
||||
/** Applies a function `f` to all elements of this $coll.
|
||||
*
|
||||
* Note: this method underlies the implementation of most other bulk operations.
|
||||
* It's important to implement this method in an efficient way.
|
||||
*
|
||||
*
|
||||
* @param f the function that is applied for its side-effect to every element.
|
||||
* The result of function `f` is discarded.
|
||||
*
|
||||
* @tparam U the type parameter describing the result of function `f`.
|
||||
* This result will always be ignored. Typically `U` is `Unit`,
|
||||
* but this is not necessary.
|
||||
*
|
||||
* @usecase def foreach(f: A => Unit): Unit
|
||||
*/
|
||||
def foreach[U](f: A => U): Unit
|
||||
|
||||
/** Tests whether this $coll is empty.
|
||||
*
|
||||
* @return `true` if the $coll contain no elements, `false` otherwise.
|
||||
*/
|
||||
def isEmpty: Boolean = {
|
||||
var result = true
|
||||
breakable {
|
||||
for (x <- this) {
|
||||
result = false
|
||||
break
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/** Tests whether this $coll is known to have a finite size.
|
||||
* All strict collections are known to have finite size. For a non-strict collection
|
||||
* such as `Stream`, the predicate returns `true` if all elements have been computed.
|
||||
* It returns `false` if the stream is not yet evaluated to the end.
|
||||
*
|
||||
* Note: many collection methods will not work on collections of infinite sizes.
|
||||
*
|
||||
* @return `true` if this collection is known to have finite size, `false` otherwise.
|
||||
*/
|
||||
def hasDefiniteSize = true
|
||||
|
||||
def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.seq.size)
|
||||
b ++= thisCollection
|
||||
b ++= that.seq
|
||||
b.result
|
||||
}
|
||||
|
||||
@bridge
|
||||
def ++[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
|
||||
++(that: GenTraversableOnce[B])(bf)
|
||||
|
||||
/** Concatenates this $coll with the elements of a traversable collection.
|
||||
* It differs from ++ in that the right operand determines the type of the
|
||||
* resulting collection rather than the left one.
|
||||
*
|
||||
* @param that the traversable to append.
|
||||
* @tparam B the element type of the returned collection.
|
||||
* @tparam That $thatinfo
|
||||
* @param bf $bfinfo
|
||||
* @return a new collection of type `That` which contains all elements
|
||||
* of this $coll followed by all elements of `that`.
|
||||
*
|
||||
* @usecase def ++:[B](that: TraversableOnce[B]): $Coll[B]
|
||||
*
|
||||
* @return a new $coll which contains all elements of this $coll
|
||||
* followed by all elements of `that`.
|
||||
*/
|
||||
def ++:[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.size)
|
||||
b ++= that
|
||||
b ++= thisCollection
|
||||
b.result
|
||||
}
|
||||
|
||||
/** This overload exists because: for the implementation of ++: we should reuse
|
||||
* that of ++ because many collections override it with more efficient versions.
|
||||
* Since TraversableOnce has no '++' method, we have to implement that directly,
|
||||
* but Traversable and down can use the overload.
|
||||
*/
|
||||
def ++:[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
|
||||
(that ++ seq)(breakOut)
|
||||
|
||||
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
b.sizeHint(this)
|
||||
for (x <- this) b += f(x)
|
||||
b.result
|
||||
}
|
||||
|
||||
def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
for (x <- this) b ++= f(x).seq
|
||||
b.result
|
||||
}
|
||||
|
||||
/** Selects all elements of this $coll which satisfy a predicate.
|
||||
*
|
||||
* @param p the predicate used to test elements.
|
||||
* @return a new $coll consisting of all elements of this $coll that satisfy the given
|
||||
* predicate `p`. The order of the elements is preserved.
|
||||
*/
|
||||
def filter(p: A => Boolean): Repr = {
|
||||
val b = newBuilder
|
||||
for (x <- this)
|
||||
if (p(x)) b += x
|
||||
b.result
|
||||
}
|
||||
|
||||
/** Selects all elements of this $coll which do not satisfy a predicate.
|
||||
*
|
||||
* @param p the predicate used to test elements.
|
||||
* @return a new $coll consisting of all elements of this $coll that do not satisfy the given
|
||||
* predicate `p`. The order of the elements is preserved.
|
||||
*/
|
||||
def filterNot(p: A => Boolean): Repr = filter(!p(_))
|
||||
|
||||
def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
for (x <- this) if (pf.isDefinedAt(x)) b += pf(x)
|
||||
b.result
|
||||
}
|
||||
|
||||
/** Builds a new collection by applying an option-valued function to all
|
||||
* elements of this $coll on which the function is defined.
|
||||
*
|
||||
* @param f the option-valued function which filters and maps the $coll.
|
||||
* @tparam B the element type of the returned collection.
|
||||
* @tparam That $thatinfo
|
||||
* @param bf $bfinfo
|
||||
* @return a new collection of type `That` resulting from applying the option-valued function
|
||||
* `f` to each element and collecting all defined results.
|
||||
* The order of the elements is preserved.
|
||||
*
|
||||
* @usecase def filterMap[B](f: A => Option[B]): $Coll[B]
|
||||
*
|
||||
* @param pf the partial function which filters and maps the $coll.
|
||||
* @return a new $coll resulting from applying the given option-valued function
|
||||
* `f` to each element and collecting all defined results.
|
||||
* The order of the elements is preserved.
|
||||
def filterMap[B, That](f: A => Option[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
for (x <- this)
|
||||
f(x) match {
|
||||
case Some(y) => b += y
|
||||
case _ =>
|
||||
}
|
||||
b.result
|
||||
}
|
||||
*/
|
||||
|
||||
/** Partitions this $coll in two ${coll}s according to a predicate.
|
||||
*
|
||||
* @param p the predicate on which to partition.
|
||||
* @return a pair of ${coll}s: the first $coll consists of all elements that
|
||||
* satisfy the predicate `p` and the second $coll consists of all elements
|
||||
* that don't. The relative order of the elements in the resulting ${coll}s
|
||||
* is the same as in the original $coll.
|
||||
*/
|
||||
def partition(p: A => Boolean): (Repr, Repr) = {
|
||||
val l, r = newBuilder
|
||||
for (x <- this) (if (p(x)) l else r) += x
|
||||
(l.result, r.result)
|
||||
}
|
||||
|
||||
def groupBy[K](f: A => K): immutable.Map[K, Repr] = {
|
||||
val m = mutable.Map.empty[K, Builder[A, Repr]]
|
||||
for (elem <- this) {
|
||||
val key = f(elem)
|
||||
val bldr = m.getOrElseUpdate(key, newBuilder)
|
||||
bldr += elem
|
||||
}
|
||||
val b = immutable.Map.newBuilder[K, Repr]
|
||||
for ((k, v) <- m)
|
||||
b += ((k, v.result))
|
||||
|
||||
b.result
|
||||
}
|
||||
|
||||
/** Tests whether a predicate holds for all elements of this $coll.
|
||||
*
|
||||
* $mayNotTerminateInf
|
||||
*
|
||||
* @param p the predicate used to test elements.
|
||||
* @return `true` if the given predicate `p` holds for all elements
|
||||
* of this $coll, otherwise `false`.
|
||||
*/
|
||||
def forall(p: A => Boolean): Boolean = {
|
||||
var result = true
|
||||
breakable {
|
||||
for (x <- this)
|
||||
if (!p(x)) { result = false; break }
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/** Tests whether a predicate holds for some of the elements of this $coll.
|
||||
*
|
||||
* $mayNotTerminateInf
|
||||
*
|
||||
* @param p the predicate used to test elements.
|
||||
* @return `true` if the given predicate `p` holds for some of the
|
||||
* elements of this $coll, otherwise `false`.
|
||||
*/
|
||||
def exists(p: A => Boolean): Boolean = {
|
||||
var result = false
|
||||
breakable {
|
||||
for (x <- this)
|
||||
if (p(x)) { result = true; break }
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/** Finds the first element of the $coll satisfying a predicate, if any.
|
||||
*
|
||||
* $mayNotTerminateInf
|
||||
* $orderDependent
|
||||
*
|
||||
* @param p the predicate used to test elements.
|
||||
* @return an option value containing the first element in the $coll
|
||||
* that satisfies `p`, or `None` if none exists.
|
||||
*/
|
||||
def find(p: A => Boolean): Option[A] = {
|
||||
var result: Option[A] = None
|
||||
breakable {
|
||||
for (x <- this)
|
||||
if (p(x)) { result = Some(x); break }
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
def scan[B >: A, That](z: B)(op: (B, B) => B)(implicit cbf: CanBuildFrom[Repr, B, That]): That = scanLeft(z)(op)
|
||||
|
||||
def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
b.sizeHint(this, 1)
|
||||
var acc = z
|
||||
b += acc
|
||||
for (x <- this) { acc = op(acc, x); b += acc }
|
||||
b.result
|
||||
}
|
||||
|
||||
@migration(2, 9,
|
||||
"This scanRight definition has changed in 2.9.\n" +
|
||||
"The previous behavior can be reproduced with scanRight.reverse."
|
||||
)
|
||||
def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
var scanned = List(z)
|
||||
var acc = z
|
||||
for (x <- reversed) {
|
||||
acc = op(x, acc)
|
||||
scanned ::= acc
|
||||
}
|
||||
val b = bf(repr)
|
||||
for (elem <- scanned) b += elem
|
||||
b.result
|
||||
}
|
||||
|
||||
/** Selects the first element of this $coll.
|
||||
* $orderDependent
|
||||
* @return the first element of this $coll.
|
||||
* @throws `NoSuchElementException` if the $coll is empty.
|
||||
*/
|
||||
def head: A = {
|
||||
var result: () => A = () => throw new NoSuchElementException
|
||||
breakable {
|
||||
for (x <- this) {
|
||||
result = () => x
|
||||
break
|
||||
}
|
||||
}
|
||||
result()
|
||||
}
|
||||
|
||||
/** Optionally selects the first element.
|
||||
* $orderDependent
|
||||
* @return the first element of this $coll if it is nonempty, `None` if it is empty.
|
||||
*/
|
||||
def headOption: Option[A] = if (isEmpty) None else Some(head)
|
||||
|
||||
/** Selects all elements except the first.
|
||||
* $orderDependent
|
||||
* @return a $coll consisting of all elements of this $coll
|
||||
* except the first one.
|
||||
* @throws `UnsupportedOperationException` if the $coll is empty.
|
||||
*/
|
||||
override def tail: Repr = {
|
||||
if (isEmpty) throw new UnsupportedOperationException("empty.tail")
|
||||
drop(1)
|
||||
}
|
||||
|
||||
/** Selects the last element.
|
||||
* $orderDependent
|
||||
* @return The last element of this $coll.
|
||||
* @throws NoSuchElementException If the $coll is empty.
|
||||
*/
|
||||
def last: A = {
|
||||
var lst = head
|
||||
for (x <- this)
|
||||
lst = x
|
||||
lst
|
||||
}
|
||||
|
||||
/** Optionally selects the last element.
|
||||
* $orderDependent
|
||||
* @return the last element of this $coll$ if it is nonempty, `None` if it is empty.
|
||||
*/
|
||||
def lastOption: Option[A] = if (isEmpty) None else Some(last)
|
||||
|
||||
/** Selects all elements except the last.
|
||||
* $orderDependent
|
||||
* @return a $coll consisting of all elements of this $coll
|
||||
* except the last one.
|
||||
* @throws `UnsupportedOperationException` if the $coll is empty.
|
||||
*/
|
||||
def init: Repr = {
|
||||
if (isEmpty) throw new UnsupportedOperationException("empty.init")
|
||||
var lst = head
|
||||
var follow = false
|
||||
val b = newBuilder
|
||||
b.sizeHint(this, -1)
|
||||
for (x <- this.seq) {
|
||||
if (follow) b += lst
|
||||
else follow = true
|
||||
lst = x
|
||||
}
|
||||
b.result
|
||||
}
|
||||
|
||||
def take(n: Int): Repr = slice(0, n)
|
||||
|
||||
def drop(n: Int): Repr =
|
||||
if (n <= 0) {
|
||||
val b = newBuilder
|
||||
b.sizeHint(this)
|
||||
b ++= thisCollection result
|
||||
}
|
||||
else sliceWithKnownDelta(n, Int.MaxValue, -n)
|
||||
|
||||
def slice(from: Int, until: Int): Repr = sliceWithKnownBound(math.max(from, 0), until)
|
||||
|
||||
// Precondition: from >= 0, until > 0, builder already configured for building.
|
||||
private[this] def sliceInternal(from: Int, until: Int, b: Builder[A, Repr]): Repr = {
|
||||
var i = 0
|
||||
breakable {
|
||||
for (x <- this.seq) {
|
||||
if (i >= from) b += x
|
||||
i += 1
|
||||
if (i >= until) break
|
||||
}
|
||||
}
|
||||
b.result
|
||||
}
|
||||
// Precondition: from >= 0
|
||||
private[scala] def sliceWithKnownDelta(from: Int, until: Int, delta: Int): Repr = {
|
||||
val b = newBuilder
|
||||
if (until <= from) b.result
|
||||
else {
|
||||
b.sizeHint(this, delta)
|
||||
sliceInternal(from, until, b)
|
||||
}
|
||||
}
|
||||
// Precondition: from >= 0
|
||||
private[scala] def sliceWithKnownBound(from: Int, until: Int): Repr = {
|
||||
val b = newBuilder
|
||||
if (until <= from) b.result
|
||||
else {
|
||||
b.sizeHintBounded(until - from, this)
|
||||
sliceInternal(from, until, b)
|
||||
}
|
||||
}
|
||||
|
||||
def takeWhile(p: A => Boolean): Repr = {
|
||||
val b = newBuilder
|
||||
breakable {
|
||||
for (x <- this) {
|
||||
if (!p(x)) break
|
||||
b += x
|
||||
}
|
||||
}
|
||||
b.result
|
||||
}
|
||||
|
||||
def dropWhile(p: A => Boolean): Repr = {
|
||||
val b = newBuilder
|
||||
var go = false
|
||||
for (x <- this) {
|
||||
if (!p(x)) go = true
|
||||
if (go) b += x
|
||||
}
|
||||
b.result
|
||||
}
|
||||
|
||||
def span(p: A => Boolean): (Repr, Repr) = {
|
||||
val l, r = newBuilder
|
||||
var toLeft = true
|
||||
for (x <- this) {
|
||||
toLeft = toLeft && p(x)
|
||||
(if (toLeft) l else r) += x
|
||||
}
|
||||
(l.result, r.result)
|
||||
}
|
||||
|
||||
def splitAt(n: Int): (Repr, Repr) = {
|
||||
val l, r = newBuilder
|
||||
l.sizeHintBounded(n, this)
|
||||
if (n >= 0) r.sizeHint(this, -n)
|
||||
var i = 0
|
||||
for (x <- this) {
|
||||
(if (i < n) l else r) += x
|
||||
i += 1
|
||||
}
|
||||
(l.result, r.result)
|
||||
}
|
||||
|
||||
/** Iterates over the tails of this $coll. The first value will be this
|
||||
* $coll and the final one will be an empty $coll, with the intervening
|
||||
* values the results of successive applications of `tail`.
|
||||
*
|
||||
* @return an iterator over all the tails of this $coll
|
||||
* @example `List(1,2,3).tails = Iterator(List(1,2,3), List(2,3), List(3), Nil)`
|
||||
*/
|
||||
def tails: Iterator[Repr] = iterateUntilEmpty(_.tail)
|
||||
|
||||
/** Iterates over the inits of this $coll. The first value will be this
|
||||
* $coll and the final one will be an empty $coll, with the intervening
|
||||
* values the results of successive applications of `init`.
|
||||
*
|
||||
* @return an iterator over all the inits of this $coll
|
||||
* @example `List(1,2,3).inits = Iterator(List(1,2,3), List(1,2), List(1), Nil)`
|
||||
*/
|
||||
def inits: Iterator[Repr] = iterateUntilEmpty(_.init)
|
||||
|
||||
/** Copies elements of this $coll to an array.
|
||||
* Fills the given array `xs` with at most `len` elements of
|
||||
* this $coll, starting at position `start`.
|
||||
* Copying will stop once either the end of the current $coll is reached,
|
||||
* or the end of the array is reached, or `len` elements have been copied.
|
||||
*
|
||||
* $willNotTerminateInf
|
||||
*
|
||||
* @param xs the array to fill.
|
||||
* @param start the starting index.
|
||||
* @param len the maximal number of elements to copy.
|
||||
* @tparam B the type of the elements of the array.
|
||||
*
|
||||
*
|
||||
* @usecase def copyToArray(xs: Array[A], start: Int, len: Int): Unit
|
||||
*/
|
||||
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
|
||||
var i = start
|
||||
val end = (start + len) min xs.length
|
||||
breakable {
|
||||
for (x <- this) {
|
||||
if (i >= end) break
|
||||
xs(i) = x
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def toTraversable: Traversable[A] = thisCollection
|
||||
def toIterator: Iterator[A] = toStream.iterator
|
||||
def toStream: Stream[A] = toBuffer.toStream
|
||||
|
||||
/** Converts this $coll to a string.
|
||||
*
|
||||
* @return a string representation of this collection. By default this
|
||||
* string consists of the `stringPrefix` of this $coll,
|
||||
* followed by all elements separated by commas and enclosed in parentheses.
|
||||
*/
|
||||
override def toString = mkString(stringPrefix + "(", ", ", ")")
|
||||
|
||||
/** Defines the prefix of this object's `toString` representation.
|
||||
*
|
||||
* @return a string representation which starts the result of `toString`
|
||||
* applied to this $coll. By default the string prefix is the
|
||||
* simple name of the collection class $coll.
|
||||
*/
|
||||
def stringPrefix : String = {
|
||||
var string = repr.asInstanceOf[AnyRef].getClass.getName
|
||||
val idx1 = string.lastIndexOf('.' : Int)
|
||||
if (idx1 != -1) string = string.substring(idx1 + 1)
|
||||
val idx2 = string.indexOf('$')
|
||||
if (idx2 != -1) string = string.substring(0, idx2)
|
||||
string
|
||||
}
|
||||
|
||||
/** Creates a non-strict view of this $coll.
|
||||
*
|
||||
* @return a non-strict view of this $coll.
|
||||
*/
|
||||
def view = new TraversableView[A, Repr] {
|
||||
protected lazy val underlying = self.repr
|
||||
override def foreach[U](f: A => U) = self foreach f
|
||||
}
|
||||
|
||||
/** Creates a non-strict view of a slice of this $coll.
|
||||
*
|
||||
* Note: the difference between `view` and `slice` is that `view` produces
|
||||
* a view of the current $coll, whereas `slice` produces a new $coll.
|
||||
*
|
||||
* Note: `view(from, to)` is equivalent to `view.slice(from, to)`
|
||||
* $orderDependent
|
||||
*
|
||||
* @param from the index of the first element of the view
|
||||
* @param until the index of the element following the view
|
||||
* @return a non-strict view of a slice of this $coll, starting at index `from`
|
||||
* and extending up to (but not including) index `until`.
|
||||
*/
|
||||
def view(from: Int, until: Int): TraversableView[A, Repr] = view.slice(from, until)
|
||||
|
||||
/** Creates a non-strict filter of this $coll.
|
||||
*
|
||||
* Note: the difference between `c filter p` and `c withFilter p` is that
|
||||
* the former creates a new collection, whereas the latter only
|
||||
* restricts the domain of subsequent `map`, `flatMap`, `foreach`,
|
||||
* and `withFilter` operations.
|
||||
* $orderDependent
|
||||
*
|
||||
* @param p the predicate used to test elements.
|
||||
* @return an object of class `WithFilter`, which supports
|
||||
* `map`, `flatMap`, `foreach`, and `withFilter` operations.
|
||||
* All these operations apply to those elements of this $coll which
|
||||
* satisfy the predicate `p`.
|
||||
*/
|
||||
def withFilter(p: A => Boolean): FilterMonadic[A, Repr] = new WithFilter(p)
|
||||
|
||||
/** A class supporting filtered operations. Instances of this class are
|
||||
* returned by method `withFilter`.
|
||||
*/
|
||||
class WithFilter(p: A => Boolean) extends FilterMonadic[A, Repr] {
|
||||
|
||||
/** Builds a new collection by applying a function to all elements of the
|
||||
* outer $coll containing this `WithFilter` instance that satisfy predicate `p`.
|
||||
*
|
||||
* @param f the function to apply to each element.
|
||||
* @tparam B the element type of the returned collection.
|
||||
* @tparam That $thatinfo
|
||||
* @param bf $bfinfo
|
||||
* @return a new collection of type `That` resulting from applying
|
||||
* the given function `f` to each element of the outer $coll
|
||||
* that satisfies predicate `p` and collecting the results.
|
||||
*
|
||||
* @usecase def map[B](f: A => B): $Coll[B]
|
||||
*
|
||||
* @return a new $coll resulting from applying the given function
|
||||
* `f` to each element of the outer $coll that satisfies
|
||||
* predicate `p` and collecting the results.
|
||||
*/
|
||||
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
for (x <- self)
|
||||
if (p(x)) b += f(x)
|
||||
b.result
|
||||
}
|
||||
|
||||
/** Builds a new collection by applying a function to all elements of the
|
||||
* outer $coll containing this `WithFilter` instance that satisfy
|
||||
* predicate `p` and concatenating the results.
|
||||
*
|
||||
* @param f the function to apply to each element.
|
||||
* @tparam B the element type of the returned collection.
|
||||
* @tparam That $thatinfo
|
||||
* @param bf $bfinfo
|
||||
* @return a new collection of type `That` resulting from applying
|
||||
* the given collection-valued function `f` to each element
|
||||
* of the outer $coll that satisfies predicate `p` and
|
||||
* concatenating the results.
|
||||
*
|
||||
* @usecase def flatMap[B](f: A => TraversableOnce[B]): $Coll[B]
|
||||
*
|
||||
* @return a new $coll resulting from applying the given collection-valued function
|
||||
* `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results.
|
||||
*/
|
||||
def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
|
||||
val b = bf(repr)
|
||||
for (x <- self)
|
||||
if (p(x)) b ++= f(x).seq
|
||||
b.result
|
||||
}
|
||||
|
||||
/** Applies a function `f` to all elements of the outer $coll containing
|
||||
* this `WithFilter` instance that satisfy predicate `p`.
|
||||
*
|
||||
* @param f the function that is applied for its side-effect to every element.
|
||||
* The result of function `f` is discarded.
|
||||
*
|
||||
* @tparam U the type parameter describing the result of function `f`.
|
||||
* This result will always be ignored. Typically `U` is `Unit`,
|
||||
* but this is not necessary.
|
||||
*
|
||||
* @usecase def foreach(f: A => Unit): Unit
|
||||
*/
|
||||
def foreach[U](f: A => U): Unit =
|
||||
for (x <- self)
|
||||
if (p(x)) f(x)
|
||||
|
||||
/** Further refines the filter for this $coll.
|
||||
*
|
||||
* @param q the predicate used to test elements.
|
||||
* @return an object of class `WithFilter`, which supports
|
||||
* `map`, `flatMap`, `foreach`, and `withFilter` operations.
|
||||
* All these operations apply to those elements of this $coll which
|
||||
* satisfy the predicate `q` in addition to the predicate `p`.
|
||||
*/
|
||||
def withFilter(q: A => Boolean): WithFilter =
|
||||
new WithFilter(x => p(x) && q(x))
|
||||
}
|
||||
|
||||
// A helper for tails and inits.
|
||||
private def iterateUntilEmpty(f: Traversable[A @uV] => Traversable[A @uV]): Iterator[Repr] = {
|
||||
val it = Iterator.iterate(thisCollection)(f) takeWhile (x => !x.isEmpty)
|
||||
it ++ Iterator(Nil) map (newBuilder ++= _ result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</textarea>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
theme: "ambiance",
|
||||
mode: "text/x-scala"
|
||||
});
|
||||
</script>
|
||||
</article>
|
File diff suppressed because one or more lines are too long
@ -1,88 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Clojure mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="clojure.js"></script>
|
||||
<style>.CodeMirror {background: #f8f8f8;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Clojure</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Clojure mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
; Conway's Game of Life, based on the work of:
|
||||
;; Laurent Petit https://gist.github.com/1200343
|
||||
;; Christophe Grand http://clj-me.cgrand.net/2011/08/19/conways-game-of-life
|
||||
|
||||
(ns ^{:doc "Conway's Game of Life."}
|
||||
game-of-life)
|
||||
|
||||
;; Core game of life's algorithm functions
|
||||
|
||||
(defn neighbours
|
||||
"Given a cell's coordinates, returns the coordinates of its neighbours."
|
||||
[[x y]]
|
||||
(for [dx [-1 0 1] dy (if (zero? dx) [-1 1] [-1 0 1])]
|
||||
[(+ dx x) (+ dy y)]))
|
||||
|
||||
(defn step
|
||||
"Given a set of living cells, computes the new set of living cells."
|
||||
[cells]
|
||||
(set (for [[cell n] (frequencies (mapcat neighbours cells))
|
||||
:when (or (= n 3) (and (= n 2) (cells cell)))]
|
||||
cell)))
|
||||
|
||||
;; Utility methods for displaying game on a text terminal
|
||||
|
||||
(defn print-board
|
||||
"Prints a board on *out*, representing a step in the game."
|
||||
[board w h]
|
||||
(doseq [x (range (inc w)) y (range (inc h))]
|
||||
(if (= y 0) (print "\n"))
|
||||
(print (if (board [x y]) "[X]" " . "))))
|
||||
|
||||
(defn display-grids
|
||||
"Prints a squence of boards on *out*, representing several steps."
|
||||
[grids w h]
|
||||
(doseq [board grids]
|
||||
(print-board board w h)
|
||||
(print "\n")))
|
||||
|
||||
;; Launches an example board
|
||||
|
||||
(def
|
||||
^{:doc "board represents the initial set of living cells"}
|
||||
board #{[2 1] [2 2] [2 3]})
|
||||
|
||||
(display-grids (take 3 (iterate step board)) 5 5)
|
||||
|
||||
;; Let's play with characters
|
||||
(println \1 \a \# \\
|
||||
\" \( \newline
|
||||
\} \" \space
|
||||
\tab \return \backspace
|
||||
\u1000 \uAaAa \u9F9F)
|
||||
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-clojure</code>.</p>
|
||||
|
||||
</article>
|
@ -1,255 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
/**
|
||||
* Author: Gautam Mehta
|
||||
* Branched from CodeMirror's Scheme mode
|
||||
*/
|
||||
(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("cobol", function () {
|
||||
var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
|
||||
ATOM = "atom", NUMBER = "number", KEYWORD = "keyword", MODTAG = "header",
|
||||
COBOLLINENUM = "def", PERIOD = "link";
|
||||
function makeKeywords(str) {
|
||||
var obj = {}, words = str.split(" ");
|
||||
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
var atoms = makeKeywords("TRUE FALSE ZEROES ZEROS ZERO SPACES SPACE LOW-VALUE LOW-VALUES ");
|
||||
var keywords = makeKeywords(
|
||||
"ACCEPT ACCESS ACQUIRE ADD ADDRESS " +
|
||||
"ADVANCING AFTER ALIAS ALL ALPHABET " +
|
||||
"ALPHABETIC ALPHABETIC-LOWER ALPHABETIC-UPPER ALPHANUMERIC ALPHANUMERIC-EDITED " +
|
||||
"ALSO ALTER ALTERNATE AND ANY " +
|
||||
"ARE AREA AREAS ARITHMETIC ASCENDING " +
|
||||
"ASSIGN AT ATTRIBUTE AUTHOR AUTO " +
|
||||
"AUTO-SKIP AUTOMATIC B-AND B-EXOR B-LESS " +
|
||||
"B-NOT B-OR BACKGROUND-COLOR BACKGROUND-COLOUR BEEP " +
|
||||
"BEFORE BELL BINARY BIT BITS " +
|
||||
"BLANK BLINK BLOCK BOOLEAN BOTTOM " +
|
||||
"BY CALL CANCEL CD CF " +
|
||||
"CH CHARACTER CHARACTERS CLASS CLOCK-UNITS " +
|
||||
"CLOSE COBOL CODE CODE-SET COL " +
|
||||
"COLLATING COLUMN COMMA COMMIT COMMITMENT " +
|
||||
"COMMON COMMUNICATION COMP COMP-0 COMP-1 " +
|
||||
"COMP-2 COMP-3 COMP-4 COMP-5 COMP-6 " +
|
||||
"COMP-7 COMP-8 COMP-9 COMPUTATIONAL COMPUTATIONAL-0 " +
|
||||
"COMPUTATIONAL-1 COMPUTATIONAL-2 COMPUTATIONAL-3 COMPUTATIONAL-4 COMPUTATIONAL-5 " +
|
||||
"COMPUTATIONAL-6 COMPUTATIONAL-7 COMPUTATIONAL-8 COMPUTATIONAL-9 COMPUTE " +
|
||||
"CONFIGURATION CONNECT CONSOLE CONTAINED CONTAINS " +
|
||||
"CONTENT CONTINUE CONTROL CONTROL-AREA CONTROLS " +
|
||||
"CONVERTING COPY CORR CORRESPONDING COUNT " +
|
||||
"CRT CRT-UNDER CURRENCY CURRENT CURSOR " +
|
||||
"DATA DATE DATE-COMPILED DATE-WRITTEN DAY " +
|
||||
"DAY-OF-WEEK DB DB-ACCESS-CONTROL-KEY DB-DATA-NAME DB-EXCEPTION " +
|
||||
"DB-FORMAT-NAME DB-RECORD-NAME DB-SET-NAME DB-STATUS DBCS " +
|
||||
"DBCS-EDITED DE DEBUG-CONTENTS DEBUG-ITEM DEBUG-LINE " +
|
||||
"DEBUG-NAME DEBUG-SUB-1 DEBUG-SUB-2 DEBUG-SUB-3 DEBUGGING " +
|
||||
"DECIMAL-POINT DECLARATIVES DEFAULT DELETE DELIMITED " +
|
||||
"DELIMITER DEPENDING DESCENDING DESCRIBED DESTINATION " +
|
||||
"DETAIL DISABLE DISCONNECT DISPLAY DISPLAY-1 " +
|
||||
"DISPLAY-2 DISPLAY-3 DISPLAY-4 DISPLAY-5 DISPLAY-6 " +
|
||||
"DISPLAY-7 DISPLAY-8 DISPLAY-9 DIVIDE DIVISION " +
|
||||
"DOWN DROP DUPLICATE DUPLICATES DYNAMIC " +
|
||||
"EBCDIC EGI EJECT ELSE EMI " +
|
||||
"EMPTY EMPTY-CHECK ENABLE END END. END-ACCEPT END-ACCEPT. " +
|
||||
"END-ADD END-CALL END-COMPUTE END-DELETE END-DISPLAY " +
|
||||
"END-DIVIDE END-EVALUATE END-IF END-INVOKE END-MULTIPLY " +
|
||||
"END-OF-PAGE END-PERFORM END-READ END-RECEIVE END-RETURN " +
|
||||
"END-REWRITE END-SEARCH END-START END-STRING END-SUBTRACT " +
|
||||
"END-UNSTRING END-WRITE END-XML ENTER ENTRY " +
|
||||
"ENVIRONMENT EOP EQUAL EQUALS ERASE " +
|
||||
"ERROR ESI EVALUATE EVERY EXCEEDS " +
|
||||
"EXCEPTION EXCLUSIVE EXIT EXTEND EXTERNAL " +
|
||||
"EXTERNALLY-DESCRIBED-KEY FD FETCH FILE FILE-CONTROL " +
|
||||
"FILE-STREAM FILES FILLER FINAL FIND " +
|
||||
"FINISH FIRST FOOTING FOR FOREGROUND-COLOR " +
|
||||
"FOREGROUND-COLOUR FORMAT FREE FROM FULL " +
|
||||
"FUNCTION GENERATE GET GIVING GLOBAL " +
|
||||
"GO GOBACK GREATER GROUP HEADING " +
|
||||
"HIGH-VALUE HIGH-VALUES HIGHLIGHT I-O I-O-CONTROL " +
|
||||
"ID IDENTIFICATION IF IN INDEX " +
|
||||
"INDEX-1 INDEX-2 INDEX-3 INDEX-4 INDEX-5 " +
|
||||
"INDEX-6 INDEX-7 INDEX-8 INDEX-9 INDEXED " +
|
||||
"INDIC INDICATE INDICATOR INDICATORS INITIAL " +
|
||||
"INITIALIZE INITIATE INPUT INPUT-OUTPUT INSPECT " +
|
||||
"INSTALLATION INTO INVALID INVOKE IS " +
|
||||
"JUST JUSTIFIED KANJI KEEP KEY " +
|
||||
"LABEL LAST LD LEADING LEFT " +
|
||||
"LEFT-JUSTIFY LENGTH LENGTH-CHECK LESS LIBRARY " +
|
||||
"LIKE LIMIT LIMITS LINAGE LINAGE-COUNTER " +
|
||||
"LINE LINE-COUNTER LINES LINKAGE LOCAL-STORAGE " +
|
||||
"LOCALE LOCALLY LOCK " +
|
||||
"MEMBER MEMORY MERGE MESSAGE METACLASS " +
|
||||
"MODE MODIFIED MODIFY MODULES MOVE " +
|
||||
"MULTIPLE MULTIPLY NATIONAL NATIVE NEGATIVE " +
|
||||
"NEXT NO NO-ECHO NONE NOT " +
|
||||
"NULL NULL-KEY-MAP NULL-MAP NULLS NUMBER " +
|
||||
"NUMERIC NUMERIC-EDITED OBJECT OBJECT-COMPUTER OCCURS " +
|
||||
"OF OFF OMITTED ON ONLY " +
|
||||
"OPEN OPTIONAL OR ORDER ORGANIZATION " +
|
||||
"OTHER OUTPUT OVERFLOW OWNER PACKED-DECIMAL " +
|
||||
"PADDING PAGE PAGE-COUNTER PARSE PERFORM " +
|
||||
"PF PH PIC PICTURE PLUS " +
|
||||
"POINTER POSITION POSITIVE PREFIX PRESENT " +
|
||||
"PRINTING PRIOR PROCEDURE PROCEDURE-POINTER PROCEDURES " +
|
||||
"PROCEED PROCESS PROCESSING PROGRAM PROGRAM-ID " +
|
||||
"PROMPT PROTECTED PURGE QUEUE QUOTE " +
|
||||
"QUOTES RANDOM RD READ READY " +
|
||||
"REALM RECEIVE RECONNECT RECORD RECORD-NAME " +
|
||||
"RECORDS RECURSIVE REDEFINES REEL REFERENCE " +
|
||||
"REFERENCE-MONITOR REFERENCES RELATION RELATIVE RELEASE " +
|
||||
"REMAINDER REMOVAL RENAMES REPEATED REPLACE " +
|
||||
"REPLACING REPORT REPORTING REPORTS REPOSITORY " +
|
||||
"REQUIRED RERUN RESERVE RESET RETAINING " +
|
||||
"RETRIEVAL RETURN RETURN-CODE RETURNING REVERSE-VIDEO " +
|
||||
"REVERSED REWIND REWRITE RF RH " +
|
||||
"RIGHT RIGHT-JUSTIFY ROLLBACK ROLLING ROUNDED " +
|
||||
"RUN SAME SCREEN SD SEARCH " +
|
||||
"SECTION SECURE SECURITY SEGMENT SEGMENT-LIMIT " +
|
||||
"SELECT SEND SENTENCE SEPARATE SEQUENCE " +
|
||||
"SEQUENTIAL SET SHARED SIGN SIZE " +
|
||||
"SKIP1 SKIP2 SKIP3 SORT SORT-MERGE " +
|
||||
"SORT-RETURN SOURCE SOURCE-COMPUTER SPACE-FILL " +
|
||||
"SPECIAL-NAMES STANDARD STANDARD-1 STANDARD-2 " +
|
||||
"START STARTING STATUS STOP STORE " +
|
||||
"STRING SUB-QUEUE-1 SUB-QUEUE-2 SUB-QUEUE-3 SUB-SCHEMA " +
|
||||
"SUBFILE SUBSTITUTE SUBTRACT SUM SUPPRESS " +
|
||||
"SYMBOLIC SYNC SYNCHRONIZED SYSIN SYSOUT " +
|
||||
"TABLE TALLYING TAPE TENANT TERMINAL " +
|
||||
"TERMINATE TEST TEXT THAN THEN " +
|
||||
"THROUGH THRU TIME TIMES TITLE " +
|
||||
"TO TOP TRAILING TRAILING-SIGN TRANSACTION " +
|
||||
"TYPE TYPEDEF UNDERLINE UNEQUAL UNIT " +
|
||||
"UNSTRING UNTIL UP UPDATE UPON " +
|
||||
"USAGE USAGE-MODE USE USING VALID " +
|
||||
"VALIDATE VALUE VALUES VARYING VLR " +
|
||||
"WAIT WHEN WHEN-COMPILED WITH WITHIN " +
|
||||
"WORDS WORKING-STORAGE WRITE XML XML-CODE " +
|
||||
"XML-EVENT XML-NTEXT XML-TEXT ZERO ZERO-FILL " );
|
||||
|
||||
var builtins = makeKeywords("- * ** / + < <= = > >= ");
|
||||
var tests = {
|
||||
digit: /\d/,
|
||||
digit_or_colon: /[\d:]/,
|
||||
hex: /[0-9a-f]/i,
|
||||
sign: /[+-]/,
|
||||
exponent: /e/i,
|
||||
keyword_char: /[^\s\(\[\;\)\]]/,
|
||||
symbol: /[\w*+\-]/
|
||||
};
|
||||
function isNumber(ch, stream){
|
||||
// hex
|
||||
if ( ch === '0' && stream.eat(/x/i) ) {
|
||||
stream.eatWhile(tests.hex);
|
||||
return true;
|
||||
}
|
||||
// leading sign
|
||||
if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
|
||||
stream.eat(tests.sign);
|
||||
ch = stream.next();
|
||||
}
|
||||
if ( tests.digit.test(ch) ) {
|
||||
stream.eat(ch);
|
||||
stream.eatWhile(tests.digit);
|
||||
if ( '.' == stream.peek()) {
|
||||
stream.eat('.');
|
||||
stream.eatWhile(tests.digit);
|
||||
}
|
||||
if ( stream.eat(tests.exponent) ) {
|
||||
stream.eat(tests.sign);
|
||||
stream.eatWhile(tests.digit);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
startState: function () {
|
||||
return {
|
||||
indentStack: null,
|
||||
indentation: 0,
|
||||
mode: false
|
||||
};
|
||||
},
|
||||
token: function (stream, state) {
|
||||
if (state.indentStack == null && stream.sol()) {
|
||||
// update indentation, but only if indentStack is empty
|
||||
state.indentation = 6 ; //stream.indentation();
|
||||
}
|
||||
// skip spaces
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
var returnType = null;
|
||||
switch(state.mode){
|
||||
case "string": // multi-line string parsing mode
|
||||
var next = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == "\"" || next == "\'") {
|
||||
state.mode = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
returnType = STRING; // continue on in string mode
|
||||
break;
|
||||
default: // default parsing mode
|
||||
var ch = stream.next();
|
||||
var col = stream.column();
|
||||
if (col >= 0 && col <= 5) {
|
||||
returnType = COBOLLINENUM;
|
||||
} else if (col >= 72 && col <= 79) {
|
||||
stream.skipToEnd();
|
||||
returnType = MODTAG;
|
||||
} else if (ch == "*" && col == 6) { // comment
|
||||
stream.skipToEnd(); // rest of the line is a comment
|
||||
returnType = COMMENT;
|
||||
} else if (ch == "\"" || ch == "\'") {
|
||||
state.mode = "string";
|
||||
returnType = STRING;
|
||||
} else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
|
||||
returnType = ATOM;
|
||||
} else if (ch == ".") {
|
||||
returnType = PERIOD;
|
||||
} else if (isNumber(ch,stream)){
|
||||
returnType = NUMBER;
|
||||
} else {
|
||||
if (stream.current().match(tests.symbol)) {
|
||||
while (col < 71) {
|
||||
if (stream.eat(tests.symbol) === undefined) {
|
||||
break;
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
|
||||
returnType = KEYWORD;
|
||||
} else if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase())) {
|
||||
returnType = BUILTIN;
|
||||
} else if (atoms && atoms.propertyIsEnumerable(stream.current().toUpperCase())) {
|
||||
returnType = ATOM;
|
||||
} else returnType = null;
|
||||
}
|
||||
}
|
||||
return returnType;
|
||||
},
|
||||
indent: function (state) {
|
||||
if (state.indentStack == null) return state.indentation;
|
||||
return state.indentStack.indent;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-cobol", "cobol");
|
||||
|
||||
});
|
@ -1,210 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: COBOL mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../../theme/neat.css">
|
||||
<link rel="stylesheet" href="../../theme/elegant.css">
|
||||
<link rel="stylesheet" href="../../theme/erlang-dark.css">
|
||||
<link rel="stylesheet" href="../../theme/night.css">
|
||||
<link rel="stylesheet" href="../../theme/monokai.css">
|
||||
<link rel="stylesheet" href="../../theme/cobalt.css">
|
||||
<link rel="stylesheet" href="../../theme/eclipse.css">
|
||||
<link rel="stylesheet" href="../../theme/rubyblue.css">
|
||||
<link rel="stylesheet" href="../../theme/lesser-dark.css">
|
||||
<link rel="stylesheet" href="../../theme/xq-dark.css">
|
||||
<link rel="stylesheet" href="../../theme/xq-light.css">
|
||||
<link rel="stylesheet" href="../../theme/ambiance.css">
|
||||
<link rel="stylesheet" href="../../theme/blackboard.css">
|
||||
<link rel="stylesheet" href="../../theme/vibrant-ink.css">
|
||||
<link rel="stylesheet" href="../../theme/solarized.css">
|
||||
<link rel="stylesheet" href="../../theme/twilight.css">
|
||||
<link rel="stylesheet" href="../../theme/midnight.css">
|
||||
<link rel="stylesheet" href="../../addon/dialog/dialog.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="cobol.js"></script>
|
||||
<script src="../../addon/selection/active-line.js"></script>
|
||||
<script src="../../addon/search/search.js"></script>
|
||||
<script src="../../addon/dialog/dialog.js"></script>
|
||||
<script src="../../addon/search/searchcursor.js"></script>
|
||||
<style>
|
||||
.CodeMirror {
|
||||
border: 1px solid #eee;
|
||||
font-size : 20px;
|
||||
height : auto !important;
|
||||
}
|
||||
.CodeMirror-activeline-background {background: #555555 !important;}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">COBOL</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>COBOL mode</h2>
|
||||
|
||||
<p> Select Theme <select onchange="selectTheme()" id="selectTheme">
|
||||
<option>default</option>
|
||||
<option>ambiance</option>
|
||||
<option>blackboard</option>
|
||||
<option>cobalt</option>
|
||||
<option>eclipse</option>
|
||||
<option>elegant</option>
|
||||
<option>erlang-dark</option>
|
||||
<option>lesser-dark</option>
|
||||
<option>midnight</option>
|
||||
<option>monokai</option>
|
||||
<option>neat</option>
|
||||
<option>night</option>
|
||||
<option>rubyblue</option>
|
||||
<option>solarized dark</option>
|
||||
<option>solarized light</option>
|
||||
<option selected>twilight</option>
|
||||
<option>vibrant-ink</option>
|
||||
<option>xq-dark</option>
|
||||
<option>xq-light</option>
|
||||
</select> Select Font Size <select onchange="selectFontsize()" id="selectFontSize">
|
||||
<option value="13px">13px</option>
|
||||
<option value="14px">14px</option>
|
||||
<option value="16px">16px</option>
|
||||
<option value="18px">18px</option>
|
||||
<option value="20px" selected="selected">20px</option>
|
||||
<option value="24px">24px</option>
|
||||
<option value="26px">26px</option>
|
||||
<option value="28px">28px</option>
|
||||
<option value="30px">30px</option>
|
||||
<option value="32px">32px</option>
|
||||
<option value="34px">34px</option>
|
||||
<option value="36px">36px</option>
|
||||
</select>
|
||||
<label for="checkBoxReadOnly">Read-only</label>
|
||||
<input type="checkbox" id="checkBoxReadOnly" onchange="selectReadOnly()">
|
||||
<label for="id_tabToIndentSpace">Insert Spaces on Tab</label>
|
||||
<input type="checkbox" id="id_tabToIndentSpace" onchange="tabToIndentSpace()">
|
||||
</p>
|
||||
<textarea id="code" name="code">
|
||||
---------1---------2---------3---------4---------5---------6---------7---------8
|
||||
12345678911234567892123456789312345678941234567895123456789612345678971234567898
|
||||
000010 IDENTIFICATION DIVISION. MODTGHERE
|
||||
000020 PROGRAM-ID. SAMPLE.
|
||||
000030 AUTHOR. TEST SAM.
|
||||
000040 DATE-WRITTEN. 5 February 2013
|
||||
000041
|
||||
000042* A sample program just to show the form.
|
||||
000043* The program copies its input to the output,
|
||||
000044* and counts the number of records.
|
||||
000045* At the end this number is printed.
|
||||
000046
|
||||
000050 ENVIRONMENT DIVISION.
|
||||
000060 INPUT-OUTPUT SECTION.
|
||||
000070 FILE-CONTROL.
|
||||
000080 SELECT STUDENT-FILE ASSIGN TO SYSIN
|
||||
000090 ORGANIZATION IS LINE SEQUENTIAL.
|
||||
000100 SELECT PRINT-FILE ASSIGN TO SYSOUT
|
||||
000110 ORGANIZATION IS LINE SEQUENTIAL.
|
||||
000120
|
||||
000130 DATA DIVISION.
|
||||
000140 FILE SECTION.
|
||||
000150 FD STUDENT-FILE
|
||||
000160 RECORD CONTAINS 43 CHARACTERS
|
||||
000170 DATA RECORD IS STUDENT-IN.
|
||||
000180 01 STUDENT-IN PIC X(43).
|
||||
000190
|
||||
000200 FD PRINT-FILE
|
||||
000210 RECORD CONTAINS 80 CHARACTERS
|
||||
000220 DATA RECORD IS PRINT-LINE.
|
||||
000230 01 PRINT-LINE PIC X(80).
|
||||
000240
|
||||
000250 WORKING-STORAGE SECTION.
|
||||
000260 01 DATA-REMAINS-SWITCH PIC X(2) VALUE SPACES.
|
||||
000261 01 RECORDS-WRITTEN PIC 99.
|
||||
000270
|
||||
000280 01 DETAIL-LINE.
|
||||
000290 05 FILLER PIC X(7) VALUE SPACES.
|
||||
000300 05 RECORD-IMAGE PIC X(43).
|
||||
000310 05 FILLER PIC X(30) VALUE SPACES.
|
||||
000311
|
||||
000312 01 SUMMARY-LINE.
|
||||
000313 05 FILLER PIC X(7) VALUE SPACES.
|
||||
000314 05 TOTAL-READ PIC 99.
|
||||
000315 05 FILLER PIC X VALUE SPACE.
|
||||
000316 05 FILLER PIC X(17)
|
||||
000317 VALUE 'Records were read'.
|
||||
000318 05 FILLER PIC X(53) VALUE SPACES.
|
||||
000319
|
||||
000320 PROCEDURE DIVISION.
|
||||
000321
|
||||
000330 PREPARE-SENIOR-REPORT.
|
||||
000340 OPEN INPUT STUDENT-FILE
|
||||
000350 OUTPUT PRINT-FILE.
|
||||
000351 MOVE ZERO TO RECORDS-WRITTEN.
|
||||
000360 READ STUDENT-FILE
|
||||
000370 AT END MOVE 'NO' TO DATA-REMAINS-SWITCH
|
||||
000380 END-READ.
|
||||
000390 PERFORM PROCESS-RECORDS
|
||||
000410 UNTIL DATA-REMAINS-SWITCH = 'NO'.
|
||||
000411 PERFORM PRINT-SUMMARY.
|
||||
000420 CLOSE STUDENT-FILE
|
||||
000430 PRINT-FILE.
|
||||
000440 STOP RUN.
|
||||
000450
|
||||
000460 PROCESS-RECORDS.
|
||||
000470 MOVE STUDENT-IN TO RECORD-IMAGE.
|
||||
000480 MOVE DETAIL-LINE TO PRINT-LINE.
|
||||
000490 WRITE PRINT-LINE.
|
||||
000500 ADD 1 TO RECORDS-WRITTEN.
|
||||
000510 READ STUDENT-FILE
|
||||
000520 AT END MOVE 'NO' TO DATA-REMAINS-SWITCH
|
||||
000530 END-READ.
|
||||
000540
|
||||
000550 PRINT-SUMMARY.
|
||||
000560 MOVE RECORDS-WRITTEN TO TOTAL-READ.
|
||||
000570 MOVE SUMMARY-LINE TO PRINT-LINE.
|
||||
000571 WRITE PRINT-LINE.
|
||||
000572
|
||||
000580
|
||||
</textarea>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-cobol",
|
||||
theme : "twilight",
|
||||
styleActiveLine: true,
|
||||
showCursorWhenSelecting : true,
|
||||
});
|
||||
function selectTheme() {
|
||||
var themeInput = document.getElementById("selectTheme");
|
||||
var theme = themeInput.options[themeInput.selectedIndex].innerHTML;
|
||||
editor.setOption("theme", theme);
|
||||
}
|
||||
function selectFontsize() {
|
||||
var fontSizeInput = document.getElementById("selectFontSize");
|
||||
var fontSize = fontSizeInput.options[fontSizeInput.selectedIndex].innerHTML;
|
||||
editor.getWrapperElement().style.fontSize = fontSize;
|
||||
editor.refresh();
|
||||
}
|
||||
function selectReadOnly() {
|
||||
editor.setOption("readOnly", document.getElementById("checkBoxReadOnly").checked);
|
||||
}
|
||||
function tabToIndentSpace() {
|
||||
if (document.getElementById("id_tabToIndentSpace").checked) {
|
||||
editor.setOption("extraKeys", {Tab: function(cm) { cm.replaceSelection(" ", "end"); }});
|
||||
} else {
|
||||
editor.setOption("extraKeys", {Tab: function(cm) { cm.replaceSelection(" ", "end"); }});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</article>
|
@ -1,369 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
/**
|
||||
* Link to the project's GitHub page:
|
||||
* https://github.com/pickhardt/coffeescript-codemirror-mode
|
||||
*/
|
||||
(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("coffeescript", function(conf) {
|
||||
var ERRORCLASS = "error";
|
||||
|
||||
function wordRegexp(words) {
|
||||
return new RegExp("^((" + words.join(")|(") + "))\\b");
|
||||
}
|
||||
|
||||
var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
|
||||
var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
|
||||
var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
|
||||
var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
|
||||
|
||||
var wordOperators = wordRegexp(["and", "or", "not",
|
||||
"is", "isnt", "in",
|
||||
"instanceof", "typeof"]);
|
||||
var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
|
||||
"switch", "try", "catch", "finally", "class"];
|
||||
var commonKeywords = ["break", "by", "continue", "debugger", "delete",
|
||||
"do", "in", "of", "new", "return", "then",
|
||||
"this", "@", "throw", "when", "until", "extends"];
|
||||
|
||||
var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
|
||||
|
||||
indentKeywords = wordRegexp(indentKeywords);
|
||||
|
||||
|
||||
var stringPrefixes = /^('{3}|\"{3}|['\"])/;
|
||||
var regexPrefixes = /^(\/{3}|\/)/;
|
||||
var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
|
||||
var constants = wordRegexp(commonConstants);
|
||||
|
||||
// Tokenizers
|
||||
function tokenBase(stream, state) {
|
||||
// Handle scope changes
|
||||
if (stream.sol()) {
|
||||
if (state.scope.align === null) state.scope.align = false;
|
||||
var scopeOffset = state.scope.offset;
|
||||
if (stream.eatSpace()) {
|
||||
var lineOffset = stream.indentation();
|
||||
if (lineOffset > scopeOffset && state.scope.type == "coffee") {
|
||||
return "indent";
|
||||
} else if (lineOffset < scopeOffset) {
|
||||
return "dedent";
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
if (scopeOffset > 0) {
|
||||
dedent(stream, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var ch = stream.peek();
|
||||
|
||||
// Handle docco title comment (single line)
|
||||
if (stream.match("####")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
|
||||
// Handle multi line comments
|
||||
if (stream.match("###")) {
|
||||
state.tokenize = longComment;
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
|
||||
// Single line comment
|
||||
if (ch === "#") {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
|
||||
// Handle number literals
|
||||
if (stream.match(/^-?[0-9\.]/, false)) {
|
||||
var floatLiteral = false;
|
||||
// Floats
|
||||
if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
if (stream.match(/^-?\d+\.\d*/)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
if (stream.match(/^-?\.\d+/)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
|
||||
if (floatLiteral) {
|
||||
// prevent from getting extra . on 1..
|
||||
if (stream.peek() == "."){
|
||||
stream.backUp(1);
|
||||
}
|
||||
return "number";
|
||||
}
|
||||
// Integers
|
||||
var intLiteral = false;
|
||||
// Hex
|
||||
if (stream.match(/^-?0x[0-9a-f]+/i)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
// Decimal
|
||||
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
// Zero by itself with no other piece of number.
|
||||
if (stream.match(/^-?0(?![\dx])/i)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
if (intLiteral) {
|
||||
return "number";
|
||||
}
|
||||
}
|
||||
|
||||
// Handle strings
|
||||
if (stream.match(stringPrefixes)) {
|
||||
state.tokenize = tokenFactory(stream.current(), false, "string");
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
// Handle regex literals
|
||||
if (stream.match(regexPrefixes)) {
|
||||
if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
|
||||
state.tokenize = tokenFactory(stream.current(), true, "string-2");
|
||||
return state.tokenize(stream, state);
|
||||
} else {
|
||||
stream.backUp(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle operators and delimiters
|
||||
if (stream.match(operators) || stream.match(wordOperators)) {
|
||||
return "operator";
|
||||
}
|
||||
if (stream.match(delimiters)) {
|
||||
return "punctuation";
|
||||
}
|
||||
|
||||
if (stream.match(constants)) {
|
||||
return "atom";
|
||||
}
|
||||
|
||||
if (stream.match(keywords)) {
|
||||
return "keyword";
|
||||
}
|
||||
|
||||
if (stream.match(identifiers)) {
|
||||
return "variable";
|
||||
}
|
||||
|
||||
if (stream.match(properties)) {
|
||||
return "property";
|
||||
}
|
||||
|
||||
// Handle non-detected items
|
||||
stream.next();
|
||||
return ERRORCLASS;
|
||||
}
|
||||
|
||||
function tokenFactory(delimiter, singleline, outclass) {
|
||||
return function(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
stream.eatWhile(/[^'"\/\\]/);
|
||||
if (stream.eat("\\")) {
|
||||
stream.next();
|
||||
if (singleline && stream.eol()) {
|
||||
return outclass;
|
||||
}
|
||||
} else if (stream.match(delimiter)) {
|
||||
state.tokenize = tokenBase;
|
||||
return outclass;
|
||||
} else {
|
||||
stream.eat(/['"\/]/);
|
||||
}
|
||||
}
|
||||
if (singleline) {
|
||||
if (conf.mode.singleLineStringErrors) {
|
||||
outclass = ERRORCLASS;
|
||||
} else {
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
}
|
||||
return outclass;
|
||||
};
|
||||
}
|
||||
|
||||
function longComment(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
stream.eatWhile(/[^#]/);
|
||||
if (stream.match("###")) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
stream.eatWhile("#");
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function indent(stream, state, type) {
|
||||
type = type || "coffee";
|
||||
var offset = 0, align = false, alignOffset = null;
|
||||
for (var scope = state.scope; scope; scope = scope.prev) {
|
||||
if (scope.type === "coffee" || scope.type == "}") {
|
||||
offset = scope.offset + conf.indentUnit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type !== "coffee") {
|
||||
align = null;
|
||||
alignOffset = stream.column() + stream.current().length;
|
||||
} else if (state.scope.align) {
|
||||
state.scope.align = false;
|
||||
}
|
||||
state.scope = {
|
||||
offset: offset,
|
||||
type: type,
|
||||
prev: state.scope,
|
||||
align: align,
|
||||
alignOffset: alignOffset
|
||||
};
|
||||
}
|
||||
|
||||
function dedent(stream, state) {
|
||||
if (!state.scope.prev) return;
|
||||
if (state.scope.type === "coffee") {
|
||||
var _indent = stream.indentation();
|
||||
var matched = false;
|
||||
for (var scope = state.scope; scope; scope = scope.prev) {
|
||||
if (_indent === scope.offset) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
return true;
|
||||
}
|
||||
while (state.scope.prev && state.scope.offset !== _indent) {
|
||||
state.scope = state.scope.prev;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
state.scope = state.scope.prev;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function tokenLexer(stream, state) {
|
||||
var style = state.tokenize(stream, state);
|
||||
var current = stream.current();
|
||||
|
||||
// Handle "." connected identifiers
|
||||
if (current === ".") {
|
||||
style = state.tokenize(stream, state);
|
||||
current = stream.current();
|
||||
if (/^\.[\w$]+$/.test(current)) {
|
||||
return "variable";
|
||||
} else {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle scope changes.
|
||||
if (current === "return") {
|
||||
state.dedent = true;
|
||||
}
|
||||
if (((current === "->" || current === "=>") &&
|
||||
!state.lambda &&
|
||||
!stream.peek())
|
||||
|| style === "indent") {
|
||||
indent(stream, state);
|
||||
}
|
||||
var delimiter_index = "[({".indexOf(current);
|
||||
if (delimiter_index !== -1) {
|
||||
indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
|
||||
}
|
||||
if (indentKeywords.exec(current)){
|
||||
indent(stream, state);
|
||||
}
|
||||
if (current == "then"){
|
||||
dedent(stream, state);
|
||||
}
|
||||
|
||||
|
||||
if (style === "dedent") {
|
||||
if (dedent(stream, state)) {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
delimiter_index = "])}".indexOf(current);
|
||||
if (delimiter_index !== -1) {
|
||||
while (state.scope.type == "coffee" && state.scope.prev)
|
||||
state.scope = state.scope.prev;
|
||||
if (state.scope.type == current)
|
||||
state.scope = state.scope.prev;
|
||||
}
|
||||
if (state.dedent && stream.eol()) {
|
||||
if (state.scope.type == "coffee" && state.scope.prev)
|
||||
state.scope = state.scope.prev;
|
||||
state.dedent = false;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
var external = {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: tokenBase,
|
||||
scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
|
||||
lastToken: null,
|
||||
lambda: false,
|
||||
dedent: 0
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var fillAlign = state.scope.align === null && state.scope;
|
||||
if (fillAlign && stream.sol()) fillAlign.align = false;
|
||||
|
||||
var style = tokenLexer(stream, state);
|
||||
if (fillAlign && style && style != "comment") fillAlign.align = true;
|
||||
|
||||
state.lastToken = {style:style, content: stream.current()};
|
||||
|
||||
if (stream.eol() && stream.lambda) {
|
||||
state.lambda = false;
|
||||
}
|
||||
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, text) {
|
||||
if (state.tokenize != tokenBase) return 0;
|
||||
var scope = state.scope;
|
||||
var closer = text && "])}".indexOf(text.charAt(0)) > -1;
|
||||
if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
|
||||
var closes = closer && scope.type === text.charAt(0);
|
||||
if (scope.align)
|
||||
return scope.alignOffset - (closes ? 1 : 0);
|
||||
else
|
||||
return (closes ? scope.prev : scope).offset;
|
||||
},
|
||||
|
||||
lineComment: "#",
|
||||
fold: "indent"
|
||||
};
|
||||
return external;
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
|
||||
|
||||
});
|
@ -1,740 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: CoffeeScript mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="coffeescript.js"></script>
|
||||
<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">CoffeeScript</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>CoffeeScript mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
# CoffeeScript mode for CodeMirror
|
||||
# Copyright (c) 2011 Jeff Pickhardt, released under
|
||||
# the MIT License.
|
||||
#
|
||||
# Modified from the Python CodeMirror mode, which also is
|
||||
# under the MIT License Copyright (c) 2010 Timothy Farrell.
|
||||
#
|
||||
# The following script, Underscore.coffee, is used to
|
||||
# demonstrate CoffeeScript mode for CodeMirror.
|
||||
#
|
||||
# To download CoffeeScript mode for CodeMirror, go to:
|
||||
# https://github.com/pickhardt/coffeescript-codemirror-mode
|
||||
|
||||
# **Underscore.coffee
|
||||
# (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.**
|
||||
# Underscore is freely distributable under the terms of the
|
||||
# [MIT license](http://en.wikipedia.org/wiki/MIT_License).
|
||||
# Portions of Underscore are inspired by or borrowed from
|
||||
# [Prototype.js](http://prototypejs.org/api), Oliver Steele's
|
||||
# [Functional](http://osteele.com), and John Resig's
|
||||
# [Micro-Templating](http://ejohn.org).
|
||||
# For all details and documentation:
|
||||
# http://documentcloud.github.com/underscore/
|
||||
|
||||
|
||||
# Baseline setup
|
||||
# --------------
|
||||
|
||||
# Establish the root object, `window` in the browser, or `global` on the server.
|
||||
root = this
|
||||
|
||||
|
||||
# Save the previous value of the `_` variable.
|
||||
previousUnderscore = root._
|
||||
|
||||
### Multiline
|
||||
comment
|
||||
###
|
||||
|
||||
# Establish the object that gets thrown to break out of a loop iteration.
|
||||
# `StopIteration` is SOP on Mozilla.
|
||||
breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
|
||||
|
||||
|
||||
#### Docco style single line comment (title)
|
||||
|
||||
|
||||
# Helper function to escape **RegExp** contents, because JS doesn't have one.
|
||||
escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
|
||||
|
||||
|
||||
# Save bytes in the minified (but not gzipped) version:
|
||||
ArrayProto = Array.prototype
|
||||
ObjProto = Object.prototype
|
||||
|
||||
|
||||
# Create quick reference variables for speed access to core prototypes.
|
||||
slice = ArrayProto.slice
|
||||
unshift = ArrayProto.unshift
|
||||
toString = ObjProto.toString
|
||||
hasOwnProperty = ObjProto.hasOwnProperty
|
||||
propertyIsEnumerable = ObjProto.propertyIsEnumerable
|
||||
|
||||
|
||||
# All **ECMA5** native implementations we hope to use are declared here.
|
||||
nativeForEach = ArrayProto.forEach
|
||||
nativeMap = ArrayProto.map
|
||||
nativeReduce = ArrayProto.reduce
|
||||
nativeReduceRight = ArrayProto.reduceRight
|
||||
nativeFilter = ArrayProto.filter
|
||||
nativeEvery = ArrayProto.every
|
||||
nativeSome = ArrayProto.some
|
||||
nativeIndexOf = ArrayProto.indexOf
|
||||
nativeLastIndexOf = ArrayProto.lastIndexOf
|
||||
nativeIsArray = Array.isArray
|
||||
nativeKeys = Object.keys
|
||||
|
||||
|
||||
# Create a safe reference to the Underscore object for use below.
|
||||
_ = (obj) -> new wrapper(obj)
|
||||
|
||||
|
||||
# Export the Underscore object for **CommonJS**.
|
||||
if typeof(exports) != 'undefined' then exports._ = _
|
||||
|
||||
|
||||
# Export Underscore to global scope.
|
||||
root._ = _
|
||||
|
||||
|
||||
# Current version.
|
||||
_.VERSION = '1.1.0'
|
||||
|
||||
|
||||
# Collection Functions
|
||||
# --------------------
|
||||
|
||||
# The cornerstone, an **each** implementation.
|
||||
# Handles objects implementing **forEach**, arrays, and raw objects.
|
||||
_.each = (obj, iterator, context) ->
|
||||
try
|
||||
if nativeForEach and obj.forEach is nativeForEach
|
||||
obj.forEach iterator, context
|
||||
else if _.isNumber obj.length
|
||||
iterator.call context, obj[i], i, obj for i in [0...obj.length]
|
||||
else
|
||||
iterator.call context, val, key, obj for own key, val of obj
|
||||
catch e
|
||||
throw e if e isnt breaker
|
||||
obj
|
||||
|
||||
|
||||
# Return the results of applying the iterator to each element. Use JavaScript
|
||||
# 1.6's version of **map**, if possible.
|
||||
_.map = (obj, iterator, context) ->
|
||||
return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
|
||||
results = []
|
||||
_.each obj, (value, index, list) ->
|
||||
results.push iterator.call context, value, index, list
|
||||
results
|
||||
|
||||
|
||||
# **Reduce** builds up a single result from a list of values. Also known as
|
||||
# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
|
||||
_.reduce = (obj, iterator, memo, context) ->
|
||||
if nativeReduce and obj.reduce is nativeReduce
|
||||
iterator = _.bind iterator, context if context
|
||||
return obj.reduce iterator, memo
|
||||
_.each obj, (value, index, list) ->
|
||||
memo = iterator.call context, memo, value, index, list
|
||||
memo
|
||||
|
||||
|
||||
# The right-associative version of **reduce**, also known as **foldr**. Uses
|
||||
# JavaScript 1.8's version of **reduceRight**, if available.
|
||||
_.reduceRight = (obj, iterator, memo, context) ->
|
||||
if nativeReduceRight and obj.reduceRight is nativeReduceRight
|
||||
iterator = _.bind iterator, context if context
|
||||
return obj.reduceRight iterator, memo
|
||||
reversed = _.clone(_.toArray(obj)).reverse()
|
||||
_.reduce reversed, iterator, memo, context
|
||||
|
||||
|
||||
# Return the first value which passes a truth test.
|
||||
_.detect = (obj, iterator, context) ->
|
||||
result = null
|
||||
_.each obj, (value, index, list) ->
|
||||
if iterator.call context, value, index, list
|
||||
result = value
|
||||
_.breakLoop()
|
||||
result
|
||||
|
||||
|
||||
# Return all the elements that pass a truth test. Use JavaScript 1.6's
|
||||
# **filter**, if it exists.
|
||||
_.filter = (obj, iterator, context) ->
|
||||
return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
|
||||
results = []
|
||||
_.each obj, (value, index, list) ->
|
||||
results.push value if iterator.call context, value, index, list
|
||||
results
|
||||
|
||||
|
||||
# Return all the elements for which a truth test fails.
|
||||
_.reject = (obj, iterator, context) ->
|
||||
results = []
|
||||
_.each obj, (value, index, list) ->
|
||||
results.push value if not iterator.call context, value, index, list
|
||||
results
|
||||
|
||||
|
||||
# Determine whether all of the elements match a truth test. Delegate to
|
||||
# JavaScript 1.6's **every**, if it is present.
|
||||
_.every = (obj, iterator, context) ->
|
||||
iterator ||= _.identity
|
||||
return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
|
||||
result = true
|
||||
_.each obj, (value, index, list) ->
|
||||
_.breakLoop() unless (result = result and iterator.call(context, value, index, list))
|
||||
result
|
||||
|
||||
|
||||
# Determine if at least one element in the object matches a truth test. Use
|
||||
# JavaScript 1.6's **some**, if it exists.
|
||||
_.some = (obj, iterator, context) ->
|
||||
iterator ||= _.identity
|
||||
return obj.some iterator, context if nativeSome and obj.some is nativeSome
|
||||
result = false
|
||||
_.each obj, (value, index, list) ->
|
||||
_.breakLoop() if (result = iterator.call(context, value, index, list))
|
||||
result
|
||||
|
||||
|
||||
# Determine if a given value is included in the array or object,
|
||||
# based on `===`.
|
||||
_.include = (obj, target) ->
|
||||
return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
|
||||
return true for own key, val of obj when val is target
|
||||
false
|
||||
|
||||
|
||||
# Invoke a method with arguments on every item in a collection.
|
||||
_.invoke = (obj, method) ->
|
||||
args = _.rest arguments, 2
|
||||
(if method then val[method] else val).apply(val, args) for val in obj
|
||||
|
||||
|
||||
# Convenience version of a common use case of **map**: fetching a property.
|
||||
_.pluck = (obj, key) ->
|
||||
_.map(obj, (val) -> val[key])
|
||||
|
||||
|
||||
# Return the maximum item or (item-based computation).
|
||||
_.max = (obj, iterator, context) ->
|
||||
return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
|
||||
result = computed: -Infinity
|
||||
_.each obj, (value, index, list) ->
|
||||
computed = if iterator then iterator.call(context, value, index, list) else value
|
||||
computed >= result.computed and (result = {value: value, computed: computed})
|
||||
result.value
|
||||
|
||||
|
||||
# Return the minimum element (or element-based computation).
|
||||
_.min = (obj, iterator, context) ->
|
||||
return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
|
||||
result = computed: Infinity
|
||||
_.each obj, (value, index, list) ->
|
||||
computed = if iterator then iterator.call(context, value, index, list) else value
|
||||
computed < result.computed and (result = {value: value, computed: computed})
|
||||
result.value
|
||||
|
||||
|
||||
# Sort the object's values by a criterion produced by an iterator.
|
||||
_.sortBy = (obj, iterator, context) ->
|
||||
_.pluck(((_.map obj, (value, index, list) ->
|
||||
{value: value, criteria: iterator.call(context, value, index, list)}
|
||||
).sort((left, right) ->
|
||||
a = left.criteria; b = right.criteria
|
||||
if a < b then -1 else if a > b then 1 else 0
|
||||
)), 'value')
|
||||
|
||||
|
||||
# Use a comparator function to figure out at what index an object should
|
||||
# be inserted so as to maintain order. Uses binary search.
|
||||
_.sortedIndex = (array, obj, iterator) ->
|
||||
iterator ||= _.identity
|
||||
low = 0
|
||||
high = array.length
|
||||
while low < high
|
||||
mid = (low + high) >> 1
|
||||
if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
|
||||
low
|
||||
|
||||
|
||||
# Convert anything iterable into a real, live array.
|
||||
_.toArray = (iterable) ->
|
||||
return [] if (!iterable)
|
||||
return iterable.toArray() if (iterable.toArray)
|
||||
return iterable if (_.isArray(iterable))
|
||||
return slice.call(iterable) if (_.isArguments(iterable))
|
||||
_.values(iterable)
|
||||
|
||||
|
||||
# Return the number of elements in an object.
|
||||
_.size = (obj) -> _.toArray(obj).length
|
||||
|
||||
|
||||
# Array Functions
|
||||
# ---------------
|
||||
|
||||
# Get the first element of an array. Passing `n` will return the first N
|
||||
# values in the array. Aliased as **head**. The `guard` check allows it to work
|
||||
# with **map**.
|
||||
_.first = (array, n, guard) ->
|
||||
if n and not guard then slice.call(array, 0, n) else array[0]
|
||||
|
||||
|
||||
# Returns everything but the first entry of the array. Aliased as **tail**.
|
||||
# Especially useful on the arguments object. Passing an `index` will return
|
||||
# the rest of the values in the array from that index onward. The `guard`
|
||||
# check allows it to work with **map**.
|
||||
_.rest = (array, index, guard) ->
|
||||
slice.call(array, if _.isUndefined(index) or guard then 1 else index)
|
||||
|
||||
|
||||
# Get the last element of an array.
|
||||
_.last = (array) -> array[array.length - 1]
|
||||
|
||||
|
||||
# Trim out all falsy values from an array.
|
||||
_.compact = (array) -> item for item in array when item
|
||||
|
||||
|
||||
# Return a completely flattened version of an array.
|
||||
_.flatten = (array) ->
|
||||
_.reduce array, (memo, value) ->
|
||||
return memo.concat(_.flatten(value)) if _.isArray value
|
||||
memo.push value
|
||||
memo
|
||||
, []
|
||||
|
||||
|
||||
# Return a version of the array that does not contain the specified value(s).
|
||||
_.without = (array) ->
|
||||
values = _.rest arguments
|
||||
val for val in _.toArray(array) when not _.include values, val
|
||||
|
||||
|
||||
# Produce a duplicate-free version of the array. If the array has already
|
||||
# been sorted, you have the option of using a faster algorithm.
|
||||
_.uniq = (array, isSorted) ->
|
||||
memo = []
|
||||
for el, i in _.toArray array
|
||||
memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
|
||||
memo
|
||||
|
||||
|
||||
# Produce an array that contains every item shared between all the
|
||||
# passed-in arrays.
|
||||
_.intersect = (array) ->
|
||||
rest = _.rest arguments
|
||||
_.select _.uniq(array), (item) ->
|
||||
_.all rest, (other) ->
|
||||
_.indexOf(other, item) >= 0
|
||||
|
||||
|
||||
# Zip together multiple lists into a single array -- elements that share
|
||||
# an index go together.
|
||||
_.zip = ->
|
||||
length = _.max _.pluck arguments, 'length'
|
||||
results = new Array length
|
||||
for i in [0...length]
|
||||
results[i] = _.pluck arguments, String i
|
||||
results
|
||||
|
||||
|
||||
# If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE),
|
||||
# we need this function. Return the position of the first occurrence of an
|
||||
# item in an array, or -1 if the item is not included in the array.
|
||||
_.indexOf = (array, item) ->
|
||||
return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
|
||||
i = 0; l = array.length
|
||||
while l - i
|
||||
if array[i] is item then return i else i++
|
||||
-1
|
||||
|
||||
|
||||
# Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function,
|
||||
# if possible.
|
||||
_.lastIndexOf = (array, item) ->
|
||||
return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
|
||||
i = array.length
|
||||
while i
|
||||
if array[i] is item then return i else i--
|
||||
-1
|
||||
|
||||
|
||||
# Generate an integer Array containing an arithmetic progression. A port of
|
||||
# [the native Python **range** function](http://docs.python.org/library/functions.html#range).
|
||||
_.range = (start, stop, step) ->
|
||||
a = arguments
|
||||
solo = a.length <= 1
|
||||
i = start = if solo then 0 else a[0]
|
||||
stop = if solo then a[0] else a[1]
|
||||
step = a[2] or 1
|
||||
len = Math.ceil((stop - start) / step)
|
||||
return [] if len <= 0
|
||||
range = new Array len
|
||||
idx = 0
|
||||
loop
|
||||
return range if (if step > 0 then i - stop else stop - i) >= 0
|
||||
range[idx] = i
|
||||
idx++
|
||||
i+= step
|
||||
|
||||
|
||||
# Function Functions
|
||||
# ------------------
|
||||
|
||||
# Create a function bound to a given object (assigning `this`, and arguments,
|
||||
# optionally). Binding with arguments is also known as **curry**.
|
||||
_.bind = (func, obj) ->
|
||||
args = _.rest arguments, 2
|
||||
-> func.apply obj or root, args.concat arguments
|
||||
|
||||
|
||||
# Bind all of an object's methods to that object. Useful for ensuring that
|
||||
# all callbacks defined on an object belong to it.
|
||||
_.bindAll = (obj) ->
|
||||
funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
|
||||
_.each funcs, (f) -> obj[f] = _.bind obj[f], obj
|
||||
obj
|
||||
|
||||
|
||||
# Delays a function for the given number of milliseconds, and then calls
|
||||
# it with the arguments supplied.
|
||||
_.delay = (func, wait) ->
|
||||
args = _.rest arguments, 2
|
||||
setTimeout((-> func.apply(func, args)), wait)
|
||||
|
||||
|
||||
# Memoize an expensive function by storing its results.
|
||||
_.memoize = (func, hasher) ->
|
||||
memo = {}
|
||||
hasher or= _.identity
|
||||
->
|
||||
key = hasher.apply this, arguments
|
||||
return memo[key] if key of memo
|
||||
memo[key] = func.apply this, arguments
|
||||
|
||||
|
||||
# Defers a function, scheduling it to run after the current call stack has
|
||||
# cleared.
|
||||
_.defer = (func) ->
|
||||
_.delay.apply _, [func, 1].concat _.rest arguments
|
||||
|
||||
|
||||
# Returns the first function passed as an argument to the second,
|
||||
# allowing you to adjust arguments, run code before and after, and
|
||||
# conditionally execute the original function.
|
||||
_.wrap = (func, wrapper) ->
|
||||
-> wrapper.apply wrapper, [func].concat arguments
|
||||
|
||||
|
||||
# Returns a function that is the composition of a list of functions, each
|
||||
# consuming the return value of the function that follows.
|
||||
_.compose = ->
|
||||
funcs = arguments
|
||||
->
|
||||
args = arguments
|
||||
for i in [funcs.length - 1..0] by -1
|
||||
args = [funcs[i].apply(this, args)]
|
||||
args[0]
|
||||
|
||||
|
||||
# Object Functions
|
||||
# ----------------
|
||||
|
||||
# Retrieve the names of an object's properties.
|
||||
_.keys = nativeKeys or (obj) ->
|
||||
return _.range 0, obj.length if _.isArray(obj)
|
||||
key for key, val of obj
|
||||
|
||||
|
||||
# Retrieve the values of an object's properties.
|
||||
_.values = (obj) ->
|
||||
_.map obj, _.identity
|
||||
|
||||
|
||||
# Return a sorted list of the function names available in Underscore.
|
||||
_.functions = (obj) ->
|
||||
_.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
|
||||
|
||||
|
||||
# Extend a given object with all of the properties in a source object.
|
||||
_.extend = (obj) ->
|
||||
for source in _.rest(arguments)
|
||||
obj[key] = val for key, val of source
|
||||
obj
|
||||
|
||||
|
||||
# Create a (shallow-cloned) duplicate of an object.
|
||||
_.clone = (obj) ->
|
||||
return obj.slice 0 if _.isArray obj
|
||||
_.extend {}, obj
|
||||
|
||||
|
||||
# Invokes interceptor with the obj, and then returns obj.
|
||||
# The primary purpose of this method is to "tap into" a method chain,
|
||||
# in order to perform operations on intermediate results within
|
||||
the chain.
|
||||
_.tap = (obj, interceptor) ->
|
||||
interceptor obj
|
||||
obj
|
||||
|
||||
|
||||
# Perform a deep comparison to check if two objects are equal.
|
||||
_.isEqual = (a, b) ->
|
||||
# Check object identity.
|
||||
return true if a is b
|
||||
# Different types?
|
||||
atype = typeof(a); btype = typeof(b)
|
||||
return false if atype isnt btype
|
||||
# Basic equality test (watch out for coercions).
|
||||
return true if `a == b`
|
||||
# One is falsy and the other truthy.
|
||||
return false if (!a and b) or (a and !b)
|
||||
# One of them implements an `isEqual()`?
|
||||
return a.isEqual(b) if a.isEqual
|
||||
# Check dates' integer values.
|
||||
return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
|
||||
# Both are NaN?
|
||||
return false if _.isNaN(a) and _.isNaN(b)
|
||||
# Compare regular expressions.
|
||||
if _.isRegExp(a) and _.isRegExp(b)
|
||||
return a.source is b.source and
|
||||
a.global is b.global and
|
||||
a.ignoreCase is b.ignoreCase and
|
||||
a.multiline is b.multiline
|
||||
# If a is not an object by this point, we can't handle it.
|
||||
return false if atype isnt 'object'
|
||||
# Check for different array lengths before comparing contents.
|
||||
return false if a.length and (a.length isnt b.length)
|
||||
# Nothing else worked, deep compare the contents.
|
||||
aKeys = _.keys(a); bKeys = _.keys(b)
|
||||
# Different object sizes?
|
||||
return false if aKeys.length isnt bKeys.length
|
||||
# Recursive comparison of contents.
|
||||
return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
|
||||
true
|
||||
|
||||
|
||||
# Is a given array or object empty?
|
||||
_.isEmpty = (obj) ->
|
||||
return obj.length is 0 if _.isArray(obj) or _.isString(obj)
|
||||
return false for own key of obj
|
||||
true
|
||||
|
||||
|
||||
# Is a given value a DOM element?
|
||||
_.isElement = (obj) -> obj and obj.nodeType is 1
|
||||
|
||||
|
||||
# Is a given value an array?
|
||||
_.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
|
||||
|
||||
|
||||
# Is a given variable an arguments object?
|
||||
_.isArguments = (obj) -> obj and obj.callee
|
||||
|
||||
|
||||
# Is the given value a function?
|
||||
_.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
|
||||
|
||||
|
||||
# Is the given value a string?
|
||||
_.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
|
||||
|
||||
|
||||
# Is a given value a number?
|
||||
_.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
|
||||
|
||||
|
||||
# Is a given value a boolean?
|
||||
_.isBoolean = (obj) -> obj is true or obj is false
|
||||
|
||||
|
||||
# Is a given value a Date?
|
||||
_.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
|
||||
|
||||
|
||||
# Is the given value a regular expression?
|
||||
_.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
|
||||
|
||||
|
||||
# Is the given value NaN -- this one is interesting. `NaN != NaN`, and
|
||||
# `isNaN(undefined) == true`, so we make sure it's a number first.
|
||||
_.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj)
|
||||
|
||||
|
||||
# Is a given value equal to null?
|
||||
_.isNull = (obj) -> obj is null
|
||||
|
||||
|
||||
# Is a given variable undefined?
|
||||
_.isUndefined = (obj) -> typeof obj is 'undefined'
|
||||
|
||||
|
||||
# Utility Functions
|
||||
# -----------------
|
||||
|
||||
# Run Underscore.js in noConflict mode, returning the `_` variable to its
|
||||
# previous owner. Returns a reference to the Underscore object.
|
||||
_.noConflict = ->
|
||||
root._ = previousUnderscore
|
||||
this
|
||||
|
||||
|
||||
# Keep the identity function around for default iterators.
|
||||
_.identity = (value) -> value
|
||||
|
||||
|
||||
# Run a function `n` times.
|
||||
_.times = (n, iterator, context) ->
|
||||
iterator.call context, i for i in [0...n]
|
||||
|
||||
|
||||
# Break out of the middle of an iteration.
|
||||
_.breakLoop = -> throw breaker
|
||||
|
||||
|
||||
# Add your own custom functions to the Underscore object, ensuring that
|
||||
# they're correctly added to the OOP wrapper as well.
|
||||
_.mixin = (obj) ->
|
||||
for name in _.functions(obj)
|
||||
addToWrapper name, _[name] = obj[name]
|
||||
|
||||
|
||||
# Generate a unique integer id (unique within the entire client session).
|
||||
# Useful for temporary DOM ids.
|
||||
idCounter = 0
|
||||
_.uniqueId = (prefix) ->
|
||||
(prefix or '') + idCounter++
|
||||
|
||||
|
||||
# By default, Underscore uses **ERB**-style template delimiters, change the
|
||||
# following template settings to use alternative delimiters.
|
||||
_.templateSettings = {
|
||||
start: '<%'
|
||||
end: '%>'
|
||||
interpolate: /<%=(.+?)%>/g
|
||||
}
|
||||
|
||||
|
||||
# JavaScript templating a-la **ERB**, pilfered from John Resig's
|
||||
# *Secrets of the JavaScript Ninja*, page 83.
|
||||
# Single-quote fix from Rick Strahl.
|
||||
# With alterations for arbitrary delimiters, and to preserve whitespace.
|
||||
_.template = (str, data) ->
|
||||
c = _.templateSettings
|
||||
endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
|
||||
fn = new Function 'obj',
|
||||
'var p=[],print=function(){p.push.apply(p,arguments);};' +
|
||||
'with(obj||{}){p.push(\'' +
|
||||
str.replace(/\r/g, '\\r')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\t/g, '\\t')
|
||||
.replace(endMatch,"<22><><EFBFBD>")
|
||||
.split("'").join("\\'")
|
||||
.split("<22><><EFBFBD>").join("'")
|
||||
.replace(c.interpolate, "',$1,'")
|
||||
.split(c.start).join("');")
|
||||
.split(c.end).join("p.push('") +
|
||||
"');}return p.join('');"
|
||||
if data then fn(data) else fn
|
||||
|
||||
|
||||
# Aliases
|
||||
# -------
|
||||
|
||||
_.forEach = _.each
|
||||
_.foldl = _.inject = _.reduce
|
||||
_.foldr = _.reduceRight
|
||||
_.select = _.filter
|
||||
_.all = _.every
|
||||
_.any = _.some
|
||||
_.contains = _.include
|
||||
_.head = _.first
|
||||
_.tail = _.rest
|
||||
_.methods = _.functions
|
||||
|
||||
|
||||
# Setup the OOP Wrapper
|
||||
# ---------------------
|
||||
|
||||
# If Underscore is called as a function, it returns a wrapped object that
|
||||
# can be used OO-style. This wrapper holds altered versions of all the
|
||||
# underscore functions. Wrapped objects may be chained.
|
||||
wrapper = (obj) ->
|
||||
this._wrapped = obj
|
||||
this
|
||||
|
||||
|
||||
# Helper function to continue chaining intermediate results.
|
||||
result = (obj, chain) ->
|
||||
if chain then _(obj).chain() else obj
|
||||
|
||||
|
||||
# A method to easily add functions to the OOP wrapper.
|
||||
addToWrapper = (name, func) ->
|
||||
wrapper.prototype[name] = ->
|
||||
args = _.toArray arguments
|
||||
unshift.call args, this._wrapped
|
||||
result func.apply(_, args), this._chain
|
||||
|
||||
|
||||
# Add all ofthe Underscore functions to the wrapper object.
|
||||
_.mixin _
|
||||
|
||||
|
||||
# Add all mutator Array functions to the wrapper.
|
||||
_.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
|
||||
method = Array.prototype[name]
|
||||
wrapper.prototype[name] = ->
|
||||
method.apply(this._wrapped, arguments)
|
||||
result(this._wrapped, this._chain)
|
||||
|
||||
|
||||
# Add all accessor Array functions to the wrapper.
|
||||
_.each ['concat', 'join', 'slice'], (name) ->
|
||||
method = Array.prototype[name]
|
||||
wrapper.prototype[name] = ->
|
||||
result(method.apply(this._wrapped, arguments), this._chain)
|
||||
|
||||
|
||||
# Start chaining a wrapped Underscore object.
|
||||
wrapper::chain = ->
|
||||
this._chain = true
|
||||
this
|
||||
|
||||
|
||||
# Extracts the result from a wrapped and chained object.
|
||||
wrapper::value = -> this._wrapped
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-coffeescript</code>.</p>
|
||||
|
||||
<p>The CoffeeScript mode was written by Jeff Pickhardt.</p>
|
||||
|
||||
</article>
|
@ -1,120 +0,0 @@
|
||||
// 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("commonlisp", function (config) {
|
||||
var assumeBody = /^with|^def|^do|^prog|case$|^cond$|bind$|when$|unless$/;
|
||||
var numLiteral = /^(?:[+\-]?(?:\d+|\d*\.\d+)(?:[efd][+\-]?\d+)?|[+\-]?\d+(?:\/[+\-]?\d+)?|#b[+\-]?[01]+|#o[+\-]?[0-7]+|#x[+\-]?[\da-f]+)/;
|
||||
var symbol = /[^\s'`,@()\[\]";]/;
|
||||
var type;
|
||||
|
||||
function readSym(stream) {
|
||||
var ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "\\") stream.next();
|
||||
else if (!symbol.test(ch)) { stream.backUp(1); break; }
|
||||
}
|
||||
return stream.current();
|
||||
}
|
||||
|
||||
function base(stream, state) {
|
||||
if (stream.eatSpace()) {type = "ws"; return null;}
|
||||
if (stream.match(numLiteral)) return "number";
|
||||
var ch = stream.next();
|
||||
if (ch == "\\") ch = stream.next();
|
||||
|
||||
if (ch == '"') return (state.tokenize = inString)(stream, state);
|
||||
else if (ch == "(") { type = "open"; return "bracket"; }
|
||||
else if (ch == ")" || ch == "]") { type = "close"; return "bracket"; }
|
||||
else if (ch == ";") { stream.skipToEnd(); type = "ws"; return "comment"; }
|
||||
else if (/['`,@]/.test(ch)) return null;
|
||||
else if (ch == "|") {
|
||||
if (stream.skipTo("|")) { stream.next(); return "symbol"; }
|
||||
else { stream.skipToEnd(); return "error"; }
|
||||
} else if (ch == "#") {
|
||||
var ch = stream.next();
|
||||
if (ch == "[") { type = "open"; return "bracket"; }
|
||||
else if (/[+\-=\.']/.test(ch)) return null;
|
||||
else if (/\d/.test(ch) && stream.match(/^\d*#/)) return null;
|
||||
else if (ch == "|") return (state.tokenize = inComment)(stream, state);
|
||||
else if (ch == ":") { readSym(stream); return "meta"; }
|
||||
else return "error";
|
||||
} else {
|
||||
var name = readSym(stream);
|
||||
if (name == ".") return null;
|
||||
type = "symbol";
|
||||
if (name == "nil" || name == "t") return "atom";
|
||||
if (name.charAt(0) == ":") return "keyword";
|
||||
if (name.charAt(0) == "&") return "variable-2";
|
||||
return "variable";
|
||||
}
|
||||
}
|
||||
|
||||
function inString(stream, state) {
|
||||
var escaped = false, next;
|
||||
while (next = stream.next()) {
|
||||
if (next == '"' && !escaped) { state.tokenize = base; break; }
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return "string";
|
||||
}
|
||||
|
||||
function inComment(stream, state) {
|
||||
var next, last;
|
||||
while (next = stream.next()) {
|
||||
if (next == "#" && last == "|") { state.tokenize = base; break; }
|
||||
last = next;
|
||||
}
|
||||
type = "ws";
|
||||
return "comment";
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function () {
|
||||
return {ctx: {prev: null, start: 0, indentTo: 0}, tokenize: base};
|
||||
},
|
||||
|
||||
token: function (stream, state) {
|
||||
if (stream.sol() && typeof state.ctx.indentTo != "number")
|
||||
state.ctx.indentTo = state.ctx.start + 1;
|
||||
|
||||
type = null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (type != "ws") {
|
||||
if (state.ctx.indentTo == null) {
|
||||
if (type == "symbol" && assumeBody.test(stream.current()))
|
||||
state.ctx.indentTo = state.ctx.start + config.indentUnit;
|
||||
else
|
||||
state.ctx.indentTo = "next";
|
||||
} else if (state.ctx.indentTo == "next") {
|
||||
state.ctx.indentTo = stream.column();
|
||||
}
|
||||
}
|
||||
if (type == "open") state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null};
|
||||
else if (type == "close") state.ctx = state.ctx.prev || state.ctx;
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function (state, _textAfter) {
|
||||
var i = state.ctx.indentTo;
|
||||
return typeof i == "number" ? i : state.ctx.start + 1;
|
||||
},
|
||||
|
||||
lineComment: ";;",
|
||||
blockCommentStart: "#|",
|
||||
blockCommentEnd: "|#"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-common-lisp", "commonlisp");
|
||||
|
||||
});
|
@ -1,177 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Common Lisp mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="commonlisp.js"></script>
|
||||
<style>.CodeMirror {background: #f8f8f8;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Common Lisp</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Common Lisp mode</h2>
|
||||
<form><textarea id="code" name="code">(in-package :cl-postgres)
|
||||
|
||||
;; These are used to synthesize reader and writer names for integer
|
||||
;; reading/writing functions when the amount of bytes and the
|
||||
;; signedness is known. Both the macro that creates the functions and
|
||||
;; some macros that use them create names this way.
|
||||
(eval-when (:compile-toplevel :load-toplevel :execute)
|
||||
(defun integer-reader-name (bytes signed)
|
||||
(intern (with-standard-io-syntax
|
||||
(format nil "~a~a~a~a" '#:read- (if signed "" '#:u) '#:int bytes))))
|
||||
(defun integer-writer-name (bytes signed)
|
||||
(intern (with-standard-io-syntax
|
||||
(format nil "~a~a~a~a" '#:write- (if signed "" '#:u) '#:int bytes)))))
|
||||
|
||||
(defmacro integer-reader (bytes)
|
||||
"Create a function to read integers from a binary stream."
|
||||
(let ((bits (* bytes 8)))
|
||||
(labels ((return-form (signed)
|
||||
(if signed
|
||||
`(if (logbitp ,(1- bits) result)
|
||||
(dpb result (byte ,(1- bits) 0) -1)
|
||||
result)
|
||||
`result))
|
||||
(generate-reader (signed)
|
||||
`(defun ,(integer-reader-name bytes signed) (socket)
|
||||
(declare (type stream socket)
|
||||
#.*optimize*)
|
||||
,(if (= bytes 1)
|
||||
`(let ((result (the (unsigned-byte 8) (read-byte socket))))
|
||||
(declare (type (unsigned-byte 8) result))
|
||||
,(return-form signed))
|
||||
`(let ((result 0))
|
||||
(declare (type (unsigned-byte ,bits) result))
|
||||
,@(loop :for byte :from (1- bytes) :downto 0
|
||||
:collect `(setf (ldb (byte 8 ,(* 8 byte)) result)
|
||||
(the (unsigned-byte 8) (read-byte socket))))
|
||||
,(return-form signed))))))
|
||||
`(progn
|
||||
;; This causes weird errors on SBCL in some circumstances. Disabled for now.
|
||||
;; (declaim (inline ,(integer-reader-name bytes t)
|
||||
;; ,(integer-reader-name bytes nil)))
|
||||
(declaim (ftype (function (t) (signed-byte ,bits))
|
||||
,(integer-reader-name bytes t)))
|
||||
,(generate-reader t)
|
||||
(declaim (ftype (function (t) (unsigned-byte ,bits))
|
||||
,(integer-reader-name bytes nil)))
|
||||
,(generate-reader nil)))))
|
||||
|
||||
(defmacro integer-writer (bytes)
|
||||
"Create a function to write integers to a binary stream."
|
||||
(let ((bits (* 8 bytes)))
|
||||
`(progn
|
||||
(declaim (inline ,(integer-writer-name bytes t)
|
||||
,(integer-writer-name bytes nil)))
|
||||
(defun ,(integer-writer-name bytes nil) (socket value)
|
||||
(declare (type stream socket)
|
||||
(type (unsigned-byte ,bits) value)
|
||||
#.*optimize*)
|
||||
,@(if (= bytes 1)
|
||||
`((write-byte value socket))
|
||||
(loop :for byte :from (1- bytes) :downto 0
|
||||
:collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
|
||||
socket)))
|
||||
(values))
|
||||
(defun ,(integer-writer-name bytes t) (socket value)
|
||||
(declare (type stream socket)
|
||||
(type (signed-byte ,bits) value)
|
||||
#.*optimize*)
|
||||
,@(if (= bytes 1)
|
||||
`((write-byte (ldb (byte 8 0) value) socket))
|
||||
(loop :for byte :from (1- bytes) :downto 0
|
||||
:collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
|
||||
socket)))
|
||||
(values)))))
|
||||
|
||||
;; All the instances of the above that we need.
|
||||
|
||||
(integer-reader 1)
|
||||
(integer-reader 2)
|
||||
(integer-reader 4)
|
||||
(integer-reader 8)
|
||||
|
||||
(integer-writer 1)
|
||||
(integer-writer 2)
|
||||
(integer-writer 4)
|
||||
|
||||
(defun write-bytes (socket bytes)
|
||||
"Write a byte-array to a stream."
|
||||
(declare (type stream socket)
|
||||
(type (simple-array (unsigned-byte 8)) bytes)
|
||||
#.*optimize*)
|
||||
(write-sequence bytes socket))
|
||||
|
||||
(defun write-str (socket string)
|
||||
"Write a null-terminated string to a stream \(encoding it when UTF-8
|
||||
support is enabled.)."
|
||||
(declare (type stream socket)
|
||||
(type string string)
|
||||
#.*optimize*)
|
||||
(enc-write-string string socket)
|
||||
(write-uint1 socket 0))
|
||||
|
||||
(declaim (ftype (function (t unsigned-byte)
|
||||
(simple-array (unsigned-byte 8) (*)))
|
||||
read-bytes))
|
||||
(defun read-bytes (socket length)
|
||||
"Read a byte array of the given length from a stream."
|
||||
(declare (type stream socket)
|
||||
(type fixnum length)
|
||||
#.*optimize*)
|
||||
(let ((result (make-array length :element-type '(unsigned-byte 8))))
|
||||
(read-sequence result socket)
|
||||
result))
|
||||
|
||||
(declaim (ftype (function (t) string) read-str))
|
||||
(defun read-str (socket)
|
||||
"Read a null-terminated string from a stream. Takes care of encoding
|
||||
when UTF-8 support is enabled."
|
||||
(declare (type stream socket)
|
||||
#.*optimize*)
|
||||
(enc-read-string socket :null-terminated t))
|
||||
|
||||
(defun skip-bytes (socket length)
|
||||
"Skip a given number of bytes in a binary stream."
|
||||
(declare (type stream socket)
|
||||
(type (unsigned-byte 32) length)
|
||||
#.*optimize*)
|
||||
(dotimes (i length)
|
||||
(read-byte socket)))
|
||||
|
||||
(defun skip-str (socket)
|
||||
"Skip a null-terminated string."
|
||||
(declare (type stream socket)
|
||||
#.*optimize*)
|
||||
(loop :for char :of-type fixnum = (read-byte socket)
|
||||
:until (zerop char)))
|
||||
|
||||
(defun ensure-socket-is-closed (socket &key abort)
|
||||
(when (open-stream-p socket)
|
||||
(handler-case
|
||||
(close socket :abort abort)
|
||||
(error (error)
|
||||
(warn "Ignoring the error which happened while trying to close PostgreSQL socket: ~A" error)))))
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {lineNumbers: true});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-common-lisp</code>.</p>
|
||||
|
||||
</article>
|
@ -1,717 +0,0 @@
|
||||
// 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("css", function(config, parserConfig) {
|
||||
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
|
||||
|
||||
var indentUnit = config.indentUnit,
|
||||
tokenHooks = parserConfig.tokenHooks,
|
||||
mediaTypes = parserConfig.mediaTypes || {},
|
||||
mediaFeatures = parserConfig.mediaFeatures || {},
|
||||
propertyKeywords = parserConfig.propertyKeywords || {},
|
||||
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
|
||||
colorKeywords = parserConfig.colorKeywords || {},
|
||||
valueKeywords = parserConfig.valueKeywords || {},
|
||||
fontProperties = parserConfig.fontProperties || {},
|
||||
allowNested = parserConfig.allowNested;
|
||||
|
||||
var type, override;
|
||||
function ret(style, tp) { type = tp; return style; }
|
||||
|
||||
// Tokenizers
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (tokenHooks[ch]) {
|
||||
var result = tokenHooks[ch](stream, state);
|
||||
if (result !== false) return result;
|
||||
}
|
||||
if (ch == "@") {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("def", stream.current());
|
||||
} else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
|
||||
return ret(null, "compare");
|
||||
} else if (ch == "\"" || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
} else if (ch == "#") {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("atom", "hash");
|
||||
} else if (ch == "!") {
|
||||
stream.match(/^\s*\w*/);
|
||||
return ret("keyword", "important");
|
||||
} else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
|
||||
stream.eatWhile(/[\w.%]/);
|
||||
return ret("number", "unit");
|
||||
} else if (ch === "-") {
|
||||
if (/[\d.]/.test(stream.peek())) {
|
||||
stream.eatWhile(/[\w.%]/);
|
||||
return ret("number", "unit");
|
||||
} else if (stream.match(/^\w+-/)) {
|
||||
return ret("meta", "meta");
|
||||
}
|
||||
} else if (/[,+>*\/]/.test(ch)) {
|
||||
return ret(null, "select-op");
|
||||
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
||||
return ret("qualifier", "qualifier");
|
||||
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
|
||||
return ret(null, ch);
|
||||
} else if (ch == "u" && stream.match("rl(")) {
|
||||
stream.backUp(1);
|
||||
state.tokenize = tokenParenthesized;
|
||||
return ret("property", "word");
|
||||
} else if (/[\w\\\-]/.test(ch)) {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("property", "word");
|
||||
} else {
|
||||
return ret(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == quote && !escaped) {
|
||||
if (quote == ")") stream.backUp(1);
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
if (ch == quote || !escaped && quote != ")") state.tokenize = null;
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
|
||||
function tokenParenthesized(stream, state) {
|
||||
stream.next(); // Must be '('
|
||||
if (!stream.match(/\s*[\"\')]/, false))
|
||||
state.tokenize = tokenString(")");
|
||||
else
|
||||
state.tokenize = null;
|
||||
return ret(null, "(");
|
||||
}
|
||||
|
||||
// Context management
|
||||
|
||||
function Context(type, indent, prev) {
|
||||
this.type = type;
|
||||
this.indent = indent;
|
||||
this.prev = prev;
|
||||
}
|
||||
|
||||
function pushContext(state, stream, type) {
|
||||
state.context = new Context(type, stream.indentation() + indentUnit, state.context);
|
||||
return type;
|
||||
}
|
||||
|
||||
function popContext(state) {
|
||||
state.context = state.context.prev;
|
||||
return state.context.type;
|
||||
}
|
||||
|
||||
function pass(type, stream, state) {
|
||||
return states[state.context.type](type, stream, state);
|
||||
}
|
||||
function popAndPass(type, stream, state, n) {
|
||||
for (var i = n || 1; i > 0; i--)
|
||||
state.context = state.context.prev;
|
||||
return pass(type, stream, state);
|
||||
}
|
||||
|
||||
// Parser
|
||||
|
||||
function wordAsValue(stream) {
|
||||
var word = stream.current().toLowerCase();
|
||||
if (valueKeywords.hasOwnProperty(word))
|
||||
override = "atom";
|
||||
else if (colorKeywords.hasOwnProperty(word))
|
||||
override = "keyword";
|
||||
else
|
||||
override = "variable";
|
||||
}
|
||||
|
||||
var states = {};
|
||||
|
||||
states.top = function(type, stream, state) {
|
||||
if (type == "{") {
|
||||
return pushContext(state, stream, "block");
|
||||
} else if (type == "}" && state.context.prev) {
|
||||
return popContext(state);
|
||||
} else if (type == "@media") {
|
||||
return pushContext(state, stream, "media");
|
||||
} else if (type == "@font-face") {
|
||||
return "font_face_before";
|
||||
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
|
||||
return "keyframes";
|
||||
} else if (type && type.charAt(0) == "@") {
|
||||
return pushContext(state, stream, "at");
|
||||
} else if (type == "hash") {
|
||||
override = "builtin";
|
||||
} else if (type == "word") {
|
||||
override = "tag";
|
||||
} else if (type == "variable-definition") {
|
||||
return "maybeprop";
|
||||
} else if (type == "interpolation") {
|
||||
return pushContext(state, stream, "interpolation");
|
||||
} else if (type == ":") {
|
||||
return "pseudo";
|
||||
} else if (allowNested && type == "(") {
|
||||
return pushContext(state, stream, "parens");
|
||||
}
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.block = function(type, stream, state) {
|
||||
if (type == "word") {
|
||||
var word = stream.current().toLowerCase();
|
||||
if (propertyKeywords.hasOwnProperty(word)) {
|
||||
override = "property";
|
||||
return "maybeprop";
|
||||
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
|
||||
override = "string-2";
|
||||
return "maybeprop";
|
||||
} else if (allowNested) {
|
||||
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
|
||||
return "block";
|
||||
} else {
|
||||
override += " error";
|
||||
return "maybeprop";
|
||||
}
|
||||
} else if (type == "meta") {
|
||||
return "block";
|
||||
} else if (!allowNested && (type == "hash" || type == "qualifier")) {
|
||||
override = "error";
|
||||
return "block";
|
||||
} else {
|
||||
return states.top(type, stream, state);
|
||||
}
|
||||
};
|
||||
|
||||
states.maybeprop = function(type, stream, state) {
|
||||
if (type == ":") return pushContext(state, stream, "prop");
|
||||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.prop = function(type, stream, state) {
|
||||
if (type == ";") return popContext(state);
|
||||
if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
|
||||
if (type == "}" || type == "{") return popAndPass(type, stream, state);
|
||||
if (type == "(") return pushContext(state, stream, "parens");
|
||||
|
||||
if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
||||
override += " error";
|
||||
} else if (type == "word") {
|
||||
wordAsValue(stream);
|
||||
} else if (type == "interpolation") {
|
||||
return pushContext(state, stream, "interpolation");
|
||||
}
|
||||
return "prop";
|
||||
};
|
||||
|
||||
states.propBlock = function(type, _stream, state) {
|
||||
if (type == "}") return popContext(state);
|
||||
if (type == "word") { override = "property"; return "maybeprop"; }
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.parens = function(type, stream, state) {
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
||||
if (type == ")") return popContext(state);
|
||||
if (type == "(") return pushContext(state, stream, "parens");
|
||||
if (type == "word") wordAsValue(stream);
|
||||
return "parens";
|
||||
};
|
||||
|
||||
states.pseudo = function(type, stream, state) {
|
||||
if (type == "word") {
|
||||
override = "variable-3";
|
||||
return state.context.type;
|
||||
}
|
||||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.media = function(type, stream, state) {
|
||||
if (type == "(") return pushContext(state, stream, "media_parens");
|
||||
if (type == "}") return popAndPass(type, stream, state);
|
||||
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
|
||||
|
||||
if (type == "word") {
|
||||
var word = stream.current().toLowerCase();
|
||||
if (word == "only" || word == "not" || word == "and")
|
||||
override = "keyword";
|
||||
else if (mediaTypes.hasOwnProperty(word))
|
||||
override = "attribute";
|
||||
else if (mediaFeatures.hasOwnProperty(word))
|
||||
override = "property";
|
||||
else
|
||||
override = "error";
|
||||
}
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.media_parens = function(type, stream, state) {
|
||||
if (type == ")") return popContext(state);
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
|
||||
return states.media(type, stream, state);
|
||||
};
|
||||
|
||||
states.font_face_before = function(type, stream, state) {
|
||||
if (type == "{")
|
||||
return pushContext(state, stream, "font_face");
|
||||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.font_face = function(type, stream, state) {
|
||||
if (type == "}") return popContext(state);
|
||||
if (type == "word") {
|
||||
if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
|
||||
override = "error";
|
||||
else
|
||||
override = "property";
|
||||
return "maybeprop";
|
||||
}
|
||||
return "font_face";
|
||||
};
|
||||
|
||||
states.keyframes = function(type, stream, state) {
|
||||
if (type == "word") { override = "variable"; return "keyframes"; }
|
||||
if (type == "{") return pushContext(state, stream, "top");
|
||||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.at = function(type, stream, state) {
|
||||
if (type == ";") return popContext(state);
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
||||
if (type == "word") override = "tag";
|
||||
else if (type == "hash") override = "builtin";
|
||||
return "at";
|
||||
};
|
||||
|
||||
states.interpolation = function(type, stream, state) {
|
||||
if (type == "}") return popContext(state);
|
||||
if (type == "{" || type == ";") return popAndPass(type, stream, state);
|
||||
if (type != "variable") override = "error";
|
||||
return "interpolation";
|
||||
};
|
||||
|
||||
return {
|
||||
startState: function(base) {
|
||||
return {tokenize: null,
|
||||
state: "top",
|
||||
context: new Context("top", base || 0, null)};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (!state.tokenize && stream.eatSpace()) return null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style && typeof style == "object") {
|
||||
type = style[1];
|
||||
style = style[0];
|
||||
}
|
||||
override = style;
|
||||
state.state = states[state.state](type, stream, state);
|
||||
return override;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
var cx = state.context, ch = textAfter && textAfter.charAt(0);
|
||||
var indent = cx.indent;
|
||||
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
|
||||
if (cx.prev &&
|
||||
(ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
|
||||
ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
|
||||
ch == "{" && (cx.type == "at" || cx.type == "media"))) {
|
||||
indent = cx.indent - indentUnit;
|
||||
cx = cx.prev;
|
||||
}
|
||||
return indent;
|
||||
},
|
||||
|
||||
electricChars: "}",
|
||||
blockCommentStart: "/*",
|
||||
blockCommentEnd: "*/",
|
||||
fold: "brace"
|
||||
};
|
||||
});
|
||||
|
||||
function keySet(array) {
|
||||
var keys = {};
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
keys[array[i]] = true;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
var mediaTypes_ = [
|
||||
"all", "aural", "braille", "handheld", "print", "projection", "screen",
|
||||
"tty", "tv", "embossed"
|
||||
], mediaTypes = keySet(mediaTypes_);
|
||||
|
||||
var mediaFeatures_ = [
|
||||
"width", "min-width", "max-width", "height", "min-height", "max-height",
|
||||
"device-width", "min-device-width", "max-device-width", "device-height",
|
||||
"min-device-height", "max-device-height", "aspect-ratio",
|
||||
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
|
||||
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
|
||||
"max-color", "color-index", "min-color-index", "max-color-index",
|
||||
"monochrome", "min-monochrome", "max-monochrome", "resolution",
|
||||
"min-resolution", "max-resolution", "scan", "grid"
|
||||
], mediaFeatures = keySet(mediaFeatures_);
|
||||
|
||||
var propertyKeywords_ = [
|
||||
"align-content", "align-items", "align-self", "alignment-adjust",
|
||||
"alignment-baseline", "anchor-point", "animation", "animation-delay",
|
||||
"animation-direction", "animation-duration", "animation-fill-mode",
|
||||
"animation-iteration-count", "animation-name", "animation-play-state",
|
||||
"animation-timing-function", "appearance", "azimuth", "backface-visibility",
|
||||
"background", "background-attachment", "background-clip", "background-color",
|
||||
"background-image", "background-origin", "background-position",
|
||||
"background-repeat", "background-size", "baseline-shift", "binding",
|
||||
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
|
||||
"bookmark-target", "border", "border-bottom", "border-bottom-color",
|
||||
"border-bottom-left-radius", "border-bottom-right-radius",
|
||||
"border-bottom-style", "border-bottom-width", "border-collapse",
|
||||
"border-color", "border-image", "border-image-outset",
|
||||
"border-image-repeat", "border-image-slice", "border-image-source",
|
||||
"border-image-width", "border-left", "border-left-color",
|
||||
"border-left-style", "border-left-width", "border-radius", "border-right",
|
||||
"border-right-color", "border-right-style", "border-right-width",
|
||||
"border-spacing", "border-style", "border-top", "border-top-color",
|
||||
"border-top-left-radius", "border-top-right-radius", "border-top-style",
|
||||
"border-top-width", "border-width", "bottom", "box-decoration-break",
|
||||
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
|
||||
"caption-side", "clear", "clip", "color", "color-profile", "column-count",
|
||||
"column-fill", "column-gap", "column-rule", "column-rule-color",
|
||||
"column-rule-style", "column-rule-width", "column-span", "column-width",
|
||||
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
|
||||
"cue-after", "cue-before", "cursor", "direction", "display",
|
||||
"dominant-baseline", "drop-initial-after-adjust",
|
||||
"drop-initial-after-align", "drop-initial-before-adjust",
|
||||
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
|
||||
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
|
||||
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
|
||||
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
|
||||
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
|
||||
"font-stretch", "font-style", "font-synthesis", "font-variant",
|
||||
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
|
||||
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
|
||||
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
|
||||
"grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
|
||||
"grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
|
||||
"grid-template", "grid-template-areas", "grid-template-columns",
|
||||
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
|
||||
"icon", "image-orientation", "image-rendering", "image-resolution",
|
||||
"inline-box-align", "justify-content", "left", "letter-spacing",
|
||||
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
|
||||
"line-stacking-shift", "line-stacking-strategy", "list-style",
|
||||
"list-style-image", "list-style-position", "list-style-type", "margin",
|
||||
"margin-bottom", "margin-left", "margin-right", "margin-top",
|
||||
"marker-offset", "marks", "marquee-direction", "marquee-loop",
|
||||
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
|
||||
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
|
||||
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
|
||||
"opacity", "order", "orphans", "outline",
|
||||
"outline-color", "outline-offset", "outline-style", "outline-width",
|
||||
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
|
||||
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
|
||||
"page", "page-break-after", "page-break-before", "page-break-inside",
|
||||
"page-policy", "pause", "pause-after", "pause-before", "perspective",
|
||||
"perspective-origin", "pitch", "pitch-range", "play-during", "position",
|
||||
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
|
||||
"region-break-before", "region-break-inside", "region-fragment",
|
||||
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
|
||||
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
|
||||
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
|
||||
"shape-outside", "size", "speak", "speak-as", "speak-header",
|
||||
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
|
||||
"tab-size", "table-layout", "target", "target-name", "target-new",
|
||||
"target-position", "text-align", "text-align-last", "text-decoration",
|
||||
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
|
||||
"text-decoration-style", "text-emphasis", "text-emphasis-color",
|
||||
"text-emphasis-position", "text-emphasis-style", "text-height",
|
||||
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
|
||||
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
|
||||
"text-wrap", "top", "transform", "transform-origin", "transform-style",
|
||||
"transition", "transition-delay", "transition-duration",
|
||||
"transition-property", "transition-timing-function", "unicode-bidi",
|
||||
"vertical-align", "visibility", "voice-balance", "voice-duration",
|
||||
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
|
||||
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
|
||||
"word-spacing", "word-wrap", "z-index",
|
||||
// SVG-specific
|
||||
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
|
||||
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
|
||||
"color-interpolation", "color-interpolation-filters",
|
||||
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
|
||||
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
|
||||
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
|
||||
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
|
||||
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
|
||||
"glyph-orientation-vertical", "text-anchor", "writing-mode"
|
||||
], propertyKeywords = keySet(propertyKeywords_);
|
||||
|
||||
var nonStandardPropertyKeywords_ = [
|
||||
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
|
||||
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
|
||||
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
|
||||
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
|
||||
"searchfield-results-decoration", "zoom"
|
||||
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
|
||||
|
||||
var colorKeywords_ = [
|
||||
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
|
||||
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
|
||||
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
|
||||
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
|
||||
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
|
||||
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
|
||||
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
|
||||
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
|
||||
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
|
||||
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
|
||||
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
|
||||
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
|
||||
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
|
||||
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
|
||||
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
|
||||
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
|
||||
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
|
||||
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
|
||||
"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
|
||||
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
|
||||
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
|
||||
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
|
||||
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
|
||||
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
|
||||
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
|
||||
"whitesmoke", "yellow", "yellowgreen"
|
||||
], colorKeywords = keySet(colorKeywords_);
|
||||
|
||||
var valueKeywords_ = [
|
||||
"above", "absolute", "activeborder", "activecaption", "afar",
|
||||
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
|
||||
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
||||
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
|
||||
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
|
||||
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
|
||||
"both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
|
||||
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
|
||||
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
||||
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
|
||||
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
||||
"col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
|
||||
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
|
||||
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
|
||||
"decimal-leading-zero", "default", "default-button", "destination-atop",
|
||||
"destination-in", "destination-out", "destination-over", "devanagari",
|
||||
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
|
||||
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
||||
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
|
||||
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
|
||||
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
|
||||
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
|
||||
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
|
||||
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
|
||||
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
|
||||
"ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
|
||||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
|
||||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
|
||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
|
||||
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
|
||||
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
||||
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
||||
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
|
||||
"italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
|
||||
"landscape", "lao", "large", "larger", "left", "level", "lighter",
|
||||
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
|
||||
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
|
||||
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
|
||||
"lower-roman", "lowercase", "ltr", "malayalam", "match",
|
||||
"media-controls-background", "media-current-time-display",
|
||||
"media-fullscreen-button", "media-mute-button", "media-play-button",
|
||||
"media-return-to-realtime-button", "media-rewind-button",
|
||||
"media-seek-back-button", "media-seek-forward-button", "media-slider",
|
||||
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
|
||||
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
|
||||
"menu", "menulist", "menulist-button", "menulist-text",
|
||||
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
|
||||
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
|
||||
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
|
||||
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
|
||||
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
|
||||
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
|
||||
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
|
||||
"painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
|
||||
"polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
|
||||
"radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
|
||||
"relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
|
||||
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
|
||||
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
|
||||
"searchfield-cancel-button", "searchfield-decoration",
|
||||
"searchfield-results-button", "searchfield-results-decoration",
|
||||
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
|
||||
"single", "skip-white-space", "slide", "slider-horizontal",
|
||||
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
||||
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
|
||||
"source-atop", "source-in", "source-out", "source-over", "space", "square",
|
||||
"square-button", "start", "static", "status-bar", "stretch", "stroke",
|
||||
"sub", "subpixel-antialiased", "super", "sw-resize", "table",
|
||||
"table-caption", "table-cell", "table-column", "table-column-group",
|
||||
"table-footer-group", "table-header-group", "table-row", "table-row-group",
|
||||
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
|
||||
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
|
||||
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
|
||||
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
|
||||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
|
||||
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
|
||||
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
||||
"vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
||||
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
|
||||
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
|
||||
"xx-large", "xx-small"
|
||||
], valueKeywords = keySet(valueKeywords_);
|
||||
|
||||
var fontProperties_ = [
|
||||
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
|
||||
"font-stretch", "font-weight", "font-style"
|
||||
], fontProperties = keySet(fontProperties_);
|
||||
|
||||
var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_)
|
||||
.concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
|
||||
CodeMirror.registerHelper("hintWords", "css", allWords);
|
||||
|
||||
function tokenCComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (maybeEnd && ch == "/") {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ["comment", "comment"];
|
||||
}
|
||||
|
||||
function tokenSGMLComment(stream, state) {
|
||||
if (stream.skipTo("-->")) {
|
||||
stream.match("-->");
|
||||
state.tokenize = null;
|
||||
} else {
|
||||
stream.skipToEnd();
|
||||
}
|
||||
return ["comment", "comment"];
|
||||
}
|
||||
|
||||
CodeMirror.defineMIME("text/css", {
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
tokenHooks: {
|
||||
"<": function(stream, state) {
|
||||
if (!stream.match("!--")) return false;
|
||||
state.tokenize = tokenSGMLComment;
|
||||
return tokenSGMLComment(stream, state);
|
||||
},
|
||||
"/": function(stream, state) {
|
||||
if (!stream.eat("*")) return false;
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
}
|
||||
},
|
||||
name: "css"
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-scss", {
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ["comment", "comment"];
|
||||
} else if (stream.eat("*")) {
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
} else {
|
||||
return ["operator", "operator"];
|
||||
}
|
||||
},
|
||||
":": function(stream) {
|
||||
if (stream.match(/\s*\{/))
|
||||
return [null, "{"];
|
||||
return false;
|
||||
},
|
||||
"$": function(stream) {
|
||||
stream.match(/^[\w-]+/);
|
||||
if (stream.match(/^\s*:/, false))
|
||||
return ["variable-2", "variable-definition"];
|
||||
return ["variable-2", "variable"];
|
||||
},
|
||||
"#": function(stream) {
|
||||
if (!stream.eat("{")) return false;
|
||||
return [null, "interpolation"];
|
||||
}
|
||||
},
|
||||
name: "css",
|
||||
helperType: "scss"
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-less", {
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ["comment", "comment"];
|
||||
} else if (stream.eat("*")) {
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
} else {
|
||||
return ["operator", "operator"];
|
||||
}
|
||||
},
|
||||
"@": function(stream) {
|
||||
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
if (stream.match(/^\s*:/, false))
|
||||
return ["variable-2", "variable-definition"];
|
||||
return ["variable-2", "variable"];
|
||||
},
|
||||
"&": function() {
|
||||
return ["atom", "atom"];
|
||||
}
|
||||
},
|
||||
name: "css",
|
||||
helperType: "less"
|
||||
});
|
||||
|
||||
});
|
@ -1,70 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: CSS mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="css.js"></script>
|
||||
<style>.CodeMirror {background: #f8f8f8;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">CSS</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>CSS mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
/* Some example CSS */
|
||||
|
||||
@import url("something.css");
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 3em 6em;
|
||||
font-family: tahoma, arial, sans-serif;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#navigation a {
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
h1:before, h2:before {
|
||||
content: "::";
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: courier, monospace;
|
||||
font-size: 80%;
|
||||
color: #418A8A;
|
||||
}
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/css</code>, <code>text/x-scss</code> (<a href="scss.html">demo</a>), <code>text/x-less</code> (<a href="less.html">demo</a>).</p>
|
||||
|
||||
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>, <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
|
||||
|
||||
</article>
|
@ -1,152 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: LESS mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="css.js"></script>
|
||||
<style>.CodeMirror {border: 1px solid #ddd; line-height: 1.2;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">LESS</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>LESS mode</h2>
|
||||
<form><textarea id="code" name="code">@media screen and (device-aspect-ratio: 16/9) { … }
|
||||
@media screen and (device-aspect-ratio: 1280/720) { … }
|
||||
@media screen and (device-aspect-ratio: 2560/1440) { … }
|
||||
|
||||
html:lang(fr-be)
|
||||
|
||||
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
|
||||
|
||||
img:nth-of-type(2n+1) { float: right; }
|
||||
img:nth-of-type(2n) { float: left; }
|
||||
|
||||
body > h2:not(:first-of-type):not(:last-of-type)
|
||||
|
||||
html|*:not(:link):not(:visited)
|
||||
*|*:not(:hover)
|
||||
p::first-line { text-transform: uppercase }
|
||||
|
||||
@namespace foo url(http://www.example.com);
|
||||
foo|h1 { color: blue } /* first rule */
|
||||
|
||||
span[hello="Ocean"][goodbye="Land"]
|
||||
|
||||
E[foo]{
|
||||
padding:65px;
|
||||
}
|
||||
|
||||
input[type="search"]::-webkit-search-decoration,
|
||||
input[type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
|
||||
}
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
.btn {
|
||||
// reset here as of 2.0.3 due to Recess property order
|
||||
border-color: #ccc;
|
||||
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
|
||||
}
|
||||
fieldset span button, fieldset span input[type="file"] {
|
||||
font-size:12px;
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.rounded-corners (@radius: 5px) {
|
||||
border-radius: @radius;
|
||||
-webkit-border-radius: @radius;
|
||||
-moz-border-radius: @radius;
|
||||
}
|
||||
|
||||
@import url("something.css");
|
||||
|
||||
@light-blue: hsl(190, 50%, 65%);
|
||||
|
||||
#menu {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 3;
|
||||
clear: both;
|
||||
display: block;
|
||||
background-color: @blue;
|
||||
height: 42px;
|
||||
border-top: 2px solid lighten(@alpha-blue, 20%);
|
||||
border-bottom: 2px solid darken(@alpha-blue, 25%);
|
||||
.box-shadow(0, 1px, 8px, 0.6);
|
||||
-moz-box-shadow: 0 0 0 #000; // Because firefox sucks.
|
||||
|
||||
&.docked {
|
||||
background-color: hsla(210, 60%, 40%, 0.4);
|
||||
}
|
||||
&:hover {
|
||||
background-color: @blue;
|
||||
}
|
||||
|
||||
#dropdown {
|
||||
margin: 0 0 0 117px;
|
||||
padding: 0;
|
||||
padding-top: 5px;
|
||||
display: none;
|
||||
width: 190px;
|
||||
border-top: 2px solid @medium;
|
||||
color: @highlight;
|
||||
border: 2px solid darken(@medium, 25%);
|
||||
border-left-color: darken(@medium, 15%);
|
||||
border-right-color: darken(@medium, 15%);
|
||||
border-top-width: 0;
|
||||
background-color: darken(@medium, 10%);
|
||||
ul {
|
||||
padding: 0px;
|
||||
}
|
||||
li {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
text-align: left;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
a {
|
||||
display: block;
|
||||
padding: 0px 15px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
&:hover {
|
||||
background-color: darken(@medium, 15%);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.border-radius(5px, bottom);
|
||||
.box-shadow(0, 6px, 8px, 0.5);
|
||||
}
|
||||
}
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers : true,
|
||||
matchBrackets : true,
|
||||
mode: "text/x-less"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
|
||||
|
||||
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>, <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
|
||||
</article>
|
@ -1,51 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); }
|
||||
|
||||
MT("variable",
|
||||
"[variable-2 @base]: [atom #f04615];",
|
||||
"[qualifier .class] {",
|
||||
" [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]",
|
||||
" [property color]: [variable saturate]([variable-2 @base], [number 5%]);",
|
||||
"}");
|
||||
|
||||
MT("amp",
|
||||
"[qualifier .child], [qualifier .sibling] {",
|
||||
" [qualifier .parent] [atom &] {",
|
||||
" [property color]: [keyword black];",
|
||||
" }",
|
||||
" [atom &] + [atom &] {",
|
||||
" [property color]: [keyword red];",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
MT("mixin",
|
||||
"[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
|
||||
" [property color]: [variable darken]([variable-2 @color], [number 10%]);",
|
||||
"}",
|
||||
"[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
|
||||
" [property color]: [variable lighten]([variable-2 @color], [number 10%]);",
|
||||
"}",
|
||||
"[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
|
||||
" [property display]: [atom block];",
|
||||
"}",
|
||||
"[variable-2 @switch]: [variable light];",
|
||||
"[qualifier .class] {",
|
||||
" [qualifier .mixin]([variable-2 @switch]; [atom #888]);",
|
||||
"}");
|
||||
|
||||
MT("nest",
|
||||
"[qualifier .one] {",
|
||||
" [def @media] ([property width]: [number 400px]) {",
|
||||
" [property font-size]: [number 1.2em];",
|
||||
" [def @media] [attribute print] [keyword and] [property color] {",
|
||||
" [property color]: [keyword blue];",
|
||||
" }",
|
||||
" }",
|
||||
"}");
|
||||
})();
|
@ -1,157 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: SCSS mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="css.js"></script>
|
||||
<style>.CodeMirror {background: #f8f8f8;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">SCSS</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>SCSS mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
/* Some example SCSS */
|
||||
|
||||
@import "compass/css3";
|
||||
$variable: #333;
|
||||
|
||||
$blue: #3bbfce;
|
||||
$margin: 16px;
|
||||
|
||||
.content-navigation {
|
||||
#nested {
|
||||
background-color: black;
|
||||
}
|
||||
border-color: $blue;
|
||||
color:
|
||||
darken($blue, 9%);
|
||||
}
|
||||
|
||||
.border {
|
||||
padding: $margin / 2;
|
||||
margin: $margin / 2;
|
||||
border-color: $blue;
|
||||
}
|
||||
|
||||
@mixin table-base {
|
||||
th {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
td, th {padding: 2px}
|
||||
}
|
||||
|
||||
table.hl {
|
||||
margin: 2em 0;
|
||||
td.ln {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
font: {
|
||||
family: serif;
|
||||
weight: bold;
|
||||
size: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin left($dist) {
|
||||
float: left;
|
||||
margin-left: $dist;
|
||||
}
|
||||
|
||||
#data {
|
||||
@include left(10px);
|
||||
@include table-base;
|
||||
}
|
||||
|
||||
.source {
|
||||
@include flow-into(target);
|
||||
border: 10px solid green;
|
||||
margin: 20px;
|
||||
width: 200px; }
|
||||
|
||||
.new-container {
|
||||
@include flow-from(target);
|
||||
border: 10px solid red;
|
||||
margin: 20px;
|
||||
width: 200px; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 3em 6em;
|
||||
font-family: tahoma, arial, sans-serif;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
@mixin yellow() {
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
.big {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.nested {
|
||||
@include border-radius(3px);
|
||||
@extend .big;
|
||||
p {
|
||||
background: whitesmoke;
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#navigation a {
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
h1:before, h2:before {
|
||||
content: "::";
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: courier, monospace;
|
||||
font-size: 80%;
|
||||
color: #418A8A;
|
||||
}
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-scss"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
|
||||
|
||||
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>, <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>
|
||||
|
||||
</article>
|
@ -1,110 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
|
||||
|
||||
MT('url_with_quotation',
|
||||
"[tag foo] { [property background]:[atom url]([string test.jpg]) }");
|
||||
|
||||
MT('url_with_double_quotes',
|
||||
"[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
|
||||
|
||||
MT('url_with_single_quotes',
|
||||
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
|
||||
|
||||
MT('string',
|
||||
"[def @import] [string \"compass/css3\"]");
|
||||
|
||||
MT('important_keyword',
|
||||
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
|
||||
|
||||
MT('variable',
|
||||
"[variable-2 $blue]:[atom #333]");
|
||||
|
||||
MT('variable_as_attribute',
|
||||
"[tag foo] { [property color]:[variable-2 $blue] }");
|
||||
|
||||
MT('numbers',
|
||||
"[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
|
||||
|
||||
MT('number_percentage',
|
||||
"[tag foo] { [property width]:[number 80%] }");
|
||||
|
||||
MT('selector',
|
||||
"[builtin #hello][qualifier .world]{}");
|
||||
|
||||
MT('singleline_comment',
|
||||
"[comment // this is a comment]");
|
||||
|
||||
MT('multiline_comment',
|
||||
"[comment /*foobar*/]");
|
||||
|
||||
MT('attribute_with_hyphen',
|
||||
"[tag foo] { [property font-size]:[number 10px] }");
|
||||
|
||||
MT('string_after_attribute',
|
||||
"[tag foo] { [property content]:[string \"::\"] }");
|
||||
|
||||
MT('directives',
|
||||
"[def @include] [qualifier .mixin]");
|
||||
|
||||
MT('basic_structure',
|
||||
"[tag p] { [property background]:[keyword red]; }");
|
||||
|
||||
MT('nested_structure',
|
||||
"[tag p] { [tag a] { [property color]:[keyword red]; } }");
|
||||
|
||||
MT('mixin',
|
||||
"[def @mixin] [tag table-base] {}");
|
||||
|
||||
MT('number_without_semicolon',
|
||||
"[tag p] {[property width]:[number 12]}",
|
||||
"[tag a] {[property color]:[keyword red];}");
|
||||
|
||||
MT('atom_in_nested_block',
|
||||
"[tag p] { [tag a] { [property color]:[atom #000]; } }");
|
||||
|
||||
MT('interpolation_in_property',
|
||||
"[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
|
||||
|
||||
MT('interpolation_in_selector',
|
||||
"[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
|
||||
|
||||
MT('interpolation_error',
|
||||
"[tag foo]#{[error foo]} { [property color]:[atom #000]; }");
|
||||
|
||||
MT("divide_operator",
|
||||
"[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
|
||||
|
||||
MT('nested_structure_with_id_selector',
|
||||
"[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
|
||||
|
||||
MT('indent_mixin',
|
||||
"[def @mixin] [tag container] (",
|
||||
" [variable-2 $a]: [number 10],",
|
||||
" [variable-2 $b]: [number 10])",
|
||||
"{}");
|
||||
|
||||
MT('indent_nested',
|
||||
"[tag foo] {",
|
||||
" [tag bar] {",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
MT('indent_parentheses',
|
||||
"[tag foo] {",
|
||||
" [property color]: [variable darken]([variable-2 $blue],",
|
||||
" [number 9%]);",
|
||||
"}");
|
||||
|
||||
MT('indent_vardef',
|
||||
"[variable-2 $name]:",
|
||||
" [string 'val'];",
|
||||
"[tag tag] {",
|
||||
" [tag inner] {",
|
||||
" [property margin]: [number 3px];",
|
||||
" }",
|
||||
"}");
|
||||
})();
|
@ -1,135 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({indentUnit: 2}, "css");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
|
||||
|
||||
// Error, because "foobarhello" is neither a known type or property, but
|
||||
// property was expected (after "and"), and it should be in parenthese.
|
||||
MT("atMediaUnknownType",
|
||||
"[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
|
||||
|
||||
// Soft error, because "foobarhello" is not a known property or type.
|
||||
MT("atMediaUnknownProperty",
|
||||
"[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
|
||||
|
||||
// Make sure nesting works with media queries
|
||||
MT("atMediaMaxWidthNested",
|
||||
"[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
|
||||
|
||||
MT("tagSelector",
|
||||
"[tag foo] { }");
|
||||
|
||||
MT("classSelector",
|
||||
"[qualifier .foo-bar_hello] { }");
|
||||
|
||||
MT("idSelector",
|
||||
"[builtin #foo] { [error #foo] }");
|
||||
|
||||
MT("tagSelectorUnclosed",
|
||||
"[tag foo] { [property margin]: [number 0] } [tag bar] { }");
|
||||
|
||||
MT("tagStringNoQuotes",
|
||||
"[tag foo] { [property font-family]: [variable hello] [variable world]; }");
|
||||
|
||||
MT("tagStringDouble",
|
||||
"[tag foo] { [property font-family]: [string \"hello world\"]; }");
|
||||
|
||||
MT("tagStringSingle",
|
||||
"[tag foo] { [property font-family]: [string 'hello world']; }");
|
||||
|
||||
MT("tagColorKeyword",
|
||||
"[tag foo] {",
|
||||
" [property color]: [keyword black];",
|
||||
" [property color]: [keyword navy];",
|
||||
" [property color]: [keyword yellow];",
|
||||
"}");
|
||||
|
||||
MT("tagColorHex3",
|
||||
"[tag foo] { [property background]: [atom #fff]; }");
|
||||
|
||||
MT("tagColorHex6",
|
||||
"[tag foo] { [property background]: [atom #ffffff]; }");
|
||||
|
||||
MT("tagColorHex4",
|
||||
"[tag foo] { [property background]: [atom&error #ffff]; }");
|
||||
|
||||
MT("tagColorHexInvalid",
|
||||
"[tag foo] { [property background]: [atom&error #ffg]; }");
|
||||
|
||||
MT("tagNegativeNumber",
|
||||
"[tag foo] { [property margin]: [number -5px]; }");
|
||||
|
||||
MT("tagPositiveNumber",
|
||||
"[tag foo] { [property padding]: [number 5px]; }");
|
||||
|
||||
MT("tagVendor",
|
||||
"[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
|
||||
|
||||
MT("tagBogusProperty",
|
||||
"[tag foo] { [property&error barhelloworld]: [number 0]; }");
|
||||
|
||||
MT("tagTwoProperties",
|
||||
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
|
||||
|
||||
MT("tagTwoPropertiesURL",
|
||||
"[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
|
||||
|
||||
MT("commentSGML",
|
||||
"[comment <!--comment-->]");
|
||||
|
||||
MT("commentSGML2",
|
||||
"[comment <!--comment]",
|
||||
"[comment -->] [tag div] {}");
|
||||
|
||||
MT("indent_tagSelector",
|
||||
"[tag strong], [tag em] {",
|
||||
" [property background]: [atom rgba](",
|
||||
" [number 255], [number 255], [number 0], [number .2]",
|
||||
" );",
|
||||
"}");
|
||||
|
||||
MT("indent_atMedia",
|
||||
"[def @media] {",
|
||||
" [tag foo] {",
|
||||
" [property color]:",
|
||||
" [keyword yellow];",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
MT("indent_comma",
|
||||
"[tag foo] {",
|
||||
" [property font-family]: [variable verdana],",
|
||||
" [atom sans-serif];",
|
||||
"}");
|
||||
|
||||
MT("indent_parentheses",
|
||||
"[tag foo]:[variable-3 before] {",
|
||||
" [property background]: [atom url](",
|
||||
"[string blahblah]",
|
||||
"[string etc]",
|
||||
"[string ]) [keyword !important];",
|
||||
"}");
|
||||
|
||||
MT("font_face",
|
||||
"[def @font-face] {",
|
||||
" [property font-family]: [string 'myfont'];",
|
||||
" [error nonsense]: [string 'abc'];",
|
||||
" [property src]: [atom url]([string http://blah]),",
|
||||
" [atom url]([string http://foo]);",
|
||||
"}");
|
||||
|
||||
MT("empty_url",
|
||||
"[def @import] [tag url]() [tag screen];");
|
||||
|
||||
MT("parens",
|
||||
"[qualifier .foo] {",
|
||||
" [property background-image]: [variable fade]([atom #000], [number 20%]);",
|
||||
" [property border-image]: [variable linear-gradient](",
|
||||
" [atom to] [atom bottom],",
|
||||
" [variable fade]([atom #000], [number 20%]) [number 0%],",
|
||||
" [variable fade]([atom #000], [number 20%]) [number 100%]",
|
||||
" );",
|
||||
"}");
|
||||
})();
|
@ -1,146 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// By the Neo4j Team and contributors.
|
||||
// https://github.com/neo4j-contrib/CodeMirror
|
||||
|
||||
(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";
|
||||
var wordRegexp = function(words) {
|
||||
return new RegExp("^(?:" + words.join("|") + ")$", "i");
|
||||
};
|
||||
|
||||
CodeMirror.defineMode("cypher", function(config) {
|
||||
var tokenBase = function(stream/*, state*/) {
|
||||
var ch = stream.next(), curPunc = null;
|
||||
if (ch === "\"" || ch === "'") {
|
||||
stream.match(/.+?["']/);
|
||||
return "string";
|
||||
}
|
||||
if (/[{}\(\),\.;\[\]]/.test(ch)) {
|
||||
curPunc = ch;
|
||||
return "node";
|
||||
} else if (ch === "/" && stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
} else if (operatorChars.test(ch)) {
|
||||
stream.eatWhile(operatorChars);
|
||||
return null;
|
||||
} else {
|
||||
stream.eatWhile(/[_\w\d]/);
|
||||
if (stream.eat(":")) {
|
||||
stream.eatWhile(/[\w\d_\-]/);
|
||||
return "atom";
|
||||
}
|
||||
var word = stream.current();
|
||||
if (funcs.test(word)) return "builtin";
|
||||
if (preds.test(word)) return "def";
|
||||
if (keywords.test(word)) return "keyword";
|
||||
return "variable";
|
||||
}
|
||||
};
|
||||
var pushContext = function(state, type, col) {
|
||||
return state.context = {
|
||||
prev: state.context,
|
||||
indent: state.indent,
|
||||
col: col,
|
||||
type: type
|
||||
};
|
||||
};
|
||||
var popContext = function(state) {
|
||||
state.indent = state.context.indent;
|
||||
return state.context = state.context.prev;
|
||||
};
|
||||
var indentUnit = config.indentUnit;
|
||||
var curPunc;
|
||||
var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
|
||||
var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
|
||||
var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
|
||||
var operatorChars = /[*+\-<>=&|~%^]/;
|
||||
|
||||
return {
|
||||
startState: function(/*base*/) {
|
||||
return {
|
||||
tokenize: tokenBase,
|
||||
context: null,
|
||||
indent: 0,
|
||||
col: 0
|
||||
};
|
||||
},
|
||||
token: function(stream, state) {
|
||||
if (stream.sol()) {
|
||||
if (state.context && (state.context.align == null)) {
|
||||
state.context.align = false;
|
||||
}
|
||||
state.indent = stream.indentation();
|
||||
}
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
var style = state.tokenize(stream, state);
|
||||
if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
|
||||
state.context.align = true;
|
||||
}
|
||||
if (curPunc === "(") {
|
||||
pushContext(state, ")", stream.column());
|
||||
} else if (curPunc === "[") {
|
||||
pushContext(state, "]", stream.column());
|
||||
} else if (curPunc === "{") {
|
||||
pushContext(state, "}", stream.column());
|
||||
} else if (/[\]\}\)]/.test(curPunc)) {
|
||||
while (state.context && state.context.type === "pattern") {
|
||||
popContext(state);
|
||||
}
|
||||
if (state.context && curPunc === state.context.type) {
|
||||
popContext(state);
|
||||
}
|
||||
} else if (curPunc === "." && state.context && state.context.type === "pattern") {
|
||||
popContext(state);
|
||||
} else if (/atom|string|variable/.test(style) && state.context) {
|
||||
if (/[\}\]]/.test(state.context.type)) {
|
||||
pushContext(state, "pattern", stream.column());
|
||||
} else if (state.context.type === "pattern" && !state.context.align) {
|
||||
state.context.align = true;
|
||||
state.context.col = stream.column();
|
||||
}
|
||||
}
|
||||
return style;
|
||||
},
|
||||
indent: function(state, textAfter) {
|
||||
var firstChar = textAfter && textAfter.charAt(0);
|
||||
var context = state.context;
|
||||
if (/[\]\}]/.test(firstChar)) {
|
||||
while (context && context.type === "pattern") {
|
||||
context = context.prev;
|
||||
}
|
||||
}
|
||||
var closing = context && firstChar === context.type;
|
||||
if (!context) return 0;
|
||||
if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
|
||||
if (context.align) return context.col + (closing ? 0 : 1);
|
||||
return context.indent + (closing ? 0 : indentUnit);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.modeExtensions["cypher"] = {
|
||||
autoFormatLineBreaks: function(text) {
|
||||
var i, lines, reProcessedPortion;
|
||||
var lines = text.split("\n");
|
||||
var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
|
||||
for (var i = 0; i < lines.length; i++)
|
||||
lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
|
||||
return lines.join("\n");
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.defineMIME("application/x-cypher-query", "cypher");
|
||||
|
||||
});
|
@ -1,63 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Cypher Mode for CodeMirror</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css" />
|
||||
<link rel="stylesheet" href="../../theme/neo.css" />
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="cypher.js"></script>
|
||||
<style>
|
||||
.CodeMirror {
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Cypher Mode for CodeMirror</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Cypher Mode for CodeMirror</h2>
|
||||
<form>
|
||||
<textarea id="code" name="code">// Cypher Mode for CodeMirror, using the neo theme
|
||||
MATCH (joe { name: 'Joe' })-[:knows*2..2]-(friend_of_friend)
|
||||
WHERE NOT (joe)-[:knows]-(friend_of_friend)
|
||||
RETURN friend_of_friend.name, COUNT(*)
|
||||
ORDER BY COUNT(*) DESC , friend_of_friend.name
|
||||
</textarea>
|
||||
</form>
|
||||
<p><strong>MIME types defined:</strong>
|
||||
<code><a href="?mime=application/x-cypher-query">application/x-cypher-query</a></code>
|
||||
</p>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
var mime = 'application/x-cypher-query';
|
||||
// get mime type
|
||||
if (window.location.href.indexOf('mime=') > -1) {
|
||||
mime = window.location.href.substr(window.location.href.indexOf('mime=') + 5);
|
||||
}
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById('code'), {
|
||||
mode: mime,
|
||||
indentWithTabs: true,
|
||||
smartIndent: true,
|
||||
lineNumbers: true,
|
||||
matchBrackets : true,
|
||||
autofocus: true,
|
||||
theme: 'neo'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
</article>
|
@ -1,218 +0,0 @@
|
||||
// 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("d", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit,
|
||||
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
|
||||
keywords = parserConfig.keywords || {},
|
||||
builtin = parserConfig.builtin || {},
|
||||
blockKeywords = parserConfig.blockKeywords || {},
|
||||
atoms = parserConfig.atoms || {},
|
||||
hooks = parserConfig.hooks || {},
|
||||
multiLineStrings = parserConfig.multiLineStrings;
|
||||
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
|
||||
|
||||
var curPunc;
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (hooks[ch]) {
|
||||
var result = hooks[ch](stream, state);
|
||||
if (result !== false) return result;
|
||||
}
|
||||
if (ch == '"' || ch == "'" || ch == "`") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
||||
curPunc = ch;
|
||||
return null;
|
||||
}
|
||||
if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
return "number";
|
||||
}
|
||||
if (ch == "/") {
|
||||
if (stream.eat("+")) {
|
||||
state.tokenize = tokenComment;
|
||||
return tokenNestedComment(stream, state);
|
||||
}
|
||||
if (stream.eat("*")) {
|
||||
state.tokenize = tokenComment;
|
||||
return tokenComment(stream, state);
|
||||
}
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
}
|
||||
if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return "operator";
|
||||
}
|
||||
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
|
||||
var cur = stream.current();
|
||||
if (keywords.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "keyword";
|
||||
}
|
||||
if (builtin.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "builtin";
|
||||
}
|
||||
if (atoms.propertyIsEnumerable(cur)) return "atom";
|
||||
return "variable";
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, next, end = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote && !escaped) {end = true; break;}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
if (end || !(escaped || multiLineStrings))
|
||||
state.tokenize = null;
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function tokenNestedComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "+");
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function Context(indented, column, type, align, prev) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.align = align;
|
||||
this.prev = prev;
|
||||
}
|
||||
function pushContext(state, col, type) {
|
||||
var indent = state.indented;
|
||||
if (state.context && state.context.type == "statement")
|
||||
indent = state.context.indented;
|
||||
return state.context = new Context(indent, col, type, null, state.context);
|
||||
}
|
||||
function popContext(state) {
|
||||
var t = state.context.type;
|
||||
if (t == ")" || t == "]" || t == "}")
|
||||
state.indented = state.context.indented;
|
||||
return state.context = state.context.prev;
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: null,
|
||||
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
|
||||
indented: 0,
|
||||
startOfLine: true
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var ctx = state.context;
|
||||
if (stream.sol()) {
|
||||
if (ctx.align == null) ctx.align = false;
|
||||
state.indented = stream.indentation();
|
||||
state.startOfLine = true;
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
curPunc = null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style == "comment" || style == "meta") return style;
|
||||
if (ctx.align == null) ctx.align = true;
|
||||
|
||||
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
|
||||
else if (curPunc == "{") pushContext(state, stream.column(), "}");
|
||||
else if (curPunc == "[") pushContext(state, stream.column(), "]");
|
||||
else if (curPunc == "(") pushContext(state, stream.column(), ")");
|
||||
else if (curPunc == "}") {
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
if (ctx.type == "}") ctx = popContext(state);
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
}
|
||||
else if (curPunc == ctx.type) popContext(state);
|
||||
else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
|
||||
pushContext(state, stream.column(), "statement");
|
||||
state.startOfLine = false;
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
|
||||
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
||||
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
||||
var closing = firstChar == ctx.type;
|
||||
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
|
||||
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
|
||||
else return ctx.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: "{}"
|
||||
};
|
||||
});
|
||||
|
||||
function words(str) {
|
||||
var obj = {}, words = str.split(" ");
|
||||
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " +
|
||||
"out scope struct switch try union unittest version while with";
|
||||
|
||||
CodeMirror.defineMIME("text/x-d", {
|
||||
name: "d",
|
||||
keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " +
|
||||
"debug default delegate delete deprecated export extern final finally function goto immutable " +
|
||||
"import inout invariant is lazy macro module new nothrow override package pragma private " +
|
||||
"protected public pure ref return shared short static super synchronized template this " +
|
||||
"throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " +
|
||||
blockKeywords),
|
||||
blockKeywords: words(blockKeywords),
|
||||
builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " +
|
||||
"ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
|
||||
atoms: words("exit failure success true false null"),
|
||||
hooks: {
|
||||
"@": function(stream, _state) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
@ -1,273 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: D mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="d.js"></script>
|
||||
<style>.CodeMirror {border: 2px inset #dee;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">D</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>D mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
/* D demo code // copied from phobos/sd/metastrings.d */
|
||||
// Written in the D programming language.
|
||||
|
||||
/**
|
||||
Templates with which to do compile-time manipulation of strings.
|
||||
|
||||
Macros:
|
||||
WIKI = Phobos/StdMetastrings
|
||||
|
||||
Copyright: Copyright Digital Mars 2007 - 2009.
|
||||
License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
|
||||
Authors: $(WEB digitalmars.com, Walter Bright),
|
||||
Don Clugston
|
||||
Source: $(PHOBOSSRC std/_metastrings.d)
|
||||
*/
|
||||
/*
|
||||
Copyright Digital Mars 2007 - 2009.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
module std.metastrings;
|
||||
|
||||
/**
|
||||
Formats constants into a string at compile time. Analogous to $(XREF
|
||||
string,format).
|
||||
|
||||
Parameters:
|
||||
|
||||
A = tuple of constants, which can be strings, characters, or integral
|
||||
values.
|
||||
|
||||
Formats:
|
||||
* The formats supported are %s for strings, and %%
|
||||
* for the % character.
|
||||
Example:
|
||||
---
|
||||
import std.metastrings;
|
||||
import std.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
string s = Format!("Arg %s = %s", "foo", 27);
|
||||
writefln(s); // "Arg foo = 27"
|
||||
}
|
||||
* ---
|
||||
*/
|
||||
|
||||
template Format(A...)
|
||||
{
|
||||
static if (A.length == 0)
|
||||
enum Format = "";
|
||||
else static if (is(typeof(A[0]) : const(char)[]))
|
||||
enum Format = FormatString!(A[0], A[1..$]);
|
||||
else
|
||||
enum Format = toStringNow!(A[0]) ~ Format!(A[1..$]);
|
||||
}
|
||||
|
||||
template FormatString(const(char)[] F, A...)
|
||||
{
|
||||
static if (F.length == 0)
|
||||
enum FormatString = Format!(A);
|
||||
else static if (F.length == 1)
|
||||
enum FormatString = F[0] ~ Format!(A);
|
||||
else static if (F[0..2] == "%s")
|
||||
enum FormatString
|
||||
= toStringNow!(A[0]) ~ FormatString!(F[2..$],A[1..$]);
|
||||
else static if (F[0..2] == "%%")
|
||||
enum FormatString = "%" ~ FormatString!(F[2..$],A);
|
||||
else
|
||||
{
|
||||
static assert(F[0] != '%', "unrecognized format %" ~ F[1]);
|
||||
enum FormatString = F[0] ~ FormatString!(F[1..$],A);
|
||||
}
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
auto s = Format!("hel%slo", "world", -138, 'c', true);
|
||||
assert(s == "helworldlo-138ctrue", "[" ~ s ~ "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert constant argument to a string.
|
||||
*/
|
||||
|
||||
template toStringNow(ulong v)
|
||||
{
|
||||
static if (v < 10)
|
||||
enum toStringNow = "" ~ cast(char)(v + '0');
|
||||
else
|
||||
enum toStringNow = toStringNow!(v / 10) ~ toStringNow!(v % 10);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
static assert(toStringNow!(1uL << 62) == "4611686018427387904");
|
||||
}
|
||||
|
||||
/// ditto
|
||||
template toStringNow(long v)
|
||||
{
|
||||
static if (v < 0)
|
||||
enum toStringNow = "-" ~ toStringNow!(cast(ulong) -v);
|
||||
else
|
||||
enum toStringNow = toStringNow!(cast(ulong) v);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
static assert(toStringNow!(0x100000000) == "4294967296");
|
||||
static assert(toStringNow!(-138L) == "-138");
|
||||
}
|
||||
|
||||
/// ditto
|
||||
template toStringNow(uint U)
|
||||
{
|
||||
enum toStringNow = toStringNow!(cast(ulong)U);
|
||||
}
|
||||
|
||||
/// ditto
|
||||
template toStringNow(int I)
|
||||
{
|
||||
enum toStringNow = toStringNow!(cast(long)I);
|
||||
}
|
||||
|
||||
/// ditto
|
||||
template toStringNow(bool B)
|
||||
{
|
||||
enum toStringNow = B ? "true" : "false";
|
||||
}
|
||||
|
||||
/// ditto
|
||||
template toStringNow(string S)
|
||||
{
|
||||
enum toStringNow = S;
|
||||
}
|
||||
|
||||
/// ditto
|
||||
template toStringNow(char C)
|
||||
{
|
||||
enum toStringNow = "" ~ C;
|
||||
}
|
||||
|
||||
|
||||
/********
|
||||
* Parse unsigned integer literal from the start of string s.
|
||||
* returns:
|
||||
* .value = the integer literal as a string,
|
||||
* .rest = the string following the integer literal
|
||||
* Otherwise:
|
||||
* .value = null,
|
||||
* .rest = s
|
||||
*/
|
||||
|
||||
template parseUinteger(const(char)[] s)
|
||||
{
|
||||
static if (s.length == 0)
|
||||
{
|
||||
enum value = "";
|
||||
enum rest = "";
|
||||
}
|
||||
else static if (s[0] >= '0' && s[0] <= '9')
|
||||
{
|
||||
enum value = s[0] ~ parseUinteger!(s[1..$]).value;
|
||||
enum rest = parseUinteger!(s[1..$]).rest;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum value = "";
|
||||
enum rest = s;
|
||||
}
|
||||
}
|
||||
|
||||
/********
|
||||
Parse integer literal optionally preceded by $(D '-') from the start
|
||||
of string $(D s).
|
||||
|
||||
Returns:
|
||||
.value = the integer literal as a string,
|
||||
.rest = the string following the integer literal
|
||||
|
||||
Otherwise:
|
||||
.value = null,
|
||||
.rest = s
|
||||
*/
|
||||
|
||||
template parseInteger(const(char)[] s)
|
||||
{
|
||||
static if (s.length == 0)
|
||||
{
|
||||
enum value = "";
|
||||
enum rest = "";
|
||||
}
|
||||
else static if (s[0] >= '0' && s[0] <= '9')
|
||||
{
|
||||
enum value = s[0] ~ parseUinteger!(s[1..$]).value;
|
||||
enum rest = parseUinteger!(s[1..$]).rest;
|
||||
}
|
||||
else static if (s.length >= 2 &&
|
||||
s[0] == '-' && s[1] >= '0' && s[1] <= '9')
|
||||
{
|
||||
enum value = s[0..2] ~ parseUinteger!(s[2..$]).value;
|
||||
enum rest = parseUinteger!(s[2..$]).rest;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum value = "";
|
||||
enum rest = s;
|
||||
}
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
assert(parseUinteger!("1234abc").value == "1234");
|
||||
assert(parseUinteger!("1234abc").rest == "abc");
|
||||
assert(parseInteger!("-1234abc").value == "-1234");
|
||||
assert(parseInteger!("-1234abc").rest == "abc");
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated aliases held for backward compatibility.
|
||||
*/
|
||||
deprecated alias toStringNow ToString;
|
||||
/// Ditto
|
||||
deprecated alias parseUinteger ParseUinteger;
|
||||
/// Ditto
|
||||
deprecated alias parseUinteger ParseInteger;
|
||||
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
indentUnit: 4,
|
||||
mode: "text/x-d"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Simple mode that handle D-Syntax (<a href="http://www.dlang.org">DLang Homepage</a>).</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-d</code>
|
||||
.</p>
|
||||
</article>
|
@ -1,47 +0,0 @@
|
||||
// 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("diff", function() {
|
||||
|
||||
var TOKEN_NAMES = {
|
||||
'+': 'positive',
|
||||
'-': 'negative',
|
||||
'@': 'meta'
|
||||
};
|
||||
|
||||
return {
|
||||
token: function(stream) {
|
||||
var tw_pos = stream.string.search(/[\t ]+?$/);
|
||||
|
||||
if (!stream.sol() || tw_pos === 0) {
|
||||
stream.skipToEnd();
|
||||
return ("error " + (
|
||||
TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
|
||||
}
|
||||
|
||||
var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
|
||||
|
||||
if (tw_pos === -1) {
|
||||
stream.skipToEnd();
|
||||
} else {
|
||||
stream.pos = tw_pos;
|
||||
}
|
||||
|
||||
return token_name;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-diff", "diff");
|
||||
|
||||
});
|
@ -1,117 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Diff mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="diff.js"></script>
|
||||
<style>
|
||||
.CodeMirror {border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}
|
||||
span.cm-meta {color: #a0b !important;}
|
||||
span.cm-error { background-color: black; opacity: 0.4;}
|
||||
span.cm-error.cm-string { background-color: red; }
|
||||
span.cm-error.cm-tag { background-color: #2b2; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Diff</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Diff mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
diff --git a/index.html b/index.html
|
||||
index c1d9156..7764744 100644
|
||||
--- a/index.html
|
||||
+++ b/index.html
|
||||
@@ -95,7 +95,8 @@ StringStream.prototype = {
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
- autoMatchBrackets: true
|
||||
+ autoMatchBrackets: true,
|
||||
+ onGutterClick: function(x){console.log(x);}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
diff --git a/lib/codemirror.js b/lib/codemirror.js
|
||||
index 04646a9..9a39cc7 100644
|
||||
--- a/lib/codemirror.js
|
||||
+++ b/lib/codemirror.js
|
||||
@@ -399,10 +399,16 @@ var CodeMirror = (function() {
|
||||
}
|
||||
|
||||
function onMouseDown(e) {
|
||||
- var start = posFromMouse(e), last = start;
|
||||
+ var start = posFromMouse(e), last = start, target = e.target();
|
||||
if (!start) return;
|
||||
setCursor(start.line, start.ch, false);
|
||||
if (e.button() != 1) return;
|
||||
+ if (target.parentNode == gutter) {
|
||||
+ if (options.onGutterClick)
|
||||
+ options.onGutterClick(indexOf(gutter.childNodes, target) + showingFrom);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!focused) onFocus();
|
||||
|
||||
e.stop();
|
||||
@@ -808,7 +814,7 @@ var CodeMirror = (function() {
|
||||
for (var i = showingFrom; i < showingTo; ++i) {
|
||||
var marker = lines[i].gutterMarker;
|
||||
if (marker) html.push('<div class="' + marker.style + '">' + htmlEscape(marker.text) + '</div>');
|
||||
- else html.push("<div>" + (options.lineNumbers ? i + 1 : "\u00a0") + "</div>");
|
||||
+ else html.push("<div>" + (options.lineNumbers ? i + options.firstLineNumber : "\u00a0") + "</div>");
|
||||
}
|
||||
gutter.style.display = "none"; // TODO test whether this actually helps
|
||||
gutter.innerHTML = html.join("");
|
||||
@@ -1371,10 +1377,8 @@ var CodeMirror = (function() {
|
||||
if (option == "parser") setParser(value);
|
||||
else if (option === "lineNumbers") setLineNumbers(value);
|
||||
else if (option === "gutter") setGutter(value);
|
||||
- else if (option === "readOnly") options.readOnly = value;
|
||||
- else if (option === "indentUnit") {options.indentUnit = indentUnit = value; setParser(options.parser);}
|
||||
- else if (/^(?:enterMode|tabMode|indentWithTabs|readOnly|autoMatchBrackets|undoDepth)$/.test(option)) options[option] = value;
|
||||
- else throw new Error("Can't set option " + option);
|
||||
+ else if (option === "indentUnit") {options.indentUnit = value; setParser(options.parser);}
|
||||
+ else options[option] = value;
|
||||
},
|
||||
cursorCoords: cursorCoords,
|
||||
undo: operation(undo),
|
||||
@@ -1402,7 +1406,8 @@ var CodeMirror = (function() {
|
||||
replaceRange: operation(replaceRange),
|
||||
|
||||
operation: function(f){return operation(f)();},
|
||||
- refresh: function(){updateDisplay([{from: 0, to: lines.length}]);}
|
||||
+ refresh: function(){updateDisplay([{from: 0, to: lines.length}]);},
|
||||
+ getInputField: function(){return input;}
|
||||
};
|
||||
return instance;
|
||||
}
|
||||
@@ -1420,6 +1425,7 @@ var CodeMirror = (function() {
|
||||
readOnly: false,
|
||||
onChange: null,
|
||||
onCursorActivity: null,
|
||||
+ onGutterClick: null,
|
||||
autoMatchBrackets: false,
|
||||
workTime: 200,
|
||||
workDelay: 300,
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-diff</code>.</p>
|
||||
|
||||
</article>
|
@ -1,67 +0,0 @@
|
||||
// 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"), require("../htmlmixed/htmlmixed"),
|
||||
require("../../addon/mode/overlay"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
|
||||
"../../addon/mode/overlay"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("django:inner", function() {
|
||||
var keywords = ["block", "endblock", "for", "endfor", "in", "true", "false",
|
||||
"loop", "none", "self", "super", "if", "endif", "as", "not", "and",
|
||||
"else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
|
||||
"ifnotequal", "endifnotequal", "extends", "include", "load", "length", "comment",
|
||||
"endcomment", "empty"];
|
||||
keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
|
||||
|
||||
function tokenBase (stream, state) {
|
||||
stream.eatWhile(/[^\{]/);
|
||||
var ch = stream.next();
|
||||
if (ch == "{") {
|
||||
if (ch = stream.eat(/\{|%|#/)) {
|
||||
state.tokenize = inTag(ch);
|
||||
return "tag";
|
||||
}
|
||||
}
|
||||
}
|
||||
function inTag (close) {
|
||||
if (close == "{") {
|
||||
close = "}";
|
||||
}
|
||||
return function (stream, state) {
|
||||
var ch = stream.next();
|
||||
if ((ch == close) && stream.eat("}")) {
|
||||
state.tokenize = tokenBase;
|
||||
return "tag";
|
||||
}
|
||||
if (stream.match(keywords)) {
|
||||
return "keyword";
|
||||
}
|
||||
return close == "#" ? "comment" : "string";
|
||||
};
|
||||
}
|
||||
return {
|
||||
startState: function () {
|
||||
return {tokenize: tokenBase};
|
||||
},
|
||||
token: function (stream, state) {
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMode("django", function(config) {
|
||||
var htmlBase = CodeMirror.getMode(config, "text/html");
|
||||
var djangoInner = CodeMirror.getMode(config, "django:inner");
|
||||
return CodeMirror.overlayMode(htmlBase, djangoInner);
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-django", "django");
|
||||
});
|
@ -1,63 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Django template mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/mode/overlay.js"></script>
|
||||
<script src="../xml/xml.js"></script>
|
||||
<script src="../htmlmixed/htmlmixed.js"></script>
|
||||
<script src="django.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Django</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Django template mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>My Django web application</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
{{ page.title }}
|
||||
</h1>
|
||||
<ul class="my-list">
|
||||
{% for item in items %}
|
||||
<li>{% item.name %}</li>
|
||||
{% empty %}
|
||||
<li>You have no items in your list.</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "django",
|
||||
indentUnit: 4,
|
||||
indentWithTabs: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Mode for HTML with embedded Django template markup.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-django</code></p>
|
||||
</article>
|
@ -1,80 +0,0 @@
|
||||
// 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"), require("../../addon/mode/simple"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
// Collect all Dockerfile directives
|
||||
var instructions = ["from", "maintainer", "run", "cmd", "expose", "env",
|
||||
"add", "copy", "entrypoint", "volume", "user",
|
||||
"workdir", "onbuild"],
|
||||
instructionRegex = "(" + instructions.join('|') + ")",
|
||||
instructionOnlyLine = new RegExp(instructionRegex + "\\s*$", "i"),
|
||||
instructionWithArguments = new RegExp(instructionRegex + "(\\s+)", "i");
|
||||
|
||||
CodeMirror.defineSimpleMode("dockerfile", {
|
||||
start: [
|
||||
// Block comment: This is a line starting with a comment
|
||||
{
|
||||
regex: /#.*$/,
|
||||
token: "comment",
|
||||
next: "start"
|
||||
},
|
||||
// Highlight an instruction without any arguments (for convenience)
|
||||
{
|
||||
regex: instructionOnlyLine,
|
||||
token: "variable-2",
|
||||
next: "start"
|
||||
},
|
||||
// Highlight an instruction followed by arguments
|
||||
{
|
||||
regex: instructionWithArguments,
|
||||
token: ["variable-2", null],
|
||||
next: "arguments"
|
||||
},
|
||||
// Fail-safe return to start
|
||||
{
|
||||
token: null,
|
||||
next: "start"
|
||||
}
|
||||
],
|
||||
arguments: [
|
||||
{
|
||||
// Line comment without instruction arguments is an error
|
||||
regex: /#.*$/,
|
||||
token: "error",
|
||||
next: "start"
|
||||
},
|
||||
{
|
||||
regex: /[^#]+\\$/,
|
||||
token: null,
|
||||
next: "arguments"
|
||||
},
|
||||
{
|
||||
// Match everything except for the inline comment
|
||||
regex: /[^#]+/,
|
||||
token: null,
|
||||
next: "start"
|
||||
},
|
||||
{
|
||||
regex: /$/,
|
||||
token: null,
|
||||
next: "start"
|
||||
},
|
||||
// Fail safe return to start
|
||||
{
|
||||
token: null,
|
||||
next: "start"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
|
||||
});
|
@ -1,72 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Dockerfile mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/mode/simple.js"></script>
|
||||
<script src="dockerfile.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Dockerfile</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Dockerfile mode</h2>
|
||||
<form><textarea id="code" name="code"># Install Ghost blogging platform and run development environment
|
||||
#
|
||||
# VERSION 1.0.0
|
||||
|
||||
FROM ubuntu:12.10
|
||||
MAINTAINER Amer Grgic "amer@livebyt.es"
|
||||
WORKDIR /data/ghost
|
||||
|
||||
# Install dependencies for nginx installation
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y python g++ make software-properties-common --force-yes
|
||||
RUN add-apt-repository ppa:chris-lea/node.js
|
||||
RUN apt-get update
|
||||
# Install unzip
|
||||
RUN apt-get install -y unzip
|
||||
# Install curl
|
||||
RUN apt-get install -y curl
|
||||
# Install nodejs & npm
|
||||
RUN apt-get install -y rlwrap
|
||||
RUN apt-get install -y nodejs
|
||||
# Download Ghost v0.4.1
|
||||
RUN curl -L https://ghost.org/zip/ghost-latest.zip -o /tmp/ghost.zip
|
||||
# Unzip Ghost zip to /data/ghost
|
||||
RUN unzip -uo /tmp/ghost.zip -d /data/ghost
|
||||
# Add custom config js to /data/ghost
|
||||
ADD ./config.example.js /data/ghost/config.js
|
||||
# Install Ghost with NPM
|
||||
RUN cd /data/ghost/ && npm install --production
|
||||
# Expose port 2368
|
||||
EXPOSE 2368
|
||||
# Run Ghost
|
||||
CMD ["npm","start"]
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "dockerfile"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Dockerfile syntac highlighting for CodeMirror.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-dockerfile</code></p>
|
||||
</article>
|
@ -1,142 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
/*
|
||||
DTD mode
|
||||
Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
|
||||
Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
|
||||
GitHub: @peterkroon
|
||||
*/
|
||||
|
||||
(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("dtd", function(config) {
|
||||
var indentUnit = config.indentUnit, type;
|
||||
function ret(style, tp) {type = tp; return style;}
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
|
||||
if (ch == "<" && stream.eat("!") ) {
|
||||
if (stream.eatWhile(/[\-]/)) {
|
||||
state.tokenize = tokenSGMLComment;
|
||||
return tokenSGMLComment(stream, state);
|
||||
} else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent");
|
||||
} else if (ch == "<" && stream.eat("?")) { //xml declaration
|
||||
state.tokenize = inBlock("meta", "?>");
|
||||
return ret("meta", ch);
|
||||
} else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
|
||||
else if (ch == "|") return ret("keyword", "seperator");
|
||||
else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
|
||||
else if (ch.match(/[\[\]]/)) return ret("rule", ch);
|
||||
else if (ch == "\"" || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
} else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) {
|
||||
var sc = stream.current();
|
||||
if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1);
|
||||
return ret("tag", "tag");
|
||||
} else if (ch == "%" || ch == "*" ) return ret("number", "number");
|
||||
else {
|
||||
stream.eatWhile(/[\w\\\-_%.{,]/);
|
||||
return ret(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
function tokenSGMLComment(stream, state) {
|
||||
var dashes = 0, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (dashes >= 2 && ch == ">") {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
dashes = (ch == "-") ? dashes + 1 : 0;
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == quote && !escaped) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
return ret("string", "tag");
|
||||
};
|
||||
}
|
||||
|
||||
function inBlock(style, terminator) {
|
||||
return function(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
if (stream.match(terminator)) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
stream.next();
|
||||
}
|
||||
return style;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function(base) {
|
||||
return {tokenize: tokenBase,
|
||||
baseIndent: base || 0,
|
||||
stack: []};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
|
||||
var context = state.stack[state.stack.length-1];
|
||||
if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule");
|
||||
else if (type === "endtag") state.stack[state.stack.length-1] = "endtag";
|
||||
else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop();
|
||||
else if (type == "[") state.stack.push("[");
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
var n = state.stack.length;
|
||||
|
||||
if( textAfter.match(/\]\s+|\]/) )n=n-1;
|
||||
else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
|
||||
if(textAfter.substr(0,1) === "<")n;
|
||||
else if( type == "doindent" && textAfter.length > 1 )n;
|
||||
else if( type == "doindent")n--;
|
||||
else if( type == ">" && textAfter.length > 1)n;
|
||||
else if( type == "tag" && textAfter !== ">")n;
|
||||
else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--;
|
||||
else if( type == "tag")n++;
|
||||
else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--;
|
||||
else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule")n;
|
||||
else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1;
|
||||
else if( textAfter === ">")n;
|
||||
else n=n-1;
|
||||
//over rule them all
|
||||
if(type == null || type == "]")n--;
|
||||
}
|
||||
|
||||
return state.baseIndent + n * indentUnit;
|
||||
},
|
||||
|
||||
electricChars: "]>"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("application/xml-dtd", "dtd");
|
||||
|
||||
});
|
@ -1,89 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: DTD mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="dtd.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">DTD</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>DTD mode</h2>
|
||||
<form><textarea id="code" name="code"><?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!ATTLIST title
|
||||
xmlns CDATA #FIXED "http://docbook.org/ns/docbook"
|
||||
role CDATA #IMPLIED
|
||||
%db.common.attributes;
|
||||
%db.common.linking.attributes;
|
||||
>
|
||||
|
||||
<!--
|
||||
Try: http://docbook.org/xml/5.0/dtd/docbook.dtd
|
||||
-->
|
||||
|
||||
<!DOCTYPE xsl:stylesheet
|
||||
[
|
||||
<!ENTITY nbsp "&#160;">
|
||||
<!ENTITY copy "&#169;">
|
||||
<!ENTITY reg "&#174;">
|
||||
<!ENTITY trade "&#8482;">
|
||||
<!ENTITY mdash "&#8212;">
|
||||
<!ENTITY ldquo "&#8220;">
|
||||
<!ENTITY rdquo "&#8221;">
|
||||
<!ENTITY pound "&#163;">
|
||||
<!ENTITY yen "&#165;">
|
||||
<!ENTITY euro "&#8364;">
|
||||
<!ENTITY mathml "http://www.w3.org/1998/Math/MathML">
|
||||
]
|
||||
>
|
||||
|
||||
<!ELEMENT title (#PCDATA|inlinemediaobject|remark|superscript|subscript|xref|link|olink|anchor|biblioref|alt|annotation|indexterm|abbrev|acronym|date|emphasis|footnote|footnoteref|foreignphrase|phrase|quote|wordasword|firstterm|glossterm|coref|trademark|productnumber|productname|database|application|hardware|citation|citerefentry|citetitle|citebiblioid|author|person|personname|org|orgname|editor|jobtitle|replaceable|package|parameter|termdef|nonterminal|systemitem|option|optional|property|inlineequation|tag|markup|token|symbol|literal|code|constant|email|uri|guiicon|guibutton|guimenuitem|guimenu|guisubmenu|guilabel|menuchoice|mousebutton|keycombo|keycap|keycode|keysym|shortcut|accel|prompt|envar|filename|command|computeroutput|userinput|function|varname|returnvalue|type|classname|exceptionname|interfacename|methodname|modifier|initializer|ooclass|ooexception|oointerface|errorcode|errortext|errorname|errortype)*>
|
||||
|
||||
<!ENTITY % db.common.attributes "
|
||||
xml:id ID #IMPLIED
|
||||
version CDATA #IMPLIED
|
||||
xml:lang CDATA #IMPLIED
|
||||
xml:base CDATA #IMPLIED
|
||||
remap CDATA #IMPLIED
|
||||
xreflabel CDATA #IMPLIED
|
||||
revisionflag (changed|added|deleted|off) #IMPLIED
|
||||
dir (ltr|rtl|lro|rlo) #IMPLIED
|
||||
arch CDATA #IMPLIED
|
||||
audience CDATA #IMPLIED
|
||||
condition CDATA #IMPLIED
|
||||
conformance CDATA #IMPLIED
|
||||
os CDATA #IMPLIED
|
||||
revision CDATA #IMPLIED
|
||||
security CDATA #IMPLIED
|
||||
userlevel CDATA #IMPLIED
|
||||
vendor CDATA #IMPLIED
|
||||
wordsize CDATA #IMPLIED
|
||||
annotations CDATA #IMPLIED
|
||||
|
||||
"></textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: {name: "dtd", alignCDATA: true},
|
||||
lineNumbers: true,
|
||||
lineWrapping: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>application/xml-dtd</code>.</p>
|
||||
</article>
|
@ -1,299 +0,0 @@
|
||||
// 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("dylan", function(_config) {
|
||||
// Words
|
||||
var words = {
|
||||
// Words that introduce unnamed definitions like "define interface"
|
||||
unnamedDefinition: ["interface"],
|
||||
|
||||
// Words that introduce simple named definitions like "define library"
|
||||
namedDefinition: ["module", "library", "macro",
|
||||
"C-struct", "C-union",
|
||||
"C-function", "C-callable-wrapper"
|
||||
],
|
||||
|
||||
// Words that introduce type definitions like "define class".
|
||||
// These are also parameterized like "define method" and are
|
||||
// appended to otherParameterizedDefinitionWords
|
||||
typeParameterizedDefinition: ["class", "C-subtype", "C-mapped-subtype"],
|
||||
|
||||
// Words that introduce trickier definitions like "define method".
|
||||
// These require special definitions to be added to startExpressions
|
||||
otherParameterizedDefinition: ["method", "function",
|
||||
"C-variable", "C-address"
|
||||
],
|
||||
|
||||
// Words that introduce module constant definitions.
|
||||
// These must also be simple definitions and are
|
||||
// appended to otherSimpleDefinitionWords
|
||||
constantSimpleDefinition: ["constant"],
|
||||
|
||||
// Words that introduce module variable definitions.
|
||||
// These must also be simple definitions and are
|
||||
// appended to otherSimpleDefinitionWords
|
||||
variableSimpleDefinition: ["variable"],
|
||||
|
||||
// Other words that introduce simple definitions
|
||||
// (without implicit bodies).
|
||||
otherSimpleDefinition: ["generic", "domain",
|
||||
"C-pointer-type",
|
||||
"table"
|
||||
],
|
||||
|
||||
// Words that begin statements with implicit bodies.
|
||||
statement: ["if", "block", "begin", "method", "case",
|
||||
"for", "select", "when", "unless", "until",
|
||||
"while", "iterate", "profiling", "dynamic-bind"
|
||||
],
|
||||
|
||||
// Patterns that act as separators in compound statements.
|
||||
// This may include any general pattern that must be indented
|
||||
// specially.
|
||||
separator: ["finally", "exception", "cleanup", "else",
|
||||
"elseif", "afterwards"
|
||||
],
|
||||
|
||||
// Keywords that do not require special indentation handling,
|
||||
// but which should be highlighted
|
||||
other: ["above", "below", "by", "from", "handler", "in",
|
||||
"instance", "let", "local", "otherwise", "slot",
|
||||
"subclass", "then", "to", "keyed-by", "virtual"
|
||||
],
|
||||
|
||||
// Condition signaling function calls
|
||||
signalingCalls: ["signal", "error", "cerror",
|
||||
"break", "check-type", "abort"
|
||||
]
|
||||
};
|
||||
|
||||
words["otherDefinition"] =
|
||||
words["unnamedDefinition"]
|
||||
.concat(words["namedDefinition"])
|
||||
.concat(words["otherParameterizedDefinition"]);
|
||||
|
||||
words["definition"] =
|
||||
words["typeParameterizedDefinition"]
|
||||
.concat(words["otherDefinition"]);
|
||||
|
||||
words["parameterizedDefinition"] =
|
||||
words["typeParameterizedDefinition"]
|
||||
.concat(words["otherParameterizedDefinition"]);
|
||||
|
||||
words["simpleDefinition"] =
|
||||
words["constantSimpleDefinition"]
|
||||
.concat(words["variableSimpleDefinition"])
|
||||
.concat(words["otherSimpleDefinition"]);
|
||||
|
||||
words["keyword"] =
|
||||
words["statement"]
|
||||
.concat(words["separator"])
|
||||
.concat(words["other"]);
|
||||
|
||||
// Patterns
|
||||
var symbolPattern = "[-_a-zA-Z?!*@<>$%]+";
|
||||
var symbol = new RegExp("^" + symbolPattern);
|
||||
var patterns = {
|
||||
// Symbols with special syntax
|
||||
symbolKeyword: symbolPattern + ":",
|
||||
symbolClass: "<" + symbolPattern + ">",
|
||||
symbolGlobal: "\\*" + symbolPattern + "\\*",
|
||||
symbolConstant: "\\$" + symbolPattern
|
||||
};
|
||||
var patternStyles = {
|
||||
symbolKeyword: "atom",
|
||||
symbolClass: "tag",
|
||||
symbolGlobal: "variable-2",
|
||||
symbolConstant: "variable-3"
|
||||
};
|
||||
|
||||
// Compile all patterns to regular expressions
|
||||
for (var patternName in patterns)
|
||||
if (patterns.hasOwnProperty(patternName))
|
||||
patterns[patternName] = new RegExp("^" + patterns[patternName]);
|
||||
|
||||
// Names beginning "with-" and "without-" are commonly
|
||||
// used as statement macro
|
||||
patterns["keyword"] = [/^with(?:out)?-[-_a-zA-Z?!*@<>$%]+/];
|
||||
|
||||
var styles = {};
|
||||
styles["keyword"] = "keyword";
|
||||
styles["definition"] = "def";
|
||||
styles["simpleDefinition"] = "def";
|
||||
styles["signalingCalls"] = "builtin";
|
||||
|
||||
// protected words lookup table
|
||||
var wordLookup = {};
|
||||
var styleLookup = {};
|
||||
|
||||
[
|
||||
"keyword",
|
||||
"definition",
|
||||
"simpleDefinition",
|
||||
"signalingCalls"
|
||||
].forEach(function(type) {
|
||||
words[type].forEach(function(word) {
|
||||
wordLookup[word] = type;
|
||||
styleLookup[word] = styles[type];
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function chain(stream, state, f) {
|
||||
state.tokenize = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
var type, content;
|
||||
|
||||
function ret(_type, style, _content) {
|
||||
type = _type;
|
||||
content = _content;
|
||||
return style;
|
||||
}
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
// String
|
||||
var ch = stream.peek();
|
||||
if (ch == "'" || ch == '"') {
|
||||
stream.next();
|
||||
return chain(stream, state, tokenString(ch, "string", "string"));
|
||||
}
|
||||
// Comment
|
||||
else if (ch == "/") {
|
||||
stream.next();
|
||||
if (stream.eat("*")) {
|
||||
return chain(stream, state, tokenComment);
|
||||
} else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
} else {
|
||||
stream.skipTo(" ");
|
||||
return ret("operator", "operator");
|
||||
}
|
||||
}
|
||||
// Decimal
|
||||
else if (/\d/.test(ch)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
// Hash
|
||||
else if (ch == "#") {
|
||||
stream.next();
|
||||
// Symbol with string syntax
|
||||
ch = stream.peek();
|
||||
if (ch == '"') {
|
||||
stream.next();
|
||||
return chain(stream, state, tokenString('"', "symbol", "string-2"));
|
||||
}
|
||||
// Binary number
|
||||
else if (ch == "b") {
|
||||
stream.next();
|
||||
stream.eatWhile(/[01]/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
// Hex number
|
||||
else if (ch == "x") {
|
||||
stream.next();
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
// Octal number
|
||||
else if (ch == "o") {
|
||||
stream.next();
|
||||
stream.eatWhile(/[0-7]/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
// Hash symbol
|
||||
else {
|
||||
stream.eatWhile(/[-a-zA-Z]/);
|
||||
return ret("hash", "keyword");
|
||||
}
|
||||
} else if (stream.match("end")) {
|
||||
return ret("end", "keyword");
|
||||
}
|
||||
for (var name in patterns) {
|
||||
if (patterns.hasOwnProperty(name)) {
|
||||
var pattern = patterns[name];
|
||||
if ((pattern instanceof Array && pattern.some(function(p) {
|
||||
return stream.match(p);
|
||||
})) || stream.match(pattern))
|
||||
return ret(name, patternStyles[name], stream.current());
|
||||
}
|
||||
}
|
||||
if (stream.match("define")) {
|
||||
return ret("definition", "def");
|
||||
} else {
|
||||
stream.eatWhile(/[\w\-]/);
|
||||
// Keyword
|
||||
if (wordLookup[stream.current()]) {
|
||||
return ret(wordLookup[stream.current()], styleLookup[stream.current()], stream.current());
|
||||
} else if (stream.current().match(symbol)) {
|
||||
return ret("variable", "variable");
|
||||
} else {
|
||||
stream.next();
|
||||
return ret("other", "variable-2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false,
|
||||
ch;
|
||||
while ((ch = stream.next())) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
function tokenString(quote, type, style) {
|
||||
return function(stream, state) {
|
||||
var next, end = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (end)
|
||||
state.tokenize = tokenBase;
|
||||
return ret(type, style);
|
||||
};
|
||||
}
|
||||
|
||||
// Interface
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
tokenize: tokenBase,
|
||||
currentIndent: 0
|
||||
};
|
||||
},
|
||||
token: function(stream, state) {
|
||||
if (stream.eatSpace())
|
||||
return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
return style;
|
||||
},
|
||||
blockCommentStart: "/*",
|
||||
blockCommentEnd: "*/"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-dylan", "dylan");
|
||||
|
||||
});
|
@ -1,407 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Dylan mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="../../addon/comment/continuecomment.js"></script>
|
||||
<script src="../../addon/comment/comment.js"></script>
|
||||
<script src="dylan.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Dylan</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Dylan mode</h2>
|
||||
|
||||
|
||||
<div><textarea id="code" name="code">
|
||||
Module: locators-internals
|
||||
Synopsis: Abstract modeling of locations
|
||||
Author: Andy Armstrong
|
||||
Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc.
|
||||
All rights reserved.
|
||||
License: See License.txt in this distribution for details.
|
||||
Warranty: Distributed WITHOUT WARRANTY OF ANY KIND
|
||||
|
||||
define open generic locator-server
|
||||
(locator :: <locator>) => (server :: false-or(<server-locator>));
|
||||
define open generic locator-host
|
||||
(locator :: <locator>) => (host :: false-or(<string>));
|
||||
define open generic locator-volume
|
||||
(locator :: <locator>) => (volume :: false-or(<string>));
|
||||
define open generic locator-directory
|
||||
(locator :: <locator>) => (directory :: false-or(<directory-locator>));
|
||||
define open generic locator-relative?
|
||||
(locator :: <locator>) => (relative? :: <boolean>);
|
||||
define open generic locator-path
|
||||
(locator :: <locator>) => (path :: <sequence>);
|
||||
define open generic locator-base
|
||||
(locator :: <locator>) => (base :: false-or(<string>));
|
||||
define open generic locator-extension
|
||||
(locator :: <locator>) => (extension :: false-or(<string>));
|
||||
|
||||
/// Locator classes
|
||||
|
||||
define open abstract class <directory-locator> (<physical-locator>)
|
||||
end class <directory-locator>;
|
||||
|
||||
define open abstract class <file-locator> (<physical-locator>)
|
||||
end class <file-locator>;
|
||||
|
||||
define method as
|
||||
(class == <directory-locator>, string :: <string>)
|
||||
=> (locator :: <directory-locator>)
|
||||
as(<native-directory-locator>, string)
|
||||
end method as;
|
||||
|
||||
define method make
|
||||
(class == <directory-locator>,
|
||||
#key server :: false-or(<server-locator>) = #f,
|
||||
path :: <sequence> = #[],
|
||||
relative? :: <boolean> = #f,
|
||||
name :: false-or(<string>) = #f)
|
||||
=> (locator :: <directory-locator>)
|
||||
make(<native-directory-locator>,
|
||||
server: server,
|
||||
path: path,
|
||||
relative?: relative?,
|
||||
name: name)
|
||||
end method make;
|
||||
|
||||
define method as
|
||||
(class == <file-locator>, string :: <string>)
|
||||
=> (locator :: <file-locator>)
|
||||
as(<native-file-locator>, string)
|
||||
end method as;
|
||||
|
||||
define method make
|
||||
(class == <file-locator>,
|
||||
#key directory :: false-or(<directory-locator>) = #f,
|
||||
base :: false-or(<string>) = #f,
|
||||
extension :: false-or(<string>) = #f,
|
||||
name :: false-or(<string>) = #f)
|
||||
=> (locator :: <file-locator>)
|
||||
make(<native-file-locator>,
|
||||
directory: directory,
|
||||
base: base,
|
||||
extension: extension,
|
||||
name: name)
|
||||
end method make;
|
||||
|
||||
/// Locator coercion
|
||||
|
||||
//---*** andrewa: This caching scheme doesn't work yet, so disable it.
|
||||
define constant $cache-locators? = #f;
|
||||
define constant $cache-locator-strings? = #f;
|
||||
|
||||
define constant $locator-to-string-cache = make(<object-table>, weak: #"key");
|
||||
define constant $string-to-locator-cache = make(<string-table>, weak: #"value");
|
||||
|
||||
define open generic locator-as-string
|
||||
(class :: subclass(<string>), locator :: <locator>)
|
||||
=> (string :: <string>);
|
||||
|
||||
define open generic string-as-locator
|
||||
(class :: subclass(<locator>), string :: <string>)
|
||||
=> (locator :: <locator>);
|
||||
|
||||
define sealed sideways method as
|
||||
(class :: subclass(<string>), locator :: <locator>)
|
||||
=> (string :: <string>)
|
||||
let string = element($locator-to-string-cache, locator, default: #f);
|
||||
if (string)
|
||||
as(class, string)
|
||||
else
|
||||
let string = locator-as-string(class, locator);
|
||||
if ($cache-locator-strings?)
|
||||
element($locator-to-string-cache, locator) := string;
|
||||
else
|
||||
string
|
||||
end
|
||||
end
|
||||
end method as;
|
||||
|
||||
define sealed sideways method as
|
||||
(class :: subclass(<locator>), string :: <string>)
|
||||
=> (locator :: <locator>)
|
||||
let locator = element($string-to-locator-cache, string, default: #f);
|
||||
if (instance?(locator, class))
|
||||
locator
|
||||
else
|
||||
let locator = string-as-locator(class, string);
|
||||
if ($cache-locators?)
|
||||
element($string-to-locator-cache, string) := locator;
|
||||
else
|
||||
locator
|
||||
end
|
||||
end
|
||||
end method as;
|
||||
|
||||
/// Locator conditions
|
||||
|
||||
define class <locator-error> (<format-string-condition>, <error>)
|
||||
end class <locator-error>;
|
||||
|
||||
define function locator-error
|
||||
(format-string :: <string>, #rest format-arguments)
|
||||
error(make(<locator-error>,
|
||||
format-string: format-string,
|
||||
format-arguments: format-arguments))
|
||||
end function locator-error;
|
||||
|
||||
/// Useful locator protocols
|
||||
|
||||
define open generic locator-test
|
||||
(locator :: <directory-locator>) => (test :: <function>);
|
||||
|
||||
define method locator-test
|
||||
(locator :: <directory-locator>) => (test :: <function>)
|
||||
\=
|
||||
end method locator-test;
|
||||
|
||||
define open generic locator-might-have-links?
|
||||
(locator :: <directory-locator>) => (links? :: <boolean>);
|
||||
|
||||
define method locator-might-have-links?
|
||||
(locator :: <directory-locator>) => (links? :: singleton(#f))
|
||||
#f
|
||||
end method locator-might-have-links?;
|
||||
|
||||
define method locator-relative?
|
||||
(locator :: <file-locator>) => (relative? :: <boolean>)
|
||||
let directory = locator.locator-directory;
|
||||
~directory | directory.locator-relative?
|
||||
end method locator-relative?;
|
||||
|
||||
define method current-directory-locator?
|
||||
(locator :: <directory-locator>) => (current-directory? :: <boolean>)
|
||||
locator.locator-relative?
|
||||
& locator.locator-path = #[#"self"]
|
||||
end method current-directory-locator?;
|
||||
|
||||
define method locator-directory
|
||||
(locator :: <directory-locator>) => (parent :: false-or(<directory-locator>))
|
||||
let path = locator.locator-path;
|
||||
unless (empty?(path))
|
||||
make(object-class(locator),
|
||||
server: locator.locator-server,
|
||||
path: copy-sequence(path, end: path.size - 1),
|
||||
relative?: locator.locator-relative?)
|
||||
end
|
||||
end method locator-directory;
|
||||
|
||||
/// Simplify locator
|
||||
|
||||
define open generic simplify-locator
|
||||
(locator :: <physical-locator>)
|
||||
=> (simplified-locator :: <physical-locator>);
|
||||
|
||||
define method simplify-locator
|
||||
(locator :: <directory-locator>)
|
||||
=> (simplified-locator :: <directory-locator>)
|
||||
let path = locator.locator-path;
|
||||
let relative? = locator.locator-relative?;
|
||||
let resolve-parent? = ~locator.locator-might-have-links?;
|
||||
let simplified-path
|
||||
= simplify-path(path,
|
||||
resolve-parent?: resolve-parent?,
|
||||
relative?: relative?);
|
||||
if (path ~= simplified-path)
|
||||
make(object-class(locator),
|
||||
server: locator.locator-server,
|
||||
path: simplified-path,
|
||||
relative?: locator.locator-relative?)
|
||||
else
|
||||
locator
|
||||
end
|
||||
end method simplify-locator;
|
||||
|
||||
define method simplify-locator
|
||||
(locator :: <file-locator>) => (simplified-locator :: <file-locator>)
|
||||
let directory = locator.locator-directory;
|
||||
let simplified-directory = directory & simplify-locator(directory);
|
||||
if (directory ~= simplified-directory)
|
||||
make(object-class(locator),
|
||||
directory: simplified-directory,
|
||||
base: locator.locator-base,
|
||||
extension: locator.locator-extension)
|
||||
else
|
||||
locator
|
||||
end
|
||||
end method simplify-locator;
|
||||
|
||||
/// Subdirectory locator
|
||||
|
||||
define open generic subdirectory-locator
|
||||
(locator :: <directory-locator>, #rest sub-path)
|
||||
=> (subdirectory :: <directory-locator>);
|
||||
|
||||
define method subdirectory-locator
|
||||
(locator :: <directory-locator>, #rest sub-path)
|
||||
=> (subdirectory :: <directory-locator>)
|
||||
let old-path = locator.locator-path;
|
||||
let new-path = concatenate-as(<simple-object-vector>, old-path, sub-path);
|
||||
make(object-class(locator),
|
||||
server: locator.locator-server,
|
||||
path: new-path,
|
||||
relative?: locator.locator-relative?)
|
||||
end method subdirectory-locator;
|
||||
|
||||
/// Relative locator
|
||||
|
||||
define open generic relative-locator
|
||||
(locator :: <physical-locator>, from-locator :: <physical-locator>)
|
||||
=> (relative-locator :: <physical-locator>);
|
||||
|
||||
define method relative-locator
|
||||
(locator :: <directory-locator>, from-locator :: <directory-locator>)
|
||||
=> (relative-locator :: <directory-locator>)
|
||||
let path = locator.locator-path;
|
||||
let from-path = from-locator.locator-path;
|
||||
case
|
||||
~locator.locator-relative? & from-locator.locator-relative? =>
|
||||
locator-error
|
||||
("Cannot find relative path of absolute locator %= from relative locator %=",
|
||||
locator, from-locator);
|
||||
locator.locator-server ~= from-locator.locator-server =>
|
||||
locator;
|
||||
path = from-path =>
|
||||
make(object-class(locator),
|
||||
path: vector(#"self"),
|
||||
relative?: #t);
|
||||
otherwise =>
|
||||
make(object-class(locator),
|
||||
path: relative-path(path, from-path, test: locator.locator-test),
|
||||
relative?: #t);
|
||||
end
|
||||
end method relative-locator;
|
||||
|
||||
define method relative-locator
|
||||
(locator :: <file-locator>, from-directory :: <directory-locator>)
|
||||
=> (relative-locator :: <file-locator>)
|
||||
let directory = locator.locator-directory;
|
||||
let relative-directory = directory & relative-locator(directory, from-directory);
|
||||
if (relative-directory ~= directory)
|
||||
simplify-locator
|
||||
(make(object-class(locator),
|
||||
directory: relative-directory,
|
||||
base: locator.locator-base,
|
||||
extension: locator.locator-extension))
|
||||
else
|
||||
locator
|
||||
end
|
||||
end method relative-locator;
|
||||
|
||||
define method relative-locator
|
||||
(locator :: <physical-locator>, from-locator :: <file-locator>)
|
||||
=> (relative-locator :: <physical-locator>)
|
||||
let from-directory = from-locator.locator-directory;
|
||||
case
|
||||
from-directory =>
|
||||
relative-locator(locator, from-directory);
|
||||
~locator.locator-relative? =>
|
||||
locator-error
|
||||
("Cannot find relative path of absolute locator %= from relative locator %=",
|
||||
locator, from-locator);
|
||||
otherwise =>
|
||||
locator;
|
||||
end
|
||||
end method relative-locator;
|
||||
|
||||
/// Merge locators
|
||||
|
||||
define open generic merge-locators
|
||||
(locator :: <physical-locator>, from-locator :: <physical-locator>)
|
||||
=> (merged-locator :: <physical-locator>);
|
||||
|
||||
/// Merge locators
|
||||
|
||||
define method merge-locators
|
||||
(locator :: <directory-locator>, from-locator :: <directory-locator>)
|
||||
=> (merged-locator :: <directory-locator>)
|
||||
if (locator.locator-relative?)
|
||||
let path = concatenate(from-locator.locator-path, locator.locator-path);
|
||||
simplify-locator
|
||||
(make(object-class(locator),
|
||||
server: from-locator.locator-server,
|
||||
path: path,
|
||||
relative?: from-locator.locator-relative?))
|
||||
else
|
||||
locator
|
||||
end
|
||||
end method merge-locators;
|
||||
|
||||
define method merge-locators
|
||||
(locator :: <file-locator>, from-locator :: <directory-locator>)
|
||||
=> (merged-locator :: <file-locator>)
|
||||
let directory = locator.locator-directory;
|
||||
let merged-directory
|
||||
= if (directory)
|
||||
merge-locators(directory, from-locator)
|
||||
else
|
||||
simplify-locator(from-locator)
|
||||
end;
|
||||
if (merged-directory ~= directory)
|
||||
make(object-class(locator),
|
||||
directory: merged-directory,
|
||||
base: locator.locator-base,
|
||||
extension: locator.locator-extension)
|
||||
else
|
||||
locator
|
||||
end
|
||||
end method merge-locators;
|
||||
|
||||
define method merge-locators
|
||||
(locator :: <physical-locator>, from-locator :: <file-locator>)
|
||||
=> (merged-locator :: <physical-locator>)
|
||||
let from-directory = from-locator.locator-directory;
|
||||
if (from-directory)
|
||||
merge-locators(locator, from-directory)
|
||||
else
|
||||
locator
|
||||
end
|
||||
end method merge-locators;
|
||||
|
||||
/// Locator protocols
|
||||
|
||||
define sideways method supports-open-locator?
|
||||
(locator :: <file-locator>) => (openable? :: <boolean>)
|
||||
~locator.locator-relative?
|
||||
end method supports-open-locator?;
|
||||
|
||||
define sideways method open-locator
|
||||
(locator :: <file-locator>, #rest keywords, #key, #all-keys)
|
||||
=> (stream :: <stream>)
|
||||
apply(open-file-stream, locator, keywords)
|
||||
end method open-locator;
|
||||
</textarea></div>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "text/x-dylan",
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
continueComments: "Enter",
|
||||
extraKeys: {"Ctrl-Q": "toggleComment"},
|
||||
tabMode: "indent",
|
||||
indentUnit: 2
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-dylan</code>.</p>
|
||||
</article>
|
@ -1,207 +0,0 @@
|
||||
// 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("ecl", function(config) {
|
||||
|
||||
function words(str) {
|
||||
var obj = {}, words = str.split(" ");
|
||||
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
function metaHook(stream, state) {
|
||||
if (!state.startOfLine) return false;
|
||||
stream.skipToEnd();
|
||||
return "meta";
|
||||
}
|
||||
|
||||
var indentUnit = config.indentUnit;
|
||||
var keyword = words("abs acos allnodes ascii asin asstring atan atan2 ave case choose choosen choosesets clustersize combine correlation cos cosh count covariance cron dataset dedup define denormalize distribute distributed distribution ebcdic enth error evaluate event eventextra eventname exists exp failcode failmessage fetch fromunicode getisvalid global graph group hash hash32 hash64 hashcrc hashmd5 having if index intformat isvalid iterate join keyunicode length library limit ln local log loop map matched matchlength matchposition matchtext matchunicode max merge mergejoin min nolocal nonempty normalize parse pipe power preload process project pull random range rank ranked realformat recordof regexfind regexreplace regroup rejected rollup round roundup row rowdiff sample set sin sinh sizeof soapcall sort sorted sqrt stepped stored sum table tan tanh thisnode topn tounicode transfer trim truncate typeof ungroup unicodeorder variance which workunit xmldecode xmlencode xmltext xmlunicode");
|
||||
var variable = words("apply assert build buildindex evaluate fail keydiff keypatch loadxml nothor notify output parallel sequential soapcall wait");
|
||||
var variable_2 = words("__compressed__ all and any as atmost before beginc++ best between case const counter csv descend encrypt end endc++ endmacro except exclusive expire export extend false few first flat from full function group header heading hole ifblock import in interface joined keep keyed last left limit load local locale lookup macro many maxcount maxlength min skew module named nocase noroot noscan nosort not of only opt or outer overwrite packed partition penalty physicallength pipe quote record relationship repeat return right scan self separator service shared skew skip sql store terminator thor threshold token transform trim true type unicodeorder unsorted validate virtual whole wild within xml xpath");
|
||||
var variable_3 = words("ascii big_endian boolean data decimal ebcdic integer pattern qstring real record rule set of string token udecimal unicode unsigned varstring varunicode");
|
||||
var builtin = words("checkpoint deprecated failcode failmessage failure global independent onwarning persist priority recovery stored success wait when");
|
||||
var blockKeywords = words("catch class do else finally for if switch try while");
|
||||
var atoms = words("true false null");
|
||||
var hooks = {"#": metaHook};
|
||||
var multiLineStrings;
|
||||
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
|
||||
|
||||
var curPunc;
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (hooks[ch]) {
|
||||
var result = hooks[ch](stream, state);
|
||||
if (result !== false) return result;
|
||||
}
|
||||
if (ch == '"' || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
||||
curPunc = ch;
|
||||
return null;
|
||||
}
|
||||
if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
return "number";
|
||||
}
|
||||
if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
state.tokenize = tokenComment;
|
||||
return tokenComment(stream, state);
|
||||
}
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
}
|
||||
if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return "operator";
|
||||
}
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
var cur = stream.current().toLowerCase();
|
||||
if (keyword.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "keyword";
|
||||
} else if (variable.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "variable";
|
||||
} else if (variable_2.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "variable-2";
|
||||
} else if (variable_3.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "variable-3";
|
||||
} else if (builtin.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "builtin";
|
||||
} else { //Data types are of from KEYWORD##
|
||||
var i = cur.length - 1;
|
||||
while(i >= 0 && (!isNaN(cur[i]) || cur[i] == '_'))
|
||||
--i;
|
||||
|
||||
if (i > 0) {
|
||||
var cur2 = cur.substr(0, i + 1);
|
||||
if (variable_3.propertyIsEnumerable(cur2)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur2)) curPunc = "newstatement";
|
||||
return "variable-3";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (atoms.propertyIsEnumerable(cur)) return "atom";
|
||||
return null;
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, next, end = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote && !escaped) {end = true; break;}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
if (end || !(escaped || multiLineStrings))
|
||||
state.tokenize = tokenBase;
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function Context(indented, column, type, align, prev) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.align = align;
|
||||
this.prev = prev;
|
||||
}
|
||||
function pushContext(state, col, type) {
|
||||
return state.context = new Context(state.indented, col, type, null, state.context);
|
||||
}
|
||||
function popContext(state) {
|
||||
var t = state.context.type;
|
||||
if (t == ")" || t == "]" || t == "}")
|
||||
state.indented = state.context.indented;
|
||||
return state.context = state.context.prev;
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: null,
|
||||
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
|
||||
indented: 0,
|
||||
startOfLine: true
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var ctx = state.context;
|
||||
if (stream.sol()) {
|
||||
if (ctx.align == null) ctx.align = false;
|
||||
state.indented = stream.indentation();
|
||||
state.startOfLine = true;
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
curPunc = null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style == "comment" || style == "meta") return style;
|
||||
if (ctx.align == null) ctx.align = true;
|
||||
|
||||
if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
|
||||
else if (curPunc == "{") pushContext(state, stream.column(), "}");
|
||||
else if (curPunc == "[") pushContext(state, stream.column(), "]");
|
||||
else if (curPunc == "(") pushContext(state, stream.column(), ")");
|
||||
else if (curPunc == "}") {
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
if (ctx.type == "}") ctx = popContext(state);
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
}
|
||||
else if (curPunc == ctx.type) popContext(state);
|
||||
else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
|
||||
pushContext(state, stream.column(), "statement");
|
||||
state.startOfLine = false;
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase && state.tokenize != null) return 0;
|
||||
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
||||
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
||||
var closing = firstChar == ctx.type;
|
||||
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
|
||||
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
|
||||
else return ctx.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: "{}"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-ecl", "ecl");
|
||||
|
||||
});
|
@ -1,52 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: ECL mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="ecl.js"></script>
|
||||
<style>.CodeMirror {border: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">ECL</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>ECL mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
/*
|
||||
sample useless code to demonstrate ecl syntax highlighting
|
||||
this is a multiline comment!
|
||||
*/
|
||||
|
||||
// this is a singleline comment!
|
||||
|
||||
import ut;
|
||||
r :=
|
||||
record
|
||||
string22 s1 := '123';
|
||||
integer4 i1 := 123;
|
||||
end;
|
||||
#option('tmp', true);
|
||||
d := dataset('tmp::qb', r, thor);
|
||||
output(d);
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p>Based on CodeMirror's clike mode. For more information see <a href="http://hpccsystems.com">HPCC Systems</a> web site.</p>
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-ecl</code>.</p>
|
||||
|
||||
</article>
|
@ -1,162 +0,0 @@
|
||||
// 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("eiffel", function() {
|
||||
function wordObj(words) {
|
||||
var o = {};
|
||||
for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
|
||||
return o;
|
||||
}
|
||||
var keywords = wordObj([
|
||||
'note',
|
||||
'across',
|
||||
'when',
|
||||
'variant',
|
||||
'until',
|
||||
'unique',
|
||||
'undefine',
|
||||
'then',
|
||||
'strip',
|
||||
'select',
|
||||
'retry',
|
||||
'rescue',
|
||||
'require',
|
||||
'rename',
|
||||
'reference',
|
||||
'redefine',
|
||||
'prefix',
|
||||
'once',
|
||||
'old',
|
||||
'obsolete',
|
||||
'loop',
|
||||
'local',
|
||||
'like',
|
||||
'is',
|
||||
'inspect',
|
||||
'infix',
|
||||
'include',
|
||||
'if',
|
||||
'frozen',
|
||||
'from',
|
||||
'external',
|
||||
'export',
|
||||
'ensure',
|
||||
'end',
|
||||
'elseif',
|
||||
'else',
|
||||
'do',
|
||||
'creation',
|
||||
'create',
|
||||
'check',
|
||||
'alias',
|
||||
'agent',
|
||||
'separate',
|
||||
'invariant',
|
||||
'inherit',
|
||||
'indexing',
|
||||
'feature',
|
||||
'expanded',
|
||||
'deferred',
|
||||
'class',
|
||||
'Void',
|
||||
'True',
|
||||
'Result',
|
||||
'Precursor',
|
||||
'False',
|
||||
'Current',
|
||||
'create',
|
||||
'attached',
|
||||
'detachable',
|
||||
'as',
|
||||
'and',
|
||||
'implies',
|
||||
'not',
|
||||
'or'
|
||||
]);
|
||||
var operators = wordObj([":=", "and then","and", "or","<<",">>"]);
|
||||
var curPunc;
|
||||
|
||||
function chain(newtok, stream, state) {
|
||||
state.tokenize.push(newtok);
|
||||
return newtok(stream, state);
|
||||
}
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
curPunc = null;
|
||||
if (stream.eatSpace()) return null;
|
||||
var ch = stream.next();
|
||||
if (ch == '"'||ch == "'") {
|
||||
return chain(readQuoted(ch, "string"), stream, state);
|
||||
} else if (ch == "-"&&stream.eat("-")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
} else if (ch == ":"&&stream.eat("=")) {
|
||||
return "operator";
|
||||
} else if (/[0-9]/.test(ch)) {
|
||||
stream.eatWhile(/[xXbBCc0-9\.]/);
|
||||
stream.eat(/[\?\!]/);
|
||||
return "ident";
|
||||
} else if (/[a-zA-Z_0-9]/.test(ch)) {
|
||||
stream.eatWhile(/[a-zA-Z_0-9]/);
|
||||
stream.eat(/[\?\!]/);
|
||||
return "ident";
|
||||
} else if (/[=+\-\/*^%<>~]/.test(ch)) {
|
||||
stream.eatWhile(/[=+\-\/*^%<>~]/);
|
||||
return "operator";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function readQuoted(quote, style, unescaped) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == quote && (unescaped || !escaped)) {
|
||||
state.tokenize.pop();
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && ch == "%";
|
||||
}
|
||||
return style;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {tokenize: [tokenBase]};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var style = state.tokenize[state.tokenize.length-1](stream, state);
|
||||
if (style == "ident") {
|
||||
var word = stream.current();
|
||||
style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
|
||||
: operators.propertyIsEnumerable(stream.current()) ? "operator"
|
||||
: /^[A-Z][A-Z_0-9]*$/g.test(word) ? "tag"
|
||||
: /^0[bB][0-1]+$/g.test(word) ? "number"
|
||||
: /^0[cC][0-7]+$/g.test(word) ? "number"
|
||||
: /^0[xX][a-fA-F0-9]+$/g.test(word) ? "number"
|
||||
: /^([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)$/g.test(word) ? "number"
|
||||
: /^[0-9]+$/g.test(word) ? "number"
|
||||
: "variable";
|
||||
}
|
||||
return style;
|
||||
},
|
||||
lineComment: "--"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-eiffel", "eiffel");
|
||||
|
||||
});
|
@ -1,429 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Eiffel mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../../theme/neat.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="eiffel.js"></script>
|
||||
<style>
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
.cm-s-default span.cm-arrow { color: red; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Eiffel</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Eiffel mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
note
|
||||
description: "[
|
||||
Project-wide universal properties.
|
||||
This class is an ancestor to all developer-written classes.
|
||||
ANY may be customized for individual projects or teams.
|
||||
]"
|
||||
|
||||
library: "Free implementation of ELKS library"
|
||||
status: "See notice at end of class."
|
||||
legal: "See notice at end of class."
|
||||
date: "$Date: 2013-01-25 11:49:00 -0800 (Fri, 25 Jan 2013) $"
|
||||
revision: "$Revision: 712 $"
|
||||
|
||||
class
|
||||
ANY
|
||||
|
||||
feature -- Customization
|
||||
|
||||
feature -- Access
|
||||
|
||||
generator: STRING
|
||||
-- Name of current object's generating class
|
||||
-- (base class of the type of which it is a direct instance)
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
generator_not_void: Result /= Void
|
||||
generator_not_empty: not Result.is_empty
|
||||
end
|
||||
|
||||
generating_type: TYPE [detachable like Current]
|
||||
-- Type of current object
|
||||
-- (type of which it is a direct instance)
|
||||
do
|
||||
Result := {detachable like Current}
|
||||
ensure
|
||||
generating_type_not_void: Result /= Void
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
conforms_to (other: ANY): BOOLEAN
|
||||
-- Does type of current object conform to type
|
||||
-- of `other' (as per Eiffel: The Language, chapter 13)?
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
external
|
||||
"built_in"
|
||||
end
|
||||
|
||||
same_type (other: ANY): BOOLEAN
|
||||
-- Is type of current object identical to type of `other'?
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
definition: Result = (conforms_to (other) and
|
||||
other.conforms_to (Current))
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_equal (other: like Current): BOOLEAN
|
||||
-- Is `other' attached to an object considered
|
||||
-- equal to current object?
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
symmetric: Result implies other ~ Current
|
||||
consistent: standard_is_equal (other) implies Result
|
||||
end
|
||||
|
||||
frozen standard_is_equal (other: like Current): BOOLEAN
|
||||
-- Is `other' attached to an object of the same type
|
||||
-- as current object, and field-by-field identical to it?
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
same_type: Result implies same_type (other)
|
||||
symmetric: Result implies other.standard_is_equal (Current)
|
||||
end
|
||||
|
||||
frozen equal (a: detachable ANY; b: like a): BOOLEAN
|
||||
-- Are `a' and `b' either both void or attached
|
||||
-- to objects considered equal?
|
||||
do
|
||||
if a = Void then
|
||||
Result := b = Void
|
||||
else
|
||||
Result := b /= Void and then
|
||||
a.is_equal (b)
|
||||
end
|
||||
ensure
|
||||
definition: Result = (a = Void and b = Void) or else
|
||||
((a /= Void and b /= Void) and then
|
||||
a.is_equal (b))
|
||||
end
|
||||
|
||||
frozen standard_equal (a: detachable ANY; b: like a): BOOLEAN
|
||||
-- Are `a' and `b' either both void or attached to
|
||||
-- field-by-field identical objects of the same type?
|
||||
-- Always uses default object comparison criterion.
|
||||
do
|
||||
if a = Void then
|
||||
Result := b = Void
|
||||
else
|
||||
Result := b /= Void and then
|
||||
a.standard_is_equal (b)
|
||||
end
|
||||
ensure
|
||||
definition: Result = (a = Void and b = Void) or else
|
||||
((a /= Void and b /= Void) and then
|
||||
a.standard_is_equal (b))
|
||||
end
|
||||
|
||||
frozen is_deep_equal (other: like Current): BOOLEAN
|
||||
-- Are `Current' and `other' attached to isomorphic object structures?
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
shallow_implies_deep: standard_is_equal (other) implies Result
|
||||
same_type: Result implies same_type (other)
|
||||
symmetric: Result implies other.is_deep_equal (Current)
|
||||
end
|
||||
|
||||
frozen deep_equal (a: detachable ANY; b: like a): BOOLEAN
|
||||
-- Are `a' and `b' either both void
|
||||
-- or attached to isomorphic object structures?
|
||||
do
|
||||
if a = Void then
|
||||
Result := b = Void
|
||||
else
|
||||
Result := b /= Void and then a.is_deep_equal (b)
|
||||
end
|
||||
ensure
|
||||
shallow_implies_deep: standard_equal (a, b) implies Result
|
||||
both_or_none_void: (a = Void) implies (Result = (b = Void))
|
||||
same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b))
|
||||
symmetric: Result implies deep_equal (b, a)
|
||||
end
|
||||
|
||||
feature -- Duplication
|
||||
|
||||
frozen twin: like Current
|
||||
-- New object equal to `Current'
|
||||
-- `twin' calls `copy'; to change copying/twinning semantics, redefine `copy'.
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
twin_not_void: Result /= Void
|
||||
is_equal: Result ~ Current
|
||||
end
|
||||
|
||||
copy (other: like Current)
|
||||
-- Update current object using fields of object attached
|
||||
-- to `other', so as to yield equal objects.
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
type_identity: same_type (other)
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
is_equal: Current ~ other
|
||||
end
|
||||
|
||||
frozen standard_copy (other: like Current)
|
||||
-- Copy every field of `other' onto corresponding field
|
||||
-- of current object.
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
type_identity: same_type (other)
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
is_standard_equal: standard_is_equal (other)
|
||||
end
|
||||
|
||||
frozen clone (other: detachable ANY): like other
|
||||
-- Void if `other' is void; otherwise new object
|
||||
-- equal to `other'
|
||||
--
|
||||
-- For non-void `other', `clone' calls `copy';
|
||||
-- to change copying/cloning semantics, redefine `copy'.
|
||||
obsolete
|
||||
"Use `twin' instead."
|
||||
do
|
||||
if other /= Void then
|
||||
Result := other.twin
|
||||
end
|
||||
ensure
|
||||
equal: Result ~ other
|
||||
end
|
||||
|
||||
frozen standard_clone (other: detachable ANY): like other
|
||||
-- Void if `other' is void; otherwise new object
|
||||
-- field-by-field identical to `other'.
|
||||
-- Always uses default copying semantics.
|
||||
obsolete
|
||||
"Use `standard_twin' instead."
|
||||
do
|
||||
if other /= Void then
|
||||
Result := other.standard_twin
|
||||
end
|
||||
ensure
|
||||
equal: standard_equal (Result, other)
|
||||
end
|
||||
|
||||
frozen standard_twin: like Current
|
||||
-- New object field-by-field identical to `other'.
|
||||
-- Always uses default copying semantics.
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
standard_twin_not_void: Result /= Void
|
||||
equal: standard_equal (Result, Current)
|
||||
end
|
||||
|
||||
frozen deep_twin: like Current
|
||||
-- New object structure recursively duplicated from Current.
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
deep_twin_not_void: Result /= Void
|
||||
deep_equal: deep_equal (Current, Result)
|
||||
end
|
||||
|
||||
frozen deep_clone (other: detachable ANY): like other
|
||||
-- Void if `other' is void: otherwise, new object structure
|
||||
-- recursively duplicated from the one attached to `other'
|
||||
obsolete
|
||||
"Use `deep_twin' instead."
|
||||
do
|
||||
if other /= Void then
|
||||
Result := other.deep_twin
|
||||
end
|
||||
ensure
|
||||
deep_equal: deep_equal (other, Result)
|
||||
end
|
||||
|
||||
frozen deep_copy (other: like Current)
|
||||
-- Effect equivalent to that of:
|
||||
-- `copy' (`other' . `deep_twin')
|
||||
require
|
||||
other_not_void: other /= Void
|
||||
do
|
||||
copy (other.deep_twin)
|
||||
ensure
|
||||
deep_equal: deep_equal (Current, other)
|
||||
end
|
||||
|
||||
feature {NONE} -- Retrieval
|
||||
|
||||
frozen internal_correct_mismatch
|
||||
-- Called from runtime to perform a proper dynamic dispatch on `correct_mismatch'
|
||||
-- from MISMATCH_CORRECTOR.
|
||||
local
|
||||
l_msg: STRING
|
||||
l_exc: EXCEPTIONS
|
||||
do
|
||||
if attached {MISMATCH_CORRECTOR} Current as l_corrector then
|
||||
l_corrector.correct_mismatch
|
||||
else
|
||||
create l_msg.make_from_string ("Mismatch: ")
|
||||
create l_exc
|
||||
l_msg.append (generating_type.name)
|
||||
l_exc.raise_retrieval_exception (l_msg)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
io: STD_FILES
|
||||
-- Handle to standard file setup
|
||||
once
|
||||
create Result
|
||||
Result.set_output_default
|
||||
ensure
|
||||
io_not_void: Result /= Void
|
||||
end
|
||||
|
||||
out: STRING
|
||||
-- New string containing terse printable representation
|
||||
-- of current object
|
||||
do
|
||||
Result := tagged_out
|
||||
ensure
|
||||
out_not_void: Result /= Void
|
||||
end
|
||||
|
||||
frozen tagged_out: STRING
|
||||
-- New string containing terse printable representation
|
||||
-- of current object
|
||||
external
|
||||
"built_in"
|
||||
ensure
|
||||
tagged_out_not_void: Result /= Void
|
||||
end
|
||||
|
||||
print (o: detachable ANY)
|
||||
-- Write terse external representation of `o'
|
||||
-- on standard output.
|
||||
do
|
||||
if o /= Void then
|
||||
io.put_string (o.out)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Platform
|
||||
|
||||
Operating_environment: OPERATING_ENVIRONMENT
|
||||
-- Objects available from the operating system
|
||||
once
|
||||
create Result
|
||||
ensure
|
||||
operating_environment_not_void: Result /= Void
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Process instances of classes with no creation clause.
|
||||
-- (Default: do nothing.)
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
default_rescue
|
||||
-- Process exception for routines with no Rescue clause.
|
||||
-- (Default: do nothing.)
|
||||
do
|
||||
end
|
||||
|
||||
frozen do_nothing
|
||||
-- Execute a null action.
|
||||
do
|
||||
end
|
||||
|
||||
frozen default: detachable like Current
|
||||
-- Default value of object's type
|
||||
do
|
||||
end
|
||||
|
||||
frozen default_pointer: POINTER
|
||||
-- Default value of type `POINTER'
|
||||
-- (Avoid the need to write `p'.`default' for
|
||||
-- some `p' of type `POINTER'.)
|
||||
do
|
||||
ensure
|
||||
-- Result = Result.default
|
||||
end
|
||||
|
||||
frozen as_attached: attached like Current
|
||||
-- Attached version of Current
|
||||
-- (Can be used during transitional period to convert
|
||||
-- non-void-safe classes to void-safe ones.)
|
||||
do
|
||||
Result := Current
|
||||
end
|
||||
|
||||
invariant
|
||||
reflexive_equality: standard_is_equal (Current)
|
||||
reflexive_conformance: conforms_to (Current)
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "text/x-eiffel",
|
||||
indentUnit: 4,
|
||||
lineNumbers: true,
|
||||
theme: "neat"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-eiffel</code>.</p>
|
||||
|
||||
<p> Created by <a href="https://github.com/ynh">YNH</a>.</p>
|
||||
</article>
|
@ -1,622 +0,0 @@
|
||||
// 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 (is_member(w,operatorAtomWords)) {
|
||||
return rval(state,stream,"operator");
|
||||
}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 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) {
|
||||
var last = s.length-1;
|
||||
|
||||
if (s[last].type === "dot") {
|
||||
return [];
|
||||
}
|
||||
if (s[last].type === "fun" && s[last-1].token === "fun") {
|
||||
return s.slice(0,last-1);
|
||||
}
|
||||
switch (s[s.length-1].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: "%"
|
||||
};
|
||||
});
|
||||
|
||||
});
|
@ -1,76 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Erlang mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../../theme/erlang-dark.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="erlang.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Erlang</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Erlang mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
%% -*- mode: erlang; erlang-indent-level: 2 -*-
|
||||
%%% Created : 7 May 2012 by mats cronqvist <masse@klarna.com>
|
||||
|
||||
%% @doc
|
||||
%% Demonstrates how to print a record.
|
||||
%% @end
|
||||
|
||||
-module('ex').
|
||||
-author('mats cronqvist').
|
||||
-export([demo/0,
|
||||
rec_info/1]).
|
||||
|
||||
-record(demo,{a="One",b="Two",c="Three",d="Four"}).
|
||||
|
||||
rec_info(demo) -> record_info(fields,demo).
|
||||
|
||||
demo() -> expand_recs(?MODULE,#demo{a="A",b="BB"}).
|
||||
|
||||
expand_recs(M,List) when is_list(List) ->
|
||||
[expand_recs(M,L)||L<-List];
|
||||
expand_recs(M,Tup) when is_tuple(Tup) ->
|
||||
case tuple_size(Tup) of
|
||||
L when L < 1 -> Tup;
|
||||
L ->
|
||||
try
|
||||
Fields = M:rec_info(element(1,Tup)),
|
||||
L = length(Fields)+1,
|
||||
lists:zip(Fields,expand_recs(M,tl(tuple_to_list(Tup))))
|
||||
catch
|
||||
_:_ -> list_to_tuple(expand_recs(M,tuple_to_list(Tup)))
|
||||
end
|
||||
end;
|
||||
expand_recs(_,Term) ->
|
||||
Term.
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
extraKeys: {"Tab": "indentAuto"},
|
||||
theme: "erlang-dark"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-erlang</code>.</p>
|
||||
</article>
|
@ -1,188 +0,0 @@
|
||||
// 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("fortran", function() {
|
||||
function words(array) {
|
||||
var keys = {};
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
keys[array[i]] = true;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
var keywords = words([
|
||||
"abstract", "accept", "allocatable", "allocate",
|
||||
"array", "assign", "asynchronous", "backspace",
|
||||
"bind", "block", "byte", "call", "case",
|
||||
"class", "close", "common", "contains",
|
||||
"continue", "cycle", "data", "deallocate",
|
||||
"decode", "deferred", "dimension", "do",
|
||||
"elemental", "else", "encode", "end",
|
||||
"endif", "entry", "enumerator", "equivalence",
|
||||
"exit", "external", "extrinsic", "final",
|
||||
"forall", "format", "function", "generic",
|
||||
"go", "goto", "if", "implicit", "import", "include",
|
||||
"inquire", "intent", "interface", "intrinsic",
|
||||
"module", "namelist", "non_intrinsic",
|
||||
"non_overridable", "none", "nopass",
|
||||
"nullify", "open", "optional", "options",
|
||||
"parameter", "pass", "pause", "pointer",
|
||||
"print", "private", "program", "protected",
|
||||
"public", "pure", "read", "recursive", "result",
|
||||
"return", "rewind", "save", "select", "sequence",
|
||||
"stop", "subroutine", "target", "then", "to", "type",
|
||||
"use", "value", "volatile", "where", "while",
|
||||
"write"]);
|
||||
var builtins = words(["abort", "abs", "access", "achar", "acos",
|
||||
"adjustl", "adjustr", "aimag", "aint", "alarm",
|
||||
"all", "allocated", "alog", "amax", "amin",
|
||||
"amod", "and", "anint", "any", "asin",
|
||||
"associated", "atan", "besj", "besjn", "besy",
|
||||
"besyn", "bit_size", "btest", "cabs", "ccos",
|
||||
"ceiling", "cexp", "char", "chdir", "chmod",
|
||||
"clog", "cmplx", "command_argument_count",
|
||||
"complex", "conjg", "cos", "cosh", "count",
|
||||
"cpu_time", "cshift", "csin", "csqrt", "ctime",
|
||||
"c_funloc", "c_loc", "c_associated", "c_null_ptr",
|
||||
"c_null_funptr", "c_f_pointer", "c_null_char",
|
||||
"c_alert", "c_backspace", "c_form_feed",
|
||||
"c_new_line", "c_carriage_return",
|
||||
"c_horizontal_tab", "c_vertical_tab", "dabs",
|
||||
"dacos", "dasin", "datan", "date_and_time",
|
||||
"dbesj", "dbesj", "dbesjn", "dbesy", "dbesy",
|
||||
"dbesyn", "dble", "dcos", "dcosh", "ddim", "derf",
|
||||
"derfc", "dexp", "digits", "dim", "dint", "dlog",
|
||||
"dlog", "dmax", "dmin", "dmod", "dnint",
|
||||
"dot_product", "dprod", "dsign", "dsinh",
|
||||
"dsin", "dsqrt", "dtanh", "dtan", "dtime",
|
||||
"eoshift", "epsilon", "erf", "erfc", "etime",
|
||||
"exit", "exp", "exponent", "extends_type_of",
|
||||
"fdate", "fget", "fgetc", "float", "floor",
|
||||
"flush", "fnum", "fputc", "fput", "fraction",
|
||||
"fseek", "fstat", "ftell", "gerror", "getarg",
|
||||
"get_command", "get_command_argument",
|
||||
"get_environment_variable", "getcwd",
|
||||
"getenv", "getgid", "getlog", "getpid",
|
||||
"getuid", "gmtime", "hostnm", "huge", "iabs",
|
||||
"iachar", "iand", "iargc", "ibclr", "ibits",
|
||||
"ibset", "ichar", "idate", "idim", "idint",
|
||||
"idnint", "ieor", "ierrno", "ifix", "imag",
|
||||
"imagpart", "index", "int", "ior", "irand",
|
||||
"isatty", "ishft", "ishftc", "isign",
|
||||
"iso_c_binding", "is_iostat_end", "is_iostat_eor",
|
||||
"itime", "kill", "kind", "lbound", "len", "len_trim",
|
||||
"lge", "lgt", "link", "lle", "llt", "lnblnk", "loc",
|
||||
"log", "logical", "long", "lshift", "lstat", "ltime",
|
||||
"matmul", "max", "maxexponent", "maxloc", "maxval",
|
||||
"mclock", "merge", "move_alloc", "min", "minexponent",
|
||||
"minloc", "minval", "mod", "modulo", "mvbits",
|
||||
"nearest", "new_line", "nint", "not", "or", "pack",
|
||||
"perror", "precision", "present", "product", "radix",
|
||||
"rand", "random_number", "random_seed", "range",
|
||||
"real", "realpart", "rename", "repeat", "reshape",
|
||||
"rrspacing", "rshift", "same_type_as", "scale",
|
||||
"scan", "second", "selected_int_kind",
|
||||
"selected_real_kind", "set_exponent", "shape",
|
||||
"short", "sign", "signal", "sinh", "sin", "sleep",
|
||||
"sngl", "spacing", "spread", "sqrt", "srand", "stat",
|
||||
"sum", "symlnk", "system", "system_clock", "tan",
|
||||
"tanh", "time", "tiny", "transfer", "transpose",
|
||||
"trim", "ttynam", "ubound", "umask", "unlink",
|
||||
"unpack", "verify", "xor", "zabs", "zcos", "zexp",
|
||||
"zlog", "zsin", "zsqrt"]);
|
||||
|
||||
var dataTypes = words(["c_bool", "c_char", "c_double", "c_double_complex",
|
||||
"c_float", "c_float_complex", "c_funptr", "c_int",
|
||||
"c_int16_t", "c_int32_t", "c_int64_t", "c_int8_t",
|
||||
"c_int_fast16_t", "c_int_fast32_t", "c_int_fast64_t",
|
||||
"c_int_fast8_t", "c_int_least16_t", "c_int_least32_t",
|
||||
"c_int_least64_t", "c_int_least8_t", "c_intmax_t",
|
||||
"c_intptr_t", "c_long", "c_long_double",
|
||||
"c_long_double_complex", "c_long_long", "c_ptr",
|
||||
"c_short", "c_signed_char", "c_size_t", "character",
|
||||
"complex", "double", "integer", "logical", "real"]);
|
||||
var isOperatorChar = /[+\-*&=<>\/\:]/;
|
||||
var litOperator = new RegExp("(\.and\.|\.or\.|\.eq\.|\.lt\.|\.le\.|\.gt\.|\.ge\.|\.ne\.|\.not\.|\.eqv\.|\.neqv\.)", "i");
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
|
||||
if (stream.match(litOperator)){
|
||||
return 'operator';
|
||||
}
|
||||
|
||||
var ch = stream.next();
|
||||
if (ch == "!") {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
if (ch == '"' || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
if (/[\[\]\(\),]/.test(ch)) {
|
||||
return null;
|
||||
}
|
||||
if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
return "number";
|
||||
}
|
||||
if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return "operator";
|
||||
}
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
var word = stream.current().toLowerCase();
|
||||
|
||||
if (keywords.hasOwnProperty(word)){
|
||||
return 'keyword';
|
||||
}
|
||||
if (builtins.hasOwnProperty(word) || dataTypes.hasOwnProperty(word)) {
|
||||
return 'builtin';
|
||||
}
|
||||
return "variable";
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, next, end = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote && !escaped) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
if (end || !escaped) state.tokenize = null;
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {tokenize: null};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.eatSpace()) return null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style == "comment" || style == "meta") return style;
|
||||
return style;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-fortran", "fortran");
|
||||
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user