mirror of
https://github.com/documize/community.git
synced 2025-07-22 22:59:43 +02:00
upgraded libs and improved Markdown editing experience
This commit is contained in:
parent
2e146cf767
commit
ea1a8000ee
165 changed files with 15930 additions and 19013 deletions
|
@ -8,7 +8,7 @@ The mission is to bring software dev inspired features (refactoring, testing, li
|
|||
|
||||
## Latest version
|
||||
|
||||
v0.43.0
|
||||
v0.43.1
|
||||
|
||||
## OS Support
|
||||
|
||||
|
|
|
@ -94,7 +94,16 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this.set('codeEditor', null);
|
||||
let editor = this.get('codeEditor');
|
||||
|
||||
if (is.not.null(editor)) {
|
||||
editor.toTextArea();
|
||||
editor = null;
|
||||
this.set('codeEditor', null);
|
||||
}
|
||||
|
||||
this.destroyTooltips();
|
||||
|
||||
},
|
||||
|
||||
// Wrap code in PRE tag with language identifier for subsequent rendering.
|
||||
|
|
|
@ -74,6 +74,12 @@ export default Ember.Component.extend({
|
|||
willDestroyElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
let editor = this.get('codeEditor');
|
||||
if (is.not.null(editor)) {
|
||||
editor.toTextArea();
|
||||
editor = null;
|
||||
}
|
||||
|
||||
this.set('codeEditor', null);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -35,46 +35,35 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
let self = this;
|
||||
// let self = this;
|
||||
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
|
||||
|
||||
let rawBody = this.get('meta.rawBody');
|
||||
let cleanBody = rawBody.replace("</pre>", "");
|
||||
this.set('pageBody', this.get('meta.rawBody').trim());
|
||||
|
||||
cleanBody = cleanBody.replace('<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="', "");
|
||||
let startPos = cleanBody.indexOf('">');
|
||||
let syntax = {
|
||||
mode: "markdown",
|
||||
name: "Markdown"
|
||||
};
|
||||
// let opts = [];
|
||||
// let syntax = {
|
||||
// mode: "markdown",
|
||||
// name: "Markdown"
|
||||
// };
|
||||
|
||||
if (startPos !== -1) {
|
||||
syntax = cleanBody.substring(0, startPos);
|
||||
cleanBody = cleanBody.substring(startPos + 2);
|
||||
}
|
||||
// _.each(_.sortBy(CodeMirror.modeInfo, 'name'), function(item) {
|
||||
// let i = {
|
||||
// mode: item.mode,
|
||||
// name: item.name
|
||||
// };
|
||||
// opts.pushObject(i);
|
||||
|
||||
this.set('pageBody', cleanBody);
|
||||
// if (item.mode === syntax) {
|
||||
// self.set('codeSyntax', i);
|
||||
// }
|
||||
// });
|
||||
|
||||
let opts = [];
|
||||
// this.set('syntaxOptions', opts);
|
||||
|
||||
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), function(item) {
|
||||
let i = {
|
||||
mode: item.mode,
|
||||
name: item.name
|
||||
};
|
||||
opts.pushObject(i);
|
||||
|
||||
if (item.mode === syntax) {
|
||||
self.set('codeSyntax', i);
|
||||
}
|
||||
});
|
||||
|
||||
this.set('syntaxOptions', opts);
|
||||
|
||||
// default check
|
||||
if (is.null(this.get("codeSyntax"))) {
|
||||
this.set("codeSyntax", opts.findBy("mode", "markdown"));
|
||||
}
|
||||
// // default check
|
||||
// if (is.null(this.get("codeSyntax"))) {
|
||||
// this.set("codeSyntax", opts.findBy("mode", "markdown"));
|
||||
// }
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
|
@ -83,17 +72,25 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this.set('codeEditor', null);
|
||||
let editor = this.get('codeEditor');
|
||||
|
||||
if (this.get('editMode')) {
|
||||
editor.toTextArea();
|
||||
editor = null;
|
||||
}
|
||||
|
||||
this.set('codeEditor', null);
|
||||
this.destroyTooltips();
|
||||
},
|
||||
|
||||
getBody() {
|
||||
return this.get('codeEditor').getDoc().getValue();
|
||||
return this.get('codeEditor').getDoc().getValue().trim();
|
||||
},
|
||||
|
||||
attachEditor() {
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById(this.get('editorId')), {
|
||||
theme: "default",
|
||||
mode: "markdown",
|
||||
lineNumbers: false,
|
||||
lineWrapping: true,
|
||||
indentUnit: 4,
|
||||
|
@ -112,8 +109,8 @@ export default Ember.Component.extend(TooltipMixin, {
|
|||
let syntax = this.get("codeSyntax");
|
||||
|
||||
if (is.not.undefined(syntax)) {
|
||||
CodeMirror.autoLoadMode(editor, syntax.mode);
|
||||
editor.setOption("mode", syntax.mode);
|
||||
CodeMirror.autoLoadMode(editor, "markdown");
|
||||
editor.setOption("mode", "markdown");
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<script src="/codemirror/lib/codemirror.js"></script>
|
||||
<script src="/codemirror/mode/meta.js"></script>
|
||||
<script src="/codemirror/addon/mode/loadmode.js"></script>
|
||||
<script src="/codemirror/addon/mode/overlay.js"></script>
|
||||
<script src="/codemirror/addon/runmode/runmode.js"></script>
|
||||
<script src="/codemirror/addon/runmode/colorize.js"></script>
|
||||
{{content-for 'body-footer'}}
|
||||
|
|
|
@ -6,41 +6,43 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* BASICS */
|
||||
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
color: black;
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* PADDING */
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
background-color: white; /* The little square between H and V scrollbars */
|
||||
background-color: white; /* The little square between H and V scrollbars */
|
||||
}
|
||||
|
||||
/* GUTTER */
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
white-space: nowrap;
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.CodeMirror-linenumbers {}
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker { color: black; }
|
||||
|
@ -49,45 +51,45 @@
|
|||
/* CURSOR */
|
||||
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
border-left: 1px solid black;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
background: #7e7;
|
||||
width: auto;
|
||||
border: 0 !important;
|
||||
background: #7e7;
|
||||
}
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.cm-animate-fat-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
background-color: #7e7;
|
||||
width: auto;
|
||||
border: 0;
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
background-color: #7e7;
|
||||
}
|
||||
@-moz-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
|
@ -95,9 +97,15 @@
|
|||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; }
|
||||
|
||||
.CodeMirror-rulers {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: -50px; bottom: -20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.CodeMirror-ruler {
|
||||
border-left: 1px solid #ccc;
|
||||
position: absolute;
|
||||
border-left: 1px solid #ccc;
|
||||
top: 0; bottom: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* DEFAULT THEME */
|
||||
|
@ -148,132 +156,133 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
|||
/* STOP */
|
||||
|
||||
/* The rest of this file contains styles related to the mechanics of
|
||||
the editor. You probably shouldn't touch them. */
|
||||
the editor. You probably shouldn't touch them. */
|
||||
|
||||
.CodeMirror {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: scroll !important; /* Things will break if this is overridden */
|
||||
/* 30px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror */
|
||||
margin-bottom: -30px; margin-right: -30px;
|
||||
padding-bottom: 30px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
overflow: scroll !important; /* Things will break if this is overridden */
|
||||
/* 30px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror */
|
||||
margin-bottom: -30px; margin-right: -30px;
|
||||
padding-bottom: 30px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
}
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
border-right: 30px solid transparent;
|
||||
position: relative;
|
||||
border-right: 30px solid transparent;
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
}
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0; bottom: 0;
|
||||
right: 0; bottom: 0;
|
||||
}
|
||||
.CodeMirror-gutter-filler {
|
||||
left: 0; bottom: 0;
|
||||
left: 0; bottom: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
z-index: 3;
|
||||
position: absolute; left: 0; top: 0;
|
||||
min-height: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
margin-bottom: -30px;
|
||||
/* Hack to make IE7 behave */
|
||||
*zoom:1;
|
||||
*display:inline;
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
min-height: 1px; /* prevents collapsing before first draw */
|
||||
cursor: text;
|
||||
min-height: 1px; /* prevents collapsing before first draw */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: contextual;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.CodeMirror-widget {}
|
||||
|
||||
.CodeMirror-code {
|
||||
outline: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Force content-box sizing for the elements where we expect it */
|
||||
|
@ -282,32 +291,35 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
|||
.CodeMirror-gutter,
|
||||
.CodeMirror-gutters,
|
||||
.CodeMirror-linenumber {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-cursor { position: absolute; }
|
||||
.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
|
@ -317,21 +329,18 @@ div.CodeMirror-dragcursors {
|
|||
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background: #ffa;
|
||||
background: rgba(255, 255, 0, .4);
|
||||
background: #ffa;
|
||||
background: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
|
||||
.CodeMirror span { *vertical-align: text-bottom; }
|
||||
|
||||
/* Used to force a border model for a node */
|
||||
.cm-force-border { padding-right: .1px; }
|
||||
|
||||
@media print {
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
}
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* See issue #2901 */
|
||||
|
@ -340,6 +349,7 @@ div.CodeMirror-dragcursors {
|
|||
/* Help users use markselection to safely style text background */
|
||||
span.CodeMirror-selectedtext { background: none; }
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Name: material
|
||||
|
@ -394,6 +404,7 @@ span.CodeMirror-selectedtext { background: none; }
|
|||
color: white !important;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Name: yeti
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<div class="section-markdown-editor">
|
||||
{{#if editMode}}
|
||||
{{focus-textarea value=pageBody id=editorId class="mousetrap"}}
|
||||
<textarea id={{editorId}} class="mousetrap">{{{pageBody}}}</textarea>
|
||||
{{else}}
|
||||
<div class="mousetrap wysiwyg section-markdown-preview">
|
||||
{{{pagePreview}}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "documize",
|
||||
"version": "0.43.0",
|
||||
"version": "0.43.1",
|
||||
"description": "The Document IDE",
|
||||
"private": true,
|
||||
"repository": "",
|
||||
|
|
35
app/public/codemirror/addon/comment/comment.js
vendored
35
app/public/codemirror/addon/comment/comment.js
vendored
|
@ -44,9 +44,22 @@
|
|||
}
|
||||
});
|
||||
|
||||
// Rough heuristic to try and detect lines that are part of multi-line string
|
||||
function probablyInsideString(cm, pos, line) {
|
||||
return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"`]/.test(line)
|
||||
}
|
||||
|
||||
function getMode(cm, pos) {
|
||||
var mode = cm.getMode()
|
||||
return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
|
||||
}
|
||||
|
||||
CodeMirror.defineExtension("lineComment", function(from, to, options) {
|
||||
if (!options) options = noOptions;
|
||||
var self = this, mode = self.getModeAt(from);
|
||||
var self = this, mode = getMode(self, from);
|
||||
var firstLine = self.getLine(from.line);
|
||||
if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
|
||||
|
||||
var commentString = options.lineComment || mode.lineComment;
|
||||
if (!commentString) {
|
||||
if (options.blockCommentStart || mode.blockCommentStart) {
|
||||
|
@ -55,8 +68,7 @@
|
|||
}
|
||||
return;
|
||||
}
|
||||
var firstLine = self.getLine(from.line);
|
||||
if (firstLine == null) return;
|
||||
|
||||
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
|
||||
var pad = options.padding == null ? " " : options.padding;
|
||||
var blankLines = options.commentBlankLines || from.line == to.line;
|
||||
|
@ -88,7 +100,7 @@
|
|||
|
||||
CodeMirror.defineExtension("blockComment", function(from, to, options) {
|
||||
if (!options) options = noOptions;
|
||||
var self = this, mode = self.getModeAt(from);
|
||||
var self = this, mode = getMode(self, from);
|
||||
var startString = options.blockCommentStart || mode.blockCommentStart;
|
||||
var endString = options.blockCommentEnd || mode.blockCommentEnd;
|
||||
if (!startString || !endString) {
|
||||
|
@ -96,6 +108,7 @@
|
|||
self.lineComment(from, to, options);
|
||||
return;
|
||||
}
|
||||
if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
|
||||
|
||||
var end = Math.min(to.line, self.lastLine());
|
||||
if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
|
||||
|
@ -121,7 +134,7 @@
|
|||
|
||||
CodeMirror.defineExtension("uncomment", function(from, to, options) {
|
||||
if (!options) options = noOptions;
|
||||
var self = this, mode = self.getModeAt(from);
|
||||
var self = this, mode = getMode(self, from);
|
||||
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
|
||||
|
||||
// Try finding line comments
|
||||
|
@ -133,7 +146,7 @@
|
|||
var line = self.getLine(i);
|
||||
var found = line.indexOf(lineString);
|
||||
if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
|
||||
if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment;
|
||||
if (found == -1 && nonWS.test(line)) break lineComment;
|
||||
if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
|
||||
lines.push(line);
|
||||
}
|
||||
|
@ -155,13 +168,15 @@
|
|||
var endString = options.blockCommentEnd || mode.blockCommentEnd;
|
||||
if (!startString || !endString) return false;
|
||||
var lead = options.blockCommentLead || mode.blockCommentLead;
|
||||
var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end);
|
||||
var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString);
|
||||
var startLine = self.getLine(start), open = startLine.indexOf(startString)
|
||||
if (open == -1) return false
|
||||
var endLine = end == start ? startLine : self.getLine(end)
|
||||
var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
|
||||
if (close == -1 && start != end) {
|
||||
endLine = self.getLine(--end);
|
||||
close = endLine.lastIndexOf(endString);
|
||||
close = endLine.indexOf(endString);
|
||||
}
|
||||
if (open == -1 || close == -1 ||
|
||||
if (close == -1 ||
|
||||
!/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) ||
|
||||
!/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
|
||||
return false;
|
||||
|
|
4
app/public/codemirror/addon/dialog/dialog.js
vendored
4
app/public/codemirror/addon/dialog/dialog.js
vendored
|
@ -56,6 +56,8 @@
|
|||
|
||||
var inp = dialog.getElementsByTagName("input")[0], button;
|
||||
if (inp) {
|
||||
inp.focus();
|
||||
|
||||
if (options.value) {
|
||||
inp.value = options.value;
|
||||
if (options.selectValueOnOpen !== false) {
|
||||
|
@ -79,8 +81,6 @@
|
|||
});
|
||||
|
||||
if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
|
||||
|
||||
inp.focus();
|
||||
} else if (button = dialog.getElementsByTagName("button")[0]) {
|
||||
CodeMirror.on(button, "click", function() {
|
||||
close();
|
||||
|
|
11
app/public/codemirror/addon/display/panel.js
vendored
11
app/public/codemirror/addon/display/panel.js
vendored
|
@ -38,6 +38,9 @@
|
|||
var height = (options && options.height) || node.offsetHeight;
|
||||
this._setSize(null, info.heightLeft -= height);
|
||||
info.panels++;
|
||||
if (options.stable && isAtTop(this, node))
|
||||
this.scrollTo(null, this.getScrollInfo().top + height)
|
||||
|
||||
return new Panel(this, node, options, height);
|
||||
});
|
||||
|
||||
|
@ -54,6 +57,8 @@
|
|||
this.cleared = true;
|
||||
var info = this.cm.state.panels;
|
||||
this.cm._setSize(null, info.heightLeft += this.height);
|
||||
if (this.options.stable && isAtTop(this.cm, this.node))
|
||||
this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height)
|
||||
info.wrapper.removeChild(this.node);
|
||||
if (--info.panels == 0) removePanels(this.cm);
|
||||
};
|
||||
|
@ -109,4 +114,10 @@
|
|||
cm.setSize = cm._setSize;
|
||||
cm.setSize();
|
||||
}
|
||||
|
||||
function isAtTop(cm, dom) {
|
||||
for (var sibling = dom.nextSibling; sibling; sibling = sibling.nextSibling)
|
||||
if (sibling == cm.getWrapperElement()) return true
|
||||
return false
|
||||
}
|
||||
});
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
if (val && !prev) {
|
||||
cm.on("blur", onBlur);
|
||||
cm.on("change", onChange);
|
||||
cm.on("swapDoc", onChange);
|
||||
onChange(cm);
|
||||
} else if (!val && prev) {
|
||||
cm.off("blur", onBlur);
|
||||
cm.off("change", onChange);
|
||||
cm.off("swapDoc", onChange);
|
||||
clearPlaceholder(cm);
|
||||
var wrapper = cm.getWrapperElement();
|
||||
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
|
||||
|
|
38
app/public/codemirror/addon/display/rulers.js
vendored
38
app/public/codemirror/addon/display/rulers.js
vendored
|
@ -11,30 +11,26 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineOption("rulers", false, function(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init) {
|
||||
clearRulers(cm);
|
||||
cm.off("refresh", refreshRulers);
|
||||
CodeMirror.defineOption("rulers", false, function(cm, val) {
|
||||
if (cm.state.rulerDiv) {
|
||||
cm.state.rulerDiv.parentElement.removeChild(cm.state.rulerDiv)
|
||||
cm.state.rulerDiv = null
|
||||
cm.off("refresh", drawRulers)
|
||||
}
|
||||
if (val && val.length) {
|
||||
setRulers(cm);
|
||||
cm.on("refresh", refreshRulers);
|
||||
cm.state.rulerDiv = cm.display.lineSpace.parentElement.insertBefore(document.createElement("div"), cm.display.lineSpace)
|
||||
cm.state.rulerDiv.className = "CodeMirror-rulers"
|
||||
drawRulers(cm)
|
||||
cm.on("refresh", drawRulers)
|
||||
}
|
||||
});
|
||||
|
||||
function clearRulers(cm) {
|
||||
for (var i = cm.display.lineSpace.childNodes.length - 1; i >= 0; i--) {
|
||||
var node = cm.display.lineSpace.childNodes[i];
|
||||
if (/(^|\s)CodeMirror-ruler($|\s)/.test(node.className))
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
function setRulers(cm) {
|
||||
function drawRulers(cm) {
|
||||
cm.state.rulerDiv.textContent = ""
|
||||
var val = cm.getOption("rulers");
|
||||
var cw = cm.defaultCharWidth();
|
||||
var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left;
|
||||
var minH = cm.display.scroller.offsetHeight + 30;
|
||||
cm.state.rulerDiv.style.minHeight = (cm.display.scroller.offsetHeight + 30) + "px";
|
||||
for (var i = 0; i < val.length; i++) {
|
||||
var elt = document.createElement("div");
|
||||
elt.className = "CodeMirror-ruler";
|
||||
|
@ -49,15 +45,7 @@
|
|||
if (conf.width) elt.style.borderLeftWidth = conf.width;
|
||||
}
|
||||
elt.style.left = (left + col * cw) + "px";
|
||||
elt.style.top = "-50px";
|
||||
elt.style.bottom = "-20px";
|
||||
elt.style.minHeight = minH + "px";
|
||||
cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv);
|
||||
cm.state.rulerDiv.appendChild(elt)
|
||||
}
|
||||
}
|
||||
|
||||
function refreshRulers(cm) {
|
||||
clearRulers(cm);
|
||||
setRulers(cm);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
function getConfig(cm) {
|
||||
var deflt = cm.state.closeBrackets;
|
||||
if (!deflt) return null;
|
||||
if (!deflt || deflt.override) return deflt;
|
||||
var mode = cm.getModeAt(cm.getCursor());
|
||||
return mode.closeBrackets || deflt;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@
|
|||
}
|
||||
for (var i = ranges.length - 1; i >= 0; i--) {
|
||||
var cur = ranges[i].head;
|
||||
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
|
||||
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,14 +109,16 @@
|
|||
var ranges = cm.listSelections();
|
||||
var opening = pos % 2 == 0;
|
||||
|
||||
var type, next;
|
||||
var type;
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
var range = ranges[i], cur = range.head, curType;
|
||||
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
|
||||
if (opening && !range.empty()) {
|
||||
curType = "surround";
|
||||
} else if ((identical || !opening) && next == ch) {
|
||||
if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
|
||||
if (identical && stringStartsAfter(cm, cur))
|
||||
curType = "both";
|
||||
else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
|
||||
curType = "skipThree";
|
||||
else
|
||||
curType = "skip";
|
||||
|
@ -183,7 +185,7 @@
|
|||
function enteringString(cm, pos, ch) {
|
||||
var line = cm.getLine(pos.line);
|
||||
var token = cm.getTokenAt(pos);
|
||||
if (/\bstring2?\b/.test(token.type)) return false;
|
||||
if (/\bstring2?\b/.test(token.type) || stringStartsAfter(cm, pos)) return false;
|
||||
var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
|
||||
stream.pos = stream.start = token.start;
|
||||
for (;;) {
|
||||
|
@ -192,4 +194,9 @@
|
|||
stream.start = stream.pos;
|
||||
}
|
||||
}
|
||||
|
||||
function stringStartsAfter(cm, pos) {
|
||||
var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
|
||||
return /\bstring/.test(token.type) && token.start == pos.ch
|
||||
}
|
||||
});
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))(\s*)/,
|
||||
emptyListRE = /^(\s*)(>[> ]*|[*+-]|(\d+)[.)])(\s*)$/,
|
||||
var listRE = /^(\s*)(>[> ]*|- \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
|
||||
emptyListRE = /^(\s*)(>[> ]*|- \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
|
||||
unorderedListRE = /[*+-]\s/;
|
||||
|
||||
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
|
||||
|
@ -30,7 +30,7 @@
|
|||
return;
|
||||
}
|
||||
if (emptyListRE.test(line)) {
|
||||
cm.replaceRange("", {
|
||||
if (!/>\s*$/.test(line)) cm.replaceRange("", {
|
||||
line: pos.line, ch: 0
|
||||
}, {
|
||||
line: pos.line, ch: pos.ch + 1
|
||||
|
@ -39,7 +39,7 @@
|
|||
} else {
|
||||
var indent = match[1], after = match[5];
|
||||
var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0
|
||||
? match[2]
|
||||
? match[2].replace("x", " ")
|
||||
: (parseInt(match[3], 10) + 1) + match[4];
|
||||
|
||||
replacements[i] = "\n" + indent + bullet + after;
|
||||
|
|
|
@ -102,8 +102,10 @@
|
|||
}
|
||||
|
||||
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init)
|
||||
if (old && old != CodeMirror.Init) {
|
||||
cm.off("cursorActivity", doMatchBrackets);
|
||||
if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
|
||||
}
|
||||
if (val) {
|
||||
cm.state.matchBrackets = typeof val == "object" ? val : {};
|
||||
cm.on("cursorActivity", doMatchBrackets);
|
||||
|
|
16
app/public/codemirror/addon/fold/brace-fold.js
vendored
16
app/public/codemirror/addon/fold/brace-fold.js
vendored
|
@ -13,7 +13,7 @@
|
|||
|
||||
CodeMirror.registerHelper("fold", "brace", function(cm, start) {
|
||||
var line = start.line, lineText = cm.getLine(line);
|
||||
var startCh, tokenType;
|
||||
var tokenType;
|
||||
|
||||
function findOpening(openCh) {
|
||||
for (var at = start.ch, pass = 0;;) {
|
||||
|
@ -72,15 +72,15 @@ CodeMirror.registerHelper("fold", "import", function(cm, start) {
|
|||
}
|
||||
}
|
||||
|
||||
var start = start.line, has = hasImport(start), prev;
|
||||
if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1))
|
||||
var startLine = start.line, has = hasImport(startLine), prev;
|
||||
if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
|
||||
return null;
|
||||
for (var end = has.end;;) {
|
||||
var next = hasImport(end.line + 1);
|
||||
if (next == null) break;
|
||||
end = next.end;
|
||||
}
|
||||
return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end};
|
||||
return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
|
||||
});
|
||||
|
||||
CodeMirror.registerHelper("fold", "include", function(cm, start) {
|
||||
|
@ -91,14 +91,14 @@ CodeMirror.registerHelper("fold", "include", function(cm, start) {
|
|||
if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
|
||||
}
|
||||
|
||||
var start = start.line, has = hasInclude(start);
|
||||
if (has == null || hasInclude(start - 1) != null) return null;
|
||||
for (var end = start;;) {
|
||||
var startLine = start.line, has = hasInclude(startLine);
|
||||
if (has == null || hasInclude(startLine - 1) != null) return null;
|
||||
for (var end = startLine;;) {
|
||||
var next = hasInclude(end + 1);
|
||||
if (next == null) break;
|
||||
++end;
|
||||
}
|
||||
return {from: CodeMirror.Pos(start, has + 1),
|
||||
return {from: CodeMirror.Pos(startLine, has + 1),
|
||||
to: cm.clipPos(CodeMirror.Pos(end))};
|
||||
});
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
|
|||
}
|
||||
if (pass == 1 && found < start.ch) return;
|
||||
if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
|
||||
(lineText.slice(found - endToken.length, found) == endToken ||
|
||||
(found == 0 || lineText.slice(found - endToken.length, found) == endToken ||
|
||||
!/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
|
||||
startCh = found + startToken.length;
|
||||
break;
|
||||
|
|
5
app/public/codemirror/addon/fold/foldcode.js
vendored
5
app/public/codemirror/addon/fold/foldcode.js
vendored
|
@ -49,7 +49,7 @@
|
|||
});
|
||||
var myRange = cm.markText(range.from, range.to, {
|
||||
replacedWith: myWidget,
|
||||
clearOnEnter: true,
|
||||
clearOnEnter: getOption(cm, options, "clearOnEnter"),
|
||||
__isFold: true
|
||||
});
|
||||
myRange.on("clear", function(from, to) {
|
||||
|
@ -129,7 +129,8 @@
|
|||
rangeFinder: CodeMirror.fold.auto,
|
||||
widget: "\u2194",
|
||||
minFoldSize: 0,
|
||||
scanUp: false
|
||||
scanUp: false,
|
||||
clearOnEnter: true
|
||||
};
|
||||
|
||||
CodeMirror.defineOption("foldOptions", null);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
cm.off("viewportChange", onViewportChange);
|
||||
cm.off("fold", onFold);
|
||||
cm.off("unfold", onFold);
|
||||
cm.off("swapDoc", updateInViewport);
|
||||
cm.off("swapDoc", onChange);
|
||||
}
|
||||
if (val) {
|
||||
cm.state.foldGutter = new State(parseOptions(val));
|
||||
|
@ -30,7 +30,7 @@
|
|||
cm.on("viewportChange", onViewportChange);
|
||||
cm.on("fold", onFold);
|
||||
cm.on("unfold", onFold);
|
||||
cm.on("swapDoc", updateInViewport);
|
||||
cm.on("swapDoc", onChange);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
|||
}
|
||||
|
||||
function isFolded(cm, line) {
|
||||
var marks = cm.findMarksAt(Pos(line));
|
||||
var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
|
||||
for (var i = 0; i < marks.length; ++i)
|
||||
if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
|
||||
}
|
||||
|
|
34
app/public/codemirror/addon/fold/indent-fold.js
vendored
34
app/public/codemirror/addon/fold/indent-fold.js
vendored
|
@ -11,32 +11,36 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
function lineIndent(cm, lineNo) {
|
||||
var text = cm.getLine(lineNo)
|
||||
var spaceTo = text.search(/\S/)
|
||||
if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1))))
|
||||
return -1
|
||||
return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
|
||||
}
|
||||
!
|
||||
CodeMirror.registerHelper("fold", "indent", function(cm, start) {
|
||||
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
|
||||
if (!/\S/.test(firstLine)) return;
|
||||
var getIndent = function(line) {
|
||||
return CodeMirror.countColumn(line, null, tabSize);
|
||||
};
|
||||
var myIndent = getIndent(firstLine);
|
||||
var lastLineInFold = null;
|
||||
var myIndent = lineIndent(cm, start.line)
|
||||
if (myIndent < 0) return
|
||||
var lastLineInFold = null
|
||||
|
||||
// Go through lines until we find a line that definitely doesn't belong in
|
||||
// the block we're folding, or to the end.
|
||||
for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
|
||||
var curLine = cm.getLine(i);
|
||||
var curIndent = getIndent(curLine);
|
||||
if (curIndent > myIndent) {
|
||||
var indent = lineIndent(cm, i)
|
||||
if (indent == -1) {
|
||||
} else if (indent > myIndent) {
|
||||
// Lines with a greater indent are considered part of the block.
|
||||
lastLineInFold = i;
|
||||
} else if (!/\S/.test(curLine)) {
|
||||
// Empty lines might be breaks within the block we're trying to fold.
|
||||
} else {
|
||||
// A non-empty line at an indent equal to or less than ours marks the
|
||||
// start of another block.
|
||||
// If this line has non-space, non-comment content, and is
|
||||
// indented less or equal to the start line, it is the start of
|
||||
// another block.
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastLineInFold) return {
|
||||
from: CodeMirror.Pos(start.line, firstLine.length),
|
||||
from: CodeMirror.Pos(start.line, cm.getLine(start.line).length),
|
||||
to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
|
||||
};
|
||||
});
|
||||
|
|
10
app/public/codemirror/addon/fold/xml-fold.js
vendored
10
app/public/codemirror/addon/fold/xml-fold.js
vendored
|
@ -21,8 +21,8 @@
|
|||
function Iter(cm, line, ch, range) {
|
||||
this.line = line; this.ch = ch;
|
||||
this.cm = cm; this.text = cm.getLine(line);
|
||||
this.min = range ? range.from : cm.firstLine();
|
||||
this.max = range ? range.to - 1 : cm.lastLine();
|
||||
this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine();
|
||||
this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine();
|
||||
}
|
||||
|
||||
function tagAt(iter, ch) {
|
||||
|
@ -140,9 +140,9 @@
|
|||
var openTag = toNextTag(iter), end;
|
||||
if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;
|
||||
if (!openTag[1] && end != "selfClose") {
|
||||
var start = Pos(iter.line, iter.ch);
|
||||
var close = findMatchingClose(iter, openTag[2]);
|
||||
return close && {from: start, to: close.from};
|
||||
var startPos = Pos(iter.line, iter.ch);
|
||||
var endPos = findMatchingClose(iter, openTag[2]);
|
||||
return endPos && {from: startPos, to: endPos.from};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -97,6 +97,15 @@
|
|||
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
|
||||
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
|
||||
|
||||
function forAllProps(obj, callback) {
|
||||
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
|
||||
for (var name in obj) callback(name)
|
||||
} else {
|
||||
for (var o = obj; o; o = Object.getPrototypeOf(o))
|
||||
Object.getOwnPropertyNames(o).forEach(callback)
|
||||
}
|
||||
}
|
||||
|
||||
function getCompletions(token, context, keywords, options) {
|
||||
var found = [], start = token.string, global = options && options.globalScope || window;
|
||||
function maybeAdd(str) {
|
||||
|
@ -106,7 +115,7 @@
|
|||
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);
|
||||
forAllProps(obj, maybeAdd)
|
||||
}
|
||||
|
||||
if (context && context.length) {
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
margin: 0;
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
max-width: 19em;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
|
|
80
app/public/codemirror/addon/hint/show-hint.js
vendored
80
app/public/codemirror/addon/hint/show-hint.js
vendored
|
@ -108,24 +108,22 @@
|
|||
},
|
||||
|
||||
update: function(first) {
|
||||
if (this.tick == null) return;
|
||||
if (!this.options.hint.async) {
|
||||
this.finishUpdate(this.options.hint(this.cm, this.options), first);
|
||||
} else {
|
||||
var myTick = ++this.tick, self = this;
|
||||
this.options.hint(this.cm, function(data) {
|
||||
if (self.tick == myTick) self.finishUpdate(data, first);
|
||||
}, this.options);
|
||||
}
|
||||
if (this.tick == null) return
|
||||
var self = this, myTick = ++this.tick
|
||||
fetchHints(this.options.hint, this.cm, this.options, function(data) {
|
||||
if (self.tick == myTick) self.finishUpdate(data, first)
|
||||
})
|
||||
},
|
||||
|
||||
finishUpdate: function(data, first) {
|
||||
if (this.data) CodeMirror.signal(this.data, "update");
|
||||
if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
|
||||
this.data = data;
|
||||
|
||||
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
|
||||
if (this.widget) this.widget.close();
|
||||
|
||||
if (data && this.data && isNewCompletion(this.data, data)) return;
|
||||
this.data = data;
|
||||
|
||||
if (data && data.list.length) {
|
||||
if (picked && data.list.length == 1) {
|
||||
this.pick(data, 0);
|
||||
|
@ -137,6 +135,11 @@
|
|||
}
|
||||
};
|
||||
|
||||
function isNewCompletion(old, nw) {
|
||||
var moved = CodeMirror.cmpPos(nw.from, old.from)
|
||||
return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
|
||||
}
|
||||
|
||||
function parseOptions(cm, pos, options) {
|
||||
var editor = cm.options.hintOptions;
|
||||
var out = {};
|
||||
|
@ -226,6 +229,9 @@
|
|||
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
|
||||
(completion.options.container || document.body).appendChild(hints);
|
||||
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
|
||||
var scrolls = hints.scrollHeight > hints.clientHeight + 1
|
||||
var startScroll = cm.getScrollInfo();
|
||||
|
||||
if (overlapY > 0) {
|
||||
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
|
||||
if (curTop - height > 0) { // Fits above cursor
|
||||
|
@ -250,6 +256,8 @@
|
|||
}
|
||||
hints.style.left = (left = pos.left - overlapX) + "px";
|
||||
}
|
||||
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
|
||||
node.style.paddingRight = cm.display.nativeBarWidth + "px"
|
||||
|
||||
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
|
||||
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
|
||||
|
@ -267,7 +275,6 @@
|
|||
cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
|
||||
}
|
||||
|
||||
var startScroll = cm.getScrollInfo();
|
||||
cm.on("scroll", this.onScroll = function() {
|
||||
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
|
||||
var newTop = top + startScroll.top - curScroll.top;
|
||||
|
@ -355,40 +362,31 @@
|
|||
return result
|
||||
}
|
||||
|
||||
function fetchHints(hint, cm, options, callback) {
|
||||
if (hint.async) {
|
||||
hint(cm, callback, options)
|
||||
} else {
|
||||
var result = hint(cm, options)
|
||||
if (result && result.then) result.then(callback)
|
||||
else callback(result)
|
||||
}
|
||||
}
|
||||
|
||||
function resolveAutoHints(cm, pos) {
|
||||
var helpers = cm.getHelpers(pos, "hint"), words
|
||||
if (helpers.length) {
|
||||
var async = false, resolved
|
||||
for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true
|
||||
if (async) {
|
||||
resolved = function(cm, callback, options) {
|
||||
var app = applicableHelpers(cm, helpers)
|
||||
function run(i, result) {
|
||||
if (i == app.length) return callback(null)
|
||||
var helper = app[i]
|
||||
if (helper.async) {
|
||||
helper(cm, function(result) {
|
||||
if (result) callback(result)
|
||||
else run(i + 1)
|
||||
}, options)
|
||||
} else {
|
||||
var result = helper(cm, options)
|
||||
if (result) callback(result)
|
||||
else run(i + 1)
|
||||
}
|
||||
}
|
||||
run(0)
|
||||
}
|
||||
resolved.async = true
|
||||
} else {
|
||||
resolved = function(cm, options) {
|
||||
var app = applicableHelpers(cm, helpers)
|
||||
for (var i = 0; i < app.length; i++) {
|
||||
var cur = app[i](cm, options)
|
||||
if (cur && cur.list.length) return cur
|
||||
}
|
||||
var resolved = function(cm, callback, options) {
|
||||
var app = applicableHelpers(cm, helpers);
|
||||
function run(i) {
|
||||
if (i == app.length) return callback(null)
|
||||
fetchHints(app[i], cm, options, function(result) {
|
||||
if (result && result.list.length > 0) callback(result)
|
||||
else run(i + 1)
|
||||
})
|
||||
}
|
||||
run(0)
|
||||
}
|
||||
resolved.async = true
|
||||
resolved.supportsSelection = true
|
||||
return resolved
|
||||
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
|
||||
|
|
83
app/public/codemirror/addon/hint/sql-hint.js
vendored
83
app/public/codemirror/addon/hint/sql-hint.js
vendored
|
@ -18,7 +18,9 @@
|
|||
QUERY_DIV: ";",
|
||||
ALIAS_KEYWORD: "AS"
|
||||
};
|
||||
var Pos = CodeMirror.Pos;
|
||||
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
|
||||
|
||||
function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
|
||||
|
||||
function getKeywords(editor) {
|
||||
var mode = editor.doc.modeOption;
|
||||
|
@ -30,10 +32,28 @@
|
|||
return typeof item == "string" ? item : item.text;
|
||||
}
|
||||
|
||||
function getItem(list, item) {
|
||||
if (!list.slice) return list[item];
|
||||
for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item)
|
||||
return list[i];
|
||||
function wrapTable(name, value) {
|
||||
if (isArray(value)) value = {columns: value}
|
||||
if (!value.text) value.text = name
|
||||
return value
|
||||
}
|
||||
|
||||
function parseTables(input) {
|
||||
var result = {}
|
||||
if (isArray(input)) {
|
||||
for (var i = input.length - 1; i >= 0; i--) {
|
||||
var item = input[i]
|
||||
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
|
||||
}
|
||||
} else if (input) {
|
||||
for (var name in input)
|
||||
result[name.toUpperCase()] = wrapTable(name, input[name])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function getTable(name) {
|
||||
return tables[name.toUpperCase()]
|
||||
}
|
||||
|
||||
function shallowClone(object) {
|
||||
|
@ -50,11 +70,18 @@
|
|||
}
|
||||
|
||||
function addMatches(result, search, wordlist, formatter) {
|
||||
for (var word in wordlist) {
|
||||
if (!wordlist.hasOwnProperty(word)) continue;
|
||||
if (wordlist.slice) word = wordlist[word];
|
||||
|
||||
if (match(search, word)) result.push(formatter(word));
|
||||
if (isArray(wordlist)) {
|
||||
for (var i = 0; i < wordlist.length; i++)
|
||||
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
|
||||
} else {
|
||||
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
|
||||
var val = wordlist[word]
|
||||
if (!val || val === true)
|
||||
val = word
|
||||
else
|
||||
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
|
||||
if (match(search, val)) result.push(formatter(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +105,7 @@
|
|||
}
|
||||
|
||||
function nameCompletion(cur, token, result, editor) {
|
||||
// Try to complete table, colunm names and return start position of completion
|
||||
// Try to complete table, column names and return start position of completion
|
||||
var useBacktick = false;
|
||||
var nameParts = [];
|
||||
var start = token.start;
|
||||
|
@ -115,13 +142,13 @@
|
|||
var alias = false;
|
||||
var aliasTable = table;
|
||||
// Check if table is available. If not, find table by Alias
|
||||
if (!getItem(tables, table)) {
|
||||
if (!getTable(table)) {
|
||||
var oldTable = table;
|
||||
table = findTableByAlias(table, editor);
|
||||
if (table !== oldTable) alias = true;
|
||||
}
|
||||
|
||||
var columns = getItem(tables, table);
|
||||
var columns = getTable(table);
|
||||
if (columns && columns.columns)
|
||||
columns = columns.columns;
|
||||
|
||||
|
@ -151,15 +178,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function convertCurToNumber(cur) {
|
||||
// max characters of a line is 999,999.
|
||||
return cur.line + cur.ch / Math.pow(10, 6);
|
||||
}
|
||||
|
||||
function convertNumberToCur(num) {
|
||||
return Pos(Math.floor(num), +num.toString().split('.').pop());
|
||||
}
|
||||
|
||||
function findTableByAlias(alias, editor) {
|
||||
var doc = editor.doc;
|
||||
var fullQuery = doc.getValue();
|
||||
|
@ -182,15 +200,14 @@
|
|||
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
|
||||
|
||||
//find valid range
|
||||
var prevItem = 0;
|
||||
var current = convertCurToNumber(editor.getCursor());
|
||||
for (var i=0; i< separator.length; i++) {
|
||||
var _v = convertCurToNumber(separator[i]);
|
||||
if (current > prevItem && current <= _v) {
|
||||
validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) };
|
||||
var prevItem = null;
|
||||
var current = editor.getCursor()
|
||||
for (var i = 0; i < separator.length; i++) {
|
||||
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
|
||||
validRange = {start: prevItem, end: separator[i]};
|
||||
break;
|
||||
}
|
||||
prevItem = _v;
|
||||
prevItem = separator[i];
|
||||
}
|
||||
|
||||
var query = doc.getRange(validRange.start, validRange.end, false);
|
||||
|
@ -199,7 +216,7 @@
|
|||
var lineText = query[i];
|
||||
eachWord(lineText, function(word) {
|
||||
var wordUpperCase = word.toUpperCase();
|
||||
if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord))
|
||||
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
|
||||
table = previousWord;
|
||||
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
|
||||
previousWord = word;
|
||||
|
@ -210,11 +227,11 @@
|
|||
}
|
||||
|
||||
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
|
||||
tables = (options && options.tables) || {};
|
||||
tables = parseTables(options && options.tables)
|
||||
var defaultTableName = options && options.defaultTable;
|
||||
var disableKeywords = options && options.disableKeywords;
|
||||
defaultTable = defaultTableName && getItem(tables, defaultTableName);
|
||||
keywords = keywords || getKeywords(editor);
|
||||
defaultTable = defaultTableName && getTable(defaultTableName);
|
||||
keywords = getKeywords(editor);
|
||||
|
||||
if (defaultTableName && !defaultTable)
|
||||
defaultTable = findTableByAlias(defaultTableName, editor);
|
||||
|
|
4
app/public/codemirror/addon/lint/lint.css
vendored
4
app/public/codemirror/addon/lint/lint.css
vendored
|
@ -4,10 +4,10 @@
|
|||
}
|
||||
|
||||
.CodeMirror-lint-tooltip {
|
||||
background-color: infobackground;
|
||||
background-color: #ffd;
|
||||
border: 1px solid black;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
color: infotext;
|
||||
color: black;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
overflow: hidden;
|
||||
|
|
16
app/public/codemirror/addon/lint/lint.js
vendored
16
app/public/codemirror/addon/lint/lint.js
vendored
|
@ -186,9 +186,14 @@
|
|||
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
||||
}
|
||||
|
||||
function popupSpanTooltip(ann, e) {
|
||||
function popupTooltips(annotations, e) {
|
||||
var target = e.target || e.srcElement;
|
||||
showTooltipFor(e, annotationTooltip(ann), target);
|
||||
var tooltip = document.createDocumentFragment();
|
||||
for (var i = 0; i < annotations.length; i++) {
|
||||
var ann = annotations[i];
|
||||
tooltip.appendChild(annotationTooltip(ann));
|
||||
}
|
||||
showTooltipFor(e, tooltip, target);
|
||||
}
|
||||
|
||||
function onMouseOver(cm, e) {
|
||||
|
@ -196,10 +201,13 @@
|
|||
if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
|
||||
var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
|
||||
var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client"));
|
||||
|
||||
var annotations = [];
|
||||
for (var i = 0; i < spans.length; ++i) {
|
||||
var ann = spans[i].__annotation;
|
||||
if (ann) return popupSpanTooltip(ann, e);
|
||||
if (ann) annotations.push(ann);
|
||||
}
|
||||
if (annotations.length) popupTooltips(annotations, e);
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("lint", false, function(cm, val, old) {
|
||||
|
@ -218,7 +226,7 @@
|
|||
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
|
||||
if (state.options.lintOnChange !== false)
|
||||
cm.on("change", onChange);
|
||||
if (state.options.tooltips != false)
|
||||
if (state.options.tooltips != false && state.options.tooltips != "gutter")
|
||||
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
|
||||
|
||||
startLinting(cm);
|
||||
|
|
1
app/public/codemirror/addon/merge/merge.css
vendored
1
app/public/codemirror/addon/merge/merge.css
vendored
|
@ -60,6 +60,7 @@
|
|||
position: absolute;
|
||||
cursor: pointer;
|
||||
color: #44c;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copy-reverse {
|
||||
|
|
352
app/public/codemirror/addon/merge/merge.js
vendored
352
app/public/codemirror/addon/merge/merge.js
vendored
|
@ -37,15 +37,26 @@
|
|||
constructor: DiffView,
|
||||
init: function(pane, orig, options) {
|
||||
this.edit = this.mv.edit;
|
||||
(this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this);
|
||||
;(this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this);
|
||||
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options)));
|
||||
if (this.mv.options.connect == "align") {
|
||||
if (!this.edit.state.trackAlignable) this.edit.state.trackAlignable = new TrackAlignable(this.edit)
|
||||
this.orig.state.trackAlignable = new TrackAlignable(this.orig)
|
||||
}
|
||||
|
||||
this.orig.state.diffViews = [this];
|
||||
var classLocation = options.chunkClassLocation || "background";
|
||||
if (Object.prototype.toString.call(classLocation) != "[object Array]") classLocation = [classLocation]
|
||||
this.classes.classLocation = classLocation
|
||||
|
||||
this.diff = getDiff(asString(orig), asString(options.value));
|
||||
this.chunks = getChunks(this.diff);
|
||||
this.diffOutOfDate = this.dealigned = false;
|
||||
this.needsScrollSync = null
|
||||
|
||||
this.showDifferences = options.showDifferences !== false;
|
||||
},
|
||||
registerEvents: function() {
|
||||
this.forceUpdate = registerUpdate(this);
|
||||
setScrollLock(this, true, false);
|
||||
registerScroll(this);
|
||||
|
@ -88,10 +99,12 @@
|
|||
updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
|
||||
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
|
||||
}
|
||||
makeConnections(dv);
|
||||
|
||||
if (dv.mv.options.connect == "align")
|
||||
alignChunks(dv);
|
||||
makeConnections(dv);
|
||||
if (dv.needsScrollSync != null) syncScroll(dv, dv.needsScrollSync)
|
||||
|
||||
updating = false;
|
||||
}
|
||||
function setDealign(fast) {
|
||||
|
@ -113,12 +126,18 @@
|
|||
// Update faster when a line was added/removed
|
||||
setDealign(change.text.length - 1 != change.to.line - change.from.line);
|
||||
}
|
||||
function swapDoc() {
|
||||
dv.diffOutOfDate = true;
|
||||
update("full");
|
||||
}
|
||||
dv.edit.on("change", change);
|
||||
dv.orig.on("change", change);
|
||||
dv.edit.on("markerAdded", setDealign);
|
||||
dv.edit.on("markerCleared", setDealign);
|
||||
dv.orig.on("markerAdded", setDealign);
|
||||
dv.orig.on("markerCleared", setDealign);
|
||||
dv.edit.on("swapDoc", swapDoc);
|
||||
dv.orig.on("swapDoc", swapDoc);
|
||||
if (dv.mv.options.connect == "align") {
|
||||
CodeMirror.on(dv.edit.state.trackAlignable, "realign", setDealign)
|
||||
CodeMirror.on(dv.orig.state.trackAlignable, "realign", setDealign)
|
||||
}
|
||||
dv.edit.on("viewportChange", function() { set(false); });
|
||||
dv.orig.on("viewportChange", function() { set(false); });
|
||||
update();
|
||||
|
@ -127,23 +146,27 @@
|
|||
|
||||
function registerScroll(dv) {
|
||||
dv.edit.on("scroll", function() {
|
||||
syncScroll(dv, DIFF_INSERT) && makeConnections(dv);
|
||||
syncScroll(dv, true) && makeConnections(dv);
|
||||
});
|
||||
dv.orig.on("scroll", function() {
|
||||
syncScroll(dv, DIFF_DELETE) && makeConnections(dv);
|
||||
syncScroll(dv, false) && makeConnections(dv);
|
||||
});
|
||||
}
|
||||
|
||||
function syncScroll(dv, type) {
|
||||
function syncScroll(dv, toOrig) {
|
||||
// Change handler will do a refresh after a timeout when diff is out of date
|
||||
if (dv.diffOutOfDate) return false;
|
||||
if (dv.diffOutOfDate) {
|
||||
if (dv.lockScroll && dv.needsScrollSync == null) dv.needsScrollSync = toOrig
|
||||
return false
|
||||
}
|
||||
dv.needsScrollSync = null
|
||||
if (!dv.lockScroll) return true;
|
||||
var editor, other, now = +new Date;
|
||||
if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; }
|
||||
if (toOrig) { editor = dv.edit; other = dv.orig; }
|
||||
else { editor = dv.orig; other = dv.edit; }
|
||||
// Don't take action if the position of this editor was recently set
|
||||
// (to prevent feedback loops)
|
||||
if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false;
|
||||
if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 250 > now) return false;
|
||||
|
||||
var sInfo = editor.getScrollInfo();
|
||||
if (dv.mv.options.connect == "align") {
|
||||
|
@ -151,9 +174,9 @@
|
|||
} else {
|
||||
var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen;
|
||||
var mid = editor.lineAtHeight(midY, "local");
|
||||
var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT);
|
||||
var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
|
||||
var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
|
||||
var around = chunkBoundariesAround(dv.chunks, mid, toOrig);
|
||||
var off = getOffsets(editor, toOrig ? around.edit : around.orig);
|
||||
var offOther = getOffsets(other, toOrig ? around.orig : around.edit);
|
||||
var ratio = (midY - off.top) / (off.bot - off.top);
|
||||
var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top);
|
||||
|
||||
|
@ -191,16 +214,22 @@
|
|||
|
||||
// Updating the marks for editor content
|
||||
|
||||
function removeClass(editor, line, classes) {
|
||||
var locs = classes.classLocation
|
||||
for (var i = 0; i < locs.length; i++) {
|
||||
editor.removeLineClass(line, locs[i], classes.chunk);
|
||||
editor.removeLineClass(line, locs[i], classes.start);
|
||||
editor.removeLineClass(line, locs[i], classes.end);
|
||||
}
|
||||
}
|
||||
|
||||
function clearMarks(editor, arr, classes) {
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
var mark = arr[i];
|
||||
if (mark instanceof CodeMirror.TextMarker) {
|
||||
if (mark instanceof CodeMirror.TextMarker)
|
||||
mark.clear();
|
||||
} else if (mark.parent) {
|
||||
editor.removeLineClass(mark, "background", classes.chunk);
|
||||
editor.removeLineClass(mark, "background", classes.start);
|
||||
editor.removeLineClass(mark, "background", classes.end);
|
||||
}
|
||||
else if (mark.parent)
|
||||
removeClass(editor, mark, classes);
|
||||
}
|
||||
arr.length = 0;
|
||||
}
|
||||
|
@ -226,28 +255,34 @@
|
|||
});
|
||||
}
|
||||
|
||||
function addClass(editor, lineNr, classes, main, start, end) {
|
||||
var locs = classes.classLocation, line = editor.getLineHandle(lineNr);
|
||||
for (var i = 0; i < locs.length; i++) {
|
||||
if (main) editor.addLineClass(line, locs[i], classes.chunk);
|
||||
if (start) editor.addLineClass(line, locs[i], classes.start);
|
||||
if (end) editor.addLineClass(line, locs[i], classes.end);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
function markChanges(editor, diff, type, marks, from, to, classes) {
|
||||
var pos = Pos(0, 0);
|
||||
var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1));
|
||||
var cls = type == DIFF_DELETE ? classes.del : classes.insert;
|
||||
function markChunk(start, end) {
|
||||
var bfrom = Math.max(from, start), bto = Math.min(to, end);
|
||||
for (var i = bfrom; i < bto; ++i) {
|
||||
var line = editor.addLineClass(i, "background", classes.chunk);
|
||||
if (i == start) editor.addLineClass(line, "background", classes.start);
|
||||
if (i == end - 1) editor.addLineClass(line, "background", classes.end);
|
||||
marks.push(line);
|
||||
}
|
||||
for (var i = bfrom; i < bto; ++i)
|
||||
marks.push(addClass(editor, i, classes, true, i == start, i == end - 1));
|
||||
// When the chunk is empty, make sure a horizontal line shows up
|
||||
if (start == end && bfrom == end && bto == end) {
|
||||
if (bfrom)
|
||||
marks.push(editor.addLineClass(bfrom - 1, "background", classes.end));
|
||||
marks.push(addClass(editor, bfrom - 1, classes, false, false, true));
|
||||
else
|
||||
marks.push(editor.addLineClass(bfrom, "background", classes.start));
|
||||
marks.push(addClass(editor, bfrom, classes, false, true, false));
|
||||
}
|
||||
}
|
||||
|
||||
var chunkStart = 0;
|
||||
var chunkStart = 0, pending = false;
|
||||
for (var i = 0; i < diff.length; ++i) {
|
||||
var part = diff[i], tp = part[0], str = part[1];
|
||||
if (tp == DIFF_EQUAL) {
|
||||
|
@ -255,10 +290,11 @@
|
|||
moveOver(pos, str);
|
||||
var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0);
|
||||
if (cleanTo > cleanFrom) {
|
||||
if (i) markChunk(chunkStart, cleanFrom);
|
||||
if (pending) { markChunk(chunkStart, cleanFrom); pending = false }
|
||||
chunkStart = cleanTo;
|
||||
}
|
||||
} else {
|
||||
pending = true
|
||||
if (tp == type) {
|
||||
var end = moveOver(pos, str, true);
|
||||
var a = posMax(top, pos), b = posMin(bot, end);
|
||||
|
@ -268,7 +304,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1);
|
||||
if (pending) markChunk(chunkStart, pos.line + 1);
|
||||
}
|
||||
|
||||
// Updating the gap between editor and original
|
||||
|
@ -284,7 +320,9 @@
|
|||
if (dv.copyButtons) clear(dv.copyButtons);
|
||||
|
||||
var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
|
||||
var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
|
||||
var outerTop = dv.mv.wrap.getBoundingClientRect().top
|
||||
var sTopEdit = outerTop - dv.edit.getScrollerElement().getBoundingClientRect().top + dv.edit.getScrollInfo().top
|
||||
var sTopOrig = outerTop - dv.orig.getScrollerElement().getBoundingClientRect().top + dv.orig.getScrollInfo().top;
|
||||
for (var i = 0; i < dv.chunks.length; i++) {
|
||||
var ch = dv.chunks[i];
|
||||
if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from &&
|
||||
|
@ -305,29 +343,73 @@
|
|||
return origStart + (editLine - editStart);
|
||||
}
|
||||
|
||||
function findAlignedLines(dv, other) {
|
||||
var linesToAlign = [];
|
||||
for (var i = 0; i < dv.chunks.length; i++) {
|
||||
var chunk = dv.chunks[i];
|
||||
linesToAlign.push([chunk.origTo, chunk.editTo, other ? getMatchingOrigLine(chunk.editTo, other.chunks) : null]);
|
||||
// Combines information about chunks and widgets/markers to return
|
||||
// an array of lines, in a single editor, that probably need to be
|
||||
// aligned with their counterparts in the editor next to it.
|
||||
function alignableFor(cm, chunks, isOrig) {
|
||||
var tracker = cm.state.trackAlignable
|
||||
var start = cm.firstLine(), trackI = 0
|
||||
var result = []
|
||||
for (var i = 0;; i++) {
|
||||
var chunk = chunks[i]
|
||||
var chunkStart = !chunk ? cm.lastLine() + 1 : isOrig ? chunk.origFrom : chunk.editFrom
|
||||
for (; trackI < tracker.alignable.length; trackI += 2) {
|
||||
var n = tracker.alignable[trackI] + 1
|
||||
if (n <= start) continue
|
||||
if (n < chunkStart) result.push(n)
|
||||
else break
|
||||
}
|
||||
if (!chunk) break
|
||||
result.push(start = isOrig ? chunk.origTo : chunk.editTo)
|
||||
}
|
||||
if (other) {
|
||||
for (var i = 0; i < other.chunks.length; i++) {
|
||||
var chunk = other.chunks[i];
|
||||
for (var j = 0; j < linesToAlign.length; j++) {
|
||||
var align = linesToAlign[j];
|
||||
if (align[1] == chunk.editTo) {
|
||||
j = -1;
|
||||
break;
|
||||
} else if (align[1] > chunk.editTo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j > -1)
|
||||
linesToAlign.splice(j - 1, 0, [getMatchingOrigLine(chunk.editTo, dv.chunks), chunk.editTo, chunk.origTo]);
|
||||
return result
|
||||
}
|
||||
|
||||
// Given information about alignable lines in two editors, fill in
|
||||
// the result (an array of three-element arrays) to reflect the
|
||||
// lines that need to be aligned with each other.
|
||||
function mergeAlignable(result, origAlignable, chunks, setIndex) {
|
||||
var rI = 0, origI = 0, chunkI = 0, diff = 0
|
||||
for (;; rI++) {
|
||||
var nextR = result[rI], nextO = origAlignable[origI]
|
||||
if (!nextR && nextO == null) break
|
||||
|
||||
var rLine = nextR ? nextR[0] : 1e9, oLine = nextO == null ? 1e9 : nextO
|
||||
while (chunkI < chunks.length) {
|
||||
var chunk = chunks[chunkI]
|
||||
if (chunk.editTo > rLine) break
|
||||
diff += (chunk.origTo - chunk.origFrom) - (chunk.editTo - chunk.editFrom)
|
||||
chunkI++
|
||||
}
|
||||
if (rLine == oLine - diff) {
|
||||
nextR[setIndex] = oLine
|
||||
origI++
|
||||
} else if (rLine < oLine - diff) {
|
||||
nextR[setIndex] = rLine + diff
|
||||
} else {
|
||||
var record = [oLine - diff, null, null]
|
||||
record[setIndex] = oLine
|
||||
result.splice(rI, 0, record)
|
||||
origI++
|
||||
}
|
||||
}
|
||||
return linesToAlign;
|
||||
}
|
||||
|
||||
function findAlignedLines(dv, other) {
|
||||
var alignable = alignableFor(dv.edit, dv.chunks, false), result = []
|
||||
if (other) for (var i = 0, j = 0; i < other.chunks.length; i++) {
|
||||
var n = other.chunks[i].editTo
|
||||
while (j < alignable.length && alignable[j] < n) j++
|
||||
if (j == alignable.length || alignable[j] != n) alignable.splice(j++, 0, n)
|
||||
}
|
||||
for (var i = 0; i < alignable.length; i++)
|
||||
result.push([alignable[i], null, null])
|
||||
|
||||
mergeAlignable(result, alignableFor(dv.orig, dv.chunks, true), dv.chunks, 1)
|
||||
if (other)
|
||||
mergeAlignable(result, alignableFor(other.orig, other.chunks, true), other.chunks, 2)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function alignChunks(dv, force) {
|
||||
|
@ -350,7 +432,7 @@
|
|||
aligners[i].clear();
|
||||
aligners.length = 0;
|
||||
|
||||
var cm = [dv.orig, dv.edit], scroll = [];
|
||||
var cm = [dv.edit, dv.orig], scroll = [];
|
||||
if (other) cm.push(other.orig);
|
||||
for (var i = 0; i < cm.length; i++)
|
||||
scroll.push(cm[i].getScrollInfo().top);
|
||||
|
@ -385,18 +467,18 @@
|
|||
var elt = document.createElement("div");
|
||||
elt.className = "CodeMirror-merge-spacer";
|
||||
elt.style.height = size + "px"; elt.style.minWidth = "1px";
|
||||
return cm.addLineWidget(line, elt, {height: size, above: above});
|
||||
return cm.addLineWidget(line, elt, {height: size, above: above, mergeSpacer: true});
|
||||
}
|
||||
|
||||
function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) {
|
||||
var flip = dv.type == "left";
|
||||
var top = dv.orig.heightAtLine(chunk.origFrom, "local") - sTopOrig;
|
||||
var top = dv.orig.heightAtLine(chunk.origFrom, "local", true) - sTopOrig;
|
||||
if (dv.svg) {
|
||||
var topLpx = top;
|
||||
var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit;
|
||||
var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local", true) - sTopEdit;
|
||||
if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; }
|
||||
var botLpx = dv.orig.heightAtLine(chunk.origTo, "local") - sTopOrig;
|
||||
var botRpx = dv.edit.heightAtLine(chunk.editTo, "local") - sTopEdit;
|
||||
var botLpx = dv.orig.heightAtLine(chunk.origTo, "local", true) - sTopOrig;
|
||||
var botRpx = dv.edit.heightAtLine(chunk.editTo, "local", true) - sTopEdit;
|
||||
if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; }
|
||||
var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx;
|
||||
var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx;
|
||||
|
@ -410,10 +492,10 @@
|
|||
var editOriginals = dv.mv.options.allowEditingOriginals;
|
||||
copy.title = editOriginals ? "Push to left" : "Revert chunk";
|
||||
copy.chunk = chunk;
|
||||
copy.style.top = top + "px";
|
||||
copy.style.top = (chunk.origTo > chunk.origFrom ? top : dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit) + "px";
|
||||
|
||||
if (editOriginals) {
|
||||
var topReverse = dv.orig.heightAtLine(chunk.editFrom, "local") - sTopEdit;
|
||||
var topReverse = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit;
|
||||
var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc",
|
||||
"CodeMirror-merge-copy-reverse"));
|
||||
copyReverse.title = "Push to right";
|
||||
|
@ -427,8 +509,15 @@
|
|||
|
||||
function copyChunk(dv, to, from, chunk) {
|
||||
if (dv.diffOutOfDate) return;
|
||||
to.replaceRange(from.getRange(Pos(chunk.origFrom, 0), Pos(chunk.origTo, 0)),
|
||||
Pos(chunk.editFrom, 0), Pos(chunk.editTo, 0));
|
||||
var origStart = chunk.origTo > from.lastLine() ? Pos(chunk.origFrom - 1) : Pos(chunk.origFrom, 0)
|
||||
var origEnd = Pos(chunk.origTo, 0)
|
||||
var editStart = chunk.editTo > to.lastLine() ? Pos(chunk.editFrom - 1) : Pos(chunk.editFrom, 0)
|
||||
var editEnd = Pos(chunk.editTo, 0)
|
||||
var handler = dv.mv.options.revertChunk
|
||||
if (handler)
|
||||
handler(dv.mv, from, origStart, origEnd, to, editStart, editEnd)
|
||||
else
|
||||
to.replaceRange(from.getRange(origStart, origEnd), editStart, editEnd)
|
||||
}
|
||||
|
||||
// Merge view, containing 0, 1, or 2 diff views.
|
||||
|
@ -446,18 +535,18 @@
|
|||
|
||||
if (hasLeft) {
|
||||
left = this.left = new DiffView(this, "left");
|
||||
var leftPane = elt("div", null, "CodeMirror-merge-pane");
|
||||
var leftPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-left");
|
||||
wrap.push(leftPane);
|
||||
wrap.push(buildGap(left));
|
||||
}
|
||||
|
||||
var editPane = elt("div", null, "CodeMirror-merge-pane");
|
||||
var editPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-editor");
|
||||
wrap.push(editPane);
|
||||
|
||||
if (hasRight) {
|
||||
right = this.right = new DiffView(this, "right");
|
||||
wrap.push(buildGap(right));
|
||||
var rightPane = elt("div", null, "CodeMirror-merge-pane");
|
||||
var rightPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-right");
|
||||
wrap.push(rightPane);
|
||||
}
|
||||
|
||||
|
@ -470,7 +559,6 @@
|
|||
|
||||
if (left) left.init(leftPane, origLeft, options);
|
||||
if (right) right.init(rightPane, origRight, options);
|
||||
|
||||
if (options.collapseIdentical)
|
||||
this.editor().operation(function() {
|
||||
collapseIdenticalStretches(self, options.collapseIdentical);
|
||||
|
@ -479,6 +567,9 @@
|
|||
this.aligners = [];
|
||||
alignChunks(this.left || this.right, true);
|
||||
}
|
||||
if (left) left.registerEvents()
|
||||
if (right) right.registerEvents()
|
||||
|
||||
|
||||
var onResize = function() {
|
||||
if (left) makeConnections(left);
|
||||
|
@ -521,7 +612,7 @@
|
|||
}
|
||||
|
||||
MergeView.prototype = {
|
||||
constuctor: MergeView,
|
||||
constructor: MergeView,
|
||||
editor: function() { return this.edit; },
|
||||
rightOriginal: function() { return this.right && this.right.orig; },
|
||||
leftOriginal: function() { return this.left && this.left.orig; },
|
||||
|
@ -547,7 +638,6 @@
|
|||
var dmp = new diff_match_patch();
|
||||
function getDiff(a, b) {
|
||||
var diff = dmp.diff_main(a, b);
|
||||
dmp.diff_cleanupSemantic(diff);
|
||||
// The library sometimes leaves in empty parts, which confuse the algorithm
|
||||
for (var i = 0; i < diff.length; ++i) {
|
||||
var part = diff[i];
|
||||
|
@ -591,10 +681,10 @@
|
|||
function endOfLineClean(diff, i) {
|
||||
if (i == diff.length - 1) return true;
|
||||
var next = diff[i + 1][1];
|
||||
if (next.length == 1 || next.charCodeAt(0) != 10) return false;
|
||||
if ((next.length == 1 && i < diff.length - 2) || next.charCodeAt(0) != 10) return false;
|
||||
if (i == diff.length - 2) return true;
|
||||
next = diff[i + 2][1];
|
||||
return next.length > 1 && next.charCodeAt(0) == 10;
|
||||
return (next.length > 1 || i == diff.length - 3) && next.charCodeAt(0) == 10;
|
||||
}
|
||||
|
||||
function startOfLineClean(diff, i) {
|
||||
|
@ -728,6 +818,126 @@
|
|||
return out;
|
||||
}
|
||||
|
||||
// Tracks collapsed markers and line widgets, in order to be able to
|
||||
// accurately align the content of two editors.
|
||||
|
||||
var F_WIDGET = 1, F_WIDGET_BELOW = 2, F_MARKER = 4
|
||||
|
||||
function TrackAlignable(cm) {
|
||||
this.cm = cm
|
||||
this.alignable = []
|
||||
var self = this
|
||||
cm.on("markerAdded", function(_, marker) {
|
||||
if (!marker.collapsed) return
|
||||
var found = marker.find(1)
|
||||
if (found != null) self.set(found.line, F_MARKER)
|
||||
})
|
||||
cm.on("markerCleared", function(_, marker, _min, max) {
|
||||
if (max != null && marker.collapsed)
|
||||
self.check(max, F_MARKER, self.hasMarker)
|
||||
})
|
||||
cm.on("markerChanged", this.signal.bind(this))
|
||||
cm.on("lineWidgetAdded", function(_, widget, lineNo) {
|
||||
if (widget.mergeSpacer) return
|
||||
if (widget.above) self.set(lineNo - 1, F_WIDGET_BELOW)
|
||||
else self.set(lineNo, F_WIDGET)
|
||||
})
|
||||
cm.on("lineWidgetCleared", function(_, widget, lineNo) {
|
||||
if (widget.mergeSpacer) return
|
||||
if (widget.above) self.check(lineNo - 1, F_WIDGET_BELOW, self.hasWidgetBelow)
|
||||
else self.check(lineNo, F_WIDGET, self.hasWidget)
|
||||
})
|
||||
cm.on("lineWidgetChanged", this.signal.bind(this))
|
||||
cm.on("change", function(_, change) {
|
||||
var start = change.from.line, nBefore = change.to.line - change.from.line
|
||||
var nAfter = change.text.length - 1, end = start + nAfter
|
||||
if (nBefore || nAfter) self.map(start, nBefore, nAfter)
|
||||
self.check(end, F_MARKER, self.hasMarker)
|
||||
if (nBefore || nAfter) self.check(change.from.line, F_MARKER, self.hasMarker)
|
||||
})
|
||||
}
|
||||
|
||||
TrackAlignable.prototype = {
|
||||
signal: function() {
|
||||
CodeMirror.signal(this, "realign")
|
||||
},
|
||||
|
||||
set: function(n, flags) {
|
||||
var pos = -1
|
||||
for (; pos < this.alignable.length; pos += 2) {
|
||||
var diff = this.alignable[pos] - n
|
||||
if (diff == 0) {
|
||||
if ((this.alignable[pos + 1] & flags) == flags) return
|
||||
this.alignable[pos + 1] |= flags
|
||||
this.signal()
|
||||
return
|
||||
}
|
||||
if (diff > 0) break
|
||||
}
|
||||
this.signal()
|
||||
this.alignable.splice(pos, 0, n, flags)
|
||||
},
|
||||
|
||||
find: function(n) {
|
||||
for (var i = 0; i < this.alignable.length; i += 2)
|
||||
if (this.alignable[i] == n) return i
|
||||
return -1
|
||||
},
|
||||
|
||||
check: function(n, flag, pred) {
|
||||
var found = this.find(n)
|
||||
if (found == -1 || !(this.alignable[found + 1] & flag)) return
|
||||
if (!pred.call(this, n)) {
|
||||
this.signal()
|
||||
var flags = this.alignable[found + 1] & ~flag
|
||||
if (flags) this.alignable[found + 1] = flags
|
||||
else this.alignable.splice(found, 2)
|
||||
}
|
||||
},
|
||||
|
||||
hasMarker: function(n) {
|
||||
var handle = this.cm.getLineHandle(n)
|
||||
if (handle.markedSpans) for (var i = 0; i < handle.markedSpans.length; i++)
|
||||
if (handle.markedSpans[i].mark.collapsed && handle.markedSpans[i].to != null)
|
||||
return true
|
||||
return false
|
||||
},
|
||||
|
||||
hasWidget: function(n) {
|
||||
var handle = this.cm.getLineHandle(n)
|
||||
if (handle.widgets) for (var i = 0; i < handle.widgets.length; i++)
|
||||
if (!handle.widgets[i].above && !handle.widgets[i].mergeSpacer) return true
|
||||
return false
|
||||
},
|
||||
|
||||
hasWidgetBelow: function(n) {
|
||||
if (n == this.cm.lastLine()) return false
|
||||
var handle = this.cm.getLineHandle(n + 1)
|
||||
if (handle.widgets) for (var i = 0; i < handle.widgets.length; i++)
|
||||
if (handle.widgets[i].above && !handle.widgets[i].mergeSpacer) return true
|
||||
return false
|
||||
},
|
||||
|
||||
map: function(from, nBefore, nAfter) {
|
||||
var diff = nAfter - nBefore, to = from + nBefore, widgetFrom = -1, widgetTo = -1
|
||||
for (var i = 0; i < this.alignable.length; i += 2) {
|
||||
var n = this.alignable[i]
|
||||
if (n == from && (this.alignable[i + 1] & F_WIDGET_BELOW)) widgetFrom = i
|
||||
if (n == to && (this.alignable[i + 1] & F_WIDGET_BELOW)) widgetTo = i
|
||||
if (n <= from) continue
|
||||
else if (n < to) this.alignable.splice(i--, 2)
|
||||
else this.alignable[i] += diff
|
||||
}
|
||||
if (widgetFrom > -1) {
|
||||
var flags = this.alignable[widgetFrom + 1]
|
||||
if (flags == F_WIDGET_BELOW) this.alignable.splice(widgetFrom, 2)
|
||||
else this.alignable[widgetFrom + 1] = flags & ~F_WIDGET_BELOW
|
||||
}
|
||||
if (widgetTo > -1 && nAfter)
|
||||
this.set(from + nAfter, F_WIDGET_BELOW)
|
||||
}
|
||||
}
|
||||
|
||||
function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; }
|
||||
function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; }
|
||||
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
|
||||
|
|
9
app/public/codemirror/addon/mode/overlay.js
vendored
9
app/public/codemirror/addon/mode/overlay.js
vendored
|
@ -76,8 +76,13 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
|
|||
innerMode: function(state) { return {state: state.base, mode: base}; },
|
||||
|
||||
blankLine: function(state) {
|
||||
if (base.blankLine) base.blankLine(state.base);
|
||||
if (overlay.blankLine) overlay.blankLine(state.overlay);
|
||||
var baseToken, overlayToken;
|
||||
if (base.blankLine) baseToken = base.blankLine(state.base);
|
||||
if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay);
|
||||
|
||||
return overlayToken == null ?
|
||||
baseToken :
|
||||
(combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -77,17 +77,21 @@
|
|||
curLine = pos.line;
|
||||
curLineObj = cm.getLineHandle(curLine);
|
||||
}
|
||||
if (wrapping && curLineObj.height > singleLineH)
|
||||
if ((curLineObj.widgets && curLineObj.widgets.length) ||
|
||||
(wrapping && curLineObj.height > singleLineH))
|
||||
return cm.charCoords(pos, "local")[top ? "top" : "bottom"];
|
||||
var topY = cm.heightAtLine(curLineObj, "local");
|
||||
return topY + (top ? 0 : curLineObj.height);
|
||||
}
|
||||
|
||||
var lastLine = cm.lastLine()
|
||||
if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
|
||||
var ann = anns[i];
|
||||
if (ann.to.line > lastLine) continue;
|
||||
var top = nextTop || getY(ann.from, true) * hScale;
|
||||
var bottom = getY(ann.to, false) * hScale;
|
||||
while (i < anns.length - 1) {
|
||||
if (anns[i + 1].to.line > lastLine) break;
|
||||
nextTop = getY(anns[i + 1].from, true) * hScale;
|
||||
if (nextTop > bottom + .9) break;
|
||||
ann = anns[++i];
|
||||
|
|
|
@ -40,7 +40,9 @@
|
|||
if (cm.state.scrollPastEndPadding != padding) {
|
||||
cm.state.scrollPastEndPadding = padding;
|
||||
cm.display.lineSpace.parentNode.style.paddingBottom = padding;
|
||||
cm.off("refresh", updateBottomMargin);
|
||||
cm.setSize();
|
||||
cm.on("refresh", updateBottomMargin);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -59,22 +59,29 @@
|
|||
CodeMirror.on(this.node, "DOMMouseScroll", onWheel);
|
||||
}
|
||||
|
||||
Bar.prototype.moveTo = function(pos, update) {
|
||||
Bar.prototype.setPos = function(pos, force) {
|
||||
if (pos < 0) pos = 0;
|
||||
if (pos > this.total - this.screen) pos = this.total - this.screen;
|
||||
if (pos == this.pos) return;
|
||||
if (!force && pos == this.pos) return false;
|
||||
this.pos = pos;
|
||||
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
|
||||
(pos * (this.size / this.total)) + "px";
|
||||
if (update !== false) this.scroll(pos, this.orientation);
|
||||
return true
|
||||
};
|
||||
|
||||
Bar.prototype.moveTo = function(pos) {
|
||||
if (this.setPos(pos)) this.scroll(pos, this.orientation);
|
||||
}
|
||||
|
||||
var minButtonSize = 10;
|
||||
|
||||
Bar.prototype.update = function(scrollSize, clientSize, barSize) {
|
||||
this.screen = clientSize;
|
||||
this.total = scrollSize;
|
||||
this.size = barSize;
|
||||
var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize
|
||||
if (sizeChanged) {
|
||||
this.screen = clientSize;
|
||||
this.total = scrollSize;
|
||||
this.size = barSize;
|
||||
}
|
||||
|
||||
var buttonSize = this.screen * (this.size / this.total);
|
||||
if (buttonSize < minButtonSize) {
|
||||
|
@ -83,8 +90,7 @@
|
|||
}
|
||||
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
|
||||
buttonSize + "px";
|
||||
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
|
||||
this.pos * (this.size / this.total) + "px";
|
||||
this.setPos(this.pos, sizeChanged);
|
||||
};
|
||||
|
||||
function SimpleScrollbars(cls, place, scroll) {
|
||||
|
@ -111,7 +117,6 @@
|
|||
if (needsV) {
|
||||
this.vert.update(measure.scrollHeight, measure.clientHeight,
|
||||
measure.viewHeight - (needsH ? width : 0));
|
||||
this.vert.node.style.display = "block";
|
||||
this.vert.node.style.bottom = needsH ? width + "px" : "0";
|
||||
}
|
||||
if (needsH) {
|
||||
|
@ -125,11 +130,11 @@
|
|||
};
|
||||
|
||||
SimpleScrollbars.prototype.setScrollTop = function(pos) {
|
||||
this.vert.moveTo(pos, false);
|
||||
this.vert.setPos(pos);
|
||||
};
|
||||
|
||||
SimpleScrollbars.prototype.setScrollLeft = function(pos) {
|
||||
this.horiz.moveTo(pos, false);
|
||||
this.horiz.setPos(pos);
|
||||
};
|
||||
|
||||
SimpleScrollbars.prototype.clear = function() {
|
||||
|
|
|
@ -16,81 +16,118 @@
|
|||
// highlighted only if the selected text is a word. showToken, when enabled,
|
||||
// will cause the current token to be highlighted when nothing is selected.
|
||||
// delay is used to specify how much time to wait, in milliseconds, before
|
||||
// highlighting the matches.
|
||||
// highlighting the matches. If annotateScrollbar is enabled, the occurences
|
||||
// will be highlighted on the scrollbar via the matchesonscrollbar addon.
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
define(["../../lib/codemirror", "./matchesonscrollbar"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
var DEFAULT_MIN_CHARS = 2;
|
||||
var DEFAULT_TOKEN_STYLE = "matchhighlight";
|
||||
var DEFAULT_DELAY = 100;
|
||||
var DEFAULT_WORDS_ONLY = false;
|
||||
var defaults = {
|
||||
style: "matchhighlight",
|
||||
minChars: 2,
|
||||
delay: 100,
|
||||
wordsOnly: false,
|
||||
annotateScrollbar: false,
|
||||
showToken: false,
|
||||
trim: true
|
||||
}
|
||||
|
||||
function State(options) {
|
||||
if (typeof options == "object") {
|
||||
this.minChars = options.minChars;
|
||||
this.style = options.style;
|
||||
this.showToken = options.showToken;
|
||||
this.delay = options.delay;
|
||||
this.wordsOnly = options.wordsOnly;
|
||||
}
|
||||
if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
|
||||
if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
|
||||
if (this.delay == null) this.delay = DEFAULT_DELAY;
|
||||
if (this.wordsOnly == null) this.wordsOnly = DEFAULT_WORDS_ONLY;
|
||||
this.options = {}
|
||||
for (var name in defaults)
|
||||
this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name]
|
||||
this.overlay = this.timeout = null;
|
||||
this.matchesonscroll = null;
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init) {
|
||||
var over = cm.state.matchHighlighter.overlay;
|
||||
if (over) cm.removeOverlay(over);
|
||||
removeOverlay(cm);
|
||||
clearTimeout(cm.state.matchHighlighter.timeout);
|
||||
cm.state.matchHighlighter = null;
|
||||
cm.off("cursorActivity", cursorActivity);
|
||||
cm.off("focus", onFocus)
|
||||
}
|
||||
if (val) {
|
||||
cm.state.matchHighlighter = new State(val);
|
||||
highlightMatches(cm);
|
||||
var state = cm.state.matchHighlighter = new State(val);
|
||||
if (cm.hasFocus()) {
|
||||
state.active = true
|
||||
highlightMatches(cm)
|
||||
} else {
|
||||
cm.on("focus", onFocus)
|
||||
}
|
||||
cm.on("cursorActivity", cursorActivity);
|
||||
}
|
||||
});
|
||||
|
||||
function cursorActivity(cm) {
|
||||
var state = cm.state.matchHighlighter;
|
||||
if (state.active || cm.hasFocus()) scheduleHighlight(cm, state)
|
||||
}
|
||||
|
||||
function onFocus(cm) {
|
||||
var state = cm.state.matchHighlighter
|
||||
if (!state.active) {
|
||||
state.active = true
|
||||
scheduleHighlight(cm, state)
|
||||
}
|
||||
}
|
||||
|
||||
function scheduleHighlight(cm, state) {
|
||||
clearTimeout(state.timeout);
|
||||
state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay);
|
||||
state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay);
|
||||
}
|
||||
|
||||
function addOverlay(cm, query, hasBoundary, style) {
|
||||
var state = cm.state.matchHighlighter;
|
||||
cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
|
||||
if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
|
||||
var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query;
|
||||
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
|
||||
{className: "CodeMirror-selection-highlight-scrollbar"});
|
||||
}
|
||||
}
|
||||
|
||||
function removeOverlay(cm) {
|
||||
var state = cm.state.matchHighlighter;
|
||||
if (state.overlay) {
|
||||
cm.removeOverlay(state.overlay);
|
||||
state.overlay = null;
|
||||
if (state.matchesonscroll) {
|
||||
state.matchesonscroll.clear();
|
||||
state.matchesonscroll = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function highlightMatches(cm) {
|
||||
cm.operation(function() {
|
||||
var state = cm.state.matchHighlighter;
|
||||
if (state.overlay) {
|
||||
cm.removeOverlay(state.overlay);
|
||||
state.overlay = null;
|
||||
}
|
||||
if (!cm.somethingSelected() && state.showToken) {
|
||||
var re = state.showToken === true ? /[\w$]/ : state.showToken;
|
||||
removeOverlay(cm);
|
||||
if (!cm.somethingSelected() && state.options.showToken) {
|
||||
var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
|
||||
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
|
||||
while (start && re.test(line.charAt(start - 1))) --start;
|
||||
while (end < line.length && re.test(line.charAt(end))) ++end;
|
||||
if (start < end)
|
||||
cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style));
|
||||
addOverlay(cm, line.slice(start, end), re, state.options.style);
|
||||
return;
|
||||
}
|
||||
var from = cm.getCursor("from"), to = cm.getCursor("to");
|
||||
if (from.line != to.line) return;
|
||||
if (state.wordsOnly && !isWord(cm, from, to)) return;
|
||||
var selection = cm.getRange(from, to).replace(/^\s+|\s+$/g, "");
|
||||
if (selection.length >= state.minChars)
|
||||
cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style));
|
||||
if (state.options.wordsOnly && !isWord(cm, from, to)) return;
|
||||
var selection = cm.getRange(from, to)
|
||||
if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "")
|
||||
if (selection.length >= state.options.minChars)
|
||||
addOverlay(cm, selection, false, state.options.style);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
38
app/public/codemirror/addon/search/search.js
vendored
38
app/public/codemirror/addon/search/search.js
vendored
|
@ -57,12 +57,13 @@
|
|||
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
|
||||
}
|
||||
|
||||
function persistentDialog(cm, text, deflt, f) {
|
||||
cm.openDialog(text, f, {
|
||||
function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
|
||||
cm.openDialog(text, onEnter, {
|
||||
value: deflt,
|
||||
selectValueOnOpen: true,
|
||||
closeOnEnter: false,
|
||||
onClose: function() { clearSearch(cm); }
|
||||
onClose: function() { clearSearch(cm); },
|
||||
onKeyDown: onKeyDown
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -112,16 +113,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
function doSearch(cm, rev, persistent) {
|
||||
function doSearch(cm, rev, persistent, immediate) {
|
||||
var state = getSearchState(cm);
|
||||
if (state.query) return findNext(cm, rev);
|
||||
var q = cm.getSelection() || state.lastQuery;
|
||||
if (persistent && cm.openDialog) {
|
||||
var hiding = null
|
||||
persistentDialog(cm, queryDialog, q, function(query, event) {
|
||||
var searchNext = function(query, event) {
|
||||
CodeMirror.e_stop(event);
|
||||
if (!query) return;
|
||||
if (query != state.queryText) startSearch(cm, state, query);
|
||||
if (query != state.queryText) {
|
||||
startSearch(cm, state, query);
|
||||
state.posFrom = state.posTo = cm.getCursor();
|
||||
}
|
||||
if (hiding) hiding.style.opacity = 1
|
||||
findNext(cm, event.shiftKey, function(_, to) {
|
||||
var dialog
|
||||
|
@ -130,7 +134,25 @@
|
|||
dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
|
||||
(hiding = dialog).style.opacity = .4
|
||||
})
|
||||
};
|
||||
persistentDialog(cm, queryDialog, q, searchNext, function(event, query) {
|
||||
var keyName = CodeMirror.keyName(event)
|
||||
var cmd = CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
|
||||
if (!cmd) cmd = cm.getOption('extraKeys')[keyName]
|
||||
if (cmd == "findNext" || cmd == "findPrev" ||
|
||||
cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
|
||||
CodeMirror.e_stop(event);
|
||||
startSearch(cm, getSearchState(cm), query);
|
||||
cm.execCommand(cmd);
|
||||
} else if (cmd == "find" || cmd == "findPersistent") {
|
||||
CodeMirror.e_stop(event);
|
||||
searchNext(query, event);
|
||||
}
|
||||
});
|
||||
if (immediate && q) {
|
||||
startSearch(cm, state, q);
|
||||
findNext(cm, rev);
|
||||
}
|
||||
} else {
|
||||
dialog(cm, queryDialog, "Search for:", q, function(query) {
|
||||
if (query && !state.query) cm.operation(function() {
|
||||
|
@ -193,7 +215,7 @@
|
|||
replaceAll(cm, query, text)
|
||||
} else {
|
||||
clearSearch(cm);
|
||||
var cursor = getSearchCursor(cm, query, cm.getCursor());
|
||||
var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
|
||||
var advance = function() {
|
||||
var start = cursor.from(), match;
|
||||
if (!(match = cursor.findNext())) {
|
||||
|
@ -220,6 +242,8 @@
|
|||
|
||||
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
|
||||
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
|
||||
CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
|
||||
CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
|
||||
CodeMirror.commands.findNext = doSearch;
|
||||
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
|
||||
CodeMirror.commands.clearSearch = clearSearch;
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// Because sometimes you need to style the cursor's line.
|
||||
//
|
||||
// Adds an option 'styleActiveLine' which, when enabled, gives the
|
||||
// active line's wrapping <div> the CSS class "CodeMirror-activeline",
|
||||
// and gives its background <div> the class "CodeMirror-activeline-background".
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
|
@ -18,24 +12,28 @@
|
|||
"use strict";
|
||||
var WRAP_CLASS = "CodeMirror-activeline";
|
||||
var BACK_CLASS = "CodeMirror-activeline-background";
|
||||
var GUTT_CLASS = "CodeMirror-activeline-gutter";
|
||||
|
||||
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
|
||||
var prev = old && old != CodeMirror.Init;
|
||||
if (val && !prev) {
|
||||
cm.state.activeLines = [];
|
||||
updateActiveLines(cm, cm.listSelections());
|
||||
cm.on("beforeSelectionChange", selectionChange);
|
||||
} else if (!val && prev) {
|
||||
var prev = old == CodeMirror.Init ? false : old;
|
||||
if (val == prev) return
|
||||
if (prev) {
|
||||
cm.off("beforeSelectionChange", selectionChange);
|
||||
clearActiveLines(cm);
|
||||
delete cm.state.activeLines;
|
||||
}
|
||||
if (val) {
|
||||
cm.state.activeLines = [];
|
||||
updateActiveLines(cm, cm.listSelections());
|
||||
cm.on("beforeSelectionChange", selectionChange);
|
||||
}
|
||||
});
|
||||
|
||||
function clearActiveLines(cm) {
|
||||
for (var i = 0; i < cm.state.activeLines.length; i++) {
|
||||
cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
|
||||
cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
|
||||
cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +48,9 @@
|
|||
var active = [];
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
var range = ranges[i];
|
||||
if (!range.empty()) continue;
|
||||
var option = cm.getOption("styleActiveLine");
|
||||
if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
|
||||
continue
|
||||
var line = cm.getLineHandleVisualStart(range.head.line);
|
||||
if (active[active.length - 1] != line) active.push(line);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@
|
|||
for (var i = 0; i < active.length; i++) {
|
||||
cm.addLineClass(active[i], "wrap", WRAP_CLASS);
|
||||
cm.addLineClass(active[i], "background", BACK_CLASS);
|
||||
cm.addLineClass(active[i], "gutter", GUTT_CLASS);
|
||||
}
|
||||
cm.state.activeLines = active;
|
||||
});
|
||||
|
|
4
app/public/codemirror/addon/tern/tern.js
vendored
4
app/public/codemirror/addon/tern/tern.js
vendored
|
@ -179,7 +179,7 @@
|
|||
var data = findDoc(ts, doc);
|
||||
|
||||
var argHints = ts.cachedArgHints;
|
||||
if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0)
|
||||
if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) >= 0)
|
||||
ts.cachedArgHints = null;
|
||||
|
||||
var changed = data.changed;
|
||||
|
@ -306,7 +306,7 @@
|
|||
ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
|
||||
if (error || !data.type || !(/^fn\(/).test(data.type)) return;
|
||||
ts.cachedArgHints = {
|
||||
start: pos,
|
||||
start: start,
|
||||
type: parseFnType(data.type),
|
||||
name: data.exprName || data.name || "fn",
|
||||
guess: data.guess,
|
||||
|
|
4
app/public/codemirror/addon/wrap/hardwrap.js
vendored
4
app/public/codemirror/addon/wrap/hardwrap.js
vendored
|
@ -30,7 +30,9 @@
|
|||
}
|
||||
|
||||
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
|
||||
for (var at = column; at > 0; --at)
|
||||
var at = column
|
||||
while (at < text.length && text.charAt(at) == " ") at++
|
||||
for (; at > 0; --at)
|
||||
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
|
||||
for (var first = true;; first = false) {
|
||||
var endOfText = at;
|
||||
|
|
17248
app/public/codemirror/lib/codemirror.js
vendored
17248
app/public/codemirror/lib/codemirror.js
vendored
File diff suppressed because it is too large
Load diff
3
app/public/codemirror/mode/asn.1/index.html
vendored
3
app/public/codemirror/mode/asn.1/index.html
vendored
|
@ -1,4 +1,4 @@
|
|||
<!doctype html>
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: ASN.1 mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
|
@ -73,6 +73,5 @@
|
|||
<p>The development of this mode has been sponsored by <a href="http://www.ericsson.com/">Ericsson
|
||||
</a>.</p>
|
||||
<p>Coded by Asmelash Tsegay Gebretsadkan </p>
|
||||
</article>
|
||||
</article>
|
||||
|
||||
|
|
146
app/public/codemirror/mode/clike/clike.js
vendored
146
app/public/codemirror/mode/clike/clike.js
vendored
|
@ -11,6 +11,41 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
function Context(indented, column, type, info, align, prev) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.info = info;
|
||||
this.align = align;
|
||||
this.prev = prev;
|
||||
}
|
||||
function pushContext(state, col, type, info) {
|
||||
var indent = state.indented;
|
||||
if (state.context && state.context.type == "statement" && type != "statement")
|
||||
indent = state.context.indented;
|
||||
return state.context = new Context(indent, col, type, info, 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;
|
||||
}
|
||||
|
||||
function typeBefore(stream, state, pos) {
|
||||
if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
|
||||
if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true;
|
||||
if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true;
|
||||
}
|
||||
|
||||
function isTopScope(context) {
|
||||
for (;;) {
|
||||
if (!context || context.type == "top") return true;
|
||||
if (context.type == "}" && context.prev.info != "namespace") return false;
|
||||
context = context.prev;
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.defineMode("clike", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit,
|
||||
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
|
||||
|
@ -29,8 +64,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
|
||||
numberStart = parserConfig.numberStart || /[\d\.]/,
|
||||
number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
|
||||
isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
|
||||
endStatement = parserConfig.endStatement || /^[;:,]$/;
|
||||
isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/;
|
||||
|
||||
var curPunc, isDefKeyword;
|
||||
|
||||
|
@ -64,7 +98,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
}
|
||||
}
|
||||
if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
|
||||
return "operator";
|
||||
}
|
||||
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
|
||||
|
@ -111,40 +145,9 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
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 isStatement(type) {
|
||||
return type == "statement" || type == "switchstatement" || type == "namespace";
|
||||
}
|
||||
function pushContext(state, col, type) {
|
||||
var indent = state.indented;
|
||||
if (state.context && isStatement(state.context.type) && !isStatement(type))
|
||||
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;
|
||||
}
|
||||
|
||||
function typeBefore(stream, state) {
|
||||
if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
|
||||
if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
|
||||
}
|
||||
|
||||
function isTopScope(context) {
|
||||
for (;;) {
|
||||
if (!context || context.type == "top") return true;
|
||||
if (context.type == "}" && context.prev.type != "namespace") return false;
|
||||
context = context.prev;
|
||||
}
|
||||
function maybeEOL(stream, state) {
|
||||
if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
|
||||
state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
@ -153,7 +156,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: null,
|
||||
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
|
||||
context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false),
|
||||
indented: 0,
|
||||
startOfLine: true,
|
||||
prevToken: null
|
||||
|
@ -167,36 +170,32 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
state.indented = stream.indentation();
|
||||
state.startOfLine = true;
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
|
||||
curPunc = isDefKeyword = null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style == "comment" || style == "meta") return style;
|
||||
if (ctx.align == null) ctx.align = true;
|
||||
|
||||
if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
|
||||
if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false)))
|
||||
while (state.context.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 (isStatement(ctx.type)) ctx = popContext(state);
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
if (ctx.type == "}") ctx = popContext(state);
|
||||
while (isStatement(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 != ";") ||
|
||||
(isStatement(ctx.type) && curPunc == "newstatement"))) {
|
||||
var type = "statement";
|
||||
if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
|
||||
type = "switchstatement";
|
||||
else if (style == "keyword" && stream.current() == "namespace")
|
||||
type = "namespace";
|
||||
pushContext(state, stream.column(), type);
|
||||
(ctx.type == "statement" && curPunc == "newstatement"))) {
|
||||
pushContext(state, stream.column(), "statement", stream.current());
|
||||
}
|
||||
|
||||
if (style == "variable" &&
|
||||
((state.prevToken == "def" ||
|
||||
(parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
|
||||
(parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) &&
|
||||
isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
|
||||
style = "def";
|
||||
|
||||
|
@ -209,24 +208,28 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
|
||||
state.startOfLine = false;
|
||||
state.prevToken = isDefKeyword ? "def" : style || curPunc;
|
||||
maybeEOL(stream, state);
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
|
||||
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
|
||||
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
||||
if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
|
||||
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
||||
if (parserConfig.dontIndentStatements)
|
||||
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
|
||||
ctx = ctx.prev
|
||||
if (hooks.indent) {
|
||||
var hook = hooks.indent(state, ctx, textAfter);
|
||||
if (typeof hook == "number") return hook
|
||||
}
|
||||
var closing = firstChar == ctx.type;
|
||||
var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
|
||||
var switchBlock = ctx.prev && ctx.prev.info == "switch";
|
||||
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
|
||||
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
|
||||
return ctx.indented
|
||||
}
|
||||
if (isStatement(ctx.type))
|
||||
if (ctx.type == "statement")
|
||||
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
|
||||
if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
|
||||
return ctx.column + (closing ? 0 : 1);
|
||||
|
@ -264,9 +267,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
function cppHook(stream, state) {
|
||||
if (!state.startOfLine) return false
|
||||
for (var ch, next = null; ch = stream.peek();) {
|
||||
if (!ch) {
|
||||
break
|
||||
} else if (ch == "\\" && stream.match(/^.$/)) {
|
||||
if (ch == "\\" && stream.match(/^.$/)) {
|
||||
next = cppHook
|
||||
break
|
||||
} else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
|
||||
|
@ -388,6 +389,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
defKeywords: words("class namespace struct enum union"),
|
||||
typeFirstDefinitions: true,
|
||||
atoms: words("true false null"),
|
||||
dontIndentStatements: /^template$/,
|
||||
hooks: {
|
||||
"#": cppHook,
|
||||
"*": pointerHook,
|
||||
|
@ -423,16 +425,19 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
"do else enum extends final finally float for goto if implements import " +
|
||||
"instanceof interface native new package private protected public " +
|
||||
"return static strictfp super switch synchronized this throw throws transient " +
|
||||
"try volatile while"),
|
||||
"try volatile while @interface"),
|
||||
types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
|
||||
"Integer Long Number Object Short String StringBuffer StringBuilder Void"),
|
||||
blockKeywords: words("catch class do else finally for if switch try while"),
|
||||
defKeywords: words("class interface package enum"),
|
||||
defKeywords: words("class interface package enum @interface"),
|
||||
typeFirstDefinitions: true,
|
||||
atoms: words("true false null"),
|
||||
endStatement: /^[;:]$/,
|
||||
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
|
||||
hooks: {
|
||||
"@": function(stream) {
|
||||
// Don't match the @interface keyword.
|
||||
if (stream.match('interface', false)) return false;
|
||||
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
}
|
||||
|
@ -488,18 +493,15 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
/* scala */
|
||||
"abstract case catch class def do else extends final finally for forSome if " +
|
||||
"implicit import lazy match new null object override package private protected return " +
|
||||
"sealed super this throw trait try type val var while with yield _ : = => <- <: " +
|
||||
"<% >: # @ " +
|
||||
"sealed super this throw trait try type val var while with yield _ " +
|
||||
|
||||
/* package scala */
|
||||
"assert assume require print println printf readLine readBoolean readByte readShort " +
|
||||
"readChar readInt readLong readFloat readDouble " +
|
||||
|
||||
":: #:: "
|
||||
"readChar readInt readLong readFloat readDouble"
|
||||
),
|
||||
types: words(
|
||||
"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
|
||||
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
|
||||
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Int 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 " +
|
||||
|
@ -516,6 +518,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
atoms: words("true false null"),
|
||||
indentStatements: false,
|
||||
indentSwitch: false,
|
||||
isOperatorChar: /[+\-*&%=<>!?|\/#:@]/,
|
||||
hooks: {
|
||||
"@": function(stream) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
|
@ -529,6 +532,15 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
"'": function(stream) {
|
||||
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
|
||||
return "atom";
|
||||
},
|
||||
"=": function(stream, state) {
|
||||
var cx = state.context
|
||||
if (cx.type == "}" && cx.align && stream.eat(">")) {
|
||||
state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
|
||||
return "operator"
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
modeProps: {closeBrackets: {triples: '"'}}
|
||||
|
@ -660,7 +672,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
|
||||
def("text/x-objectivec", {
|
||||
name: "clike",
|
||||
keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
|
||||
keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginary BOOL Class bycopy byref id IMP in " +
|
||||
"inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
|
||||
types: words(cTypes),
|
||||
atoms: words("YES NO NULL NILL ON OFF true false"),
|
||||
|
|
4
app/public/codemirror/mode/clike/test.js
vendored
4
app/public/codemirror/mode/clike/test.js
vendored
|
@ -25,6 +25,10 @@
|
|||
"[keyword struct] [def bar]{}",
|
||||
"[variable-3 int] [variable-3 *][def baz]() {}");
|
||||
|
||||
MT("def_new_line",
|
||||
"::[variable std]::[variable SomeTerribleType][operator <][variable T][operator >]",
|
||||
"[def SomeLongMethodNameThatDoesntFitIntoOneLine]([keyword const] [variable MyType][operator &] [variable param]) {}")
|
||||
|
||||
MT("double_block",
|
||||
"[keyword for] (;;)",
|
||||
" [keyword for] (;;)",
|
||||
|
|
74
app/public/codemirror/mode/clojure/clojure.js
vendored
74
app/public/codemirror/mode/clojure/clojure.js
vendored
File diff suppressed because one or more lines are too long
|
@ -78,6 +78,9 @@
|
|||
\tab \return \backspace
|
||||
\u1000 \uAaAa \u9F9F)
|
||||
|
||||
;; Let's play with numbers
|
||||
(+ 1 -1 1/2 -1/2 -0.5 0.5)
|
||||
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
|
|
|
@ -43,11 +43,12 @@ CodeMirror.defineMode("commonlisp", function (config) {
|
|||
else { stream.skipToEnd(); return "error"; }
|
||||
} else if (ch == "#") {
|
||||
var ch = stream.next();
|
||||
if (ch == "[") { type = "open"; return "bracket"; }
|
||||
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 if (ch == "\\") { stream.next(); readSym(stream); return "string-2" }
|
||||
else return "error";
|
||||
} else {
|
||||
var name = readSym(stream);
|
||||
|
|
90
app/public/codemirror/mode/crystal/crystal.js
vendored
90
app/public/codemirror/mode/crystal/crystal.js
vendored
|
@ -29,26 +29,22 @@
|
|||
var types = /^[A-Z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/;
|
||||
var keywords = wordRegExp([
|
||||
"abstract", "alias", "as", "asm", "begin", "break", "case", "class", "def", "do",
|
||||
"else", "elsif", "end", "ensure", "enum", "extend", "for", "fun", "if", "ifdef",
|
||||
"else", "elsif", "end", "ensure", "enum", "extend", "for", "fun", "if",
|
||||
"include", "instance_sizeof", "lib", "macro", "module", "next", "of", "out", "pointerof",
|
||||
"private", "protected", "rescue", "return", "require", "sizeof", "struct",
|
||||
"super", "then", "type", "typeof", "union", "unless", "until", "when", "while", "with",
|
||||
"yield", "__DIR__", "__FILE__", "__LINE__"
|
||||
"private", "protected", "rescue", "return", "require", "select", "sizeof", "struct",
|
||||
"super", "then", "type", "typeof", "uninitialized", "union", "unless", "until", "when", "while", "with",
|
||||
"yield", "__DIR__", "__END_LINE__", "__FILE__", "__LINE__"
|
||||
]);
|
||||
var atomWords = wordRegExp(["true", "false", "nil", "self"]);
|
||||
var indentKeywordsArray = [
|
||||
"def", "fun", "macro",
|
||||
"class", "module", "struct", "lib", "enum", "union",
|
||||
"if", "unless", "case", "while", "until", "begin", "then",
|
||||
"do",
|
||||
"for", "ifdef"
|
||||
"do", "for"
|
||||
];
|
||||
var indentKeywords = wordRegExp(indentKeywordsArray);
|
||||
var dedentKeywordsArray = [
|
||||
"end",
|
||||
"else", "elsif",
|
||||
"rescue", "ensure"
|
||||
];
|
||||
var indentExpressionKeywordsArray = ["if", "unless", "case", "while", "until", "begin", "then"];
|
||||
var indentExpressionKeywords = wordRegExp(indentExpressionKeywordsArray);
|
||||
var dedentKeywordsArray = ["end", "else", "elsif", "rescue", "ensure"];
|
||||
var dedentKeywords = wordRegExp(dedentKeywordsArray);
|
||||
var dedentPunctualsArray = ["\\)", "\\}", "\\]"];
|
||||
var dedentPunctuals = new RegExp("^(?:" + dedentPunctualsArray.join("|") + ")$");
|
||||
|
@ -90,12 +86,15 @@
|
|||
} else if (state.lastToken == ".") {
|
||||
return "property";
|
||||
} else if (keywords.test(matched)) {
|
||||
if (state.lastToken != "abstract" && indentKeywords.test(matched)) {
|
||||
if (!(matched == "fun" && state.blocks.indexOf("lib") >= 0)) {
|
||||
if (indentKeywords.test(matched)) {
|
||||
if (!(matched == "fun" && state.blocks.indexOf("lib") >= 0) && !(matched == "def" && state.lastToken == "abstract")) {
|
||||
state.blocks.push(matched);
|
||||
state.currentIndent += 1;
|
||||
}
|
||||
} else if (dedentKeywords.test(matched)) {
|
||||
} else if ((state.lastStyle == "operator" || !state.lastStyle) && indentExpressionKeywords.test(matched)) {
|
||||
state.blocks.push(matched);
|
||||
state.currentIndent += 1;
|
||||
} else if (matched == "end") {
|
||||
state.blocks.pop();
|
||||
state.currentIndent -= 1;
|
||||
}
|
||||
|
@ -124,12 +123,6 @@
|
|||
return "variable-2";
|
||||
}
|
||||
|
||||
// Global variables
|
||||
if (stream.eat("$")) {
|
||||
stream.eat(/[0-9]+|\?/) || stream.match(idents) || stream.match(types);
|
||||
return "variable-3";
|
||||
}
|
||||
|
||||
// Constants and types
|
||||
if (stream.match(types)) {
|
||||
return "tag";
|
||||
|
@ -165,6 +158,9 @@
|
|||
} else if (stream.match("%w")) {
|
||||
embed = false;
|
||||
delim = stream.next();
|
||||
} else if (stream.match("%q")) {
|
||||
embed = false;
|
||||
delim = stream.next();
|
||||
} else {
|
||||
if(delim = stream.match(/^%([^\w\s=])/)) {
|
||||
delim = delim[1];
|
||||
|
@ -183,6 +179,11 @@
|
|||
return chain(tokenQuote(delim, style, embed), stream, state);
|
||||
}
|
||||
|
||||
// Here Docs
|
||||
if (matched = stream.match(/^<<-('?)([A-Z]\w*)\1/)) {
|
||||
return chain(tokenHereDoc(matched[2], !matched[1]), stream, state)
|
||||
}
|
||||
|
||||
// Characters
|
||||
if (stream.eat("'")) {
|
||||
stream.match(/^(?:[^']|\\(?:[befnrtv0'"]|[0-7]{3}|u(?:[0-9a-fA-F]{4}|\{[0-9a-fA-F]{1,6}\})))/);
|
||||
|
@ -202,14 +203,14 @@
|
|||
return "number";
|
||||
}
|
||||
|
||||
if (stream.eat(/\d/)) {
|
||||
if (stream.eat(/^\d/)) {
|
||||
stream.match(/^\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/);
|
||||
return "number";
|
||||
}
|
||||
|
||||
// Operators
|
||||
if (stream.match(operators)) {
|
||||
stream.eat("="); // Operators can follow assigin symbol.
|
||||
stream.eat("="); // Operators can follow assign symbol.
|
||||
return "operator";
|
||||
}
|
||||
|
||||
|
@ -339,7 +340,7 @@
|
|||
return style;
|
||||
}
|
||||
|
||||
escaped = ch == "\\";
|
||||
escaped = embed && ch == "\\";
|
||||
} else {
|
||||
stream.next();
|
||||
escaped = false;
|
||||
|
@ -350,12 +351,52 @@
|
|||
};
|
||||
}
|
||||
|
||||
function tokenHereDoc(phrase, embed) {
|
||||
return function (stream, state) {
|
||||
if (stream.sol()) {
|
||||
stream.eatSpace()
|
||||
if (stream.match(phrase)) {
|
||||
state.tokenize.pop();
|
||||
return "string";
|
||||
}
|
||||
}
|
||||
|
||||
var escaped = false;
|
||||
while (stream.peek()) {
|
||||
if (!escaped) {
|
||||
if (stream.match("{%", false)) {
|
||||
state.tokenize.push(tokenMacro("%", "%"));
|
||||
return "string";
|
||||
}
|
||||
|
||||
if (stream.match("{{", false)) {
|
||||
state.tokenize.push(tokenMacro("{", "}"));
|
||||
return "string";
|
||||
}
|
||||
|
||||
if (embed && stream.match("#{", false)) {
|
||||
state.tokenize.push(tokenNest("#{", "}", "meta"));
|
||||
return "string";
|
||||
}
|
||||
|
||||
escaped = embed && stream.next() == "\\";
|
||||
} else {
|
||||
stream.next();
|
||||
escaped = false;
|
||||
}
|
||||
}
|
||||
|
||||
return "string";
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function () {
|
||||
return {
|
||||
tokenize: [tokenBase],
|
||||
currentIndent: 0,
|
||||
lastToken: null,
|
||||
lastStyle: null,
|
||||
blocks: []
|
||||
};
|
||||
},
|
||||
|
@ -366,6 +407,7 @@
|
|||
|
||||
if (style && style != "comment") {
|
||||
state.lastToken = token;
|
||||
state.lastStyle = style;
|
||||
}
|
||||
|
||||
return style;
|
||||
|
|
17
app/public/codemirror/mode/crystal/index.html
vendored
17
app/public/codemirror/mode/crystal/index.html
vendored
|
@ -48,8 +48,6 @@ puts "Listening on http://0.0.0.0:8080"
|
|||
server.listen
|
||||
|
||||
module Foo
|
||||
def initialize(@foo); end
|
||||
|
||||
abstract def abstract_method : String
|
||||
|
||||
@[AlwaysInline]
|
||||
|
@ -58,7 +56,8 @@ module Foo
|
|||
end
|
||||
|
||||
struct Foo
|
||||
def initialize(@foo); end
|
||||
def initialize(@foo : ::Foo)
|
||||
end
|
||||
|
||||
def hello_world
|
||||
@foo.abstract_method
|
||||
|
@ -71,8 +70,7 @@ class Bar
|
|||
|
||||
@@foobar = 12345
|
||||
|
||||
def initialize(@bar)
|
||||
super(@bar.not_nil! + 100)
|
||||
def initialize(@bar : Int32)
|
||||
end
|
||||
|
||||
macro alias_method(name, method)
|
||||
|
@ -87,11 +85,10 @@ class Bar
|
|||
|
||||
alias_method abstract_method, a_method
|
||||
|
||||
macro def show_instance_vars : Nil
|
||||
def show_instance_vars : Nil
|
||||
{% for var in @type.instance_vars %}
|
||||
puts "@{{ var }} = #{ @{{ var }} }"
|
||||
{% end %}
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -101,9 +98,9 @@ lib LibC
|
|||
fun c_puts = "puts"(str : Char*) : Int
|
||||
end
|
||||
|
||||
$baz = Baz.new(100)
|
||||
$baz.show_instance_vars
|
||||
$baz.with_foofoo do
|
||||
baz = Baz.new(100)
|
||||
baz.show_instance_vars
|
||||
baz.with_foofoo do
|
||||
LibC.c_puts hello_world
|
||||
end
|
||||
</textarea></form>
|
||||
|
|
63
app/public/codemirror/mode/css/css.js
vendored
63
app/public/codemirror/mode/css/css.js
vendored
|
@ -28,6 +28,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
colorKeywords = parserConfig.colorKeywords || {},
|
||||
valueKeywords = parserConfig.valueKeywords || {},
|
||||
allowNested = parserConfig.allowNested,
|
||||
lineComment = parserConfig.lineComment,
|
||||
supportsAtComponent = parserConfig.supportsAtComponent === true;
|
||||
|
||||
var type, override;
|
||||
|
@ -253,6 +254,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
};
|
||||
|
||||
states.pseudo = function(type, stream, state) {
|
||||
if (type == "meta") return "pseudo";
|
||||
|
||||
if (type == "word") {
|
||||
override = "variable-3";
|
||||
return state.context.type;
|
||||
|
@ -407,6 +410,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
electricChars: "}",
|
||||
blockCommentStart: "/*",
|
||||
blockCommentEnd: "*/",
|
||||
lineComment: lineComment,
|
||||
fold: "brace"
|
||||
};
|
||||
});
|
||||
|
@ -414,7 +418,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
function keySet(array) {
|
||||
var keys = {};
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
keys[array[i]] = true;
|
||||
keys[array[i].toLowerCase()] = true;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
@ -452,8 +456,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"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", "background-attachment", "background-blend-mode", "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",
|
||||
|
@ -484,9 +488,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"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-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
|
||||
"grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
|
||||
"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",
|
||||
|
@ -494,7 +498,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"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",
|
||||
"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",
|
||||
|
@ -522,9 +526,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"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",
|
||||
"user-select", "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",
|
||||
"voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
|
||||
"word-spacing", "word-wrap", "z-index",
|
||||
// SVG-specific
|
||||
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
|
||||
|
@ -589,7 +593,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
|
||||
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
|
||||
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
||||
"arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
|
||||
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "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", "bullets", "button", "button-bevel",
|
||||
|
@ -597,11 +601,12 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
||||
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
|
||||
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
||||
"col-resize", "collapse", "column", "column-reverse", "compact", "condensed", "contain", "content",
|
||||
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
|
||||
"compact", "condensed", "contain", "content", "contents",
|
||||
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
|
||||
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
|
||||
"decimal-leading-zero", "default", "default-button", "destination-atop",
|
||||
"destination-in", "destination-out", "destination-over", "devanagari",
|
||||
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
|
||||
"decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
|
||||
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
|
||||
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
|
||||
"dot-dash", "dot-dot-dash",
|
||||
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
||||
|
@ -612,23 +617,23 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"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",
|
||||
"ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
|
||||
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
|
||||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
|
||||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
|
||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
|
||||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
|
||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
|
||||
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
|
||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
|
||||
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
||||
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
||||
"inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
|
||||
"inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
|
||||
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
|
||||
"katakana", "katakana-iroha", "keep-all", "khmer",
|
||||
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
|
||||
"landscape", "lao", "large", "larger", "left", "level", "lighter",
|
||||
"landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
|
||||
"line-through", "linear", "linear-gradient", "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", "matrix", "matrix3d",
|
||||
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
|
||||
"media-controls-background", "media-current-time-display",
|
||||
"media-fullscreen-button", "media-mute-button", "media-play-button",
|
||||
"media-return-to-realtime-button", "media-rewind-button",
|
||||
|
@ -637,10 +642,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"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",
|
||||
"mix", "mongolian", "monospace", "move", "multiple", "multiply", "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", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
|
||||
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
|
||||
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
|
||||
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
|
||||
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
|
||||
|
@ -651,15 +656,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
|
||||
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
|
||||
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
|
||||
"s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
|
||||
"scroll", "scrollbar", "se-resize", "searchfield",
|
||||
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
|
||||
"scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
|
||||
"searchfield-cancel-button", "searchfield-decoration",
|
||||
"searchfield-results-button", "searchfield-results-decoration",
|
||||
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
|
||||
"simp-chinese-formal", "simp-chinese-informal", "single",
|
||||
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
|
||||
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
||||
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
|
||||
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
|
||||
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
|
||||
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
|
||||
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
|
||||
|
@ -670,9 +675,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
|
||||
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
|
||||
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
|
||||
"trad-chinese-formal", "trad-chinese-informal",
|
||||
"trad-chinese-formal", "trad-chinese-informal", "transform",
|
||||
"translate", "translate3d", "translateX", "translateY", "translateZ",
|
||||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
|
||||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
|
||||
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
|
||||
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
||||
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
||||
|
@ -729,6 +734,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
lineComment: "//",
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
|
@ -771,6 +777,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
lineComment: "//",
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
|
|
2
app/public/codemirror/mode/css/index.html
vendored
2
app/public/codemirror/mode/css/index.html
vendored
|
@ -64,7 +64,7 @@ code {
|
|||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"},
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
4
app/public/codemirror/mode/css/less_test.js
vendored
4
app/public/codemirror/mode/css/less_test.js
vendored
|
@ -26,10 +26,10 @@
|
|||
|
||||
MT("mixin",
|
||||
"[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
|
||||
" [property color]: [variable darken]([variable-2 @color], [number 10%]);",
|
||||
" [property color]: [atom darken]([variable-2 @color], [number 10%]);",
|
||||
"}",
|
||||
"[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
|
||||
" [property color]: [variable lighten]([variable-2 @color], [number 10%]);",
|
||||
" [property color]: [atom lighten]([variable-2 @color], [number 10%]);",
|
||||
"}",
|
||||
"[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
|
||||
" [property display]: [atom block];",
|
||||
|
|
2
app/public/codemirror/mode/css/scss_test.js
vendored
2
app/public/codemirror/mode/css/scss_test.js
vendored
|
@ -95,7 +95,7 @@
|
|||
|
||||
MT('indent_parentheses',
|
||||
"[tag foo] {",
|
||||
" [property color]: [variable darken]([variable-2 $blue],",
|
||||
" [property color]: [atom darken]([variable-2 $blue],",
|
||||
" [number 9%]);",
|
||||
"}");
|
||||
|
||||
|
|
10
app/public/codemirror/mode/cypher/cypher.js
vendored
10
app/public/codemirror/mode/cypher/cypher.js
vendored
|
@ -20,8 +20,12 @@
|
|||
CodeMirror.defineMode("cypher", function(config) {
|
||||
var tokenBase = function(stream/*, state*/) {
|
||||
var ch = stream.next();
|
||||
if (ch === "\"" || ch === "'") {
|
||||
stream.match(/.+?["']/);
|
||||
if (ch ==='"') {
|
||||
stream.match(/.*?"/);
|
||||
return "string";
|
||||
}
|
||||
if (ch === "'") {
|
||||
stream.match(/.*?'/);
|
||||
return "string";
|
||||
}
|
||||
if (/[{}\(\),\.;\[\]]/.test(ch)) {
|
||||
|
@ -62,7 +66,7 @@
|
|||
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", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "reverse", "right", "round", "rtrim", "shortestPath", "sign", "sin", "size", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "toString", "trim", "type", "upper"]);
|
||||
var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]);
|
||||
var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
|
||||
var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with", "call", "yield"]);
|
||||
var operatorChars = /[*+\-<>=&|~%^]/;
|
||||
|
||||
return {
|
||||
|
|
37
app/public/codemirror/mode/cypher/test.js
vendored
Executable file
37
app/public/codemirror/mode/cypher/test.js
vendored
Executable file
|
@ -0,0 +1,37 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "cypher");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
|
||||
|
||||
MT("unbalancedDoubledQuotedString",
|
||||
"[string \"a'b\"][variable c]");
|
||||
|
||||
MT("unbalancedSingleQuotedString",
|
||||
"[string 'a\"b'][variable c]");
|
||||
|
||||
MT("doubleQuotedString",
|
||||
"[string \"a\"][variable b]");
|
||||
|
||||
MT("singleQuotedString",
|
||||
"[string 'a'][variable b]");
|
||||
|
||||
MT("single attribute (with content)",
|
||||
"[node {][atom a:][string 'a'][node }]");
|
||||
|
||||
MT("multiple attribute, singleQuotedString (with content)",
|
||||
"[node {][atom a:][string 'a'][node ,][atom b:][string 'b'][node }]");
|
||||
|
||||
MT("multiple attribute, doubleQuotedString (with content)",
|
||||
"[node {][atom a:][string \"a\"][node ,][atom b:][string \"b\"][node }]");
|
||||
|
||||
MT("single attribute (without content)",
|
||||
"[node {][atom a:][string 'a'][node }]");
|
||||
|
||||
MT("multiple attribute, singleQuotedString (without content)",
|
||||
"[node {][atom a:][string ''][node ,][atom b:][string ''][node }]");
|
||||
|
||||
MT("multiple attribute, doubleQuotedString (without content)",
|
||||
"[node {][atom a:][string \"\"][node ,][atom b:][string \"\"][node }]");
|
||||
})();
|
27
app/public/codemirror/mode/dart/dart.js
vendored
27
app/public/codemirror/mode/dart/dart.js
vendored
|
@ -72,6 +72,12 @@
|
|||
return null;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
"/": function(stream, state) {
|
||||
if (!stream.eat("*")) return false
|
||||
state.tokenize = tokenNestedComment(1)
|
||||
return state.tokenize(stream, state)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -121,6 +127,27 @@
|
|||
return "variable";
|
||||
}
|
||||
|
||||
function tokenNestedComment(depth) {
|
||||
return function (stream, state) {
|
||||
var ch
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "*" && stream.eat("/")) {
|
||||
if (depth == 1) {
|
||||
state.tokenize = null
|
||||
break
|
||||
} else {
|
||||
state.tokenize = tokenNestedComment(depth - 1)
|
||||
return state.tokenize(stream, state)
|
||||
}
|
||||
} else if (ch == "/" && stream.eat("*")) {
|
||||
state.tokenize = tokenNestedComment(depth + 1)
|
||||
return state.tokenize(stream, state)
|
||||
}
|
||||
}
|
||||
return "comment"
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
|
||||
|
||||
// This is needed to make loading through meta.js work.
|
||||
|
|
23
app/public/codemirror/mode/django/django.js
vendored
23
app/public/codemirror/mode/django/django.js
vendored
|
@ -61,16 +61,16 @@
|
|||
|
||||
// Ignore completely any stream series that do not match the
|
||||
// Django template opening tags.
|
||||
while (stream.next() != null && !stream.match("{{", false) && !stream.match("{%", false)) {}
|
||||
while (stream.next() != null && !stream.match(/\{[{%#]/, false)) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
// A string can be included in either single or double quotes (this is
|
||||
// the delimeter). Mark everything as a string until the start delimeter
|
||||
// the delimiter). Mark everything as a string until the start delimiter
|
||||
// occurs again.
|
||||
function inString (delimeter, previousTokenizer) {
|
||||
function inString (delimiter, previousTokenizer) {
|
||||
return function (stream, state) {
|
||||
if (!state.escapeNext && stream.eat(delimeter)) {
|
||||
if (!state.escapeNext && stream.eat(delimiter)) {
|
||||
state.tokenize = previousTokenizer;
|
||||
} else {
|
||||
if (state.escapeNext) {
|
||||
|
@ -80,7 +80,7 @@
|
|||
var ch = stream.next();
|
||||
|
||||
// Take into account the backslash for escaping characters, such as
|
||||
// the string delimeter.
|
||||
// the string delimiter.
|
||||
if (ch == "\\") {
|
||||
state.escapeNext = true;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
|||
return "null";
|
||||
}
|
||||
|
||||
// Dot folowed by a non-word character should be considered an error.
|
||||
// Dot followed by a non-word character should be considered an error.
|
||||
if (stream.match(/\.\W+/)) {
|
||||
return "error";
|
||||
} else if (stream.eat(".")) {
|
||||
|
@ -119,7 +119,7 @@
|
|||
return "null";
|
||||
}
|
||||
|
||||
// Pipe folowed by a non-word character should be considered an error.
|
||||
// Pipe followed by a non-word character should be considered an error.
|
||||
if (stream.match(/\.\W+/)) {
|
||||
return "error";
|
||||
} else if (stream.eat("|")) {
|
||||
|
@ -199,7 +199,7 @@
|
|||
return "null";
|
||||
}
|
||||
|
||||
// Dot folowed by a non-word character should be considered an error.
|
||||
// Dot followed by a non-word character should be considered an error.
|
||||
if (stream.match(/\.\W+/)) {
|
||||
return "error";
|
||||
} else if (stream.eat(".")) {
|
||||
|
@ -218,7 +218,7 @@
|
|||
return "null";
|
||||
}
|
||||
|
||||
// Pipe folowed by a non-word character should be considered an error.
|
||||
// Pipe followed by a non-word character should be considered an error.
|
||||
if (stream.match(/\.\W+/)) {
|
||||
return "error";
|
||||
} else if (stream.eat("|")) {
|
||||
|
@ -317,9 +317,8 @@
|
|||
|
||||
// Mark everything as comment inside the tag and the tag itself.
|
||||
function inComment (stream, state) {
|
||||
if (stream.match("#}")) {
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
if (stream.match(/^.*?#\}/)) state.tokenize = tokenBase
|
||||
else stream.skipToEnd()
|
||||
return "comment";
|
||||
}
|
||||
|
||||
|
|
12
app/public/codemirror/mode/dtd/dtd.js
vendored
12
app/public/codemirror/mode/dtd/dtd.js
vendored
|
@ -114,17 +114,17 @@ CodeMirror.defineMode("dtd", function(config) {
|
|||
|
||||
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;
|
||||
if(textAfter.substr(0,1) === "<") {}
|
||||
else if( type == "doindent" && textAfter.length > 1 ) {}
|
||||
else if( type == "doindent")n--;
|
||||
else if( type == ">" && textAfter.length > 1)n;
|
||||
else if( type == "tag" && textAfter !== ">")n;
|
||||
else if( type == ">" && textAfter.length > 1) {}
|
||||
else if( type == "tag" && textAfter !== ">") {}
|
||||
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 === ">" && state.stack[state.stack.length-1] == "rule") {}
|
||||
else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1;
|
||||
else if( textAfter === ">")n;
|
||||
else if( textAfter === ">") {}
|
||||
else n=n-1;
|
||||
//over rule them all
|
||||
if(type == null || type == "]")n--;
|
||||
|
|
107
app/public/codemirror/mode/dylan/dylan.js
vendored
107
app/public/codemirror/mode/dylan/dylan.js
vendored
|
@ -11,6 +11,14 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
function forEach(arr, f) {
|
||||
for (var i = 0; i < arr.length; i++) f(arr[i], i)
|
||||
}
|
||||
function some(arr, f) {
|
||||
for (var i = 0; i < arr.length; i++) if (f(arr[i], i)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
CodeMirror.defineMode("dylan", function(_config) {
|
||||
// Words
|
||||
var words = {
|
||||
|
@ -136,13 +144,13 @@ CodeMirror.defineMode("dylan", function(_config) {
|
|||
var wordLookup = {};
|
||||
var styleLookup = {};
|
||||
|
||||
[
|
||||
forEach([
|
||||
"keyword",
|
||||
"definition",
|
||||
"simpleDefinition",
|
||||
"signalingCalls"
|
||||
].forEach(function(type) {
|
||||
words[type].forEach(function(word) {
|
||||
], function(type) {
|
||||
forEach(words[type], function(word) {
|
||||
wordLookup[word] = type;
|
||||
styleLookup[word] = styles[type];
|
||||
});
|
||||
|
@ -169,15 +177,16 @@ CodeMirror.defineMode("dylan", function(_config) {
|
|||
} else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
} else {
|
||||
stream.skipTo(" ");
|
||||
return "operator";
|
||||
}
|
||||
stream.backUp(1);
|
||||
}
|
||||
// Decimal
|
||||
else if (/\d/.test(ch)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
|
||||
return "number";
|
||||
else if (/[+\-\d\.]/.test(ch)) {
|
||||
if (stream.match(/^[+-]?[0-9]*\.[0-9]*([esdx][+-]?[0-9]+)?/i) ||
|
||||
stream.match(/^[+-]?[0-9]+([esdx][+-]?[0-9]+)/i) ||
|
||||
stream.match(/^[+-]?\d+/)) {
|
||||
return "number";
|
||||
}
|
||||
}
|
||||
// Hash
|
||||
else if (ch == "#") {
|
||||
|
@ -186,7 +195,7 @@ CodeMirror.defineMode("dylan", function(_config) {
|
|||
ch = stream.peek();
|
||||
if (ch == '"') {
|
||||
stream.next();
|
||||
return chain(stream, state, tokenString('"', "string-2"));
|
||||
return chain(stream, state, tokenString('"', "string"));
|
||||
}
|
||||
// Binary number
|
||||
else if (ch == "b") {
|
||||
|
@ -206,29 +215,73 @@ CodeMirror.defineMode("dylan", function(_config) {
|
|||
stream.eatWhile(/[0-7]/);
|
||||
return "number";
|
||||
}
|
||||
// Hash symbol
|
||||
else {
|
||||
stream.eatWhile(/[-a-zA-Z]/);
|
||||
return "keyword";
|
||||
// Token concatenation in macros
|
||||
else if (ch == '#') {
|
||||
stream.next();
|
||||
return "punctuation";
|
||||
}
|
||||
// Sequence literals
|
||||
else if ((ch == '[') || (ch == '(')) {
|
||||
stream.next();
|
||||
return "bracket";
|
||||
// Hash symbol
|
||||
} else if (stream.match(/f|t|all-keys|include|key|next|rest/i)) {
|
||||
return "atom";
|
||||
} else {
|
||||
stream.eatWhile(/[-a-zA-Z]/);
|
||||
return "error";
|
||||
}
|
||||
} else if (ch == "~") {
|
||||
stream.next();
|
||||
ch = stream.peek();
|
||||
if (ch == "=") {
|
||||
stream.next();
|
||||
ch = stream.peek();
|
||||
if (ch == "=") {
|
||||
stream.next();
|
||||
return "operator";
|
||||
}
|
||||
return "operator";
|
||||
}
|
||||
return "operator";
|
||||
} else if (ch == ":") {
|
||||
stream.next();
|
||||
ch = stream.peek();
|
||||
if (ch == "=") {
|
||||
stream.next();
|
||||
return "operator";
|
||||
} else if (ch == ":") {
|
||||
stream.next();
|
||||
return "punctuation";
|
||||
}
|
||||
} else if ("[](){}".indexOf(ch) != -1) {
|
||||
stream.next();
|
||||
return "bracket";
|
||||
} else if (".,".indexOf(ch) != -1) {
|
||||
stream.next();
|
||||
return "punctuation";
|
||||
} else if (stream.match("end")) {
|
||||
return "keyword";
|
||||
}
|
||||
for (var name in patterns) {
|
||||
if (patterns.hasOwnProperty(name)) {
|
||||
var pattern = patterns[name];
|
||||
if ((pattern instanceof Array && pattern.some(function(p) {
|
||||
if ((pattern instanceof Array && some(pattern, function(p) {
|
||||
return stream.match(p);
|
||||
})) || stream.match(pattern))
|
||||
return patternStyles[name];
|
||||
}
|
||||
}
|
||||
if (/[+\-*\/^=<>&|]/.test(ch)) {
|
||||
stream.next();
|
||||
return "operator";
|
||||
}
|
||||
if (stream.match("define")) {
|
||||
return "def";
|
||||
} else {
|
||||
stream.eatWhile(/[\w\-]/);
|
||||
// Keyword
|
||||
if (wordLookup[stream.current()]) {
|
||||
if (wordLookup.hasOwnProperty(stream.current())) {
|
||||
return styleLookup[stream.current()];
|
||||
} else if (stream.current().match(symbol)) {
|
||||
return "variable";
|
||||
|
@ -240,29 +293,37 @@ CodeMirror.defineMode("dylan", function(_config) {
|
|||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false,
|
||||
ch;
|
||||
var maybeEnd = false, maybeNested = false, nestedCount = 0, ch;
|
||||
while ((ch = stream.next())) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
if (nestedCount > 0) {
|
||||
nestedCount--;
|
||||
} else {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
} else if (ch == "*" && maybeNested) {
|
||||
nestedCount++;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
maybeNested = (ch == "/");
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function tokenString(quote, style) {
|
||||
return function(stream, state) {
|
||||
var next, end = false;
|
||||
var escaped = false, next, end = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote) {
|
||||
if (next == quote && !escaped) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
if (end)
|
||||
if (end || !escaped) {
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
return style;
|
||||
};
|
||||
}
|
||||
|
|
88
app/public/codemirror/mode/dylan/test.js
vendored
Executable file
88
app/public/codemirror/mode/dylan/test.js
vendored
Executable file
|
@ -0,0 +1,88 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({indentUnit: 2}, "dylan");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
|
||||
|
||||
MT('comments',
|
||||
'[comment // This is a line comment]',
|
||||
'[comment /* This is a block comment */]',
|
||||
'[comment /* This is a multi]',
|
||||
'[comment line comment]',
|
||||
'[comment */]',
|
||||
'[comment /* And this is a /*]',
|
||||
'[comment /* nested */ comment */]');
|
||||
|
||||
MT('unary_operators',
|
||||
'[operator -][variable a]',
|
||||
'[operator -] [variable a]',
|
||||
'[operator ~][variable a]',
|
||||
'[operator ~] [variable a]');
|
||||
|
||||
MT('binary_operators',
|
||||
'[variable a] [operator +] [variable b]',
|
||||
'[variable a] [operator -] [variable b]',
|
||||
'[variable a] [operator *] [variable b]',
|
||||
'[variable a] [operator /] [variable b]',
|
||||
'[variable a] [operator ^] [variable b]',
|
||||
'[variable a] [operator =] [variable b]',
|
||||
'[variable a] [operator ==] [variable b]',
|
||||
'[variable a] [operator ~=] [variable b]',
|
||||
'[variable a] [operator ~==] [variable b]',
|
||||
'[variable a] [operator <] [variable b]',
|
||||
'[variable a] [operator <=] [variable b]',
|
||||
'[variable a] [operator >] [variable b]',
|
||||
'[variable a] [operator >=] [variable b]',
|
||||
'[variable a] [operator &] [variable b]',
|
||||
'[variable a] [operator |] [variable b]',
|
||||
'[variable a] [operator :=] [variable b]');
|
||||
|
||||
MT('integers',
|
||||
'[number 1]',
|
||||
'[number 123]',
|
||||
'[number -123]',
|
||||
'[number +456]',
|
||||
'[number #b010]',
|
||||
'[number #o073]',
|
||||
'[number #xabcDEF123]');
|
||||
|
||||
MT('floats',
|
||||
'[number .3]',
|
||||
'[number -1.]',
|
||||
'[number -2.335]',
|
||||
'[number +3.78d1]',
|
||||
'[number 3.78s-1]',
|
||||
'[number -3.32e+5]');
|
||||
|
||||
MT('characters_and_strings',
|
||||
"[string 'a']",
|
||||
"[string '\\\\'']",
|
||||
'[string ""]',
|
||||
'[string "a"]',
|
||||
'[string "abc def"]',
|
||||
'[string "More escaped characters: \\\\\\\\ \\\\a \\\\b \\\\e \\\\f \\\\n \\\\r \\\\t \\\\0 ..."]');
|
||||
|
||||
MT('brackets',
|
||||
'[bracket #[[]]]',
|
||||
'[bracket #()]',
|
||||
'[bracket #(][number 1][bracket )]',
|
||||
'[bracket [[][number 1][punctuation ,] [number 3][bracket ]]]',
|
||||
'[bracket ()]',
|
||||
'[bracket {}]',
|
||||
'[keyword if] [bracket (][variable foo][bracket )]',
|
||||
'[bracket (][number 1][bracket )]',
|
||||
'[bracket [[][number 1][bracket ]]]');
|
||||
|
||||
MT('hash_words',
|
||||
'[punctuation ##]',
|
||||
'[atom #f]', '[atom #F]',
|
||||
'[atom #t]', '[atom #T]',
|
||||
'[atom #all-keys]',
|
||||
'[atom #include]',
|
||||
'[atom #key]',
|
||||
'[atom #next]',
|
||||
'[atom #rest]',
|
||||
'[string #"foo"]',
|
||||
'[error #invalid]');
|
||||
})();
|
2
app/public/codemirror/mode/ebnf/ebnf.js
vendored
2
app/public/codemirror/mode/ebnf/ebnf.js
vendored
|
@ -94,7 +94,7 @@
|
|||
|
||||
if (bracesMode !== null && (state.braced || peek === "{")) {
|
||||
if (state.localState === null)
|
||||
state.localState = bracesMode.startState();
|
||||
state.localState = CodeMirror.startState(bracesMode);
|
||||
|
||||
var token = bracesMode.token(stream, state.localState),
|
||||
text = stream.current();
|
||||
|
|
5
app/public/codemirror/mode/erlang/erlang.js
vendored
5
app/public/codemirror/mode/erlang/erlang.js
vendored
|
@ -433,15 +433,16 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|||
}
|
||||
|
||||
function maybe_drop_post(s) {
|
||||
if (!s.length) return s
|
||||
var last = s.length-1;
|
||||
|
||||
if (s[last].type === "dot") {
|
||||
return [];
|
||||
}
|
||||
if (s[last].type === "fun" && s[last-1].token === "fun") {
|
||||
if (last > 1 && s[last].type === "fun" && s[last-1].token === "fun") {
|
||||
return s.slice(0,last-1);
|
||||
}
|
||||
switch (s[s.length-1].token) {
|
||||
switch (s[last].token) {
|
||||
case "}": return d(s,{g:["{"]});
|
||||
case "]": return d(s,{i:["["]});
|
||||
case ")": return d(s,{i:["("]});
|
||||
|
|
173
app/public/codemirror/mode/fcl/fcl.js
vendored
Executable file
173
app/public/codemirror/mode/fcl/fcl.js
vendored
Executable file
|
@ -0,0 +1,173 @@
|
|||
// 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("fcl", function(config) {
|
||||
var indentUnit = config.indentUnit;
|
||||
|
||||
var keywords = {
|
||||
"term": true,
|
||||
"method": true, "accu": true,
|
||||
"rule": true, "then": true, "is": true, "and": true, "or": true,
|
||||
"if": true, "default": true
|
||||
};
|
||||
|
||||
var start_blocks = {
|
||||
"var_input": true,
|
||||
"var_output": true,
|
||||
"fuzzify": true,
|
||||
"defuzzify": true,
|
||||
"function_block": true,
|
||||
"ruleblock": true
|
||||
};
|
||||
|
||||
var end_blocks = {
|
||||
"end_ruleblock": true,
|
||||
"end_defuzzify": true,
|
||||
"end_function_block": true,
|
||||
"end_fuzzify": true,
|
||||
"end_var": true
|
||||
};
|
||||
|
||||
var atoms = {
|
||||
"true": true, "false": true, "nan": true,
|
||||
"real": true, "min": true, "max": true, "cog": true, "cogs": true
|
||||
};
|
||||
|
||||
var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
|
||||
if (/[\d\.]/.test(ch)) {
|
||||
if (ch == ".") {
|
||||
stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
|
||||
} else if (ch == "0") {
|
||||
stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
|
||||
} else {
|
||||
stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
|
||||
}
|
||||
return "number";
|
||||
}
|
||||
|
||||
if (ch == "/" || 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().toLowerCase();
|
||||
if (keywords.propertyIsEnumerable(cur) ||
|
||||
start_blocks.propertyIsEnumerable(cur) ||
|
||||
end_blocks.propertyIsEnumerable(cur)) {
|
||||
return "keyword";
|
||||
}
|
||||
if (atoms.propertyIsEnumerable(cur)) return "atom";
|
||||
return "variable";
|
||||
}
|
||||
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if ((ch == "/" || 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) {
|
||||
if (!state.context.prev) return;
|
||||
var t = state.context.type;
|
||||
if (t == "end_block")
|
||||
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;
|
||||
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style == "comment") return style;
|
||||
if (ctx.align == null) ctx.align = true;
|
||||
|
||||
var cur = stream.current().toLowerCase();
|
||||
|
||||
if (start_blocks.propertyIsEnumerable(cur)) pushContext(state, stream.column(), "end_block");
|
||||
else if (end_blocks.propertyIsEnumerable(cur)) popContext(state);
|
||||
|
||||
state.startOfLine = false;
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase && state.tokenize != null) return 0;
|
||||
var ctx = state.context;
|
||||
|
||||
var closing = end_blocks.propertyIsEnumerable(textAfter);
|
||||
if (ctx.align) return ctx.column + (closing ? 0 : 1);
|
||||
else return ctx.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: "ryk",
|
||||
fold: "brace",
|
||||
blockCommentStart: "(*",
|
||||
blockCommentEnd: "*)",
|
||||
lineComment: "//"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-fcl", "fcl");
|
||||
});
|
108
app/public/codemirror/mode/fcl/index.html
vendored
Executable file
108
app/public/codemirror/mode/fcl/index.html
vendored
Executable file
|
@ -0,0 +1,108 @@
|
|||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: FCL 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/elegant.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="fcl.js"></script>
|
||||
<style>.CodeMirror {border:1px solid #999; background:#ffc}</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="#">FCL</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>FCL mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
FUNCTION_BLOCK Fuzzy_FB
|
||||
VAR_INPUT
|
||||
TimeDay : REAL; (* RANGE(0 .. 23) *)
|
||||
ApplicateHost: REAL;
|
||||
TimeConfiguration: REAL;
|
||||
TimeRequirements: REAL;
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
ProbabilityDistribution: REAL;
|
||||
ProbabilityAccess: REAL;
|
||||
END_VAR
|
||||
|
||||
FUZZIFY TimeDay
|
||||
TERM inside := (0, 0) (8, 1) (22,0);
|
||||
TERM outside := (0, 1) (8, 0) (22, 1);
|
||||
END_FUZZIFY
|
||||
|
||||
FUZZIFY ApplicateHost
|
||||
TERM few := (0, 1) (100, 0) (200, 0);
|
||||
TERM many := (0, 0) (100, 0) (200, 1);
|
||||
END_FUZZIFY
|
||||
|
||||
FUZZIFY TimeConfiguration
|
||||
TERM recently := (0, 1) (30, 1) (120, 0);
|
||||
TERM long := (0, 0) (30, 0) (120, 1);
|
||||
END_FUZZIFY
|
||||
|
||||
FUZZIFY TimeRequirements
|
||||
TERM recently := (0, 1) (30, 1) (365, 0);
|
||||
TERM long := (0, 0) (30, 0) (365, 1);
|
||||
END_FUZZIFY
|
||||
|
||||
DEFUZZIFY ProbabilityAccess
|
||||
TERM hight := 1;
|
||||
TERM medium := 0.5;
|
||||
TERM low := 0;
|
||||
ACCU: MAX;
|
||||
METHOD: COGS;
|
||||
DEFAULT := 0;
|
||||
END_DEFUZZIFY
|
||||
|
||||
DEFUZZIFY ProbabilityDistribution
|
||||
TERM hight := 1;
|
||||
TERM medium := 0.5;
|
||||
TERM low := 0;
|
||||
ACCU: MAX;
|
||||
METHOD: COGS;
|
||||
DEFAULT := 0;
|
||||
END_DEFUZZIFY
|
||||
|
||||
RULEBLOCK No1
|
||||
AND : MIN;
|
||||
RULE 1 : IF TimeDay IS outside AND ApplicateHost IS few THEN ProbabilityAccess IS hight;
|
||||
RULE 2 : IF ApplicateHost IS many THEN ProbabilityAccess IS hight;
|
||||
RULE 3 : IF TimeDay IS inside AND ApplicateHost IS few THEN ProbabilityAccess IS low;
|
||||
END_RULEBLOCK
|
||||
|
||||
RULEBLOCK No2
|
||||
AND : MIN;
|
||||
RULE 1 : IF ApplicateHost IS many THEN ProbabilityDistribution IS hight;
|
||||
END_RULEBLOCK
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
theme: "elegant",
|
||||
matchBrackets: true,
|
||||
indentUnit: 8,
|
||||
tabSize: 8,
|
||||
indentWithTabs: true,
|
||||
mode: "text/x-fcl"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME type:</strong> <code>text/x-fcl</code></p>
|
||||
</article>
|
|
@ -77,5 +77,5 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-Fortran</code>.</p>
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-fortran</code>.</p>
|
||||
</article>
|
||||
|
|
2
app/public/codemirror/mode/gfm/index.html
vendored
2
app/public/codemirror/mode/gfm/index.html
vendored
|
@ -47,7 +47,7 @@ Underscores_are_allowed_between_words.
|
|||
GFM adds syntax to strikethrough text, which is missing from standard Markdown.
|
||||
|
||||
~~Mistaken text.~~
|
||||
~~**works with other fomatting**~~
|
||||
~~**works with other formatting**~~
|
||||
|
||||
~~spans across
|
||||
lines~~
|
||||
|
|
6
app/public/codemirror/mode/gfm/test.js
vendored
6
app/public/codemirror/mode/gfm/test.js
vendored
|
@ -51,6 +51,12 @@
|
|||
"[comment ```]",
|
||||
"bar");
|
||||
|
||||
MT("fencedCodeBlockModeSwitchingObjc",
|
||||
"[comment ```objective-c]",
|
||||
"[keyword @property] [variable NSString] [operator *] [variable foo];",
|
||||
"[comment ```]",
|
||||
"bar");
|
||||
|
||||
MT("fencedCodeBlocksNoTildes",
|
||||
"~~~",
|
||||
"foo",
|
||||
|
|
6
app/public/codemirror/mode/go/go.js
vendored
6
app/public/codemirror/mode/go/go.js
vendored
|
@ -23,12 +23,13 @@ CodeMirror.defineMode("go", function(config) {
|
|||
"bool":true, "byte":true, "complex64":true, "complex128":true,
|
||||
"float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
|
||||
"int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
|
||||
"uint64":true, "int":true, "uint":true, "uintptr":true
|
||||
"uint64":true, "int":true, "uint":true, "uintptr":true, "error": true,
|
||||
"rune":true
|
||||
};
|
||||
|
||||
var atoms = {
|
||||
"true":true, "false":true, "iota":true, "nil":true, "append":true,
|
||||
"cap":true, "close":true, "complex":true, "copy":true, "imag":true,
|
||||
"cap":true, "close":true, "complex":true, "copy":true, "delete":true, "imag":true,
|
||||
"len":true, "make":true, "new":true, "panic":true, "print":true,
|
||||
"println":true, "real":true, "recover":true
|
||||
};
|
||||
|
@ -173,6 +174,7 @@ CodeMirror.defineMode("go", function(config) {
|
|||
},
|
||||
|
||||
electricChars: "{}):",
|
||||
closeBrackets: "()[]{}''\"\"``",
|
||||
fold: "brace",
|
||||
blockCommentStart: "/*",
|
||||
blockCommentEnd: "*/",
|
||||
|
|
2
app/public/codemirror/mode/groovy/groovy.js
vendored
2
app/public/codemirror/mode/groovy/groovy.js
vendored
|
@ -210,7 +210,7 @@ CodeMirror.defineMode("groovy", function(config) {
|
|||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (!state.tokenize[state.tokenize.length-1].isBase) return 0;
|
||||
if (!state.tokenize[state.tokenize.length-1].isBase) return CodeMirror.Pass;
|
||||
var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
|
||||
if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) ctx = ctx.prev;
|
||||
var closing = firstChar == ctx.type;
|
||||
|
|
6
app/public/codemirror/mode/haml/haml.js
vendored
6
app/public/codemirror/mode/haml/haml.js
vendored
|
@ -11,7 +11,7 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
// full haml mode. This handled embeded ruby and html fragments too
|
||||
// full haml mode. This handled embedded ruby and html fragments too
|
||||
CodeMirror.defineMode("haml", function(config) {
|
||||
var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
|
||||
var rubyMode = CodeMirror.getMode(config, "ruby");
|
||||
|
@ -98,8 +98,8 @@
|
|||
return {
|
||||
// default to html mode
|
||||
startState: function() {
|
||||
var htmlState = htmlMode.startState();
|
||||
var rubyState = rubyMode.startState();
|
||||
var htmlState = CodeMirror.startState(htmlMode);
|
||||
var rubyState = CodeMirror.startState(rubyMode);
|
||||
return {
|
||||
htmlState: htmlState,
|
||||
rubyState: rubyState,
|
||||
|
|
|
@ -67,9 +67,13 @@
|
|||
mode: {name: "handlebars", base: "text/html"}
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<p>Handlebars syntax highlighting for CodeMirror.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-handlebars-template</code></p>
|
||||
|
||||
<p>Supported options: <code>base</code> to set the mode to
|
||||
wrap. For example, use</p>
|
||||
<pre>mode: {name: "handlebars", base: "text/html"}</pre>
|
||||
<p>to highlight an HTML template.</p>
|
||||
</article>
|
||||
|
|
43
app/public/codemirror/mode/haskell-literate/haskell-literate.js
vendored
Executable file
43
app/public/codemirror/mode/haskell-literate/haskell-literate.js
vendored
Executable file
|
@ -0,0 +1,43 @@
|
|||
// 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("../haskell/haskell"))
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "../haskell/haskell"], mod)
|
||||
else // Plain browser env
|
||||
mod(CodeMirror)
|
||||
})(function (CodeMirror) {
|
||||
"use strict"
|
||||
|
||||
CodeMirror.defineMode("haskell-literate", function (config, parserConfig) {
|
||||
var baseMode = CodeMirror.getMode(config, (parserConfig && parserConfig.base) || "haskell")
|
||||
|
||||
return {
|
||||
startState: function () {
|
||||
return {
|
||||
inCode: false,
|
||||
baseState: CodeMirror.startState(baseMode)
|
||||
}
|
||||
},
|
||||
token: function (stream, state) {
|
||||
if (stream.sol()) {
|
||||
if (state.inCode = stream.eat(">"))
|
||||
return "meta"
|
||||
}
|
||||
if (state.inCode) {
|
||||
return baseMode.token(stream, state.baseState)
|
||||
} else {
|
||||
stream.skipToEnd()
|
||||
return "comment"
|
||||
}
|
||||
},
|
||||
innerMode: function (state) {
|
||||
return state.inCode ? {state: state.baseState, mode: baseMode} : null
|
||||
}
|
||||
}
|
||||
}, "haskell")
|
||||
|
||||
CodeMirror.defineMIME("text/x-literate-haskell", "haskell-literate")
|
||||
});
|
282
app/public/codemirror/mode/haskell-literate/index.html
vendored
Executable file
282
app/public/codemirror/mode/haskell-literate/index.html
vendored
Executable file
|
@ -0,0 +1,282 @@
|
|||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Haskell-literate 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="haskell-literate.js"></script>
|
||||
<script src="../haskell/haskell.js"></script>
|
||||
<style>.CodeMirror {
|
||||
border-top : 1px solid #DDDDDD;
|
||||
border-bottom : 1px solid #DDDDDD;
|
||||
}</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="#">Haskell-literate</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Haskell literate mode</h2>
|
||||
<form>
|
||||
<textarea id="code" name="code">
|
||||
> {-# LANGUAGE OverloadedStrings #-}
|
||||
> {-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
|
||||
> import Control.Applicative ((<$>), (<*>))
|
||||
> import Data.Maybe (isJust)
|
||||
|
||||
> import Data.Text (Text)
|
||||
> import Text.Blaze ((!))
|
||||
> import qualified Data.Text as T
|
||||
> import qualified Happstack.Server as Happstack
|
||||
> import qualified Text.Blaze.Html5 as H
|
||||
> import qualified Text.Blaze.Html5.Attributes as A
|
||||
|
||||
> import Text.Digestive
|
||||
> import Text.Digestive.Blaze.Html5
|
||||
> import Text.Digestive.Happstack
|
||||
> import Text.Digestive.Util
|
||||
|
||||
Simple forms and validation
|
||||
---------------------------
|
||||
|
||||
Let's start by creating a very simple datatype to represent a user:
|
||||
|
||||
> data User = User
|
||||
> { userName :: Text
|
||||
> , userMail :: Text
|
||||
> } deriving (Show)
|
||||
|
||||
And dive in immediately to create a `Form` for a user. The `Form v m a` type
|
||||
has three parameters:
|
||||
|
||||
- `v`: the type for messages and errors (usually a `String`-like type, `Text` in
|
||||
this case);
|
||||
- `m`: the monad we are operating in, not specified here;
|
||||
- `a`: the return type of the `Form`, in this case, this is obviously `User`.
|
||||
|
||||
> userForm :: Monad m => Form Text m User
|
||||
|
||||
We create forms by using the `Applicative` interface. A few form types are
|
||||
provided in the `Text.Digestive.Form` module, such as `text`, `string`,
|
||||
`bool`...
|
||||
|
||||
In the `digestive-functors` library, the developer is required to label each
|
||||
field using the `.:` operator. This might look like a bit of a burden, but it
|
||||
allows you to do some really useful stuff, like separating the `Form` from the
|
||||
actual HTML layout.
|
||||
|
||||
> userForm = User
|
||||
> <$> "name" .: text Nothing
|
||||
> <*> "mail" .: check "Not a valid email address" checkEmail (text Nothing)
|
||||
|
||||
The `check` function enables you to validate the result of a form. For example,
|
||||
we can validate the email address with a really naive `checkEmail` function.
|
||||
|
||||
> checkEmail :: Text -> Bool
|
||||
> checkEmail = isJust . T.find (== '@')
|
||||
|
||||
More validation
|
||||
---------------
|
||||
|
||||
For our example, we also want descriptions of Haskell libraries, and in order to
|
||||
do that, we need package versions...
|
||||
|
||||
> type Version = [Int]
|
||||
|
||||
We want to let the user input a version number such as `0.1.0.0`. This means we
|
||||
need to validate if the input `Text` is of this form, and then we need to parse
|
||||
it to a `Version` type. Fortunately, we can do this in a single function:
|
||||
`validate` allows conversion between values, which can optionally fail.
|
||||
|
||||
`readMaybe :: Read a => String -> Maybe a` is a utility function imported from
|
||||
`Text.Digestive.Util`.
|
||||
|
||||
> validateVersion :: Text -> Result Text Version
|
||||
> validateVersion = maybe (Error "Cannot parse version") Success .
|
||||
> mapM (readMaybe . T.unpack) . T.split (== '.')
|
||||
|
||||
A quick test in GHCi:
|
||||
|
||||
ghci> validateVersion (T.pack "0.3.2.1")
|
||||
Success [0,3,2,1]
|
||||
ghci> validateVersion (T.pack "0.oops")
|
||||
Error "Cannot parse version"
|
||||
|
||||
It works! This means we can now easily add a `Package` type and a `Form` for it:
|
||||
|
||||
> data Category = Web | Text | Math
|
||||
> deriving (Bounded, Enum, Eq, Show)
|
||||
|
||||
> data Package = Package Text Version Category
|
||||
> deriving (Show)
|
||||
|
||||
> packageForm :: Monad m => Form Text m Package
|
||||
> packageForm = Package
|
||||
> <$> "name" .: text Nothing
|
||||
> <*> "version" .: validate validateVersion (text (Just "0.0.0.1"))
|
||||
> <*> "category" .: choice categories Nothing
|
||||
> where
|
||||
> categories = [(x, T.pack (show x)) | x <- [minBound .. maxBound]]
|
||||
|
||||
Composing forms
|
||||
---------------
|
||||
|
||||
A release has an author and a package. Let's use this to illustrate the
|
||||
composability of the digestive-functors library: we can reuse the forms we have
|
||||
written earlier on.
|
||||
|
||||
> data Release = Release User Package
|
||||
> deriving (Show)
|
||||
|
||||
> releaseForm :: Monad m => Form Text m Release
|
||||
> releaseForm = Release
|
||||
> <$> "author" .: userForm
|
||||
> <*> "package" .: packageForm
|
||||
|
||||
Views
|
||||
-----
|
||||
|
||||
As mentioned before, one of the advantages of using digestive-functors is
|
||||
separation of forms and their actual HTML layout. In order to do this, we have
|
||||
another type, `View`.
|
||||
|
||||
We can get a `View` from a `Form` by supplying input. A `View` contains more
|
||||
information than a `Form`, it has:
|
||||
|
||||
- the original form;
|
||||
- the input given by the user;
|
||||
- any errors that have occurred.
|
||||
|
||||
It is this view that we convert to HTML. For this tutorial, we use the
|
||||
[blaze-html] library, and some helpers from the `digestive-functors-blaze`
|
||||
library.
|
||||
|
||||
[blaze-html]: http://jaspervdj.be/blaze/
|
||||
|
||||
Let's write a view for the `User` form. As you can see, we here refer to the
|
||||
different fields in the `userForm`. The `errorList` will generate a list of
|
||||
errors for the `"mail"` field.
|
||||
|
||||
> userView :: View H.Html -> H.Html
|
||||
> userView view = do
|
||||
> label "name" view "Name: "
|
||||
> inputText "name" view
|
||||
> H.br
|
||||
>
|
||||
> errorList "mail" view
|
||||
> label "mail" view "Email address: "
|
||||
> inputText "mail" view
|
||||
> H.br
|
||||
|
||||
Like forms, views are also composable: let's illustrate that by adding a view
|
||||
for the `releaseForm`, in which we reuse `userView`. In order to do this, we
|
||||
take only the parts relevant to the author from the view by using `subView`. We
|
||||
can then pass the resulting view to our own `userView`.
|
||||
We have no special view code for `Package`, so we can just add that to
|
||||
`releaseView` as well. `childErrorList` will generate a list of errors for each
|
||||
child of the specified form. In this case, this means a list of errors from
|
||||
`"package.name"` and `"package.version"`. Note how we use `foo.bar` to refer to
|
||||
nested forms.
|
||||
|
||||
> releaseView :: View H.Html -> H.Html
|
||||
> releaseView view = do
|
||||
> H.h2 "Author"
|
||||
> userView $ subView "author" view
|
||||
>
|
||||
> H.h2 "Package"
|
||||
> childErrorList "package" view
|
||||
>
|
||||
> label "package.name" view "Name: "
|
||||
> inputText "package.name" view
|
||||
> H.br
|
||||
>
|
||||
> label "package.version" view "Version: "
|
||||
> inputText "package.version" view
|
||||
> H.br
|
||||
>
|
||||
> label "package.category" view "Category: "
|
||||
> inputSelect "package.category" view
|
||||
> H.br
|
||||
|
||||
The attentive reader might have wondered what the type parameter for `View` is:
|
||||
it is the `String`-like type used for e.g. error messages.
|
||||
But wait! We have
|
||||
releaseForm :: Monad m => Form Text m Release
|
||||
releaseView :: View H.Html -> H.Html
|
||||
... doesn't this mean that we need a `View Text` rather than a `View Html`? The
|
||||
answer is yes -- but having `View Html` allows us to write these views more
|
||||
easily with the `digestive-functors-blaze` library. Fortunately, we will be able
|
||||
to fix this using the `Functor` instance of `View`.
|
||||
fmap :: Monad m => (v -> w) -> View v -> View w
|
||||
A backend
|
||||
---------
|
||||
To finish this tutorial, we need to be able to actually run this code. We need
|
||||
an HTTP server for that, and we use [Happstack] for this tutorial. The
|
||||
`digestive-functors-happstack` library gives about everything we need for this.
|
||||
[Happstack]: http://happstack.com/
|
||||
|
||||
> site :: Happstack.ServerPart Happstack.Response
|
||||
> site = do
|
||||
> Happstack.decodeBody $ Happstack.defaultBodyPolicy "/tmp" 4096 4096 4096
|
||||
> r <- runForm "test" releaseForm
|
||||
> case r of
|
||||
> (view, Nothing) -> do
|
||||
> let view' = fmap H.toHtml view
|
||||
> Happstack.ok $ Happstack.toResponse $
|
||||
> template $
|
||||
> form view' "/" $ do
|
||||
> releaseView view'
|
||||
> H.br
|
||||
> inputSubmit "Submit"
|
||||
> (_, Just release) -> Happstack.ok $ Happstack.toResponse $
|
||||
> template $ do
|
||||
> css
|
||||
> H.h1 "Release received"
|
||||
> H.p $ H.toHtml $ show release
|
||||
>
|
||||
> main :: IO ()
|
||||
> main = Happstack.simpleHTTP Happstack.nullConf site
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
||||
> template :: H.Html -> H.Html
|
||||
> template body = H.docTypeHtml $ do
|
||||
> H.head $ do
|
||||
> H.title "digestive-functors tutorial"
|
||||
> css
|
||||
> H.body body
|
||||
> css :: H.Html
|
||||
> css = H.style ! A.type_ "text/css" $ do
|
||||
> "label {width: 130px; float: left; clear: both}"
|
||||
> "ul.digestive-functors-error-list {"
|
||||
> " color: red;"
|
||||
> " list-style-type: none;"
|
||||
> " padding-left: 0px;"
|
||||
> "}"
|
||||
</textarea>
|
||||
</form>
|
||||
|
||||
<p><strong>MIME types
|
||||
defined:</strong> <code>text/x-literate-haskell</code>.</p>
|
||||
|
||||
<p>Parser configuration parameters recognized: <code>base</code> to
|
||||
set the base mode (defaults to <code>"haskell"</code>).</p>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "haskell-literate"});
|
||||
</script>
|
||||
|
||||
</article>
|
|
@ -56,7 +56,7 @@ CodeMirror.defineMode("haskell", function(_config, modeConfig) {
|
|||
if (source.eat('\'')) {
|
||||
return "string";
|
||||
}
|
||||
return "error";
|
||||
return "string error";
|
||||
}
|
||||
|
||||
if (ch == '"') {
|
||||
|
@ -166,7 +166,7 @@ CodeMirror.defineMode("haskell", function(_config, modeConfig) {
|
|||
}
|
||||
}
|
||||
setState(normal);
|
||||
return "error";
|
||||
return "string error";
|
||||
}
|
||||
|
||||
function stringGap(source, setState) {
|
||||
|
@ -194,7 +194,7 @@ CodeMirror.defineMode("haskell", function(_config, modeConfig) {
|
|||
"module", "newtype", "of", "then", "type", "where", "_");
|
||||
|
||||
setType("keyword")(
|
||||
"\.\.", ":", "::", "=", "\\", "\"", "<-", "->", "@", "~", "=>");
|
||||
"\.\.", ":", "::", "=", "\\", "<-", "->", "@", "~", "=>");
|
||||
|
||||
setType("builtin")(
|
||||
"!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<=", "=<<",
|
||||
|
|
|
@ -51,9 +51,10 @@ This is an example of EJS (embedded javascript)
|
|||
});
|
||||
</script>
|
||||
|
||||
<p>Mode for html embedded scripts like JSP and ASP.NET. Depends on HtmlMixed which in turn depends on
|
||||
JavaScript, CSS and XML.<br />Other dependancies include those of the scriping language chosen.</p>
|
||||
<p>Mode for html embedded scripts like JSP and ASP.NET. Depends on multiplex and HtmlMixed which in turn depends on
|
||||
JavaScript, CSS and XML.<br />Other dependencies include those of the scripting language chosen.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET),
|
||||
<code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)</p>
|
||||
<code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)
|
||||
and <code>application/x-erb</code></p>
|
||||
</article>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
var defaultTags = {
|
||||
script: [
|
||||
["lang", /(javascript|babel)/i, "javascript"],
|
||||
["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"],
|
||||
["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
|
||||
["type", /./, "text/plain"],
|
||||
[null, null, "javascript"]
|
||||
],
|
||||
|
@ -44,13 +44,9 @@
|
|||
return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
|
||||
}
|
||||
|
||||
function getAttrValue(stream, attr) {
|
||||
var pos = stream.pos, match;
|
||||
while (pos >= 0 && stream.string.charAt(pos) !== "<") pos--;
|
||||
if (pos < 0) return pos;
|
||||
if (match = stream.string.slice(pos, stream.pos).match(getAttrRegexp(attr)))
|
||||
return match[2];
|
||||
return "";
|
||||
function getAttrValue(text, attr) {
|
||||
var match = text.match(getAttrRegexp(attr))
|
||||
return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
|
||||
}
|
||||
|
||||
function getTagRegexp(tagName, anchored) {
|
||||
|
@ -66,10 +62,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
function findMatchingMode(tagInfo, stream) {
|
||||
function findMatchingMode(tagInfo, tagText) {
|
||||
for (var i = 0; i < tagInfo.length; i++) {
|
||||
var spec = tagInfo[i];
|
||||
if (!spec[0] || spec[1].test(getAttrValue(stream, spec[0]))) return spec[2];
|
||||
if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,15 +85,17 @@
|
|||
tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
|
||||
|
||||
function html(stream, state) {
|
||||
var tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase();
|
||||
var tagInfo = tagName && tags.hasOwnProperty(tagName) && tags[tagName];
|
||||
|
||||
var style = htmlMode.token(stream, state.htmlState), modeSpec;
|
||||
|
||||
if (tagInfo && /\btag\b/.test(style) && stream.current() === ">" &&
|
||||
(modeSpec = findMatchingMode(tagInfo, stream))) {
|
||||
var mode = CodeMirror.getMode(config, modeSpec);
|
||||
var endTagA = getTagRegexp(tagName, true), endTag = getTagRegexp(tagName, false);
|
||||
var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName
|
||||
if (tag && !/[<>\s\/]/.test(stream.current()) &&
|
||||
(tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) &&
|
||||
tags.hasOwnProperty(tagName)) {
|
||||
state.inTag = tagName + " "
|
||||
} else if (state.inTag && tag && />$/.test(stream.current())) {
|
||||
var inTag = /^([\S]+) (.*)/.exec(state.inTag)
|
||||
state.inTag = null
|
||||
var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2])
|
||||
var mode = CodeMirror.getMode(config, modeSpec)
|
||||
var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false);
|
||||
state.token = function (stream, state) {
|
||||
if (stream.match(endTagA, false)) {
|
||||
state.token = html;
|
||||
|
@ -108,14 +106,17 @@
|
|||
};
|
||||
state.localMode = mode;
|
||||
state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, ""));
|
||||
} else if (state.inTag) {
|
||||
state.inTag += stream.current()
|
||||
if (stream.eol()) state.inTag += " "
|
||||
}
|
||||
return style;
|
||||
};
|
||||
|
||||
return {
|
||||
startState: function () {
|
||||
var state = htmlMode.startState();
|
||||
return {token: html, localMode: null, localState: null, htmlState: state};
|
||||
var state = CodeMirror.startState(htmlMode);
|
||||
return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
|
||||
},
|
||||
|
||||
copyState: function (state) {
|
||||
|
@ -123,7 +124,8 @@
|
|||
if (state.localState) {
|
||||
local = CodeMirror.copyState(state.localMode, state.localState);
|
||||
}
|
||||
return {token: state.token, localMode: state.localMode, localState: local,
|
||||
return {token: state.token, inTag: state.inTag,
|
||||
localMode: state.localMode, localState: local,
|
||||
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
|
||||
},
|
||||
|
||||
|
|
29
app/public/codemirror/mode/htmlmixed/index.html
vendored
29
app/public/codemirror/mode/htmlmixed/index.html
vendored
|
@ -72,15 +72,26 @@
|
|||
<p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
|
||||
|
||||
<p>It takes an optional mode configuration
|
||||
option, <code>scriptTypes</code>, which can be used to add custom
|
||||
behavior for specific <code><script type="..."></code> tags. If
|
||||
given, it should hold an array of <code>{matches, mode}</code>
|
||||
objects, where <code>matches</code> is a string or regexp that
|
||||
matches the script type, and <code>mode</code> is
|
||||
either <code>null</code>, for script types that should stay in
|
||||
HTML mode, or a <a href="../../doc/manual.html#option_mode">mode
|
||||
spec</a> corresponding to the mode that should be used for the
|
||||
script.</p>
|
||||
option, <code>tags</code>, which can be used to add custom
|
||||
behavior for specific tags. When given, it should be an object
|
||||
mapping tag names (for example <code>script</code>) to arrays or
|
||||
three-element arrays. Those inner arrays indicate [attributeName,
|
||||
valueRegexp, <a href="../../doc/manual.html#option_mode">modeSpec</a>]
|
||||
specifications. For example, you could use <code>["type", /^foo$/,
|
||||
"foo"]</code> to map the attribute <code>type="foo"</code> to
|
||||
the <code>foo</code> mode. When the first two fields are null
|
||||
(<code>[null, null, "mode"]</code>), the given mode is used for
|
||||
any such tag that doesn't match any of the previously given
|
||||
attributes. For example:</p>
|
||||
|
||||
<pre>var myModeSpec = {
|
||||
name: "htmlmixed",
|
||||
tags: {
|
||||
style: [["type", /^text/(x-)?scss$/, "text/x-scss"],
|
||||
[null, null, "css"]],
|
||||
custom: [[null, null, "customMode"]]
|
||||
}
|
||||
}</pre>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/html</code>
|
||||
(redefined, only takes effect if you load this parser after the
|
||||
|
|
14
app/public/codemirror/mode/index.html
vendored
14
app/public/codemirror/mode/index.html
vendored
|
@ -56,9 +56,11 @@ option.</p>
|
|||
<li><a href="ebnf/index.html">EBNF</a></li>
|
||||
<li><a href="ecl/index.html">ECL</a></li>
|
||||
<li><a href="eiffel/index.html">Eiffel</a></li>
|
||||
<li><a href="https://github.com/optick/codemirror-mode-elixir">Elixir</a></li>
|
||||
<li><a href="elm/index.html">Elm</a></li>
|
||||
<li><a href="erlang/index.html">Erlang</a></li>
|
||||
<li><a href="factor/index.html">Factor</a></li>
|
||||
<li><a href="fcl/index.html">FCL</a></li>
|
||||
<li><a href="forth/index.html">Forth</a></li>
|
||||
<li><a href="fortran/index.html">Fortran</a></li>
|
||||
<li><a href="mllike/index.html">F#</a></li>
|
||||
|
@ -68,15 +70,14 @@ option.</p>
|
|||
<li><a href="groovy/index.html">Groovy</a></li>
|
||||
<li><a href="haml/index.html">HAML</a></li>
|
||||
<li><a href="handlebars/index.html">Handlebars</a></li>
|
||||
<li><a href="haskell/index.html">Haskell</a></li>
|
||||
<li><a href="haskell/index.html">Haskell</a> (<a href="haskell-literate/index.html">Literate</a>)</li>
|
||||
<li><a href="haxe/index.html">Haxe</a></li>
|
||||
<li><a href="htmlembedded/index.html">HTML embedded</a> (JSP, ASP.NET)</li>
|
||||
<li><a href="htmlmixed/index.html">HTML mixed-mode</a></li>
|
||||
<li><a href="http/index.html">HTTP</a></li>
|
||||
<li><a href="idl/index.html">IDL</a></li>
|
||||
<li><a href="clike/index.html">Java</a></li>
|
||||
<li><a href="jade/index.html">Jade</a></li>
|
||||
<li><a href="javascript/index.html">JavaScript</a></li>
|
||||
<li><a href="javascript/index.html">JavaScript</a> (<a href="jsx/index.html">JSX</a>)</li>
|
||||
<li><a href="jinja2/index.html">Jinja2</a></li>
|
||||
<li><a href="julia/index.html">Julia</a></li>
|
||||
<li><a href="kotlin/index.html">Kotlin</a></li>
|
||||
|
@ -85,6 +86,7 @@ option.</p>
|
|||
<li><a href="lua/index.html">Lua</a></li>
|
||||
<li><a href="markdown/index.html">Markdown</a> (<a href="gfm/index.html">GitHub-flavour</a>)</li>
|
||||
<li><a href="mathematica/index.html">Mathematica</a></li>
|
||||
<li><a href="mbox/index.html">mbox</a></li>
|
||||
<li><a href="mirc/index.html">mIRC</a></li>
|
||||
<li><a href="modelica/index.html">Modelica</a></li>
|
||||
<li><a href="mscgen/index.html">MscGen</a></li>
|
||||
|
@ -102,7 +104,10 @@ option.</p>
|
|||
<li><a href="asciiarmor/index.html">PGP (ASCII armor)</a></li>
|
||||
<li><a href="php/index.html">PHP</a></li>
|
||||
<li><a href="pig/index.html">Pig Latin</a></li>
|
||||
<li><a href="powershell/index.html">PowerShell</a></li>
|
||||
<li><a href="properties/index.html">Properties files</a></li>
|
||||
<li><a href="protobuf/index.html">ProtoBuf</a></li>
|
||||
<li><a href="pug/index.html">Pug</a></li>
|
||||
<li><a href="puppet/index.html">Puppet</a></li>
|
||||
<li><a href="python/index.html">Python</a></li>
|
||||
<li><a href="q/index.html">Q</a></li>
|
||||
|
@ -111,6 +116,7 @@ option.</p>
|
|||
<li><a href="rst/index.html">reStructuredText</a></li>
|
||||
<li><a href="ruby/index.html">Ruby</a></li>
|
||||
<li><a href="rust/index.html">Rust</a></li>
|
||||
<li><a href="sas/index.html">SAS</a></li>
|
||||
<li><a href="sass/index.html">Sass</a></li>
|
||||
<li><a href="spreadsheet/index.html">Spreadsheet</a></li>
|
||||
<li><a href="clike/scala.html">Scala</a></li>
|
||||
|
@ -146,8 +152,10 @@ option.</p>
|
|||
<li><a href="verilog/index.html">Verilog/SystemVerilog</a></li>
|
||||
<li><a href="vhdl/index.html">VHDL</a></li>
|
||||
<li><a href="vue/index.html">Vue.js app</a></li>
|
||||
<li><a href="webidl/index.html">Web IDL</a></li>
|
||||
<li><a href="xml/index.html">XML/HTML</a></li>
|
||||
<li><a href="xquery/index.html">XQuery</a></li>
|
||||
<li><a href="yacas/index.html">Yacas</a></li>
|
||||
<li><a href="yaml/index.html">YAML</a></li>
|
||||
<li><a href="yaml-frontmatter/index.html">YAML frontmatter</a></li>
|
||||
<li><a href="z80/index.html">Z80</a></li>
|
||||
|
|
171
app/public/codemirror/mode/javascript/javascript.js
vendored
171
app/public/codemirror/mode/javascript/javascript.js
vendored
|
@ -1,8 +1,6 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// TODO actually recognize syntax of TypeScript constructs
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
|
@ -13,6 +11,11 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
function expressionAllowed(stream, state, backUp) {
|
||||
return /^(?:operator|sof|keyword c|case|new|export|default|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
|
||||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
|
||||
}
|
||||
|
||||
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var statementIndent = parserConfig.statementIndent;
|
||||
|
@ -37,7 +40,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
|
||||
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
|
||||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
|
||||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
|
||||
"await": C, "async": kw("async")
|
||||
};
|
||||
|
||||
// Extend the 'normal' keywords with the TypeScript language extensions
|
||||
|
@ -50,6 +54,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
"namespace": C,
|
||||
"module": kw("module"),
|
||||
"enum": kw("module"),
|
||||
"type": kw("type"),
|
||||
|
||||
// scope modifiers
|
||||
"public": kw("modifier"),
|
||||
|
@ -126,8 +131,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
} else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
} else if (/^(?:operator|sof|keyword c|case|new|[\[{}\(,;:])$/.test(state.lastType) ||
|
||||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - 1)))) {
|
||||
} else if (expressionAllowed(stream, state, 1)) {
|
||||
readRegexp(stream);
|
||||
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
|
||||
return ret("regexp", "string-2");
|
||||
|
@ -142,7 +146,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
stream.skipToEnd();
|
||||
return ret("error", "error");
|
||||
} else if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
if (ch != ">" || !state.lexical || state.lexical.type != ">")
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", "operator", stream.current());
|
||||
} else if (wordRE.test(ch)) {
|
||||
stream.eatWhile(wordRE);
|
||||
|
@ -205,13 +210,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
var arrow = stream.string.indexOf("=>", stream.start);
|
||||
if (arrow < 0) return;
|
||||
|
||||
if (isTS) { // Try to skip TypeScript return type declarations after the arguments
|
||||
var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
|
||||
if (m) arrow = m.index
|
||||
}
|
||||
|
||||
var depth = 0, sawSomething = false;
|
||||
for (var pos = arrow - 1; pos >= 0; --pos) {
|
||||
var ch = stream.string.charAt(pos);
|
||||
var bracket = brackets.indexOf(ch);
|
||||
if (bracket >= 0 && bracket < 3) {
|
||||
if (!depth) { ++pos; break; }
|
||||
if (--depth == 0) break;
|
||||
if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
|
||||
} else if (bracket >= 3 && bracket < 6) {
|
||||
++depth;
|
||||
} else if (wordRE.test(ch)) {
|
||||
|
@ -340,19 +350,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
|
||||
function statement(type, value) {
|
||||
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
|
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
||||
if (type == "{") return cont(pushlex("}"), block, poplex);
|
||||
if (type == ";") return cont();
|
||||
if (type == "if") {
|
||||
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
|
||||
cx.state.cc.pop()();
|
||||
return cont(pushlex("form"), expression, statement, poplex, maybeelse);
|
||||
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
|
||||
}
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
|
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
||||
if (type == "switch") return cont(pushlex("form"), parenExpr, pushlex("}", "switch"), expect("{"),
|
||||
block, poplex, poplex);
|
||||
if (type == "case") return cont(expression, expect(":"));
|
||||
if (type == "default") return cont(expect(":"));
|
||||
|
@ -362,6 +372,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
|
||||
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
|
||||
if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
|
||||
if (type == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
|
||||
if (type == "async") return cont(statement)
|
||||
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
function expression(type) {
|
||||
|
@ -370,6 +382,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
function expressionNoComma(type) {
|
||||
return expressionInner(type, true);
|
||||
}
|
||||
function parenExpr(type) {
|
||||
if (type != "(") return pass()
|
||||
return cont(pushlex(")"), expression, expect(")"), poplex)
|
||||
}
|
||||
function expressionInner(type, noComma) {
|
||||
if (cx.state.fatArrowAt == cx.stream.start) {
|
||||
var body = noComma ? arrowBodyNoComma : arrowBody;
|
||||
|
@ -380,8 +396,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
|
||||
if (type == "function") return cont(functiondef, maybeop);
|
||||
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
|
||||
if (type == "class") return cont(pushlex("form"), classExpression, poplex);
|
||||
if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
|
||||
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
|
||||
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
|
||||
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
|
||||
|
@ -457,7 +474,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (type == "variable") {cx.marked = "property"; return cont();}
|
||||
}
|
||||
function objprop(type, value) {
|
||||
if (type == "variable" || cx.style == "keyword") {
|
||||
if (type == "async") {
|
||||
cx.marked = "property";
|
||||
return cont(objprop);
|
||||
} else if (type == "variable" || cx.style == "keyword") {
|
||||
cx.marked = "property";
|
||||
if (value == "get" || value == "set") return cont(getterSetter);
|
||||
return cont(afterprop);
|
||||
|
@ -472,6 +492,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
return cont(expression, expect("]"), afterprop);
|
||||
} else if (type == "spread") {
|
||||
return cont(expression);
|
||||
} else if (type == ":") {
|
||||
return pass(afterprop)
|
||||
}
|
||||
}
|
||||
function getterSetter(type) {
|
||||
|
@ -483,18 +505,21 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (type == ":") return cont(expressionNoComma);
|
||||
if (type == "(") return pass(functiondef);
|
||||
}
|
||||
function commasep(what, end) {
|
||||
function proceed(type) {
|
||||
if (type == ",") {
|
||||
function commasep(what, end, sep) {
|
||||
function proceed(type, value) {
|
||||
if (sep ? sep.indexOf(type) > -1 : type == ",") {
|
||||
var lex = cx.state.lexical;
|
||||
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
|
||||
return cont(what, proceed);
|
||||
return cont(function(type, value) {
|
||||
if (type == end || value == end) return pass()
|
||||
return pass(what)
|
||||
}, proceed);
|
||||
}
|
||||
if (type == end) return cont();
|
||||
if (type == end || value == end) return cont();
|
||||
return cont(expect(end));
|
||||
}
|
||||
return function(type) {
|
||||
if (type == end) return cont();
|
||||
return function(type, value) {
|
||||
if (type == end || value == end) return cont();
|
||||
return pass(what, proceed);
|
||||
};
|
||||
}
|
||||
|
@ -507,14 +532,39 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (type == "}") return cont();
|
||||
return pass(statement, block);
|
||||
}
|
||||
function maybetype(type) {
|
||||
if (isTS && type == ":") return cont(typedef);
|
||||
function maybetype(type, value) {
|
||||
if (isTS) {
|
||||
if (type == ":") return cont(typeexpr);
|
||||
if (value == "?") return cont(maybetype);
|
||||
}
|
||||
}
|
||||
function maybedefault(_, value) {
|
||||
if (value == "=") return cont(expressionNoComma);
|
||||
function typeexpr(type) {
|
||||
if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);}
|
||||
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
|
||||
if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex)
|
||||
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
|
||||
}
|
||||
function typedef(type) {
|
||||
if (type == "variable") {cx.marked = "variable-3"; return cont();}
|
||||
function maybeReturnType(type) {
|
||||
if (type == "=>") return cont(typeexpr)
|
||||
}
|
||||
function typeprop(type, value) {
|
||||
if (type == "variable" || cx.style == "keyword") {
|
||||
cx.marked = "property"
|
||||
return cont(typeprop)
|
||||
} else if (value == "?") {
|
||||
return cont(typeprop)
|
||||
} else if (type == ":") {
|
||||
return cont(typeexpr)
|
||||
}
|
||||
}
|
||||
function typearg(type) {
|
||||
if (type == "variable") return cont(typearg)
|
||||
else if (type == ":") return cont(typeexpr)
|
||||
}
|
||||
function afterType(type, value) {
|
||||
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
|
||||
if (value == "|" || type == ".") return cont(typeexpr)
|
||||
if (type == "[") return cont(expect("]"), afterType)
|
||||
}
|
||||
function vardef() {
|
||||
return pass(pattern, maybetype, maybeAssign, vardefCont);
|
||||
|
@ -533,6 +583,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
}
|
||||
if (type == "variable") cx.marked = "property";
|
||||
if (type == "spread") return cont(pattern);
|
||||
if (type == "}") return pass();
|
||||
return cont(expect(":"), pattern, maybeAssign);
|
||||
}
|
||||
function maybeAssign(_type, value) {
|
||||
|
@ -568,29 +619,38 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
function functiondef(type, value) {
|
||||
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
|
||||
if (type == "variable") {register(value); return cont(functiondef);}
|
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
|
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
|
||||
}
|
||||
function funarg(type) {
|
||||
if (type == "spread") return cont(funarg);
|
||||
return pass(pattern, maybetype, maybedefault);
|
||||
return pass(pattern, maybetype, maybeAssign);
|
||||
}
|
||||
function classExpression(type, value) {
|
||||
// Class expressions may have an optional name.
|
||||
if (type == "variable") return className(type, value);
|
||||
return classNameAfter(type, value);
|
||||
}
|
||||
function className(type, value) {
|
||||
if (type == "variable") {register(value); return cont(classNameAfter);}
|
||||
}
|
||||
function classNameAfter(type, value) {
|
||||
if (value == "extends") return cont(expression, classNameAfter);
|
||||
if (value == "extends" || value == "implements" || (isTS && type == ","))
|
||||
return cont(isTS ? typeexpr : expression, classNameAfter);
|
||||
if (type == "{") return cont(pushlex("}"), classBody, poplex);
|
||||
}
|
||||
function classBody(type, value) {
|
||||
if (type == "variable" || cx.style == "keyword") {
|
||||
if (value == "static") {
|
||||
if ((value == "async" || value == "static" || value == "get" || value == "set" ||
|
||||
(isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) &&
|
||||
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) {
|
||||
cx.marked = "keyword";
|
||||
return cont(classBody);
|
||||
}
|
||||
cx.marked = "property";
|
||||
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
|
||||
return cont(functiondef, classBody);
|
||||
return cont(isTS ? classfield : functiondef, classBody);
|
||||
}
|
||||
if (type == "[")
|
||||
return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
|
||||
if (value == "*") {
|
||||
cx.marked = "keyword";
|
||||
return cont(classBody);
|
||||
|
@ -598,19 +658,24 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (type == ";") return cont(classBody);
|
||||
if (type == "}") return cont();
|
||||
}
|
||||
function classGetterSetter(type) {
|
||||
if (type != "variable") return pass();
|
||||
cx.marked = "property";
|
||||
return cont();
|
||||
function classfield(type, value) {
|
||||
if (value == "?") return cont(classfield)
|
||||
if (type == ":") return cont(typeexpr, maybeAssign)
|
||||
return pass(functiondef)
|
||||
}
|
||||
function afterExport(_type, value) {
|
||||
function afterExport(type, value) {
|
||||
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
|
||||
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
|
||||
if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
|
||||
return pass(statement);
|
||||
}
|
||||
function exportField(type, value) {
|
||||
if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
|
||||
if (type == "variable") return pass(expressionNoComma, exportField);
|
||||
}
|
||||
function afterImport(type) {
|
||||
if (type == "string") return cont();
|
||||
return pass(importSpec, maybeFrom);
|
||||
return pass(importSpec, maybeMoreImports, maybeFrom);
|
||||
}
|
||||
function importSpec(type, value) {
|
||||
if (type == "{") return contCommasep(importSpec, "}");
|
||||
|
@ -618,6 +683,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (value == "*") cx.marked = "keyword";
|
||||
return cont(maybeAs);
|
||||
}
|
||||
function maybeMoreImports(type) {
|
||||
if (type == ",") return cont(importSpec, maybeMoreImports)
|
||||
}
|
||||
function maybeAs(_type, value) {
|
||||
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
|
||||
}
|
||||
|
@ -626,17 +694,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
}
|
||||
function arrayLiteral(type) {
|
||||
if (type == "]") return cont();
|
||||
return pass(expressionNoComma, maybeArrayComprehension);
|
||||
}
|
||||
function maybeArrayComprehension(type) {
|
||||
if (type == "for") return pass(comprehension, expect("]"));
|
||||
if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
|
||||
return pass(commasep(expressionNoComma, "]"));
|
||||
}
|
||||
function comprehension(type) {
|
||||
if (type == "for") return cont(forspec, comprehension);
|
||||
if (type == "if") return cont(expression, comprehension);
|
||||
}
|
||||
|
||||
function isContinuedStatement(state, textAfter) {
|
||||
return state.lastType == "operator" || state.lastType == "," ||
|
||||
|
@ -655,7 +714,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
||||
localVars: parserConfig.localVars,
|
||||
context: parserConfig.localVars && {vars: parserConfig.localVars},
|
||||
indented: 0
|
||||
indented: basecolumn || 0
|
||||
};
|
||||
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
|
||||
state.globalVars = parserConfig.globalVars;
|
||||
|
@ -679,14 +738,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
indent: function(state, textAfter) {
|
||||
if (state.tokenize == tokenComment) return CodeMirror.Pass;
|
||||
if (state.tokenize != tokenBase) return 0;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
|
||||
// Kludge to prevent 'maybelse' from blocking lexical scope pops
|
||||
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
|
||||
var c = state.cc[i];
|
||||
if (c == poplex) lexical = lexical.prev;
|
||||
else if (c != maybeelse) break;
|
||||
}
|
||||
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
||||
while ((lexical.type == "stat" || lexical.type == "form") &&
|
||||
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
|
||||
(top == maybeoperatorComma || top == maybeoperatorNoComma) &&
|
||||
!/^[,\.=+\-*:?[\(]/.test(textAfter))))
|
||||
lexical = lexical.prev;
|
||||
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
|
||||
lexical = lexical.prev;
|
||||
var type = lexical.type, closing = firstChar == type;
|
||||
|
@ -711,7 +774,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
|
||||
helperType: jsonMode ? "json" : "javascript",
|
||||
jsonldMode: jsonldMode,
|
||||
jsonMode: jsonMode
|
||||
jsonMode: jsonMode,
|
||||
|
||||
expressionAllowed: expressionAllowed,
|
||||
skipExpression: function(state) {
|
||||
var top = state.cc[state.cc.length - 1]
|
||||
if (top == expression || top == expressionNoComma) state.cc.pop()
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
|
137
app/public/codemirror/mode/javascript/test.js
vendored
137
app/public/codemirror/mode/javascript/test.js
vendored
|
@ -17,6 +17,10 @@
|
|||
" [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];",
|
||||
"})();");
|
||||
|
||||
MT("destructure_trailing_comma",
|
||||
"[keyword let] {[def a], [def b],} [operator =] [variable foo];",
|
||||
"[keyword let] [def c];"); // Parser still in good state?
|
||||
|
||||
MT("class_body",
|
||||
"[keyword class] [def Foo] {",
|
||||
" [property constructor]() {}",
|
||||
|
@ -27,19 +31,38 @@
|
|||
|
||||
MT("class",
|
||||
"[keyword class] [def Point] [keyword extends] [variable SuperThing] {",
|
||||
" [property get] [property prop]() { [keyword return] [number 24]; }",
|
||||
" [keyword get] [property prop]() { [keyword return] [number 24]; }",
|
||||
" [property constructor]([def x], [def y]) {",
|
||||
" [keyword super]([string 'something']);",
|
||||
" [keyword this].[property x] [operator =] [variable-2 x];",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
MT("anonymous_class_expression",
|
||||
"[keyword const] [def Adder] [operator =] [keyword class] [keyword extends] [variable Arithmetic] {",
|
||||
" [property add]([def a], [def b]) {}",
|
||||
"};");
|
||||
|
||||
MT("named_class_expression",
|
||||
"[keyword const] [def Subber] [operator =] [keyword class] [def Subtract] {",
|
||||
" [property sub]([def a], [def b]) {}",
|
||||
"};");
|
||||
|
||||
MT("class_async_method",
|
||||
"[keyword class] [def Foo] {",
|
||||
" [property sayName1]() {}",
|
||||
" [keyword async] [property sayName2]() {}",
|
||||
"}");
|
||||
|
||||
MT("import",
|
||||
"[keyword function] [def foo]() {",
|
||||
" [keyword import] [def $] [keyword from] [string 'jquery'];",
|
||||
" [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
|
||||
"}");
|
||||
|
||||
MT("import_trailing_comma",
|
||||
"[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']")
|
||||
|
||||
MT("const",
|
||||
"[keyword function] [def f]() {",
|
||||
" [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
|
||||
|
@ -71,12 +94,6 @@
|
|||
" [variable something]([variable-2 a], [meta ...][variable-2 b]);",
|
||||
"}");
|
||||
|
||||
MT("comprehension",
|
||||
"[keyword function] [def f]() {",
|
||||
" [[([variable x] [operator +] [number 1]) [keyword for] ([keyword var] [def x] [keyword in] [variable y]) [keyword if] [variable pred]([variable-2 x]) ]];",
|
||||
" ([variable u] [keyword for] ([keyword var] [def u] [keyword of] [variable generateValues]()) [keyword if] ([variable-2 u].[property color] [operator ===] [string 'blue']));",
|
||||
"}");
|
||||
|
||||
MT("quasi",
|
||||
"[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
|
||||
|
||||
|
@ -139,6 +156,19 @@
|
|||
" [number 1];",
|
||||
"[number 2];");
|
||||
|
||||
MT("indent_semicolonless_if",
|
||||
"[keyword function] [def foo]() {",
|
||||
" [keyword if] ([variable x])",
|
||||
" [variable foo]()",
|
||||
"}")
|
||||
|
||||
MT("indent_semicolonless_if_with_statement",
|
||||
"[keyword function] [def foo]() {",
|
||||
" [keyword if] ([variable x])",
|
||||
" [variable foo]()",
|
||||
" [variable bar]()",
|
||||
"}")
|
||||
|
||||
MT("multilinestring",
|
||||
"[keyword var] [def x] [operator =] [string 'foo\\]",
|
||||
"[string bar'];");
|
||||
|
@ -166,6 +196,99 @@
|
|||
" }",
|
||||
"}");
|
||||
|
||||
MT("async",
|
||||
"[keyword async] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }");
|
||||
|
||||
MT("async_assignment",
|
||||
"[keyword const] [def foo] [operator =] [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; };");
|
||||
|
||||
MT("async_object",
|
||||
"[keyword let] [def obj] [operator =] { [property async]: [atom false] };");
|
||||
|
||||
// async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173
|
||||
MT("async_object_function",
|
||||
"[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };");
|
||||
|
||||
MT("async_object_properties",
|
||||
"[keyword let] [def obj] [operator =] {",
|
||||
" [property prop1]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
|
||||
" [property prop2]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
|
||||
" [property prop3]: [keyword async] [keyword function] [def prop3]([def args]) { [keyword return] [atom true]; },",
|
||||
"};");
|
||||
|
||||
MT("async_arrow",
|
||||
"[keyword const] [def foo] [operator =] [keyword async] ([def args]) [operator =>] { [keyword return] [atom true]; };");
|
||||
|
||||
MT("async_jquery",
|
||||
"[variable $].[property ajax]({",
|
||||
" [property url]: [variable url],",
|
||||
" [property async]: [atom true],",
|
||||
" [property method]: [string 'GET']",
|
||||
"});");
|
||||
|
||||
var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript")
|
||||
function TS(name) {
|
||||
test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1))
|
||||
}
|
||||
|
||||
TS("extend_type",
|
||||
"[keyword class] [def Foo] [keyword extends] [variable-3 Some][operator <][variable-3 Type][operator >] {}")
|
||||
|
||||
TS("arrow_type",
|
||||
"[keyword let] [def x]: ([variable arg]: [variable-3 Type]) [operator =>] [variable-3 ReturnType]")
|
||||
|
||||
TS("typescript_class",
|
||||
"[keyword class] [def Foo] {",
|
||||
" [keyword public] [keyword static] [property main]() {}",
|
||||
" [keyword private] [property _foo]: [variable-3 string];",
|
||||
"}")
|
||||
|
||||
TS("typescript_literal_types",
|
||||
"[keyword import] [keyword *] [keyword as] [def Sequelize] [keyword from] [string 'sequelize'];",
|
||||
"[keyword interface] [def MyAttributes] {",
|
||||
" [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
|
||||
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
|
||||
"}",
|
||||
"[keyword interface] [def MyInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance] [operator <] [variable-3 MyAttributes] [operator >] {",
|
||||
" [property rawAttributes]: [variable-3 MyAttributes];",
|
||||
" [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
|
||||
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
|
||||
"}")
|
||||
|
||||
TS("typescript_extend_operators",
|
||||
"[keyword export] [keyword interface] [def UserModel] [keyword extends]",
|
||||
" [variable-3 Sequelize].[variable-3 Model] [operator <] [variable-3 UserInstance], [variable-3 UserAttributes] [operator >] {",
|
||||
" [property findById]: (",
|
||||
" [variable userId]: [variable-3 number]",
|
||||
" ) [operator =>] [variable-3 Promise] [operator <] [variable-3 Array] [operator <] { [property id], [property name] } [operator >>];",
|
||||
" [property updateById]: (",
|
||||
" [variable userId]: [variable-3 number],",
|
||||
" [variable isActive]: [variable-3 boolean]",
|
||||
" ) [operator =>] [variable-3 Promise] [operator <] [variable-3 AccountHolderNotificationPreferenceInstance] [operator >];",
|
||||
" }")
|
||||
|
||||
TS("typescript_interface_with_const",
|
||||
"[keyword const] [def hello]: {",
|
||||
" [property prop1][operator ?]: [variable-3 string];",
|
||||
" [property prop2][operator ?]: [variable-3 string];",
|
||||
"} [operator =] {};")
|
||||
|
||||
TS("typescript_double_extend",
|
||||
"[keyword export] [keyword interface] [def UserAttributes] {",
|
||||
" [property id][operator ?]: [variable-3 number];",
|
||||
" [property createdAt][operator ?]: [variable-3 Date];",
|
||||
"}",
|
||||
"[keyword export] [keyword interface] [def UserInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance][operator <][variable-3 UserAttributes][operator >], [variable-3 UserAttributes] {",
|
||||
" [property id]: [variable-3 number];",
|
||||
" [property createdAt]: [variable-3 Date];",
|
||||
"}");
|
||||
|
||||
TS("typescript_index_signature",
|
||||
"[keyword interface] [def A] {",
|
||||
" [[ [variable prop]: [variable-3 string] ]]: [variable-3 any];",
|
||||
" [property prop1]: [variable-3 any];",
|
||||
"}");
|
||||
|
||||
var jsonld_mode = CodeMirror.getMode(
|
||||
{indentUnit: 2},
|
||||
{name: "javascript", jsonld: true}
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
|
||||
<div><textarea id="code" name="code">
|
||||
class Greeter {
|
||||
greeting: string;
|
||||
constructor (message: string) {
|
||||
this.greeting = message;
|
||||
}
|
||||
greet() {
|
||||
return "Hello, " + this.greeting;
|
||||
}
|
||||
greeting: string;
|
||||
constructor (message: string) {
|
||||
this.greeting = message;
|
||||
}
|
||||
greet() {
|
||||
return "Hello, " + this.greeting;
|
||||
}
|
||||
}
|
||||
|
||||
var greeter = new Greeter("world");
|
||||
|
@ -42,7 +42,7 @@ var greeter = new Greeter("world");
|
|||
var button = document.createElement('button')
|
||||
button.innerText = "Say Hello"
|
||||
button.onclick = function() {
|
||||
alert(greeter.greet())
|
||||
alert(greeter.greet())
|
||||
}
|
||||
|
||||
document.body.appendChild(button)
|
||||
|
|
89
app/public/codemirror/mode/jsx/index.html
vendored
Executable file
89
app/public/codemirror/mode/jsx/index.html
vendored
Executable file
|
@ -0,0 +1,89 @@
|
|||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: JSX 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="../javascript/javascript.js"></script>
|
||||
<script src="../xml/xml.js"></script>
|
||||
<script src="jsx.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="#">JSX</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>JSX mode</h2>
|
||||
|
||||
<div><textarea id="code" name="code">// Code snippets from http://facebook.github.io/react/docs/jsx-in-depth.html
|
||||
|
||||
// Rendering HTML tags
|
||||
var myDivElement = <div className="foo" />;
|
||||
ReactDOM.render(myDivElement, document.getElementById('example'));
|
||||
|
||||
// Rendering React components
|
||||
var MyComponent = React.createClass({/*...*/});
|
||||
var myElement = <MyComponent someProperty={true} />;
|
||||
ReactDOM.render(myElement, document.getElementById('example'));
|
||||
|
||||
// Namespaced components
|
||||
var Form = MyFormComponent;
|
||||
|
||||
var App = (
|
||||
<Form>
|
||||
<Form.Row>
|
||||
<Form.Label />
|
||||
<Form.Input />
|
||||
</Form.Row>
|
||||
</Form>
|
||||
);
|
||||
|
||||
// Attribute JavaScript expressions
|
||||
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
|
||||
|
||||
// Boolean attributes
|
||||
<input type="button" disabled />;
|
||||
<input type="button" disabled={true} />;
|
||||
|
||||
// Child JavaScript expressions
|
||||
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
|
||||
|
||||
// Comments
|
||||
var content = (
|
||||
<Nav>
|
||||
{/* child comment, put {} around */}
|
||||
<Person
|
||||
/* multi
|
||||
line
|
||||
comment */
|
||||
name={window.isLoggedIn ? window.name : ''} // end of line comment
|
||||
/>
|
||||
</Nav>
|
||||
);
|
||||
</textarea></div>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "jsx"
|
||||
})
|
||||
</script>
|
||||
|
||||
<p>JSX Mode for <a href="http://facebook.github.io/react">React</a>'s
|
||||
JavaScript syntax extension.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/jsx</code>, <code>text/typescript-jsx</code>.</p>
|
||||
|
||||
</article>
|
148
app/public/codemirror/mode/jsx/jsx.js
vendored
Executable file
148
app/public/codemirror/mode/jsx/jsx.js
vendored
Executable file
|
@ -0,0 +1,148 @@
|
|||
// 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("../xml/xml"), require("../javascript/javascript"))
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
|
||||
else // Plain browser env
|
||||
mod(CodeMirror)
|
||||
})(function(CodeMirror) {
|
||||
"use strict"
|
||||
|
||||
// Depth means the amount of open braces in JS context, in XML
|
||||
// context 0 means not in tag, 1 means in tag, and 2 means in tag
|
||||
// and js block comment.
|
||||
function Context(state, mode, depth, prev) {
|
||||
this.state = state; this.mode = mode; this.depth = depth; this.prev = prev
|
||||
}
|
||||
|
||||
function copyContext(context) {
|
||||
return new Context(CodeMirror.copyState(context.mode, context.state),
|
||||
context.mode,
|
||||
context.depth,
|
||||
context.prev && copyContext(context.prev))
|
||||
}
|
||||
|
||||
CodeMirror.defineMode("jsx", function(config, modeConfig) {
|
||||
var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
|
||||
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
|
||||
|
||||
function flatXMLIndent(state) {
|
||||
var tagName = state.tagName
|
||||
state.tagName = null
|
||||
var result = xmlMode.indent(state, "")
|
||||
state.tagName = tagName
|
||||
return result
|
||||
}
|
||||
|
||||
function token(stream, state) {
|
||||
if (state.context.mode == xmlMode)
|
||||
return xmlToken(stream, state, state.context)
|
||||
else
|
||||
return jsToken(stream, state, state.context)
|
||||
}
|
||||
|
||||
function xmlToken(stream, state, cx) {
|
||||
if (cx.depth == 2) { // Inside a JS /* */ comment
|
||||
if (stream.match(/^.*?\*\//)) cx.depth = 1
|
||||
else stream.skipToEnd()
|
||||
return "comment"
|
||||
}
|
||||
|
||||
if (stream.peek() == "{") {
|
||||
xmlMode.skipAttribute(cx.state)
|
||||
|
||||
var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
|
||||
// If JS starts on same line as tag
|
||||
if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {
|
||||
while (xmlContext.prev && !xmlContext.startOfLine)
|
||||
xmlContext = xmlContext.prev
|
||||
// If tag starts the line, use XML indentation level
|
||||
if (xmlContext.startOfLine) indent -= config.indentUnit
|
||||
// Else use JS indentation level
|
||||
else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
|
||||
// Else if inside of tag
|
||||
} else if (cx.depth == 1) {
|
||||
indent += config.indentUnit
|
||||
}
|
||||
|
||||
state.context = new Context(CodeMirror.startState(jsMode, indent),
|
||||
jsMode, 0, state.context)
|
||||
return null
|
||||
}
|
||||
|
||||
if (cx.depth == 1) { // Inside of tag
|
||||
if (stream.peek() == "<") { // Tag inside of tag
|
||||
xmlMode.skipAttribute(cx.state)
|
||||
state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),
|
||||
xmlMode, 0, state.context)
|
||||
return null
|
||||
} else if (stream.match("//")) {
|
||||
stream.skipToEnd()
|
||||
return "comment"
|
||||
} else if (stream.match("/*")) {
|
||||
cx.depth = 2
|
||||
return token(stream, state)
|
||||
}
|
||||
}
|
||||
|
||||
var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop
|
||||
if (/\btag\b/.test(style)) {
|
||||
if (/>$/.test(cur)) {
|
||||
if (cx.state.context) cx.depth = 0
|
||||
else state.context = state.context.prev
|
||||
} else if (/^</.test(cur)) {
|
||||
cx.depth = 1
|
||||
}
|
||||
} else if (!style && (stop = cur.indexOf("{")) > -1) {
|
||||
stream.backUp(cur.length - stop)
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
function jsToken(stream, state, cx) {
|
||||
if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
|
||||
jsMode.skipExpression(cx.state)
|
||||
state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
|
||||
xmlMode, 0, state.context)
|
||||
return null
|
||||
}
|
||||
|
||||
var style = jsMode.token(stream, cx.state)
|
||||
if (!style && cx.depth != null) {
|
||||
var cur = stream.current()
|
||||
if (cur == "{") {
|
||||
cx.depth++
|
||||
} else if (cur == "}") {
|
||||
if (--cx.depth == 0) state.context = state.context.prev
|
||||
}
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {context: new Context(CodeMirror.startState(jsMode), jsMode)}
|
||||
},
|
||||
|
||||
copyState: function(state) {
|
||||
return {context: copyContext(state.context)}
|
||||
},
|
||||
|
||||
token: token,
|
||||
|
||||
indent: function(state, textAfter, fullLine) {
|
||||
return state.context.mode.indent(state.context.state, textAfter, fullLine)
|
||||
},
|
||||
|
||||
innerMode: function(state) {
|
||||
return state.context
|
||||
}
|
||||
}
|
||||
}, "xml", "javascript")
|
||||
|
||||
CodeMirror.defineMIME("text/jsx", "jsx")
|
||||
CodeMirror.defineMIME("text/typescript-jsx", {name: "jsx", base: {name: "javascript", typescript: true}})
|
||||
});
|
69
app/public/codemirror/mode/jsx/test.js
vendored
Executable file
69
app/public/codemirror/mode/jsx/test.js
vendored
Executable file
|
@ -0,0 +1,69 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({indentUnit: 2}, "jsx")
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)) }
|
||||
|
||||
MT("selfclose",
|
||||
"[keyword var] [def x] [operator =] [bracket&tag <] [tag foo] [bracket&tag />] [operator +] [number 1];")
|
||||
|
||||
MT("openclose",
|
||||
"([bracket&tag <][tag foo][bracket&tag >]hello [atom &][bracket&tag </][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("attr",
|
||||
"([bracket&tag <][tag foo] [attribute abc]=[string 'value'][bracket&tag >]hello [atom &][bracket&tag </][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("braced_attr",
|
||||
"([bracket&tag <][tag foo] [attribute abc]={[number 10]}[bracket&tag >]hello [atom &][bracket&tag </][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("braced_text",
|
||||
"([bracket&tag <][tag foo][bracket&tag >]hello {[number 10]} [atom &][bracket&tag </][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("nested_tag",
|
||||
"([bracket&tag <][tag foo][bracket&tag ><][tag bar][bracket&tag ></][tag bar][bracket&tag ></][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("nested_jsx",
|
||||
"[keyword return] (",
|
||||
" [bracket&tag <][tag foo][bracket&tag >]",
|
||||
" say {[number 1] [operator +] [bracket&tag <][tag bar] [attribute attr]={[number 10]}[bracket&tag />]}!",
|
||||
" [bracket&tag </][tag foo][bracket&tag >][operator ++]",
|
||||
")")
|
||||
|
||||
MT("preserve_js_context",
|
||||
"[variable x] [operator =] [string-2 `quasi${][bracket&tag <][tag foo][bracket&tag />][string-2 }quoted`]")
|
||||
|
||||
MT("line_comment",
|
||||
"([bracket&tag <][tag foo] [comment // hello]",
|
||||
" [bracket&tag ></][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("line_comment_not_in_tag",
|
||||
"([bracket&tag <][tag foo][bracket&tag >] // hello",
|
||||
" [bracket&tag </][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("block_comment",
|
||||
"([bracket&tag <][tag foo] [comment /* hello]",
|
||||
"[comment line 2]",
|
||||
"[comment line 3 */] [bracket&tag ></][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("block_comment_not_in_tag",
|
||||
"([bracket&tag <][tag foo][bracket&tag >]/* hello",
|
||||
" line 2",
|
||||
" line 3 */ [bracket&tag </][tag foo][bracket&tag >][operator ++])")
|
||||
|
||||
MT("missing_attr",
|
||||
"([bracket&tag <][tag foo] [attribute selected][bracket&tag />][operator ++])")
|
||||
|
||||
MT("indent_js",
|
||||
"([bracket&tag <][tag foo][bracket&tag >]",
|
||||
" [bracket&tag <][tag bar] [attribute baz]={[keyword function]() {",
|
||||
" [keyword return] [number 10]",
|
||||
" }}[bracket&tag />]",
|
||||
" [bracket&tag </][tag foo][bracket&tag >])")
|
||||
|
||||
MT("spread",
|
||||
"([bracket&tag <][tag foo] [attribute bar]={[meta ...][variable baz] [operator /][number 2]}[bracket&tag />])")
|
||||
|
||||
MT("tag_attribute",
|
||||
"([bracket&tag <][tag foo] [attribute bar]=[bracket&tag <][tag foo][bracket&tag />/>][operator ++])")
|
||||
})()
|
445
app/public/codemirror/mode/julia/julia.js
vendored
445
app/public/codemirror/mode/julia/julia.js
vendored
|
@ -11,64 +11,87 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("julia", function(_conf, parserConf) {
|
||||
var ERRORCLASS = 'error';
|
||||
|
||||
function wordRegexp(words) {
|
||||
return new RegExp("^((" + words.join(")|(") + "))\\b");
|
||||
CodeMirror.defineMode("julia", function(config, parserConf) {
|
||||
function wordRegexp(words, end) {
|
||||
if (typeof end === "undefined") { end = "\\b"; }
|
||||
return new RegExp("^((" + words.join(")|(") + "))" + end);
|
||||
}
|
||||
|
||||
var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b/;
|
||||
var octChar = "\\\\[0-7]{1,3}";
|
||||
var hexChar = "\\\\x[A-Fa-f0-9]{1,2}";
|
||||
var sChar = "\\\\[abefnrtv0%?'\"\\\\]";
|
||||
var uChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])";
|
||||
|
||||
var operators = parserConf.operators || wordRegexp([
|
||||
"\\.?[\\\\%*+\\-<>!=\\/^]=?", "\\.?[|&\\u00F7\\u2260\\u2264\\u2265]",
|
||||
"\\u00D7", "\\u2208", "\\u2209", "\\u220B", "\\u220C", "\\u2229",
|
||||
"\\u222A", "\\u2286", "\\u2288", "\\u228A", "\\u22c5", "\\?", "~", ":",
|
||||
"\\$", "\\.[<>]", "<<=?", ">>>?=?", "\\.[<>=]=", "->?", "\\/\\/", "=>",
|
||||
"<:", "\\bin\\b(?!\\()"], "");
|
||||
var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
|
||||
var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
|
||||
var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
|
||||
var blockClosers = ["end", "else", "elseif", "catch", "finally"];
|
||||
var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype', 'ccall'];
|
||||
var builtinList = ['true', 'false', 'enumerate', 'open', 'close', 'nothing', 'NaN', 'Inf', 'print', 'println', 'Int', 'Int8', 'Uint8', 'Int16', 'Uint16', 'Int32', 'Uint32', 'Int64', 'Uint64', 'Int128', 'Uint128', 'Bool', 'Char', 'Float16', 'Float32', 'Float64', 'Array', 'Vector', 'Matrix', 'String', 'UTF8String', 'ASCIIString', 'error', 'warn', 'info', '@printf'];
|
||||
var identifiers = parserConf.identifiers || /^[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
|
||||
|
||||
//var stringPrefixes = new RegExp("^[br]?('|\")")
|
||||
var stringPrefixes = /^(`|'|"{3}|([br]?"))/;
|
||||
var keywords = wordRegexp(keywordList);
|
||||
var builtins = wordRegexp(builtinList);
|
||||
var openers = wordRegexp(blockOpeners);
|
||||
var closers = wordRegexp(blockClosers);
|
||||
var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
|
||||
var symbol = /^:[_A-Za-z][_A-Za-z0-9]*/;
|
||||
var chars = wordRegexp([octChar, hexChar, sChar, uChar], "'");
|
||||
var openers = wordRegexp(["begin", "function", "type", "immutable", "let",
|
||||
"macro", "for", "while", "quote", "if", "else", "elseif", "try",
|
||||
"finally", "catch", "do"]);
|
||||
var closers = wordRegexp(["end", "else", "elseif", "catch", "finally"]);
|
||||
var keywords = wordRegexp(["if", "else", "elseif", "while", "for", "begin",
|
||||
"let", "end", "do", "try", "catch", "finally", "return", "break",
|
||||
"continue", "global", "local", "const", "export", "import", "importall",
|
||||
"using", "function", "macro", "module", "baremodule", "type",
|
||||
"immutable", "quote", "typealias", "abstract", "bitstype"]);
|
||||
var builtins = wordRegexp(["true", "false", "nothing", "NaN", "Inf"]);
|
||||
|
||||
function in_array(state) {
|
||||
var ch = cur_scope(state);
|
||||
if(ch=="[" || ch=="{") {
|
||||
var macro = /^@[_A-Za-z][\w]*/;
|
||||
var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
|
||||
var stringPrefixes = /^(`|"{3}|([_A-Za-z\u00A1-\uFFFF]*"))/;
|
||||
|
||||
function inArray(state) {
|
||||
return inGenerator(state, '[')
|
||||
}
|
||||
|
||||
function inGenerator(state, bracket) {
|
||||
var curr = currentScope(state),
|
||||
prev = currentScope(state, 1);
|
||||
if (typeof(bracket) === "undefined") { bracket = '('; }
|
||||
if (curr === bracket || (prev === bracket && curr === "for")) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function cur_scope(state) {
|
||||
if(state.scopes.length==0) {
|
||||
function currentScope(state, n) {
|
||||
if (typeof(n) === "undefined") { n = 0; }
|
||||
if (state.scopes.length <= n) {
|
||||
return null;
|
||||
}
|
||||
return state.scopes[state.scopes.length - 1];
|
||||
return state.scopes[state.scopes.length - (n + 1)];
|
||||
}
|
||||
|
||||
// tokenizers
|
||||
function tokenBase(stream, state) {
|
||||
// Handle multiline comments
|
||||
if (stream.match(/^#=/, false)) {
|
||||
state.tokenize = tokenComment;
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
|
||||
// Handle scope changes
|
||||
var leaving_expr = state.leaving_expr;
|
||||
if(stream.sol()) {
|
||||
leaving_expr = false;
|
||||
var leavingExpr = state.leavingExpr;
|
||||
if (stream.sol()) {
|
||||
leavingExpr = false;
|
||||
}
|
||||
state.leaving_expr = false;
|
||||
if(leaving_expr) {
|
||||
if(stream.match(/^'+/)) {
|
||||
return 'operator';
|
||||
state.leavingExpr = false;
|
||||
|
||||
if (leavingExpr) {
|
||||
if (stream.match(/^'+/)) {
|
||||
return "operator";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(stream.match(/^\.{2,3}/)) {
|
||||
return 'operator';
|
||||
if (stream.match(/^\.{2,3}/)) {
|
||||
return "operator";
|
||||
}
|
||||
|
||||
if (stream.eatSpace()) {
|
||||
|
@ -76,106 +99,103 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
|
|||
}
|
||||
|
||||
var ch = stream.peek();
|
||||
// Handle Comments
|
||||
|
||||
// Handle single line comments
|
||||
if (ch === '#') {
|
||||
stream.skipToEnd();
|
||||
return 'comment';
|
||||
}
|
||||
if(ch==='[') {
|
||||
state.scopes.push("[");
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
|
||||
if(ch==='{') {
|
||||
state.scopes.push("{");
|
||||
if (ch === '[') {
|
||||
state.scopes.push('[');
|
||||
}
|
||||
|
||||
var scope=cur_scope(state);
|
||||
if (ch === '(') {
|
||||
state.scopes.push('(');
|
||||
}
|
||||
|
||||
if(scope==='[' && ch===']') {
|
||||
var scope = currentScope(state);
|
||||
|
||||
if (inArray(state) && ch === ']') {
|
||||
if (scope === "for") { state.scopes.pop(); }
|
||||
state.scopes.pop();
|
||||
state.leaving_expr=true;
|
||||
state.leavingExpr = true;
|
||||
}
|
||||
|
||||
if(scope==='{' && ch==='}') {
|
||||
if (inGenerator(state) && ch === ')') {
|
||||
if (scope === "for") { state.scopes.pop(); }
|
||||
state.scopes.pop();
|
||||
state.leaving_expr=true;
|
||||
}
|
||||
|
||||
if(ch===')') {
|
||||
state.leaving_expr = true;
|
||||
state.leavingExpr = true;
|
||||
}
|
||||
|
||||
var match;
|
||||
if(!in_array(state) && (match=stream.match(openers, false))) {
|
||||
state.scopes.push(match);
|
||||
if (match = stream.match(openers, false)) {
|
||||
state.scopes.push(match[0]);
|
||||
}
|
||||
|
||||
if(!in_array(state) && stream.match(closers, false)) {
|
||||
if (stream.match(closers, false)) {
|
||||
state.scopes.pop();
|
||||
}
|
||||
|
||||
if(in_array(state)) {
|
||||
if(stream.match(/^end/)) {
|
||||
return 'number';
|
||||
if (inArray(state)) {
|
||||
if (state.lastToken == "end" && stream.match(/^:/)) {
|
||||
return "operator";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(stream.match(/^=>/)) {
|
||||
return 'operator';
|
||||
}
|
||||
|
||||
|
||||
// Handle Number Literals
|
||||
if (stream.match(/^[0-9\.]/, false)) {
|
||||
var imMatcher = RegExp(/^im\b/);
|
||||
var floatLiteral = false;
|
||||
// Floats
|
||||
if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
|
||||
if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
|
||||
if (stream.match(/^\.\d+/)) { floatLiteral = true; }
|
||||
if (floatLiteral) {
|
||||
// Float literals may be "imaginary"
|
||||
stream.match(imMatcher);
|
||||
state.leaving_expr = true;
|
||||
return 'number';
|
||||
}
|
||||
// Integers
|
||||
var intLiteral = false;
|
||||
// Hex
|
||||
if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; }
|
||||
// Binary
|
||||
if (stream.match(/^0b[01]+/i)) { intLiteral = true; }
|
||||
// Octal
|
||||
if (stream.match(/^0o[0-7]+/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) {
|
||||
// Integer literals may be "long"
|
||||
stream.match(imMatcher);
|
||||
state.leaving_expr = true;
|
||||
return 'number';
|
||||
if (stream.match(/^end/)) {
|
||||
return "number";
|
||||
}
|
||||
}
|
||||
|
||||
if(stream.match(/^(::)|(<:)/)) {
|
||||
return 'operator';
|
||||
// Handle type annotations
|
||||
if (stream.match(/^::(?![:\$])/)) {
|
||||
state.tokenize = tokenAnnotation;
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
|
||||
// Handle symbols
|
||||
if(!leaving_expr && stream.match(symbol)) {
|
||||
return 'string';
|
||||
if (!leavingExpr && stream.match(symbol) || stream.match(/:\./)) {
|
||||
return "builtin";
|
||||
}
|
||||
|
||||
// Handle parametric types
|
||||
if (stream.match(/^{[^}]*}(?=\()/)) {
|
||||
return "builtin";
|
||||
}
|
||||
|
||||
// Handle operators and Delimiters
|
||||
if (stream.match(operators)) {
|
||||
return 'operator';
|
||||
return "operator";
|
||||
}
|
||||
|
||||
// Handle Number Literals
|
||||
if (stream.match(/^[0-9\.]/, false)) {
|
||||
var imMatcher = RegExp(/^im\b/);
|
||||
var numberLiteral = false;
|
||||
// Floats
|
||||
if (stream.match(/^\d*\.(?!\.)\d*([Eef][\+\-]?\d+)?/i)) { numberLiteral = true; }
|
||||
if (stream.match(/^\d+\.(?!\.)\d*/)) { numberLiteral = true; }
|
||||
if (stream.match(/^\.\d+/)) { numberLiteral = true; }
|
||||
if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { numberLiteral = true; }
|
||||
// Integers
|
||||
if (stream.match(/^0x[0-9a-f]+/i)) { numberLiteral = true; } // Hex
|
||||
if (stream.match(/^0b[01]+/i)) { numberLiteral = true; } // Binary
|
||||
if (stream.match(/^0o[0-7]+/i)) { numberLiteral = true; } // Octal
|
||||
if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { numberLiteral = true; } // Decimal
|
||||
// Zero by itself with no other piece of number.
|
||||
if (stream.match(/^0(?![\dx])/i)) { numberLiteral = true; }
|
||||
if (numberLiteral) {
|
||||
// Integer literals may be "long"
|
||||
stream.match(imMatcher);
|
||||
state.leavingExpr = true;
|
||||
return "number";
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Chars
|
||||
if (stream.match(/^'/)) {
|
||||
state.tokenize = tokenChar;
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
|
||||
// Handle Strings
|
||||
if (stream.match(stringPrefixes)) {
|
||||
|
@ -184,111 +204,202 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
|
|||
}
|
||||
|
||||
if (stream.match(macro)) {
|
||||
return 'meta';
|
||||
return "meta";
|
||||
}
|
||||
|
||||
|
||||
if (stream.match(delimiters)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (stream.match(keywords)) {
|
||||
return 'keyword';
|
||||
return "keyword";
|
||||
}
|
||||
|
||||
if (stream.match(builtins)) {
|
||||
return 'builtin';
|
||||
return "builtin";
|
||||
}
|
||||
|
||||
var isDefinition = state.isDefinition || state.lastToken == "function" ||
|
||||
state.lastToken == "macro" || state.lastToken == "type" ||
|
||||
state.lastToken == "immutable";
|
||||
|
||||
if (stream.match(identifiers)) {
|
||||
state.leaving_expr=true;
|
||||
return 'variable';
|
||||
if (isDefinition) {
|
||||
if (stream.peek() === '.') {
|
||||
state.isDefinition = true;
|
||||
return "variable";
|
||||
}
|
||||
state.isDefinition = false;
|
||||
return "def";
|
||||
}
|
||||
if (stream.match(/^({[^}]*})*\(/, false)) {
|
||||
return callOrDef(stream, state);
|
||||
}
|
||||
state.leavingExpr = true;
|
||||
return "variable";
|
||||
}
|
||||
|
||||
// Handle non-detected items
|
||||
stream.next();
|
||||
return ERRORCLASS;
|
||||
return "error";
|
||||
}
|
||||
|
||||
function callOrDef(stream, state) {
|
||||
var match = stream.match(/^(\(\s*)/);
|
||||
if (match) {
|
||||
if (state.firstParenPos < 0)
|
||||
state.firstParenPos = state.scopes.length;
|
||||
state.scopes.push('(');
|
||||
state.charsAdvanced += match[1].length;
|
||||
}
|
||||
if (currentScope(state) == '(' && stream.match(/^\)/)) {
|
||||
state.scopes.pop();
|
||||
state.charsAdvanced += 1;
|
||||
if (state.scopes.length <= state.firstParenPos) {
|
||||
var isDefinition = stream.match(/^\s*?=(?!=)/, false);
|
||||
stream.backUp(state.charsAdvanced);
|
||||
state.firstParenPos = -1;
|
||||
state.charsAdvanced = 0;
|
||||
if (isDefinition)
|
||||
return "def";
|
||||
return "builtin";
|
||||
}
|
||||
}
|
||||
// Unfortunately javascript does not support multiline strings, so we have
|
||||
// to undo anything done upto here if a function call or definition splits
|
||||
// over two or more lines.
|
||||
if (stream.match(/^$/g, false)) {
|
||||
stream.backUp(state.charsAdvanced);
|
||||
while (state.scopes.length > state.firstParenPos)
|
||||
state.scopes.pop();
|
||||
state.firstParenPos = -1;
|
||||
state.charsAdvanced = 0;
|
||||
return "builtin";
|
||||
}
|
||||
state.charsAdvanced += stream.match(/^([^()]*)/)[1].length;
|
||||
return callOrDef(stream, state);
|
||||
}
|
||||
|
||||
function tokenAnnotation(stream, state) {
|
||||
stream.match(/.*?(?=,|;|{|}|\(|\)|=|$|\s)/);
|
||||
if (stream.match(/^{/)) {
|
||||
state.nestedLevels++;
|
||||
} else if (stream.match(/^}/)) {
|
||||
state.nestedLevels--;
|
||||
}
|
||||
if (state.nestedLevels > 0) {
|
||||
stream.match(/.*?(?={|})/);
|
||||
} else if (state.nestedLevels == 0) {
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
return "builtin";
|
||||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
if (stream.match(/^#=/)) {
|
||||
state.nestedLevels++;
|
||||
}
|
||||
if (!stream.match(/.*?(?=(#=|=#))/)) {
|
||||
stream.skipToEnd();
|
||||
}
|
||||
if (stream.match(/^=#/)) {
|
||||
state.nestedLevels--;
|
||||
if (state.nestedLevels == 0)
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function tokenChar(stream, state) {
|
||||
var isChar = false, match;
|
||||
if (stream.match(chars)) {
|
||||
isChar = true;
|
||||
} else if (match = stream.match(/\\u([a-f0-9]{1,4})(?=')/i)) {
|
||||
var value = parseInt(match[1], 16);
|
||||
if (value <= 55295 || value >= 57344) { // (U+0,U+D7FF), (U+E000,U+FFFF)
|
||||
isChar = true;
|
||||
stream.next();
|
||||
}
|
||||
} else if (match = stream.match(/\\U([A-Fa-f0-9]{5,8})(?=')/)) {
|
||||
var value = parseInt(match[1], 16);
|
||||
if (value <= 1114111) { // U+10FFFF
|
||||
isChar = true;
|
||||
stream.next();
|
||||
}
|
||||
}
|
||||
if (isChar) {
|
||||
state.leavingExpr = true;
|
||||
state.tokenize = tokenBase;
|
||||
return "string";
|
||||
}
|
||||
if (!stream.match(/^[^']+(?=')/)) { stream.skipToEnd(); }
|
||||
if (stream.match(/^'/)) { state.tokenize = tokenBase; }
|
||||
return "error";
|
||||
}
|
||||
|
||||
function tokenStringFactory(delimiter) {
|
||||
while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
|
||||
delimiter = delimiter.substr(1);
|
||||
}
|
||||
var singleline = delimiter.length == 1;
|
||||
var OUTCLASS = 'string';
|
||||
|
||||
delimiter = (delimiter === '`' || delimiter === '"""') ? delimiter : '"';
|
||||
function tokenString(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 (stream.eat('\\')) {
|
||||
stream.next();
|
||||
} else if (stream.match(delimiter)) {
|
||||
state.tokenize = tokenBase;
|
||||
state.leavingExpr = true;
|
||||
return "string";
|
||||
} else {
|
||||
stream.eat(/[`"]/);
|
||||
}
|
||||
if (singleline) {
|
||||
if (parserConf.singleLineStringErrors) {
|
||||
return ERRORCLASS;
|
||||
} else {
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
}
|
||||
return OUTCLASS;
|
||||
stream.eatWhile(/[^\\`"]/);
|
||||
return "string";
|
||||
}
|
||||
tokenString.isString = true;
|
||||
return tokenString;
|
||||
}
|
||||
|
||||
function tokenLexer(stream, state) {
|
||||
var style = state.tokenize(stream, state);
|
||||
var current = stream.current();
|
||||
|
||||
// Handle '.' connected identifiers
|
||||
if (current === '.') {
|
||||
style = stream.match(identifiers, false) ? null : ERRORCLASS;
|
||||
if (style === null && state.lastStyle === 'meta') {
|
||||
// Apply 'meta' style to '.' connected identifiers when
|
||||
// appropriate.
|
||||
style = 'meta';
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
var external = {
|
||||
startState: function() {
|
||||
return {
|
||||
tokenize: tokenBase,
|
||||
scopes: [],
|
||||
leaving_expr: false
|
||||
lastToken: null,
|
||||
leavingExpr: false,
|
||||
isDefinition: false,
|
||||
nestedLevels: 0,
|
||||
charsAdvanced: 0,
|
||||
firstParenPos: -1
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var style = tokenLexer(stream, state);
|
||||
state.lastStyle = style;
|
||||
var style = state.tokenize(stream, state);
|
||||
var current = stream.current();
|
||||
|
||||
if (current && style) {
|
||||
state.lastToken = current;
|
||||
}
|
||||
|
||||
// Handle '.' connected identifiers
|
||||
if (current === '.') {
|
||||
style = stream.match(identifiers, false) || stream.match(macro, false) ||
|
||||
stream.match(/\(/, false) ? "operator" : "error";
|
||||
}
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
var delta = 0;
|
||||
if(textAfter=="end" || textAfter=="]" || textAfter=="}" || textAfter=="else" || textAfter=="elseif" || textAfter=="catch" || textAfter=="finally") {
|
||||
if ( textAfter === ']' || textAfter === ')' || textAfter === "end" ||
|
||||
textAfter === "else" || textAfter === "catch" || textAfter === "elseif" ||
|
||||
textAfter === "finally" ) {
|
||||
delta = -1;
|
||||
}
|
||||
return (state.scopes.length + delta) * _conf.indentUnit;
|
||||
return (state.scopes.length + delta) * config.indentUnit;
|
||||
},
|
||||
|
||||
electricInput: /\b(end|else|catch|finally)\b/,
|
||||
blockCommentStart: "#=",
|
||||
blockCommentEnd: "=#",
|
||||
lineComment: "#",
|
||||
fold: "indent",
|
||||
electricChars: "edlsifyh]}"
|
||||
fold: "indent"
|
||||
};
|
||||
return external;
|
||||
});
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
startState: function(){
|
||||
return {
|
||||
next: 'start',
|
||||
lastToken: null
|
||||
lastToken: {style: null, indent: 0, content: ""}
|
||||
};
|
||||
},
|
||||
token: function(stream, state){
|
||||
|
|
187
app/public/codemirror/mode/markdown/markdown.js
vendored
187
app/public/codemirror/mode/markdown/markdown.js
vendored
|
@ -13,8 +13,8 @@
|
|||
|
||||
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
||||
|
||||
var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
|
||||
var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
|
||||
var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
|
||||
var htmlModeMissing = htmlMode.name == "null"
|
||||
|
||||
function getMode(name) {
|
||||
if (CodeMirror.findModeByName) {
|
||||
|
@ -55,8 +55,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
if (modeCfg.tokenTypeOverrides === undefined)
|
||||
modeCfg.tokenTypeOverrides = {};
|
||||
|
||||
var codeDepth = 0;
|
||||
|
||||
var tokenTypes = {
|
||||
header: "header",
|
||||
code: "comment",
|
||||
|
@ -65,7 +63,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
list2: "variable-3",
|
||||
list3: "keyword",
|
||||
hr: "hr",
|
||||
image: "tag",
|
||||
image: "image",
|
||||
imageAltText: "image-alt-text",
|
||||
imageMarker: "image-marker",
|
||||
formatting: "formatting",
|
||||
linkInline: "link",
|
||||
linkEmail: "link",
|
||||
|
@ -83,14 +83,13 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
}
|
||||
|
||||
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
|
||||
, ulRE = /^[*\-+]\s+/
|
||||
, olRE = /^[0-9]+([.)])\s+/
|
||||
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
|
||||
, listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
|
||||
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow listRE
|
||||
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
|
||||
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
|
||||
, textRE = /^[^#!\[\]*_\\<>` "'(~]+/
|
||||
, fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
|
||||
")[ \\t]*([\\w+#]*)");
|
||||
")[ \\t]*([\\w+#\-]*)");
|
||||
|
||||
function switchInline(stream, state, f) {
|
||||
state.f = state.inline = f;
|
||||
|
@ -121,7 +120,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
state.quote = 0;
|
||||
// Reset state.indentedCode
|
||||
state.indentedCode = false;
|
||||
if (!htmlFound && state.f == htmlBlock) {
|
||||
if (htmlModeMissing && state.f == htmlBlock) {
|
||||
state.f = inlineNormal;
|
||||
state.block = blockNormal;
|
||||
}
|
||||
|
@ -151,10 +150,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
state.list = null;
|
||||
} else if (state.indentation > 0) {
|
||||
state.list = null;
|
||||
state.listDepth = Math.floor(state.indentation / 4);
|
||||
} else { // No longer a list
|
||||
state.list = false;
|
||||
state.listDepth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,17 +188,21 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
} else if (stream.match(hrRE, true)) {
|
||||
state.hr = true;
|
||||
return tokenTypes.hr;
|
||||
} else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
|
||||
var listType = null;
|
||||
if (stream.match(ulRE, true)) {
|
||||
listType = 'ul';
|
||||
} else {
|
||||
stream.match(olRE, true);
|
||||
listType = 'ol';
|
||||
}
|
||||
} else if (match = stream.match(listRE)) {
|
||||
var listType = match[1] ? "ol" : "ul";
|
||||
state.indentation = stream.column() + stream.current().length;
|
||||
state.list = true;
|
||||
state.listDepth++;
|
||||
|
||||
// While this list item's marker's indentation
|
||||
// is less than the deepest list item's content's indentation,
|
||||
// pop the deepest list item indentation off the stack.
|
||||
while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
|
||||
state.listStack.pop();
|
||||
}
|
||||
|
||||
// Add this list item's content's indentation to the stack
|
||||
state.listStack.push(state.indentation);
|
||||
|
||||
if (modeCfg.taskLists && stream.match(taskListRE, false)) {
|
||||
state.taskList = true;
|
||||
}
|
||||
|
@ -212,10 +213,10 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
state.fencedChars = match[1]
|
||||
// try switching mode
|
||||
state.localMode = getMode(match[2]);
|
||||
if (state.localMode) state.localState = state.localMode.startState();
|
||||
if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
|
||||
state.f = state.block = local;
|
||||
if (modeCfg.highlightFormatting) state.formatting = "code-block";
|
||||
state.code = true;
|
||||
state.code = -1
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
|
@ -224,21 +225,27 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
|
||||
function htmlBlock(stream, state) {
|
||||
var style = htmlMode.token(stream, state.htmlState);
|
||||
if ((htmlFound && state.htmlState.tagStart === null &&
|
||||
(!state.htmlState.context && state.htmlState.tokenize.isInText)) ||
|
||||
(state.md_inside && stream.current().indexOf(">") > -1)) {
|
||||
state.f = inlineNormal;
|
||||
state.block = blockNormal;
|
||||
state.htmlState = null;
|
||||
if (!htmlModeMissing) {
|
||||
var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
|
||||
if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
|
||||
(!inner.state.context && inner.state.tokenize.isInText)) ||
|
||||
(state.md_inside && stream.current().indexOf(">") > -1)) {
|
||||
state.f = inlineNormal;
|
||||
state.block = blockNormal;
|
||||
state.htmlState = null;
|
||||
}
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
function local(stream, state) {
|
||||
if (stream.sol() && state.fencedChars && stream.match(state.fencedChars, false)) {
|
||||
if (state.fencedChars && stream.match(state.fencedChars)) {
|
||||
if (modeCfg.highlightFormatting) state.formatting = "code-block";
|
||||
state.localMode = state.localState = null;
|
||||
state.f = state.block = leavingLocal;
|
||||
return null;
|
||||
return getType(state)
|
||||
} else if (state.fencedChars && stream.skipTo(state.fencedChars)) {
|
||||
return "comment"
|
||||
} else if (state.localMode) {
|
||||
return state.localMode.token(stream, state.localState);
|
||||
} else {
|
||||
|
@ -253,9 +260,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
state.f = inlineNormal;
|
||||
state.fencedChars = null;
|
||||
if (modeCfg.highlightFormatting) state.formatting = "code-block";
|
||||
state.code = true;
|
||||
state.code = 1
|
||||
var returnType = getType(state);
|
||||
state.code = false;
|
||||
state.code = 0
|
||||
return returnType;
|
||||
}
|
||||
|
||||
|
@ -304,6 +311,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
|
||||
if (state.linkText) { styles.push(tokenTypes.linkText); }
|
||||
if (state.code) { styles.push(tokenTypes.code); }
|
||||
if (state.image) { styles.push(tokenTypes.image); }
|
||||
if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
|
||||
if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
|
||||
}
|
||||
|
||||
if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
|
||||
|
@ -320,7 +330,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
}
|
||||
|
||||
if (state.list !== false) {
|
||||
var listMod = (state.listDepth - 1) % 3;
|
||||
var listMod = (state.listStack.length - 1) % 3;
|
||||
if (!listMod) {
|
||||
styles.push(tokenTypes.list1);
|
||||
} else if (listMod === 1) {
|
||||
|
@ -378,15 +388,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
|
||||
var ch = stream.next();
|
||||
|
||||
if (ch === '\\') {
|
||||
stream.next();
|
||||
if (modeCfg.highlightFormatting) {
|
||||
var type = getType(state);
|
||||
var formattingEscape = tokenTypes.formatting + "-escape";
|
||||
return type ? type + " " + formattingEscape : formattingEscape;
|
||||
}
|
||||
}
|
||||
|
||||
// Matches link titles present on next line
|
||||
if (state.linkTitle) {
|
||||
state.linkTitle = false;
|
||||
|
@ -405,39 +406,62 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
if (ch === '`') {
|
||||
var previousFormatting = state.formatting;
|
||||
if (modeCfg.highlightFormatting) state.formatting = "code";
|
||||
var t = getType(state);
|
||||
var before = stream.pos;
|
||||
stream.eatWhile('`');
|
||||
var difference = 1 + stream.pos - before;
|
||||
if (!state.code) {
|
||||
codeDepth = difference;
|
||||
state.code = true;
|
||||
return getType(state);
|
||||
var count = stream.current().length
|
||||
if (state.code == 0) {
|
||||
state.code = count
|
||||
return getType(state)
|
||||
} else if (count == state.code) { // Must be exact
|
||||
var t = getType(state)
|
||||
state.code = 0
|
||||
return t
|
||||
} else {
|
||||
if (difference === codeDepth) { // Must be exact
|
||||
state.code = false;
|
||||
return t;
|
||||
}
|
||||
state.formatting = previousFormatting;
|
||||
return getType(state);
|
||||
state.formatting = previousFormatting
|
||||
return getType(state)
|
||||
}
|
||||
} else if (state.code) {
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
|
||||
stream.match(/\[[^\]]*\]/);
|
||||
state.inline = state.f = linkHref;
|
||||
return tokenTypes.image;
|
||||
if (ch === '\\') {
|
||||
stream.next();
|
||||
if (modeCfg.highlightFormatting) {
|
||||
var type = getType(state);
|
||||
var formattingEscape = tokenTypes.formatting + "-escape";
|
||||
return type ? type + " " + formattingEscape : formattingEscape;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) {
|
||||
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
|
||||
state.imageMarker = true;
|
||||
state.image = true;
|
||||
if (modeCfg.highlightFormatting) state.formatting = "image";
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
|
||||
state.imageMarker = false;
|
||||
state.imageAltText = true
|
||||
if (modeCfg.highlightFormatting) state.formatting = "image";
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
if (ch === ']' && state.imageAltText) {
|
||||
if (modeCfg.highlightFormatting) state.formatting = "image";
|
||||
var type = getType(state);
|
||||
state.imageAltText = false;
|
||||
state.image = false;
|
||||
state.inline = state.f = linkHref;
|
||||
return type;
|
||||
}
|
||||
|
||||
if (ch === '[' && stream.match(/[^\]]*\](\(.*\)| ?\[.*?\])/, false) && !state.image) {
|
||||
state.linkText = true;
|
||||
if (modeCfg.highlightFormatting) state.formatting = "link";
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
if (ch === ']' && state.linkText && stream.match(/\(.*\)| ?\[.*\]/, false)) {
|
||||
if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) {
|
||||
if (modeCfg.highlightFormatting) state.formatting = "link";
|
||||
var type = getType(state);
|
||||
state.linkText = false;
|
||||
|
@ -469,7 +493,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
return type + tokenTypes.linkEmail;
|
||||
}
|
||||
|
||||
if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
|
||||
if (ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
|
||||
var end = stream.string.indexOf(">", stream.pos);
|
||||
if (end != -1) {
|
||||
var atts = stream.string.substring(stream.start, end);
|
||||
|
@ -590,7 +614,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
}
|
||||
var ch = stream.next();
|
||||
if (ch === '(' || ch === '[') {
|
||||
state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
|
||||
state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]", 0);
|
||||
if (modeCfg.highlightFormatting) state.formatting = "link-string";
|
||||
state.linkHref = true;
|
||||
return getType(state);
|
||||
|
@ -598,6 +622,11 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
return 'error';
|
||||
}
|
||||
|
||||
var linkRE = {
|
||||
")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
|
||||
"]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/
|
||||
}
|
||||
|
||||
function getLinkHrefInside(endChar) {
|
||||
return function(stream, state) {
|
||||
var ch = stream.next();
|
||||
|
@ -610,10 +639,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
return returnState;
|
||||
}
|
||||
|
||||
if (stream.match(inlineRE(endChar), true)) {
|
||||
stream.backUp(1);
|
||||
}
|
||||
|
||||
stream.match(linkRE[endChar])
|
||||
state.linkHref = true;
|
||||
return getType(state);
|
||||
};
|
||||
|
@ -661,18 +687,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
return tokenTypes.linkHref + " url";
|
||||
}
|
||||
|
||||
var savedInlineRE = [];
|
||||
function inlineRE(endChar) {
|
||||
if (!savedInlineRE[endChar]) {
|
||||
// Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
|
||||
endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
||||
// Match any non-endChar, escaped character, as well as the closing
|
||||
// endChar.
|
||||
savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
|
||||
}
|
||||
return savedInlineRE[endChar];
|
||||
}
|
||||
|
||||
var mode = {
|
||||
startState: function() {
|
||||
return {
|
||||
|
@ -692,13 +706,14 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
linkText: false,
|
||||
linkHref: false,
|
||||
linkTitle: false,
|
||||
code: 0,
|
||||
em: false,
|
||||
strong: false,
|
||||
header: 0,
|
||||
hr: false,
|
||||
taskList: false,
|
||||
list: false,
|
||||
listDepth: 0,
|
||||
listStack: [],
|
||||
quote: 0,
|
||||
trailingSpace: 0,
|
||||
trailingSpaceNewLine: false,
|
||||
|
@ -733,7 +748,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
hr: s.hr,
|
||||
taskList: s.taskList,
|
||||
list: s.list,
|
||||
listDepth: s.listDepth,
|
||||
listStack: s.listStack.slice(0),
|
||||
quote: s.quote,
|
||||
indentedCode: s.indentedCode,
|
||||
trailingSpace: s.trailingSpace,
|
||||
|
@ -773,11 +788,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
|
||||
state.f = state.block;
|
||||
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
|
||||
var difference = Math.floor((indentation - state.indentation) / 4) * 4;
|
||||
if (difference > 4) difference = 4;
|
||||
var adjustedIndentation = state.indentation + difference;
|
||||
state.indentationDiff = adjustedIndentation - state.indentation;
|
||||
state.indentation = adjustedIndentation;
|
||||
state.indentationDiff = Math.min(indentation - state.indentation, 4);
|
||||
state.indentation = state.indentation + state.indentationDiff;
|
||||
if (indentation > 0) return null;
|
||||
}
|
||||
return state.f(stream, state);
|
||||
|
@ -793,6 +805,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|||
|
||||
getType: getType,
|
||||
|
||||
closeBrackets: "()[]{}''\"\"``",
|
||||
fold: "markdown"
|
||||
};
|
||||
return mode;
|
||||
|
|
57
app/public/codemirror/mode/markdown/test.js
vendored
57
app/public/codemirror/mode/markdown/test.js
vendored
|
@ -22,6 +22,8 @@
|
|||
"list3" : "override-list3",
|
||||
"hr" : "override-hr",
|
||||
"image" : "override-image",
|
||||
"imageAltText": "override-image-alt-text",
|
||||
"imageMarker": "override-image-marker",
|
||||
"linkInline" : "override-link-inline",
|
||||
"linkEmail" : "override-link-email",
|
||||
"linkText" : "override-link-text",
|
||||
|
@ -89,6 +91,9 @@
|
|||
FT("formatting_escape",
|
||||
"[formatting-escape \\*]");
|
||||
|
||||
FT("formatting_image",
|
||||
"[formatting&formatting-image&image&image-marker !][formatting&formatting-image&image&image-alt-text&link [[][image&image-alt-text&link alt text][formatting&formatting-image&image&image-alt-text&link ]]][formatting&formatting-link-string&string&url (][url&string http://link.to/image.jpg][formatting&formatting-link-string&string&url )]");
|
||||
|
||||
MT("plainText",
|
||||
"foo");
|
||||
|
||||
|
@ -352,11 +357,10 @@
|
|||
"[variable-2 1. foo]",
|
||||
"[variable-2 2. bar]");
|
||||
|
||||
// Lists require a preceding blank line (per Dingus)
|
||||
MT("listBogus",
|
||||
MT("listFromParagraph",
|
||||
"foo",
|
||||
"1. bar",
|
||||
"2. hello");
|
||||
"[variable-2 1. bar]",
|
||||
"[variable-2 2. hello]");
|
||||
|
||||
// List after hr
|
||||
MT("listAfterHr",
|
||||
|
@ -452,6 +456,18 @@
|
|||
"",
|
||||
"hello");
|
||||
|
||||
MT("listCommonMarkIndentationCode",
|
||||
"[variable-2 * Code blocks also affect]",
|
||||
" [variable-3 * The next level starts where the contents start.]",
|
||||
" [variable-3 * Anything less than that will keep the item on the same level.]",
|
||||
" [variable-3 * Each list item can indent the first level further and further.]",
|
||||
" [variable-3 * For the most part, this makes sense while writing a list.]",
|
||||
" [keyword * This means two items with same indentation can be different levels.]",
|
||||
" [keyword * Each level has an indent requirement that can change between items.]",
|
||||
" [keyword * A list item that meets this will be part of the next level.]",
|
||||
" [variable-3 * Otherwise, it will be part of the level where it does meet this.]",
|
||||
" [variable-2 * World]");
|
||||
|
||||
// Blockquote
|
||||
MT("blockquote",
|
||||
"[variable-2 * foo]",
|
||||
|
@ -577,6 +593,20 @@
|
|||
MT("hrDashLong",
|
||||
"[hr ---------------------------------------]");
|
||||
|
||||
//Images
|
||||
MT("Images",
|
||||
"[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)]")
|
||||
|
||||
//Images with highlight alt text
|
||||
MT("imageEm",
|
||||
"[image&image-marker !][image&image-alt-text&link [[][image-alt-text&em&image&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
|
||||
|
||||
MT("imageStrong",
|
||||
"[image&image-marker !][image&image-alt-text&link [[][image-alt-text&strong&image&link **alt text**][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
|
||||
|
||||
MT("imageEmStrong",
|
||||
"[image&image-marker !][image&image-alt-text&link [[][image-alt-text&image&strong&link **][image&image-alt-text&em&strong&link *alt text**][image&image-alt-text&em&link *][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
|
||||
|
||||
// Inline link with title
|
||||
MT("linkTitle",
|
||||
"[link [[foo]]][string&url (http://example.com/ \"bar\")] hello");
|
||||
|
@ -587,7 +617,7 @@
|
|||
|
||||
// Inline link with image
|
||||
MT("linkImage",
|
||||
"[link [[][tag ![[foo]]][string&url (http://example.com/)][link ]]][string&url (http://example.com/)] bar");
|
||||
"[link [[][link&image&image-marker !][link&image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)][link ]]][string&url (http://example.com/)] bar");
|
||||
|
||||
// Inline link with Em
|
||||
MT("linkEm",
|
||||
|
@ -603,15 +633,15 @@
|
|||
|
||||
// Image with title
|
||||
MT("imageTitle",
|
||||
"[tag ![[foo]]][string&url (http://example.com/ \"bar\")] hello");
|
||||
"[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/ \"bar\")] hello");
|
||||
|
||||
// Image without title
|
||||
MT("imageNoTitle",
|
||||
"[tag ![[foo]]][string&url (http://example.com/)] bar");
|
||||
"[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/)] bar");
|
||||
|
||||
// Image with asterisks
|
||||
MT("imageAsterisks",
|
||||
"[tag ![[*foo*]]][string&url (http://example.com/)] bar");
|
||||
"[image&image-marker !][image&image-alt-text&link [[ ][image&image-alt-text&em&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)] bar");
|
||||
|
||||
// Not a link. Should be normal text due to square brackets being used
|
||||
// regularly in text, especially in quoted material, and no space is allowed
|
||||
|
@ -635,7 +665,7 @@
|
|||
MT("linkReferenceEmStrong",
|
||||
"[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string&url [[bar]]] hello");
|
||||
|
||||
// Reference-style links with optional space separator (per docuentation)
|
||||
// Reference-style links with optional space separator (per documentation)
|
||||
// "You can optionally use a space to separate the sets of brackets"
|
||||
MT("linkReferenceSpace",
|
||||
"[link [[foo]]] [string&url [[bar]]] hello");
|
||||
|
@ -671,7 +701,7 @@
|
|||
MT("labelTitleSingleQuotes",
|
||||
"[link [[foo]]:] [string&url http://example.com/ 'bar']");
|
||||
|
||||
MT("labelTitleParenthese",
|
||||
MT("labelTitleParentheses",
|
||||
"[link [[foo]]:] [string&url http://example.com/ (bar)]");
|
||||
|
||||
MT("labelTitleInvalid",
|
||||
|
@ -688,7 +718,7 @@
|
|||
"[link [[foo]]:] [string&url http://example.com/]",
|
||||
"[string 'bar'] hello");
|
||||
|
||||
MT("labelTitleNextParenthese",
|
||||
MT("labelTitleNextParentheses",
|
||||
"[link [[foo]]:] [string&url http://example.com/]",
|
||||
"[string (bar)] hello");
|
||||
|
||||
|
@ -770,6 +800,9 @@
|
|||
MT("emStrongMixed",
|
||||
"[em *foo][em&strong __bar_hello** world]");
|
||||
|
||||
MT("linkWithNestedParens",
|
||||
"[link [[foo]]][string&url (bar(baz))]")
|
||||
|
||||
// These characters should be escaped:
|
||||
// \ backslash
|
||||
// ` backtick
|
||||
|
@ -863,7 +896,7 @@
|
|||
"[override-hr * * *]");
|
||||
|
||||
TokenTypeOverrideTest("overrideImage",
|
||||
"[override-image ![[foo]]][override-link-href&url (http://example.com/)]")
|
||||
"[override-image&override-image-marker !][override-image&override-image-alt-text&link [[alt text]]][override-link-href&url (http://link.to/image.jpg)]");
|
||||
|
||||
TokenTypeOverrideTest("overrideLinkText",
|
||||
"[override-link-text [[foo]]][override-link-href&url (http://example.com)]");
|
||||
|
|
|
@ -126,6 +126,7 @@ CodeMirror.defineMode('mathematica', function(_config, _parserConfig) {
|
|||
}
|
||||
|
||||
// everything else is an error
|
||||
stream.next(); // advance the stream.
|
||||
return 'error';
|
||||
}
|
||||
|
||||
|
|
44
app/public/codemirror/mode/mbox/index.html
vendored
Executable file
44
app/public/codemirror/mode/mbox/index.html
vendored
Executable file
|
@ -0,0 +1,44 @@
|
|||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: mbox 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="mbox.js"></script>
|
||||
<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 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 href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">mbox</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>mbox mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
From timothygu99@gmail.com Sun Apr 17 01:40:43 2016
|
||||
From: Timothy Gu <timothygu99@gmail.com>
|
||||
Date: Sat, 16 Apr 2016 18:40:43 -0700
|
||||
Subject: mbox mode
|
||||
Message-ID: <Z8d+bTT50U/az94FZnyPkDjZmW0=@gmail.com>
|
||||
|
||||
mbox mode is working!
|
||||
|
||||
Timothy
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>application/mbox</code>.</p>
|
||||
|
||||
</article>
|
129
app/public/codemirror/mode/mbox/mbox.js
vendored
Executable file
129
app/public/codemirror/mode/mbox/mbox.js
vendored
Executable file
|
@ -0,0 +1,129 @@
|
|||
// 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";
|
||||
|
||||
var rfc2822 = [
|
||||
"From", "Sender", "Reply-To", "To", "Cc", "Bcc", "Message-ID",
|
||||
"In-Reply-To", "References", "Resent-From", "Resent-Sender", "Resent-To",
|
||||
"Resent-Cc", "Resent-Bcc", "Resent-Message-ID", "Return-Path", "Received"
|
||||
];
|
||||
var rfc2822NoEmail = [
|
||||
"Date", "Subject", "Comments", "Keywords", "Resent-Date"
|
||||
];
|
||||
|
||||
CodeMirror.registerHelper("hintWords", "mbox", rfc2822.concat(rfc2822NoEmail));
|
||||
|
||||
var whitespace = /^[ \t]/;
|
||||
var separator = /^From /; // See RFC 4155
|
||||
var rfc2822Header = new RegExp("^(" + rfc2822.join("|") + "): ");
|
||||
var rfc2822HeaderNoEmail = new RegExp("^(" + rfc2822NoEmail.join("|") + "): ");
|
||||
var header = /^[^:]+:/; // Optional fields defined in RFC 2822
|
||||
var email = /^[^ ]+@[^ ]+/;
|
||||
var untilEmail = /^.*?(?=[^ ]+?@[^ ]+)/;
|
||||
var bracketedEmail = /^<.*?>/;
|
||||
var untilBracketedEmail = /^.*?(?=<.*>)/;
|
||||
|
||||
function styleForHeader(header) {
|
||||
if (header === "Subject") return "header";
|
||||
return "string";
|
||||
}
|
||||
|
||||
function readToken(stream, state) {
|
||||
if (stream.sol()) {
|
||||
// From last line
|
||||
state.inSeparator = false;
|
||||
if (state.inHeader && stream.match(whitespace)) {
|
||||
// Header folding
|
||||
return null;
|
||||
} else {
|
||||
state.inHeader = false;
|
||||
state.header = null;
|
||||
}
|
||||
|
||||
if (stream.match(separator)) {
|
||||
state.inHeaders = true;
|
||||
state.inSeparator = true;
|
||||
return "atom";
|
||||
}
|
||||
|
||||
var match;
|
||||
var emailPermitted = false;
|
||||
if ((match = stream.match(rfc2822HeaderNoEmail)) ||
|
||||
(emailPermitted = true) && (match = stream.match(rfc2822Header))) {
|
||||
state.inHeaders = true;
|
||||
state.inHeader = true;
|
||||
state.emailPermitted = emailPermitted;
|
||||
state.header = match[1];
|
||||
return "atom";
|
||||
}
|
||||
|
||||
// Use vim's heuristics: recognize custom headers only if the line is in a
|
||||
// block of legitimate headers.
|
||||
if (state.inHeaders && (match = stream.match(header))) {
|
||||
state.inHeader = true;
|
||||
state.emailPermitted = true;
|
||||
state.header = match[1];
|
||||
return "atom";
|
||||
}
|
||||
|
||||
state.inHeaders = false;
|
||||
stream.skipToEnd();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (state.inSeparator) {
|
||||
if (stream.match(email)) return "link";
|
||||
if (stream.match(untilEmail)) return "atom";
|
||||
stream.skipToEnd();
|
||||
return "atom";
|
||||
}
|
||||
|
||||
if (state.inHeader) {
|
||||
var style = styleForHeader(state.header);
|
||||
|
||||
if (state.emailPermitted) {
|
||||
if (stream.match(bracketedEmail)) return style + " link";
|
||||
if (stream.match(untilBracketedEmail)) return style;
|
||||
}
|
||||
stream.skipToEnd();
|
||||
return style;
|
||||
}
|
||||
|
||||
stream.skipToEnd();
|
||||
return null;
|
||||
};
|
||||
|
||||
CodeMirror.defineMode("mbox", function() {
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
// Is in a mbox separator
|
||||
inSeparator: false,
|
||||
// Is in a mail header
|
||||
inHeader: false,
|
||||
// If bracketed email is permitted. Only applicable when inHeader
|
||||
emailPermitted: false,
|
||||
// Name of current header
|
||||
header: null,
|
||||
// Is in a region of mail headers
|
||||
inHeaders: false
|
||||
};
|
||||
},
|
||||
token: readToken,
|
||||
blankLine: function(state) {
|
||||
state.inHeaders = state.inSeparator = state.inHeader = false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("application/mbox", "mbox");
|
||||
});
|
40
app/public/codemirror/mode/meta.js
vendored
40
app/public/codemirror/mode/meta.js
vendored
|
@ -3,9 +3,9 @@
|
|||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../codemirror"));
|
||||
mod(require("../lib/codemirror"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../codemirror"], mod);
|
||||
define(["../lib/codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
|
@ -21,7 +21,8 @@
|
|||
{name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
|
||||
{name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
|
||||
{name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
|
||||
{name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj"]},
|
||||
{name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]},
|
||||
{name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
|
||||
{name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]},
|
||||
{name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
|
||||
{name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
|
||||
|
@ -40,12 +41,14 @@
|
|||
{name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
|
||||
{name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"},
|
||||
{name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
|
||||
{name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]},
|
||||
{name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
|
||||
{name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
|
||||
{name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
|
||||
{name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
|
||||
{name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
|
||||
{name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
|
||||
{name: "FCL", mime: "text/x-fcl", mode: "fcl"},
|
||||
{name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
|
||||
{name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]},
|
||||
{name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
|
||||
|
@ -53,22 +56,24 @@
|
|||
{name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
|
||||
{name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i},
|
||||
{name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
|
||||
{name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy"]},
|
||||
{name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/},
|
||||
{name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
|
||||
{name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
|
||||
{name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]},
|
||||
{name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
|
||||
{name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
|
||||
{name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
|
||||
{name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]},
|
||||
{name: "HTTP", mime: "message/http", mode: "http"},
|
||||
{name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]},
|
||||
{name: "Jade", mime: "text/x-jade", mode: "jade", ext: ["jade"]},
|
||||
{name: "Pug", mime: "text/x-pug", mode: "pug", ext: ["jade", "pug"], alias: ["jade"]},
|
||||
{name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
|
||||
{name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]},
|
||||
{name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
|
||||
mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
|
||||
{name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
|
||||
{name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
|
||||
{name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]},
|
||||
{name: "Jinja2", mime: "null", mode: "jinja2"},
|
||||
{name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
|
||||
{name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
|
||||
|
@ -80,13 +85,14 @@
|
|||
{name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
|
||||
{name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]},
|
||||
{name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
|
||||
{name: "MUMPS", mime: "text/x-mumps", mode: "mumps"},
|
||||
{name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]},
|
||||
{name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
|
||||
{name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]},
|
||||
{name: "MySQL", mime: "text/x-mysql", mode: "sql"},
|
||||
{name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
|
||||
{name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
|
||||
{name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
|
||||
{name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"]},
|
||||
{name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]},
|
||||
{name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
|
||||
{name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
|
||||
{name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]},
|
||||
|
@ -97,16 +103,19 @@
|
|||
{name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
|
||||
{name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
|
||||
{name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
|
||||
{name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]},
|
||||
{name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]},
|
||||
{name: "Python", mime: "text/x-python", mode: "python", ext: ["py", "pyw"]},
|
||||
{name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]},
|
||||
{name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/},
|
||||
{name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
|
||||
{name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
|
||||
{name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r"], alias: ["rscript"]},
|
||||
{name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r", "R"], alias: ["rscript"]},
|
||||
{name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]},
|
||||
{name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"},
|
||||
{name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]},
|
||||
{name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]},
|
||||
{name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
|
||||
{name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]},
|
||||
{name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
|
||||
{name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
|
||||
{name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
|
||||
|
@ -122,8 +131,8 @@
|
|||
{name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
|
||||
{name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
|
||||
{name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
|
||||
{name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]},
|
||||
{name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
|
||||
{name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
|
||||
{name: "sTeX", mime: "text/x-stex", mode: "stex"},
|
||||
{name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]},
|
||||
{name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]},
|
||||
|
@ -133,20 +142,23 @@
|
|||
{name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
|
||||
{name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
|
||||
{name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
|
||||
{name: "troff", mime: "troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
|
||||
{name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
|
||||
{name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]},
|
||||
{name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
|
||||
{name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
|
||||
{name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
|
||||
{name: "Twig", mime: "text/x-twig", mode: "twig"},
|
||||
{name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]},
|
||||
{name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
|
||||
{name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
|
||||
{name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
|
||||
{name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
|
||||
{name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
|
||||
{name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
|
||||
{name: "Vue.js Component", mimes: ["script/x-vue", "text/x-vue"], mode: "vue", ext: ["vue"]},
|
||||
{name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd", "svg"], alias: ["rss", "wsdl", "xsd"]},
|
||||
{name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
|
||||
{name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
|
||||
{name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]},
|
||||
{name: "YAML", mimes: ["text/x-yaml", "text/yaml"], mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
|
||||
{name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
|
||||
{name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},
|
||||
{name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]},
|
||||
|
@ -166,6 +178,8 @@
|
|||
if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
|
||||
if (info.mimes[j] == mime) return info;
|
||||
}
|
||||
if (/\+xml$/.test(mime)) return CodeMirror.findModeByMIME("application/xml")
|
||||
if (/\+json$/.test(mime)) return CodeMirror.findModeByMIME("application/json")
|
||||
};
|
||||
|
||||
CodeMirror.findModeByExtension = function(ext) {
|
||||
|
|
9
app/public/codemirror/mode/mllike/mllike.js
vendored
9
app/public/codemirror/mode/mllike/mllike.js
vendored
|
@ -83,9 +83,12 @@ CodeMirror.defineMode('mllike', function(_config, parserConfig) {
|
|||
if ( /[+\-*&%=<>!?|]/.test(ch)) {
|
||||
return 'operator';
|
||||
}
|
||||
stream.eatWhile(/\w/);
|
||||
var cur = stream.current();
|
||||
return words.hasOwnProperty(cur) ? words[cur] : 'variable';
|
||||
if (/[\w\xa1-\uffff]/.test(ch)) {
|
||||
stream.eatWhile(/[\w\xa1-\uffff]/);
|
||||
var cur = stream.current();
|
||||
return words.hasOwnProperty(cur) ? words[cur] : 'variable';
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function tokenString(stream, state) {
|
||||
|
|
2
app/public/codemirror/mode/mscgen/index.html
vendored
2
app/public/codemirror/mode/mscgen/index.html
vendored
|
@ -59,7 +59,7 @@ msc {
|
|||
# Xù - expansions to MscGen to support inline expressions
|
||||
# https://github.com/sverweij/mscgen_js/blob/master/wikum/xu.md
|
||||
# More samples: https://sverweij.github.io/mscgen_js
|
||||
msc {
|
||||
xu {
|
||||
hscale="0.8",
|
||||
width="700";
|
||||
|
||||
|
|
8
app/public/codemirror/mode/mscgen/mscgen.js
vendored
8
app/public/codemirror/mode/mscgen/mscgen.js
vendored
|
@ -23,6 +23,7 @@
|
|||
mscgen: {
|
||||
"keywords" : ["msc"],
|
||||
"options" : ["hscale", "width", "arcgradient", "wordwraparcs"],
|
||||
"constants" : ["true", "false", "on", "off"],
|
||||
"attributes" : ["label", "idurl", "id", "url", "linecolor", "linecolour", "textcolor", "textcolour", "textbgcolor", "textbgcolour", "arclinecolor", "arclinecolour", "arctextcolor", "arctextcolour", "arctextbgcolor", "arctextbgcolour", "arcskip"],
|
||||
"brackets" : ["\\{", "\\}"], // [ and ] are brackets too, but these get handled in with lists
|
||||
"arcsWords" : ["note", "abox", "rbox", "box"],
|
||||
|
@ -31,8 +32,9 @@
|
|||
"operators" : ["="]
|
||||
},
|
||||
xu: {
|
||||
"keywords" : ["msc"],
|
||||
"keywords" : ["msc", "xu"],
|
||||
"options" : ["hscale", "width", "arcgradient", "wordwraparcs", "watermark"],
|
||||
"constants" : ["true", "false", "on", "off", "auto"],
|
||||
"attributes" : ["label", "idurl", "id", "url", "linecolor", "linecolour", "textcolor", "textcolour", "textbgcolor", "textbgcolour", "arclinecolor", "arclinecolour", "arctextcolor", "arctextcolour", "arctextbgcolor", "arctextbgcolour", "arcskip"],
|
||||
"brackets" : ["\\{", "\\}"], // [ and ] are brackets too, but these get handled in with lists
|
||||
"arcsWords" : ["note", "abox", "rbox", "box", "alt", "else", "opt", "break", "par", "seq", "strict", "neg", "critical", "ignore", "consider", "assert", "loop", "ref", "exc"],
|
||||
|
@ -43,6 +45,7 @@
|
|||
msgenny: {
|
||||
"keywords" : null,
|
||||
"options" : ["hscale", "width", "arcgradient", "wordwraparcs", "watermark"],
|
||||
"constants" : ["true", "false", "on", "off", "auto"],
|
||||
"attributes" : null,
|
||||
"brackets" : ["\\{", "\\}"],
|
||||
"arcsWords" : ["note", "abox", "rbox", "box", "alt", "else", "opt", "break", "par", "seq", "strict", "neg", "critical", "ignore", "consider", "assert", "loop", "ref", "exc"],
|
||||
|
@ -146,6 +149,9 @@
|
|||
if (!!pConfig.operators && pStream.match(wordRegexp(pConfig.operators), true, true))
|
||||
return "operator";
|
||||
|
||||
if (!!pConfig.constants && pStream.match(wordRegexp(pConfig.constants), true, true))
|
||||
return "variable";
|
||||
|
||||
/* attribute lists */
|
||||
if (!pConfig.inAttributeList && !!pConfig.attributes && pStream.match(/\[/, true, true)) {
|
||||
pConfig.inAttributeList = true;
|
||||
|
|
10
app/public/codemirror/mode/mscgen/mscgen_test.js
vendored
10
app/public/codemirror/mode/mscgen/mscgen_test.js
vendored
|
@ -29,6 +29,14 @@
|
|||
"[base alt loop opt ref else break par seq assert]"
|
||||
);
|
||||
|
||||
MT("xù/ msgenny constants classify as 'base'",
|
||||
"[base auto]"
|
||||
);
|
||||
|
||||
MT("mscgen constants classify as 'variable'",
|
||||
"[variable true]", "[variable false]", "[variable on]", "[variable off]"
|
||||
);
|
||||
|
||||
MT("mscgen options classify as keyword",
|
||||
"[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]"
|
||||
);
|
||||
|
@ -63,7 +71,7 @@
|
|||
MT("a typical program",
|
||||
"[comment # typical mscgen program]",
|
||||
"[keyword msc][base ][bracket {]",
|
||||
"[keyword wordwraparcs][operator =][string \"true\"][base , ][keyword hscale][operator =][string \"0.8\"][keyword arcgradient][operator =][base 30;]",
|
||||
"[keyword wordwraparcs][operator =][variable true][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30;]",
|
||||
"[base a][bracket [[][attribute label][operator =][string \"Entity A\"][bracket ]]][base ,]",
|
||||
"[base b][bracket [[][attribute label][operator =][string \"Entity B\"][bracket ]]][base ,]",
|
||||
"[base c][bracket [[][attribute label][operator =][string \"Entity C\"][bracket ]]][base ;]",
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
"[keyword alt]","[keyword loop]","[keyword opt]","[keyword ref]","[keyword else]","[keyword break]","[keyword par]","[keyword seq]","[keyword assert]"
|
||||
);
|
||||
|
||||
MT("xù/ msgenny constants classify as 'variable'",
|
||||
"[variable auto]",
|
||||
"[variable true]", "[variable false]", "[variable on]", "[variable off]"
|
||||
);
|
||||
|
||||
MT("mscgen options classify as keyword",
|
||||
"[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]"
|
||||
);
|
||||
|
@ -56,7 +61,7 @@
|
|||
|
||||
MT("a typical program",
|
||||
"[comment # typical msgenny program]",
|
||||
"[keyword wordwraparcs][operator =][string \"true\"][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30;]",
|
||||
"[keyword wordwraparcs][operator =][variable true][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30;]",
|
||||
"[base a : ][string \"Entity A\"][base ,]",
|
||||
"[base b : Entity B,]",
|
||||
"[base c : Entity C;]",
|
||||
|
|
19
app/public/codemirror/mode/mscgen/xu_test.js
vendored
19
app/public/codemirror/mode/mscgen/xu_test.js
vendored
|
@ -9,7 +9,13 @@
|
|||
"[keyword msc][bracket {]",
|
||||
"[base ]",
|
||||
"[bracket }]"
|
||||
);
|
||||
);
|
||||
|
||||
MT("empty chart",
|
||||
"[keyword xu][bracket {]",
|
||||
"[base ]",
|
||||
"[bracket }]"
|
||||
);
|
||||
|
||||
MT("comments",
|
||||
"[comment // a single line comment]",
|
||||
|
@ -29,6 +35,11 @@
|
|||
"[keyword alt]","[keyword loop]","[keyword opt]","[keyword ref]","[keyword else]","[keyword break]","[keyword par]","[keyword seq]","[keyword assert]"
|
||||
);
|
||||
|
||||
MT("xù/ msgenny constants classify as 'variable'",
|
||||
"[variable auto]",
|
||||
"[variable true]", "[variable false]", "[variable on]", "[variable off]"
|
||||
);
|
||||
|
||||
MT("mscgen options classify as keyword",
|
||||
"[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]"
|
||||
);
|
||||
|
@ -61,9 +72,9 @@
|
|||
);
|
||||
|
||||
MT("a typical program",
|
||||
"[comment # typical mscgen program]",
|
||||
"[keyword msc][base ][bracket {]",
|
||||
"[keyword wordwraparcs][operator =][string \"true\"][keyword hscale][operator =][string \"0.8\"][keyword arcgradient][operator =][base 30;]",
|
||||
"[comment # typical xu program]",
|
||||
"[keyword xu][base ][bracket {]",
|
||||
"[keyword wordwraparcs][operator =][string \"true\"][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30, ][keyword width][operator =][variable auto][base ;]",
|
||||
"[base a][bracket [[][attribute label][operator =][string \"Entity A\"][bracket ]]][base ,]",
|
||||
"[base b][bracket [[][attribute label][operator =][string \"Entity B\"][bracket ]]][base ,]",
|
||||
"[base c][bracket [[][attribute label][operator =][string \"Entity C\"][bracket ]]][base ;]",
|
||||
|
|
4
app/public/codemirror/mode/mumps/index.html
vendored
4
app/public/codemirror/mode/mumps/index.html
vendored
|
@ -1,4 +1,4 @@
|
|||
<!doctype html>
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: MUMPS mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
|
@ -73,7 +73,7 @@ SET2() ;EF. Return error code (also called from XUSRB)
|
|||
IF '$LENGTH($PIECE(XUSER(1),U,2)) QUIT 21 ;p419, p434
|
||||
Q 0
|
||||
;
|
||||
</textarea>
|
||||
</textarea></div>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "mumps",
|
||||
|
|
4
app/public/codemirror/mode/nginx/index.html
vendored
4
app/public/codemirror/mode/nginx/index.html
vendored
|
@ -1,5 +1,5 @@
|
|||
<!doctype html>
|
||||
|
||||
<!doctype html>
|
||||
<head>
|
||||
<title>CodeMirror: NGINX mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
|
2
app/public/codemirror/mode/nginx/nginx.js
vendored
2
app/public/codemirror/mode/nginx/nginx.js
vendored
|
@ -173,6 +173,6 @@ CodeMirror.defineMode("nginx", function(config) {
|
|||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/nginx", "text/x-nginx-conf");
|
||||
CodeMirror.defineMIME("text/x-nginx-conf", "nginx");
|
||||
|
||||
});
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue