133 changes: 132 additions & 1 deletion doc/manual.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@
</li>
<li><a href="#addons">Addons</a></li>
<li><a href="#modeapi">Writing CodeMirror Modes</a></li>
<li><a href="#vimapi">Vim Mode API</a>
<ul>
<li><a href="#vimapi_configuration">Configuration</a></li>
<li><a href="#vimapi_extending">Extending VIM</a></li>
</ul>
</li>
</ul>
</div>

Expand All @@ -63,7 +69,7 @@
<section class=first id=overview>
<h2 style="position: relative">
User manual and reference guide
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.2.0</span>
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.3.0</span>
</h2>

<p>CodeMirror is a code-editor component that can be embedded in
Expand Down Expand Up @@ -3156,6 +3162,131 @@ <h2>Writing CodeMirror Modes</h2>
looked up through <a href="#getMode"><code>getMode</code></a>.</p>
</section>

<section id="vimapi">
<h2>VIM Mode API</h2>

<p>CodeMirror has a robust VIM mode that attempts to faithfully
emulate VIM's most useful features. It can be enabled by
including <a href="../keymap/vim.js"><code>keymap/vim.js</code>
</a> and setting the <code>keymap</code> option to
<code>vim</code>.</p>

<h3 id="vimapi_configuration">Configuration</h3>

<p>VIM mode accepts configuration options for customizing
behavior at run time. These methods can be called at any time
and will affect all existing CodeMirror instances unless
specified otherwise. The methods are exposed on the
<code><strong>CodeMirror.Vim</strong></code> object.</p>

<dl>
<dt id="vimapi_setOption"><code><strong>setOption(name: string, value: any, ?cm: CodeMirror, ?cfg: object)</strong></code></dt>
<dd>Sets the value of a VIM option. <code>name</code> should
be the name of an option. If <code>cfg.scope</code> is not set
and <code>cm</code> is provided, then sets the global and
instance values of the option. Otherwise, sets either the
global or instance value of the option depending on whether
<code>cfg.scope</code> is <code>global</code> or
<code>local</code>.</dd>
<dt id="vimapi_getOption"><code><strong>getOption(name: string, ?cm: CodeMirror: ?cfg: object)</strong></code></dt>
<dd>Gets the current value of a VIM option. If
<code>cfg.scope</code> is not set and <code>cm</code> is
provided, then gets the instance value of the option, falling
back to the global value if not set. If <code>cfg.scope</code> is provided, then gets the <code>global</code> or
<code>local</code> value without checking the other.</dd>

<dt id="vimapi_map"><code><strong>map(lhs: string, rhs: string, ?context: string)</strong></code></dt>
<dd>Maps a key sequence to another key sequence. Implements
VIM's <code>:map</code> command. To map ; to : in VIM would be
<code><strong>:map ; :</strong></code>. That would translate to
<code><strong>CodeMirror.Vim.map(';', ':');</strong></code>.
The <code>context</code> can be <code>normal</code>,
<code>visual</code>, or <code>insert</code>, which correspond
to <code>:nmap</code>, <code>:vmap</code>, and
<code>:imap</code>
respectively.</dd>

<dt id="vimapi_mapCommand"><code><strong>mapCommand(keys: string, type: string, name: string, ?args: object, ?extra: object)</strong></code></dt>
<dd>Maps a key sequence to a <code>motion</code>,
<code>operator</code>, or <code>action</code> type command.
The args object is passed through to the command when it is
invoked by the provided key sequence.
<code>extras.context</code> can be <code>normal</code>,
<code>visual</code>, or <code>insert</code>, to map the key
sequence only in the corresponding mode.
<code>extras.isEdit</code> is applicable only to actions,
determining whether it is recorded for replay for the
<code>.</code> single-repeat command.
</dl>

<h3 id="vimapi_extending">Extending VIM</h3>

<p>CodeMirror's VIM mode implements a large subset of VIM's core
editing functionality. But since there's always more to be
desired, there is a set of APIs for extending VIM's
functionality. As with the configuration API, the methods are
exposed on <code><strong>CodeMirror.Vim</strong></code> and may
be called at any time.</p>

<dl>
<dt id="vimapi_defineOption"><code><strong>defineOption(name: string, default: any, type: string, ?aliases: array&lt;string&gt;, ?callback: function (?value: any, ?cm: CodeMirror) → ?any)</strong></code></dt>
<dd>Defines a VIM style option and makes it available to the
<code>:set</code> command. Type can be <code>boolean</code> or
<code>string</code>, used for validation and by
<code>:set</code> to determine which syntax to accept. If a
<code>callback</code> is passed in, VIM does not store the value of the
option itself, but instead uses the callback as a setter/getter. If the
first argument to the callback is <code>undefined</code>, then the
callback should return the value of the option. Otherwise, it should set
instead. Since VIM options have global and instance values, whether a
<code>CodeMirror</code> instance is passed in denotes whether the global
or local value should be used. Consequently, it's possible for the
callback to be called twice for a single <code>setOption</code> or
<code>getOption</code> call. Note that right now, VIM does not support
defining buffer-local options that do not have global values. If an
option should not have a global value, either always ignore the
<code>cm</code> parameter in the callback, or always pass in a
<code>cfg.scope</code> to <code>setOption</code> and
<code>getOption</code>.</dd>

<dt id="vimapi_defineMotion"><code><strong>defineMotion(name: string, fn: function(cm: CodeMirror, head: {line, ch}, ?motionArgs: object}) → {line, ch})</strong></code></dt>
<dd>Defines a motion command for VIM. The motion should return
the desired result position of the cursor. <code>head</code>
is the current position of the cursor. It can differ from
<code>cm.getCursor('head')</code> if VIM is in visual mode.
<code>motionArgs</code> is the object passed into
<strong><code>mapCommand()</code></strong>.</dd>

<dt id="vimapi_defineOperator"><strong><code>defineOperator(name: string, fn: function(cm: CodeMirror, ?operatorArgs: object, ranges: array&lt;{anchor, head}&gt;) → ?{line, ch})</code></strong></dt>
<dd>Defines an operator command, similar to <strong><code>
defineMotion</code></strong>. <code>ranges</code> is the range
of text the operator should operate on. If the cursor should
be set to a certain position after the operation finishes, it
can return a cursor object.</dd>

<dt id="vimapi_defineActon"><strong><code>defineAction(name: string, fn: function(cm: CodeMirror, ?actionArgs: object))</strong></code></dt>
<dd>Defines an action command, similar to
<strong><code>defineMotion</code></strong>. Action commands
can have arbitrary behavior, making them more flexible than
motions and operators, at the loss of orthogonality.</dd>

<dt id="vimapi_defineEx"><strong><code>defineEx(name: string, ?prefix: string, fn: function(cm: CodeMirror, ?params: object))</code></strong></dt>
<dd>Defines an Ex command, and maps it to <code>:name</code>.
If a prefix is provided, it, and any prefixed substring of the
<code>name</code> beginning with the <code>prefix</code> can
be used to invoke the command. If the <code>prefix</code> is
falsy, then <code>name</code> is used as the prefix. <code>
params.argString</code> contains the part of the prompted
string after the command name. <code>params.args</code> is
<code>params.argString</code> split by whitespace. If the
command was prefixed with a
<code><strong><a href="http://vimdoc.sourceforge.net/htmldoc/cmdline.html#cmdline-ranges">line range</a></strong></code>,
<code>params.line</code> and <code>params.lineEnd</code> will
be set.
</dl>

</section>

</article>

<script>setTimeout(function(){CodeMirror.colorize();}, 20);</script>
12 changes: 11 additions & 1 deletion doc/releases.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ <h2>Release notes and version history</h2>

<h2>Version 5.x</h2>

<p class="rel">20-05-2015: <a href="http://codemirror.net/codemirror-5.3.zip">Version 5.3</a>:</p>

<ul class="rel-note">
<li>Fix several regressions in the <a href="manual.html#addon_show-hint"><code>show-hint</code></a> addon (<code>completeSingle</code> option, <code>"shown"</code> and <code>"close"</code> events)</li>
<li>The <a href="../demo/vim.html">vim mode</a> was <a href="manual.html#vimapi">documented</a></li>
<li>New modes: <a href="../mode/asn.1/index.html">ASN.1</a>, <a href="../mode/ttcn/index.html">TTCN</a>, and <a href="../mode/ttcn-cfg/index.html">TTCN-CFG</a></li>
<li>The <a href="../mode/clike/index.html">clike</a> mode can now deep-indent <code>switch</code> statements, and rougly recognizes types and defined identifiers</li>
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/5.2.0...5.3.0">list of patches</a></li>
</ul>

<p class="rel">20-04-2015: <a href="http://codemirror.net/codemirror-5.2.zip">Version 5.2</a>:</p>

<ul class="rel-note">
Expand All @@ -41,7 +51,7 @@ <h2>Version 5.x</h2>

<li>New modes: <a href="../mode/mumps/index.html">MUMPS</a>, <a href="../mode/handlebars/index.html">Handlebars</a></li>
<li>Rewritten modes: <a href="../mode/django/index.html">Django</a>, <a href="../mode/z80/index.html">Z80</a></li>
<li>Theme: <a href="../demo/theme.html?liquibyte">Liquibyte</a></li>
<li>New theme: <a href="../demo/theme.html?liquibyte">Liquibyte</a></li>
<li>New option: <a href="manual.html#option_lineWiseCopyCut"><code>lineWiseCopyCut</code></a></li>
<li>The <a href="../demo/vim.html">Vim mode</a> now supports buffer-local options and the <code>filetype</code> setting</li>
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/5.1.0...5.2.0">list of patches</a></li>
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ <h2>This is CodeMirror</h2>
</div>
</div>
<div class=actionsleft>
Get the current version: <a href="http://codemirror.net/codemirror.zip">5.2</a>.<br>
Get the current version: <a href="http://codemirror.net/codemirror.zip">5.3</a>.<br>
You can see the <a href="https://github.com/codemirror/codemirror" title="Github repository">code</a> or<br>
read the <a href="doc/releases.html">release notes</a>.<br>
There is a <a href="doc/compress.html">minification helper</a>.
Expand Down
131 changes: 64 additions & 67 deletions keymap/vim.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,16 @@

/**
* Supported keybindings:
* Too many to list. Refer to defaultKeyMap below.
*
* Motion:
* h, j, k, l
* gj, gk
* e, E, w, W, b, B, ge, gE
* f<character>, F<character>, t<character>, T<character>
* $, ^, 0, -, +, _
* gg, G
* %
* '<character>, `<character>
*
* Operator:
* d, y, c
* dd, yy, cc
* g~, g~g~
* >, <, >>, <<
*
* Operator-Motion:
* x, X, D, Y, C, ~
*
* Action:
* a, i, s, A, I, S, o, O
* zz, z., z<CR>, zt, zb, z-
* J
* u, Ctrl-r
* m<character>
* r<character>
*
* Modes:
* ESC - leave insert mode, visual mode, and clear input state.
* Ctrl-[, Ctrl-c - same as ESC.
* Supported Ex commands:
* Refer to defaultExCommandMap below.
*
* Registers: unnamed, -, a-z, A-Z, 0-9
* (Does not respect the special case for number registers when delete
* operator is made with these commands: %, (, ), , /, ?, n, N, {, } )
* TODO: Implement the remaining registers.
*
* Marks: a-z, A-Z, and 0-9
* TODO: Implement the remaining special marks. They have more complex
* behavior.
Expand All @@ -57,6 +31,7 @@
* 6. Motion, operator, and action implementations
* 7. Helper functions for the key handler, motions, operators, and actions
* 8. Set up Vim to work as a keymap for CodeMirror.
* 9. Ex command implementations.
*/

(function(mod) {
Expand Down Expand Up @@ -227,6 +202,34 @@
{ keys: ':', type: 'ex' }
];

/**
* Ex commands
* Care must be taken when adding to the default Ex command map. For any
* pair of commands that have a shared prefix, at least one of their
* shortNames must not match the prefix of the other command.
*/
var defaultExCommandMap = [
{ name: 'colorscheme', shortName: 'colo' },
{ name: 'map' },
{ name: 'imap', shortName: 'im' },
{ name: 'nmap', shortName: 'nm' },
{ name: 'vmap', shortName: 'vm' },
{ name: 'unmap' },
{ name: 'write', shortName: 'w' },
{ name: 'undo', shortName: 'u' },
{ name: 'redo', shortName: 'red' },
{ name: 'set', shortName: 'se' },
{ name: 'set', shortName: 'se' },
{ name: 'setlocal', shortName: 'setl' },
{ name: 'setglobal', shortName: 'setg' },
{ name: 'sort', shortName: 'sor' },
{ name: 'substitute', shortName: 's', possiblyAsync: true },
{ name: 'nohlsearch', shortName: 'noh' },
{ name: 'delmarks', shortName: 'delm' },
{ name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
{ name: 'global', shortName: 'g' }
];

var Pos = CodeMirror.Pos;

var Vim = function() {
Expand Down Expand Up @@ -463,7 +466,7 @@
}
// The 'filetype' option proxies to the CodeMirror 'mode' option.
if (name === undefined) {
var mode = cm.getMode().name;
var mode = cm.getOption('mode');
return mode == 'null' ? '' : mode;
} else {
var mode = name == '' ? 'null' : name;
Expand Down Expand Up @@ -689,7 +692,9 @@
getOption: getOption,
defineOption: defineOption,
defineEx: function(name, prefix, func){
if (name.indexOf(prefix) !== 0) {
if (!prefix) {
prefix = name;
} else if (name.indexOf(prefix) !== 0) {
throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered');
}
exCommands[name]=func;
Expand Down Expand Up @@ -3635,13 +3640,17 @@
// Translates the replace part of a search and replace from ex (vim) syntax into
// javascript form. Similar to translateRegex, but additionally fixes back references
// (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'.
var charUnescapes = {'\\n': '\n', '\\r': '\r', '\\t': '\t'};
function translateRegexReplace(str) {
var escapeNextChar = false;
var out = [];
for (var i = -1; i < str.length; i++) {
var c = str.charAt(i) || '';
var n = str.charAt(i+1) || '';
if (escapeNextChar) {
if (charUnescapes[c + n]) {
out.push(charUnescapes[c+n]);
i++;
} else if (escapeNextChar) {
// At any point in the loop, escapeNextChar is true if the previous
// character was a '\' and was not escaped.
out.push(c);
Expand Down Expand Up @@ -3669,6 +3678,7 @@
}

// Unescape \ and / in the replace part, for PCRE mode.
var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'};
function unescapeRegexReplace(str) {
var stream = new CodeMirror.StringStream(str);
var output = [];
Expand All @@ -3677,13 +3687,15 @@
while (stream.peek() && stream.peek() != '\\') {
output.push(stream.next());
}
if (stream.match('\\/', true)) {
// \/ => /
output.push('/');
} else if (stream.match('\\\\', true)) {
// \\ => \
output.push('\\');
} else {
var matched = false;
for (var matcher in unescapes) {
if (stream.match(matcher, true)) {
matched = true;
output.push(unescapes[matcher]);
break;
}
}
if (!matched) {
// Don't change anything
output.push(stream.next());
}
Expand Down Expand Up @@ -3913,31 +3925,6 @@
return {top: from.line, bottom: to.line};
}

// Ex command handling
// Care must be taken when adding to the default Ex command map. For any
// pair of commands that have a shared prefix, at least one of their
// shortNames must not match the prefix of the other command.
var defaultExCommandMap = [
{ name: 'colorscheme', shortName: 'colo' },
{ name: 'map' },
{ name: 'imap', shortName: 'im' },
{ name: 'nmap', shortName: 'nm' },
{ name: 'vmap', shortName: 'vm' },
{ name: 'unmap' },
{ name: 'write', shortName: 'w' },
{ name: 'undo', shortName: 'u' },
{ name: 'redo', shortName: 'red' },
{ name: 'set', shortName: 'se' },
{ name: 'set', shortName: 'se' },
{ name: 'setlocal', shortName: 'setl' },
{ name: 'setglobal', shortName: 'setg' },
{ name: 'sort', shortName: 'sor' },
{ name: 'substitute', shortName: 's', possiblyAsync: true },
{ name: 'nohlsearch', shortName: 'noh' },
{ name: 'delmarks', shortName: 'delm' },
{ name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
{ name: 'global', shortName: 'g' }
];
var ExCommandDispatcher = function() {
this.buildCommandMap_();
};
Expand Down Expand Up @@ -4483,6 +4470,9 @@
var query = state.getQuery();
var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;
var lineEnd = params.lineEnd || lineStart;
if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) {
lineEnd = Infinity;
}
if (count) {
lineStart = lineEnd;
lineEnd = lineStart + count - 1;
Expand Down Expand Up @@ -4601,10 +4591,9 @@
searchCursor.replace(newText);
}
function next() {
var found;
// The below only loops to skip over multiple occurrences on the same
// line when 'global' is not true.
while(found = searchCursor.findNext() &&
while(searchCursor.findNext() &&
isInRange(searchCursor.from(), lineStart, lineEnd)) {
if (!global && lastPos && searchCursor.from().line == lastPos.line) {
continue;
Expand Down Expand Up @@ -4779,6 +4768,14 @@

function executeMacroRegister(cm, vim, macroModeState, registerName) {
var register = vimGlobalState.registerController.getRegister(registerName);
if (registerName == ':') {
// Read-only register containing last Ex command.
if (register.keyBuffer[0]) {
exCommandDispatcher.processCommand(cm, register.keyBuffer[0]);
}
macroModeState.isPlaying = false;
return;
}
var keyBuffer = register.keyBuffer;
var imc = 0;
macroModeState.isPlaying = true;
Expand Down
61 changes: 34 additions & 27 deletions lib/codemirror.js
Original file line number Diff line number Diff line change
Expand Up @@ -728,12 +728,9 @@
}

function postUpdateDisplay(cm, update) {
var force = update.force, viewport = update.viewport;
var viewport = update.viewport;
for (var first = true;; first = false) {
if (first && cm.options.lineWrapping && update.oldDisplayWidth != displayWidth(cm)) {
force = true;
} else {
force = false;
if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
// Clip forced viewport to actual scrollable area.
if (viewport && viewport.top != null)
viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
Expand Down Expand Up @@ -1108,32 +1105,40 @@
origin: origin || (cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
makeChange(cm.doc, changeEvent);
signalLater(cm, "inputRead", cm, changeEvent);
// When an 'electric' character is inserted, immediately trigger a reindent
if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
cm.options.smartIndent && range.head.ch < 100 &&
(!i || sel.ranges[i - 1].head.line != range.head.line)) {
var mode = cm.getModeAt(range.head);
var end = changeEnd(changeEvent);
var indented = false;
if (mode.electricChars) {
for (var j = 0; j < mode.electricChars.length; j++)
if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
indented = indentLine(cm, end.line, "smart");
break;
}
} else if (mode.electricInput) {
if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
indented = indentLine(cm, end.line, "smart");
}
if (indented) signalLater(cm, "electricInput", cm, end.line);
}
}
if (inserted && !cm.state.pasteIncoming)
triggerElectric(cm, inserted);

ensureCursorVisible(cm);
cm.curOp.updateInput = updateInput;
cm.curOp.typing = true;
cm.state.pasteIncoming = cm.state.cutIncoming = false;
}

function triggerElectric(cm, inserted) {
// When an 'electric' character is inserted, immediately trigger a reindent
if (!cm.options.electricChars || !cm.options.smartIndent) return;
var sel = cm.doc.sel;

for (var i = sel.ranges.length - 1; i >= 0; i--) {
var range = sel.ranges[i];
if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue;
var mode = cm.getModeAt(range.head);
var indented = false;
if (mode.electricChars) {
for (var j = 0; j < mode.electricChars.length; j++)
if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
indented = indentLine(cm, range.head.line, "smart");
break;
}
} else if (mode.electricInput) {
if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
indented = indentLine(cm, range.head.line, "smart");
}
if (indented) signalLater(cm, "electricInput", cm, range.head.line);
}
}

function copyableRanges(cm) {
var text = [], ranges = [];
for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
Expand Down Expand Up @@ -1836,7 +1841,7 @@
var partPos = getBidiPartAt(order, pos.ch);
side = partPos % 2 ? "right" : "left";
}
var result = nodeAndOffsetInLineMap(info.map, pos.ch, "left");
var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
result.offset = result.collapse == "right" ? result.end : result.start;
return result;
}
Expand Down Expand Up @@ -5053,6 +5058,8 @@
return commands[cmd](this);
},

triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),

findPosH: function(from, amount, unit, visually) {
var dir = 1;
if (amount < 0) { dir = -1; amount = -amount; }
Expand Down Expand Up @@ -5720,7 +5727,7 @@
for (var i = 0; i < keys.length; i++) {
var val, name;
if (i == keys.length - 1) {
name = keyname;
name = keys.join(" ");
val = value;
} else {
name = keys.slice(0, i + 1).join(" ");
Expand Down Expand Up @@ -8732,7 +8739,7 @@

// THE END

CodeMirror.version = "5.2.0";
CodeMirror.version = "5.3.0";

return CodeMirror;
});
3 changes: 1 addition & 2 deletions mode/apl/apl.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ CodeMirror.defineMode("apl", function() {
};
},
token: function(stream, state) {
var ch, funcName, word;
var ch, funcName;
if (stream.eatSpace()) {
return null;
}
Expand Down Expand Up @@ -163,7 +163,6 @@ CodeMirror.defineMode("apl", function() {
return "function jot-dot";
}
stream.eatWhile(/[\w\$_]/);
word = stream.current();
state.prev = true;
return "keyword";
}
Expand Down
204 changes: 204 additions & 0 deletions mode/asn.1/asn.1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// 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("asn.1", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = parserConfig.keywords || {},
cmipVerbs = parserConfig.cmipVerbs || {},
compareTypes = parserConfig.compareTypes || {},
status = parserConfig.status || {},
tags = parserConfig.tags || {},
storage = parserConfig.storage || {},
modifier = parserConfig.modifier || {},
accessTypes = parserConfig.accessTypes|| {},
multiLineStrings = parserConfig.multiLineStrings,
indentStatements = parserConfig.indentStatements !== false;
var isOperatorChar = /[\|\^]/;
var curPunc;

function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]\(\){}:=,;]/.test(ch)) {
curPunc = ch;
return "punctuation";
}
if (ch == "-"){
if (stream.eat("-")) {
stream.skipToEnd();
return "comment";
}
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}

stream.eatWhile(/[\w\-]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) return "keyword";
if (cmipVerbs.propertyIsEnumerable(cur)) return "variable cmipVerbs";
if (compareTypes.propertyIsEnumerable(cur)) return "atom compareTypes";
if (status.propertyIsEnumerable(cur)) return "comment status";
if (tags.propertyIsEnumerable(cur)) return "variable-3 tags";
if (storage.propertyIsEnumerable(cur)) return "builtin storage";
if (modifier.propertyIsEnumerable(cur)) return "string-2 modifier";
if (accessTypes.propertyIsEnumerable(cur)) return "atom accessTypes";

return "variable";
}

function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped){
var afterNext = stream.peek();
//look if the character if the quote is like the B in '10100010'B
if (afterNext){
afterNext = afterNext.toLowerCase();
if(afterNext == "b" || afterNext == "h" || afterNext == "o")
stream.next();
}
end = true; break;
}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}

function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
var indent = state.indented;
if (state.context && state.context.type == "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}

//Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},

token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment") return style;
if (ctx.align == null) ctx.align = true;

if ((curPunc == ";" || curPunc == ":" || curPunc == ",")
&& ctx.type == "statement"){
popContext(state);
}
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (indentStatements && (((ctx.type == "}" || ctx.type == "top")
&& curPunc != ';') || (ctx.type == "statement"
&& curPunc == "newstatement")))
pushContext(state, stream.column(), "statement");

state.startOfLine = false;
return style;
},

electricChars: "{}",
lineComment: "--",
fold: "brace"
};
});

function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}

CodeMirror.defineMIME("text/x-ttcn-asn", {
name: "asn.1",
keywords: words("DEFINITIONS OBJECTS IF DERIVED INFORMATION ACTION" +
" REPLY ANY NAMED CHARACTERIZED BEHAVIOUR REGISTERED" +
" WITH AS IDENTIFIED CONSTRAINED BY PRESENT BEGIN" +
" IMPORTS FROM UNITS SYNTAX MIN-ACCESS MAX-ACCESS" +
" MINACCESS MAXACCESS REVISION STATUS DESCRIPTION" +
" SEQUENCE SET COMPONENTS OF CHOICE DistinguishedName" +
" ENUMERATED SIZE MODULE END INDEX AUGMENTS EXTENSIBILITY" +
" IMPLIED EXPORTS"),
cmipVerbs: words("ACTIONS ADD GET NOTIFICATIONS REPLACE REMOVE"),
compareTypes: words("OPTIONAL DEFAULT MANAGED MODULE-TYPE MODULE_IDENTITY" +
" MODULE-COMPLIANCE OBJECT-TYPE OBJECT-IDENTITY" +
" OBJECT-COMPLIANCE MODE CONFIRMED CONDITIONAL" +
" SUBORDINATE SUPERIOR CLASS TRUE FALSE NULL" +
" TEXTUAL-CONVENTION"),
status: words("current deprecated mandatory obsolete"),
tags: words("APPLICATION AUTOMATIC EXPLICIT IMPLICIT PRIVATE TAGS" +
" UNIVERSAL"),
storage: words("BOOLEAN INTEGER OBJECT IDENTIFIER BIT OCTET STRING" +
" UTCTime InterfaceIndex IANAifType CMIP-Attribute" +
" REAL PACKAGE PACKAGES IpAddress PhysAddress" +
" NetworkAddress BITS BMPString TimeStamp TimeTicks" +
" TruthValue RowStatus DisplayString GeneralString" +
" GraphicString IA5String NumericString" +
" PrintableString SnmpAdminAtring TeletexString" +
" UTF8String VideotexString VisibleString StringStore" +
" ISO646String T61String UniversalString Unsigned32" +
" Integer32 Gauge Gauge32 Counter Counter32 Counter64"),
modifier: words("ATTRIBUTE ATTRIBUTES MANDATORY-GROUP MANDATORY-GROUPS" +
" GROUP GROUPS ELEMENTS EQUALITY ORDERING SUBSTRINGS" +
" DEFINED"),
accessTypes: words("not-accessible accessible-for-notify read-only" +
" read-create read-write"),
multiLineStrings: true
});
});
78 changes: 78 additions & 0 deletions mode/asn.1/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<!doctype html>

<title>CodeMirror: ASN.1 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="asn.1.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="http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One">ASN.1</a>
</ul>
</div>
<article>
<h2>ASN.1 example</h2>
<div>
<textarea id="ttcn-asn-code">
--
-- Sample ASN.1 Code
--
MyModule DEFINITIONS ::=
BEGIN

MyTypes ::= SEQUENCE {
myObjectId OBJECT IDENTIFIER,
mySeqOf SEQUENCE OF MyInt,
myBitString BIT STRING {
muxToken(0),
modemToken(1)
}
}

MyInt ::= INTEGER (0..65535)

END
</textarea>
</div>

<script>
var ttcnEditor = CodeMirror.fromTextArea(document.getElementById("ttcn-asn-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-ttcn-asn"
});
ttcnEditor.setSize(400, 400);
var mac = CodeMirror.keyMap.default == CodeMirror.keyMap.macDefault;
CodeMirror.keyMap.default[(mac ? "Cmd" : "Ctrl") + "-Space"] = "autocomplete";
</script>
<br/>
<p><strong>Language:</strong> Abstract Syntax Notation One
(<a href="http://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx">ASN.1</a>)
</p>
<p><strong>MIME types defined:</strong> <code>text/x-ttcn-asn</code></p>

<br/>
<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>

6 changes: 2 additions & 4 deletions mode/asterisk/asterisk.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ CodeMirror.defineMode("asterisk", function() {

function basicToken(stream,state){
var cur = '';
var ch = '';
ch = stream.next();
var ch = stream.next();
// comment
if(ch == ";") {
stream.skipToEnd();
Expand Down Expand Up @@ -136,7 +135,6 @@ CodeMirror.defineMode("asterisk", function() {
token: function(stream, state) {

var cur = '';
var ch = '';
if(stream.eatSpace()) return null;
// extension started
if(state.extenStart){
Expand Down Expand Up @@ -170,7 +168,7 @@ CodeMirror.defineMode("asterisk", function() {
} else if(state.extenPriority) {
state.extenPriority = false;
state.extenApplication = true;
ch = stream.next(); // get comma
stream.next(); // get comma
if(state.extenSame) return null;
stream.eatWhile(/[^,]/);
return "number";
Expand Down
134 changes: 98 additions & 36 deletions mode/clike/clike.js

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions mode/clike/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-c");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }

MT("indent",
"[variable-3 void] [def foo]([variable-3 void*] [variable a], [variable-3 int] [variable b]) {",
" [variable-3 int] [variable c] [operator =] [variable b] [operator +]",
" [number 1];",
" [keyword return] [operator *][variable a];",
"}");

MT("indent_switch",
"[keyword switch] ([variable x]) {",
" [keyword case] [number 10]:",
" [keyword return] [number 20];",
" [keyword default]:",
" [variable printf]([string \"foo %c\"], [variable x]);",
"}");

MT("def",
"[variable-3 void] [def foo]() {}",
"[keyword struct] [def bar]{}",
"[variable-3 int] [variable-3 *][def baz]() {}");
})();
17 changes: 1 addition & 16 deletions mode/css/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (type == "}") return popContext(state);
if (type == "{" || type == ";") return popAndPass(type, stream, state);
if (type == "word") override = "variable";
else if (type != "variable") override = "error";
else if (type != "variable" && type != "(" && type != ")") override = "error";
return "interpolation";
};

Expand Down Expand Up @@ -653,16 +653,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ["comment", "comment"];
}

function tokenSGMLComment(stream, state) {
if (stream.skipTo("-->")) {
stream.match("-->");
state.tokenize = null;
} else {
stream.skipToEnd();
}
return ["comment", "comment"];
}

CodeMirror.defineMIME("text/css", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
Expand All @@ -674,11 +664,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
tokenHooks: {
"<": function(stream, state) {
if (!stream.match("!--")) return false;
state.tokenize = tokenSGMLComment;
return tokenSGMLComment(stream, state);
},
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
Expand Down
7 changes: 0 additions & 7 deletions mode/css/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,6 @@
MT("tagTwoPropertiesURL",
"[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");

MT("commentSGML",
"[comment <!--comment-->]");

MT("commentSGML2",
"[comment <!--comment]",
"[comment -->] [tag div] {}");

MT("indent_tagSelector",
"[tag strong], [tag em] {",
" [property background]: [atom rgba](",
Expand Down
2 changes: 1 addition & 1 deletion mode/cypher/cypher.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

CodeMirror.defineMode("cypher", function(config) {
var tokenBase = function(stream/*, state*/) {
var ch = stream.next(), curPunc = null;
var ch = stream.next();
if (ch === "\"" || ch === "'") {
stream.match(/.+?["']/);
return "string";
Expand Down
44 changes: 18 additions & 26 deletions mode/dylan/dylan.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,12 @@ CodeMirror.defineMode("dylan", function(_config) {
return f(stream, state);
}

var type, content;

function ret(_type, style, _content) {
type = _type;
content = _content;
return style;
}

function tokenBase(stream, state) {
// String
var ch = stream.peek();
if (ch == "'" || ch == '"') {
stream.next();
return chain(stream, state, tokenString(ch, "string", "string"));
return chain(stream, state, tokenString(ch, "string"));
}
// Comment
else if (ch == "/") {
Expand All @@ -176,16 +168,16 @@ CodeMirror.defineMode("dylan", function(_config) {
return chain(stream, state, tokenComment);
} else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
return "comment";
} else {
stream.skipTo(" ");
return ret("operator", "operator");
return "operator";
}
}
// Decimal
else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
return ret("number", "number");
return "number";
}
// Hash
else if (ch == "#") {
Expand All @@ -194,55 +186,55 @@ CodeMirror.defineMode("dylan", function(_config) {
ch = stream.peek();
if (ch == '"') {
stream.next();
return chain(stream, state, tokenString('"', "symbol", "string-2"));
return chain(stream, state, tokenString('"', "string-2"));
}
// Binary number
else if (ch == "b") {
stream.next();
stream.eatWhile(/[01]/);
return ret("number", "number");
return "number";
}
// Hex number
else if (ch == "x") {
stream.next();
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
return "number";
}
// Octal number
else if (ch == "o") {
stream.next();
stream.eatWhile(/[0-7]/);
return ret("number", "number");
return "number";
}
// Hash symbol
else {
stream.eatWhile(/[-a-zA-Z]/);
return ret("hash", "keyword");
return "keyword";
}
} else if (stream.match("end")) {
return ret("end", "keyword");
return "keyword";
}
for (var name in patterns) {
if (patterns.hasOwnProperty(name)) {
var pattern = patterns[name];
if ((pattern instanceof Array && pattern.some(function(p) {
return stream.match(p);
})) || stream.match(pattern))
return ret(name, patternStyles[name], stream.current());
return patternStyles[name];
}
}
if (stream.match("define")) {
return ret("definition", "def");
return "def";
} else {
stream.eatWhile(/[\w\-]/);
// Keyword
if (wordLookup[stream.current()]) {
return ret(wordLookup[stream.current()], styleLookup[stream.current()], stream.current());
return styleLookup[stream.current()];
} else if (stream.current().match(symbol)) {
return ret("variable", "variable");
return "variable";
} else {
stream.next();
return ret("other", "variable-2");
return "variable-2";
}
}
}
Expand All @@ -257,10 +249,10 @@ CodeMirror.defineMode("dylan", function(_config) {
}
maybeEnd = (ch == "*");
}
return ret("comment", "comment");
return "comment";
}

function tokenString(quote, type, style) {
function tokenString(quote, style) {
return function(stream, state) {
var next, end = false;
while ((next = stream.next()) != null) {
Expand All @@ -271,7 +263,7 @@ CodeMirror.defineMode("dylan", function(_config) {
}
if (end)
state.tokenize = tokenBase;
return ret(type, style);
return style;
};
}

Expand Down
3 changes: 1 addition & 2 deletions mode/ecl/ecl.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ CodeMirror.defineMode("ecl", function(config) {
var blockKeywords = words("catch class do else finally for if switch try while");
var atoms = words("true false null");
var hooks = {"#": metaHook};
var multiLineStrings;
var isOperatorChar = /[+\-*&%=<>!?|\/]/;

var curPunc;
Expand Down Expand Up @@ -112,7 +111,7 @@ CodeMirror.defineMode("ecl", function(config) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
if (end || !escaped)
state.tokenize = tokenBase;
return "string";
};
Expand Down
2 changes: 0 additions & 2 deletions mode/eiffel/eiffel.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,13 @@ CodeMirror.defineMode("eiffel", function() {
'or'
]);
var operators = wordObj([":=", "and then","and", "or","<<",">>"]);
var curPunc;

function chain(newtok, stream, state) {
state.tokenize.push(newtok);
return newtok(stream, state);
}

function tokenBase(stream, state) {
curPunc = null;
if (stream.eatSpace()) return null;
var ch = stream.next();
if (ch == '"'||ch == "'") {
Expand Down
4 changes: 2 additions & 2 deletions mode/htmlmixed/htmlmixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
}
function maybeBackup(stream, pat, style) {
var cur = stream.current();
var close = cur.search(pat), m;
var close = cur.search(pat);
if (close > -1) stream.backUp(cur.length - close);
else if (m = cur.match(/<\/?$/)) {
else if (cur.match(/<\/?$/)) {
stream.backUp(cur.length);
if (!stream.match(pat, false)) stream.match(cur);
}
Expand Down
5 changes: 5 additions & 0 deletions mode/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ <h2>Language modes</h2>
<div style="-webkit-columns: 100px 2; -moz-columns: 100px 2; columns: 100px 2;">
<ul style="margin-top: 0">
<li><a href="apl/index.html">APL</a></li>
<li><a href="asn.1/index.html">ASN.1</a></li>
<li><a href="asterisk/index.html">Asterisk dialplan</a></li>
<li><a href="clike/index.html">C, C++, C#</a></li>
<li><a href="clojure/index.html">Clojure</a></li>
Expand Down Expand Up @@ -63,6 +64,7 @@ <h2>Language modes</h2>
<li><a href="handlebars/index.html">Handlebars</a></li>
<li><a href="haskell/index.html">Haskell</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>
Expand All @@ -76,6 +78,7 @@ <h2>Language modes</h2>
<li><a href="livescript/index.html">LiveScript</a></li>
<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="mirc/index.html">mIRC</a></li>
<li><a href="modelica/index.html">Modelica</a></li>
<li><a href="mumps/index.html">MUMPS</a></li>
Expand Down Expand Up @@ -122,6 +125,8 @@ <h2>Language modes</h2>
<li><a href="toml/index.html">TOML</a></li>
<li><a href="tornado/index.html">Tornado</a> (templating language)</li>
<li><a href="troff/index.html">troff</a> (for manpages)</li>
<li><a href="ttcn/index.html">TTCN</a></li>
<li><a href="ttcn-cfg/index.html">TTCN Configuration</a></li>
<li><a href="turtle/index.html">Turtle</a></li>
<li><a href="vb/index.html">VB.NET</a></li>
<li><a href="vbscript/index.html">VBScript</a></li>
Expand Down
2 changes: 0 additions & 2 deletions mode/julia/julia.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
var closers = wordRegexp(blockClosers);
var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
var symbol = /^:[_A-Za-z][_A-Za-z0-9]*/;
var indentInfo = null;

function in_array(state) {
var ch = cur_scope(state);
Expand Down Expand Up @@ -247,7 +246,6 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
}

function tokenLexer(stream, state) {
indentInfo = null;
var style = state.tokenize(stream, state);
var current = stream.current();

Expand Down
4 changes: 2 additions & 2 deletions mode/livescript/livescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
var nr = Rules[next_rule];
if (nr.splice) {
for (var i$ = 0; i$ < nr.length; ++i$) {
var r = nr[i$], m;
if (r.regex && (m = stream.match(r.regex))) {
var r = nr[i$];
if (r.regex && stream.match(r.regex)) {
state.next = r.next || state.next;
return r.token;
}
Expand Down
72 changes: 72 additions & 0 deletions mode/mathematica/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!doctype html>

<title>CodeMirror: Mathematica mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">

<link rel=stylesheet href=../../lib/codemirror.css>
<script src=../../lib/codemirror.js></script>
<script src=../../addon/edit/matchbrackets.js></script>
<script src=mathematica.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="#">Mathematica</a>
</ul>
</div>

<article>
<h2>Mathematica mode</h2>


<textarea id="mathematicaCode">
(* example Mathematica code *)
(* Dualisiert wird anhand einer Polarität an einer
Quadrik $x^t Q x = 0$ mit regulärer Matrix $Q$ (also
mit $det(Q) \neq 0$), z.B. die Identitätsmatrix.
$p$ ist eine Liste von Polynomen - ein Ideal. *)
dualize::"singular" = "Q must be regular: found Det[Q]==0.";
dualize[ Q_, p_ ] := Block[
{ m, n, xv, lv, uv, vars, polys, dual },
If[Det[Q] == 0,
Message[dualize::"singular"],
m = Length[p];
n = Length[Q] - 1;
xv = Table[Subscript[x, i], {i, 0, n}];
lv = Table[Subscript[l, i], {i, 1, m}];
uv = Table[Subscript[u, i], {i, 0, n}];
(* Konstruiere Ideal polys. *)
If[m == 0,
polys = Q.uv,
polys = Join[p, Q.uv - Transpose[Outer[D, p, xv]].lv]
];
(* Eliminiere die ersten n + 1 + m Variablen xv und lv
aus dem Ideal polys. *)
vars = Join[xv, lv];
dual = GroebnerBasis[polys, uv, vars];
(* Ersetze u mit x im Ergebnis. *)
ReplaceAll[dual, Rule[u, x]]
]
]
</textarea>

<script>
var mathematicaEditor = CodeMirror.fromTextArea(document.getElementById('mathematicaCode'), {
mode: 'text/x-mathematica',
lineNumbers: true,
matchBrackets: true
});
</script>

<p><strong>MIME types defined:</strong> <code>text/x-mathematica</code> (Mathematica).</p>
</article>
175 changes: 175 additions & 0 deletions mode/mathematica/mathematica.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Mathematica mode copyright (c) 2015 by Calin Barbat
// Based on code by Patrick Scheibe (halirutan)
// See: https://github.com/halirutan/Mathematica-Source-Highlighting/tree/master/src/lang-mma.js

(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('mathematica', function(_config, _parserConfig) {

// used pattern building blocks
var Identifier = '[a-zA-Z\\$][a-zA-Z0-9\\$]*';
var pBase = "(?:\\d+)";
var pFloat = "(?:\\.\\d+|\\d+\\.\\d*|\\d+)";
var pFloatBase = "(?:\\.\\w+|\\w+\\.\\w*|\\w+)";
var pPrecision = "(?:`(?:`?"+pFloat+")?)";

// regular expressions
var reBaseForm = new RegExp('(?:'+pBase+'(?:\\^\\^'+pFloatBase+pPrecision+'?(?:\\*\\^[+-]?\\d+)?))');
var reFloatForm = new RegExp('(?:' + pFloat + pPrecision + '?(?:\\*\\^[+-]?\\d+)?)');
var reIdInContext = new RegExp('(?:`?)(?:' + Identifier + ')(?:`(?:' + Identifier + '))*(?:`?)');

function tokenBase(stream, state) {
var ch;

// get next character
ch = stream.next();

// string
if (ch === '"') {
state.tokenize = tokenString;
return state.tokenize(stream, state);
}

// comment
if (ch === '(') {
if (stream.eat('*')) {
state.commentLevel++;
state.tokenize = tokenComment;
return state.tokenize(stream, state);
}
}

// go back one character
stream.backUp(1);

// look for numbers
// Numbers in a baseform
if (stream.match(reBaseForm, true, false)) {
return 'number';
}

// Mathematica numbers. Floats (1.2, .2, 1.) can have optionally a precision (`float) or an accuracy definition
// (``float). Note: while 1.2` is possible 1.2`` is not. At the end an exponent (float*^+12) can follow.
if (stream.match(reFloatForm, true, false)) {
return 'number';
}

/* In[23] and Out[34] */
if (stream.match(/(?:In|Out)\[[0-9]*\]/, true, false)) {
return 'atom';
}

// usage
if (stream.match(/([a-zA-Z\$]+(?:`?[a-zA-Z0-9\$])*::usage)/, true, false)) {
return 'meta';
}

// message
if (stream.match(/([a-zA-Z\$]+(?:`?[a-zA-Z0-9\$])*::[a-zA-Z\$][a-zA-Z0-9\$]*):?/, true, false)) {
return 'string-2';
}

// this makes a look-ahead match for something like variable:{_Integer}
// the match is then forwarded to the mma-patterns tokenizer.
if (stream.match(/([a-zA-Z\$][a-zA-Z0-9\$]*\s*:)(?:(?:[a-zA-Z\$][a-zA-Z0-9\$]*)|(?:[^:=>~@\^\&\*\)\[\]'\?,\|])).*/, true, false)) {
return 'variable-2';
}

// catch variables which are used together with Blank (_), BlankSequence (__) or BlankNullSequence (___)
// Cannot start with a number, but can have numbers at any other position. Examples
// blub__Integer, a1_, b34_Integer32
if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) {
return 'variable-2';
}
if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+/, true, false)) {
return 'variable-2';
}
if (stream.match(/_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) {
return 'variable-2';
}

// Named characters in Mathematica, like \[Gamma].
if (stream.match(/\\\[[a-zA-Z\$][a-zA-Z0-9\$]*\]/, true, false)) {
return 'variable-3';
}

// Match all braces separately
if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {
return 'bracket';
}

// Catch Slots (#, ##, #3, ##9 and the V10 named slots #name). I have never seen someone using more than one digit after #, so we match
// only one.
if (stream.match(/(?:#[a-zA-Z\$][a-zA-Z0-9\$]*|#+[0-9]?)/, true, false)) {
return 'variable-2';
}

// Literals like variables, keywords, functions
if (stream.match(reIdInContext, true, false)) {
return 'keyword';
}

// operators. Note that operators like @@ or /; are matched separately for each symbol.
if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {
return 'operator';
}

// everything else is an error
return 'error';
}

function tokenString(stream, state) {
var next, end = false, escaped = false;
while ((next = stream.next()) != null) {
if (next === '"' && !escaped) {
end = true;
break;
}
escaped = !escaped && next === '\\';
}
if (end && !escaped) {
state.tokenize = tokenBase;
}
return 'string';
};

function tokenComment(stream, state) {
var prev, next;
while(state.commentLevel > 0 && (next = stream.next()) != null) {
if (prev === '(' && next === '*') state.commentLevel++;
if (prev === '*' && next === ')') state.commentLevel--;
prev = next;
}
if (state.commentLevel <= 0) {
state.tokenize = tokenBase;
}
return 'comment';
}

return {
startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
token: function(stream, state) {
if (stream.eatSpace()) return null;
return state.tokenize(stream, state);
},
blockCommentStart: "(*",
blockCommentEnd: "*)"
};
});

CodeMirror.defineMIME('text/x-mathematica', {
name: 'mathematica'
});

});
1 change: 1 addition & 0 deletions mode/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
{name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
{name: "mIRC", mime: "text/mirc", mode: "mirc"},
{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: "MS SQL", mime: "text/x-mssql", mode: "sql"},
Expand Down
1 change: 1 addition & 0 deletions mode/php/php.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
helperType: "php",
keywords: keywords(phpKeywords),
blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
defKeywords: keywords("class function interface namespace trait"),
atoms: keywords(phpAtoms),
builtin: keywords(phpBuiltin),
multiLineStrings: true,
Expand Down
40 changes: 15 additions & 25 deletions mode/pig/pig.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ CodeMirror.defineMode("pig", function(_config, parserConfig) {
return f(stream, state);
}

var type;
function ret(tp, style) {
type = tp;
return style;
}

function tokenComment(stream, state) {
var isEnd = false;
var ch;
Expand All @@ -46,7 +40,7 @@ CodeMirror.defineMode("pig", function(_config, parserConfig) {
}
isEnd = (ch == "*");
}
return ret("comment", "comment");
return "comment";
}

function tokenString(quote) {
Expand All @@ -60,10 +54,11 @@ CodeMirror.defineMode("pig", function(_config, parserConfig) {
}
if (end || !(escaped || multiLineStrings))
state.tokenize = tokenBase;
return ret("string", "error");
return "error";
};
}


function tokenBase(stream, state) {
var ch = stream.next();

Expand All @@ -72,11 +67,11 @@ CodeMirror.defineMode("pig", function(_config, parserConfig) {
return chain(stream, state, tokenString(ch));
// is it one of the special chars
else if(/[\[\]{}\(\),;\.]/.test(ch))
return ret(ch);
return null;
// is it a number?
else if(/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return ret("number", "number");
return "number";
}
// multi line comment or operator
else if (ch == "/") {
Expand All @@ -85,47 +80,42 @@ CodeMirror.defineMode("pig", function(_config, parserConfig) {
}
else {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator");
return "operator";
}
}
// single line comment or operator
else if (ch=="-") {
if(stream.eat("-")){
stream.skipToEnd();
return ret("comment", "comment");
return "comment";
}
else {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator");
return "operator";
}
}
// is it an operator
else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator");
return "operator";
}
else {
// get the while word
stream.eatWhile(/[\w\$_]/);
// is it one of the listed keywords?
if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
if (stream.eat(")") || stream.eat(".")) {
//keywords can be used as variables like flatten(group), group.$0 etc..
}
else {
return ("keyword", "keyword");
}
//keywords can be used as variables like flatten(group), group.$0 etc..
if (!stream.eat(")") && !stream.eat("."))
return "keyword";
}
// is it one of the builtin functions?
if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase()))
{
return ("keyword", "variable-2");
}
return "variable-2";
// is it one of the listed types?
if (types && types.propertyIsEnumerable(stream.current().toUpperCase()))
return ("keyword", "variable-3");
return "variable-3";
// default is a 'variable'
return ret("variable", "pig-word");
return "variable";
}
}

Expand Down
4 changes: 2 additions & 2 deletions mode/sql/sql.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
}

// these keywords are used by all SQL dialects (however, a mode can still overwrite it)
var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from having in insert into is join like not on or order select set table union update values where ";
var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where ";

// turn a space-separated list into an array
function set(str) {
Expand Down Expand Up @@ -293,7 +293,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
CodeMirror.defineMIME("text/x-mysql", {
name: "sql",
client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group groupby_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group group_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
atoms: set("false true null unknown"),
operatorChars: /^[*+\-%<>!=&|^]/,
Expand Down
83 changes: 36 additions & 47 deletions mode/tiddlywiki/tiddlywiki.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,6 @@ CodeMirror.defineMode("tiddlywiki", function () {
return f(stream, state);
}

// Used as scratch variables to communicate multiple values without
// consing up tons of objects.
var type, content;

function ret(tp, style, cont) {
type = tp;
content = cont;
return style;
}

function jsTokenBase(stream, state) {
var sol = stream.sol(), ch;

Expand All @@ -95,47 +85,47 @@ CodeMirror.defineMode("tiddlywiki", function () {
return chain(stream, state, twTokenCode);
}
if (stream.match(reBlockQuote)) {
return ret('quote', 'quote');
return 'quote';
}
if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop)) {
return ret('code', 'comment');
return 'comment';
}
if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop)) {
return ret('code', 'comment');
return 'comment';
}
if (stream.match(reHR)) {
return ret('hr', 'hr');
return 'hr';
}
} // sol
ch = stream.next();

if (sol && /[\/\*!#;:>|]/.test(ch)) {
if (ch == "!") { // tw header
stream.skipToEnd();
return ret("header", "header");
return "header";
}
if (ch == "*") { // tw list
stream.eatWhile('*');
return ret("list", "comment");
return "comment";
}
if (ch == "#") { // tw numbered list
stream.eatWhile('#');
return ret("list", "comment");
return "comment";
}
if (ch == ";") { // definition list, term
stream.eatWhile(';');
return ret("list", "comment");
return "comment";
}
if (ch == ":") { // definition list, description
stream.eatWhile(':');
return ret("list", "comment");
return "comment";
}
if (ch == ">") { // single line quote
stream.eatWhile(">");
return ret("quote", "quote");
return "quote";
}
if (ch == '|') {
return ret('table', 'header');
return 'header';
}
}

Expand All @@ -146,29 +136,29 @@ CodeMirror.defineMode("tiddlywiki", function () {
// rudimentary html:// file:// link matching. TW knows much more ...
if (/[hf]/i.test(ch)) {
if (/[ti]/i.test(stream.peek()) && stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i)) {
return ret("link", "link");
return "link";
}
}
// just a little string indicator, don't want to have the whole string covered
if (ch == '"') {
return ret('string', 'string');
return 'string';
}
if (ch == '~') { // _no_ CamelCase indicator should be bold
return ret('text', 'brace');
return 'brace';
}
if (/[\[\]]/.test(ch)) { // check for [[..]]
if (stream.peek() == ch) {
stream.next();
return ret('brace', 'brace');
return 'brace';
}
}
if (ch == "@") { // check for space link. TODO fix @@...@@ highlighting
stream.eatWhile(isSpaceName);
return ret("link", "link");
return "link";
}
if (/\d/.test(ch)) { // numbers
stream.eatWhile(/\d/);
return ret("number", "number");
return "number";
}
if (ch == "/") { // tw invisible comment
if (stream.eat("%")) {
Expand All @@ -191,7 +181,7 @@ CodeMirror.defineMode("tiddlywiki", function () {
return chain(stream, state, twTokenStrike);
// mdash
if (stream.peek() == ' ')
return ret('text', 'brace');
return 'brace';
}
}
if (ch == "'") { // tw bold
Expand All @@ -205,16 +195,15 @@ CodeMirror.defineMode("tiddlywiki", function () {
}
}
else {
return ret(ch);
return null;
}

// core macro handling
stream.eatWhile(/[\w\$_]/);
var word = stream.current(),
known = textwords.propertyIsEnumerable(word) && textwords[word];

return known ? ret(known.type, known.style, word) : ret("text", null, word);

return known ? known.style : null;
} // jsTokenBase()

// tw invisible comment
Expand All @@ -228,7 +217,7 @@ CodeMirror.defineMode("tiddlywiki", function () {
}
maybeEnd = (ch == "%");
}
return ret("comment", "comment");
return "comment";
}

// tw strong / bold
Expand All @@ -242,29 +231,29 @@ CodeMirror.defineMode("tiddlywiki", function () {
}
maybeEnd = (ch == "'");
}
return ret("text", "strong");
return "strong";
}

// tw code
function twTokenCode(stream, state) {
var ch, sb = state.block;
var sb = state.block;

if (sb && stream.current()) {
return ret("code", "comment");
return "comment";
}

if (!sb && stream.match(reUntilCodeStop)) {
state.tokenize = jsTokenBase;
return ret("code", "comment");
return "comment";
}

if (sb && stream.sol() && stream.match(reCodeBlockStop)) {
state.tokenize = jsTokenBase;
return ret("code", "comment");
return "comment";
}

ch = stream.next();
return (sb) ? ret("code", "comment") : ret("code", "comment");
stream.next();
return "comment";
}

// tw em / italic
Expand All @@ -278,7 +267,7 @@ CodeMirror.defineMode("tiddlywiki", function () {
}
maybeEnd = (ch == "/");
}
return ret("text", "em");
return "em";
}

// tw underlined text
Expand All @@ -292,7 +281,7 @@ CodeMirror.defineMode("tiddlywiki", function () {
}
maybeEnd = (ch == "_");
}
return ret("text", "underlined");
return "underlined";
}

// tw strike through text looks ugly
Expand All @@ -307,27 +296,27 @@ CodeMirror.defineMode("tiddlywiki", function () {
}
maybeEnd = (ch == "-");
}
return ret("text", "strikethrough");
return "strikethrough";
}

// macro
function twTokenMacro(stream, state) {
var ch, word, known;

if (stream.current() == '<<') {
return ret('brace', 'macro');
return 'macro';
}

ch = stream.next();
if (!ch) {
state.tokenize = jsTokenBase;
return ret(ch);
return null;
}
if (ch == ">") {
if (stream.peek() == '>') {
stream.next();
state.tokenize = jsTokenBase;
return ret("brace", "macro");
return "macro";
}
}

Expand All @@ -336,10 +325,10 @@ CodeMirror.defineMode("tiddlywiki", function () {
known = keywords.propertyIsEnumerable(word) && keywords[word];

if (known) {
return ret(known.type, known.style, word);
return known.style, word;
}
else {
return ret("macro", null, word);
return null, word;
}
}

Expand Down
27 changes: 8 additions & 19 deletions mode/tiki/tiki.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,35 +52,27 @@ CodeMirror.defineMode('tiki', function(config) {
case "{": //plugin
stream.eat("/");
stream.eatSpace();
var tagName = "";
var c;
while ((c = stream.eat(/[^\s\u00a0=\"\'\/?(}]/))) tagName += c;
stream.eatWhile(/[^\s\u00a0=\"\'\/?(}]/);
state.tokenize = inPlugin;
return "tag";
break;
case "_": //bold
if (stream.eat("_")) {
if (stream.eat("_"))
return chain(inBlock("strong", "__", inText));
}
break;
case "'": //italics
if (stream.eat("'")) {
// Italic text
if (stream.eat("'"))
return chain(inBlock("em", "''", inText));
}
break;
case "(":// Wiki Link
if (stream.eat("(")) {
if (stream.eat("("))
return chain(inBlock("variable-2", "))", inText));
}
break;
case "[":// Weblink
return chain(inBlock("variable-3", "]", inText));
break;
case "|": //table
if (stream.eat("|")) {
if (stream.eat("|"))
return chain(inBlock("comment", "||"));
}
break;
case "-":
if (stream.eat("=")) {//titleBar
Expand All @@ -90,22 +82,19 @@ CodeMirror.defineMode('tiki', function(config) {
}
break;
case "=": //underline
if (stream.match("==")) {
if (stream.match("=="))
return chain(inBlock("tw-underline", "===", inText));
}
break;
case ":":
if (stream.eat(":")) {
if (stream.eat(":"))
return chain(inBlock("comment", "::"));
}
break;
case "^": //box
return chain(inBlock("tw-box", "^"));
break;
case "~": //np
if (stream.match("np~")) {
if (stream.match("np~"))
return chain(inBlock("meta", "~/np~"));
}
break;
}

Expand Down
115 changes: 115 additions & 0 deletions mode/ttcn-cfg/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<!doctype html>

<title>CodeMirror: TTCN-CFG 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="ttcn-cfg.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="http://en.wikipedia.org/wiki/TTCN">TTCN-CFG</a>
</ul>
</div>
<article>
<h2>TTCN-CFG example</h2>
<div>
<textarea id="ttcn-cfg-code">
[MODULE_PARAMETERS]
# This section shall contain the values of all parameters that are defined in your TTCN-3 modules.

[LOGGING]
# In this section you can specify the name of the log file and the classes of events
# you want to log into the file or display on console (standard error).

LogFile := "logs/%e.%h-%r.%s"
FileMask := LOG_ALL | DEBUG | MATCHING
ConsoleMask := ERROR | WARNING | TESTCASE | STATISTICS | PORTEVENT

LogSourceInfo := Yes
AppendFile := No
TimeStampFormat := DateTime
LogEventTypes := Yes
SourceInfoFormat := Single
LogEntityName := Yes

[TESTPORT_PARAMETERS]
# In this section you can specify parameters that are passed to Test Ports.

[DEFINE]
# In this section you can create macro definitions,
# that can be used in other configuration file sections except [INCLUDE].

[INCLUDE]
# To use configuration settings given in other configuration files,
# the configuration files just need to be listed in this section, with their full or relative pathnames.

[EXTERNAL_COMMANDS]
# This section can define external commands (shell scripts) to be executed by the ETS
# whenever a control part or test case is started or terminated.

BeginTestCase := ""
EndTestCase := ""
BeginControlPart := ""
EndControlPart := ""

[EXECUTE]
# In this section you can specify what parts of your test suite you want to execute.

[GROUPS]
# In this section you can specify groups of hosts. These groups can be used inside the
# [COMPONENTS] section to restrict the creation of certain PTCs to a given set of hosts.

[COMPONENTS]
# This section consists of rules restricting the location of created PTCs.

[MAIN_CONTROLLER]
# The options herein control the behavior of MC.

TCPPort := 0
KillTimer := 10.0
NumHCs := 0
LocalAddress :=
</textarea>
</div>

<script>
var ttcnEditor = CodeMirror.fromTextArea(document.getElementById("ttcn-cfg-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-ttcn-cfg"
});
ttcnEditor.setSize(600, 860);
var mac = CodeMirror.keyMap.default == CodeMirror.keyMap.macDefault;
CodeMirror.keyMap.default[(mac ? "Cmd" : "Ctrl") + "-Space"] = "autocomplete";
</script>
<br/>
<p><strong>Language:</strong> Testing and Test Control Notation -
Configuration files
(<a href="http://en.wikipedia.org/wiki/TTCN">TTCN-CFG</a>)
</p>
<p><strong>MIME types defined:</strong> <code>text/x-ttcn-cfg</code>.</p>

<br/>
<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>

214 changes: 214 additions & 0 deletions mode/ttcn-cfg/ttcn-cfg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
// 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("ttcn-cfg", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = parserConfig.keywords || {},
fileNCtrlMaskOptions = parserConfig.fileNCtrlMaskOptions || {},
externalCommands = parserConfig.externalCommands || {},
multiLineStrings = parserConfig.multiLineStrings,
indentStatements = parserConfig.indentStatements !== false;
var isOperatorChar = /[\|]/;
var curPunc;

function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[:=]/.test(ch)) {
curPunc = ch;
return "punctuation";
}
if (ch == "#"){
stream.skipToEnd();
return "comment";
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
if (ch == "["){
stream.eatWhile(/[\w_\]]/);
return "number sectionTitle";
}

stream.eatWhile(/[\w\$_]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) return "keyword";
if (fileNCtrlMaskOptions.propertyIsEnumerable(cur))
return "negative fileNCtrlMaskOptions";
if (externalCommands.propertyIsEnumerable(cur)) return "negative externalCommands";

return "variable";
}

function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped){
var afterNext = stream.peek();
//look if the character if the quote is like the B in '10100010'B
if (afterNext){
afterNext = afterNext.toLowerCase();
if(afterNext == "b" || afterNext == "h" || afterNext == "o")
stream.next();
}
end = true; break;
}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}

function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
var indent = state.indented;
if (state.context && state.context.type == "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}

//Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},

token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment") return style;
if (ctx.align == null) ctx.align = true;

if ((curPunc == ";" || curPunc == ":" || curPunc == ",")
&& ctx.type == "statement"){
popContext(state);
}
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (indentStatements && (((ctx.type == "}" || ctx.type == "top")
&& curPunc != ';') || (ctx.type == "statement"
&& curPunc == "newstatement")))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},

electricChars: "{}",
lineComment: "#",
fold: "brace"
};
});

function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i)
obj[words[i]] = true;
return obj;
}

CodeMirror.defineMIME("text/x-ttcn-cfg", {
name: "ttcn-cfg",
keywords: words("Yes No LogFile FileMask ConsoleMask AppendFile" +
" TimeStampFormat LogEventTypes SourceInfoFormat" +
" LogEntityName LogSourceInfo DiskFullAction" +
" LogFileNumber LogFileSize MatchingHints Detailed" +
" Compact SubCategories Stack Single None Seconds" +
" DateTime Time Stop Error Retry Delete TCPPort KillTimer" +
" NumHCs UnixSocketsEnabled LocalAddress"),
fileNCtrlMaskOptions: words("TTCN_EXECUTOR TTCN_ERROR TTCN_WARNING" +
" TTCN_PORTEVENT TTCN_TIMEROP TTCN_VERDICTOP" +
" TTCN_DEFAULTOP TTCN_TESTCASE TTCN_ACTION" +
" TTCN_USER TTCN_FUNCTION TTCN_STATISTICS" +
" TTCN_PARALLEL TTCN_MATCHING TTCN_DEBUG" +
" EXECUTOR ERROR WARNING PORTEVENT TIMEROP" +
" VERDICTOP DEFAULTOP TESTCASE ACTION USER" +
" FUNCTION STATISTICS PARALLEL MATCHING DEBUG" +
" LOG_ALL LOG_NOTHING ACTION_UNQUALIFIED" +
" DEBUG_ENCDEC DEBUG_TESTPORT" +
" DEBUG_UNQUALIFIED DEFAULTOP_ACTIVATE" +
" DEFAULTOP_DEACTIVATE DEFAULTOP_EXIT" +
" DEFAULTOP_UNQUALIFIED ERROR_UNQUALIFIED" +
" EXECUTOR_COMPONENT EXECUTOR_CONFIGDATA" +
" EXECUTOR_EXTCOMMAND EXECUTOR_LOGOPTIONS" +
" EXECUTOR_RUNTIME EXECUTOR_UNQUALIFIED" +
" FUNCTION_RND FUNCTION_UNQUALIFIED" +
" MATCHING_DONE MATCHING_MCSUCCESS" +
" MATCHING_MCUNSUCC MATCHING_MMSUCCESS" +
" MATCHING_MMUNSUCC MATCHING_PCSUCCESS" +
" MATCHING_PCUNSUCC MATCHING_PMSUCCESS" +
" MATCHING_PMUNSUCC MATCHING_PROBLEM" +
" MATCHING_TIMEOUT MATCHING_UNQUALIFIED" +
" PARALLEL_PORTCONN PARALLEL_PORTMAP" +
" PARALLEL_PTC PARALLEL_UNQUALIFIED" +
" PORTEVENT_DUALRECV PORTEVENT_DUALSEND" +
" PORTEVENT_MCRECV PORTEVENT_MCSEND" +
" PORTEVENT_MMRECV PORTEVENT_MMSEND" +
" PORTEVENT_MQUEUE PORTEVENT_PCIN" +
" PORTEVENT_PCOUT PORTEVENT_PMIN" +
" PORTEVENT_PMOUT PORTEVENT_PQUEUE" +
" PORTEVENT_STATE PORTEVENT_UNQUALIFIED" +
" STATISTICS_UNQUALIFIED STATISTICS_VERDICT" +
" TESTCASE_FINISH TESTCASE_START" +
" TESTCASE_UNQUALIFIED TIMEROP_GUARD" +
" TIMEROP_READ TIMEROP_START TIMEROP_STOP" +
" TIMEROP_TIMEOUT TIMEROP_UNQUALIFIED" +
" USER_UNQUALIFIED VERDICTOP_FINAL" +
" VERDICTOP_GETVERDICT VERDICTOP_SETVERDICT" +
" VERDICTOP_UNQUALIFIED WARNING_UNQUALIFIED"),
externalCommands: words("BeginControlPart EndControlPart BeginTestCase" +
" EndTestCase"),
multiLineStrings: true
});
});
118 changes: 118 additions & 0 deletions mode/ttcn/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<!doctype html>

<title>CodeMirror: TTCN 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="ttcn.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="http://en.wikipedia.org/wiki/TTCN">TTCN</a>
</ul>
</div>
<article>
<h2>TTCN example</h2>
<div>
<textarea id="ttcn-code">
module Templates {
/* import types from ASN.1 */
import from Types language "ASN.1:1997" all;

/* During the conversion phase from ASN.1 to TTCN-3 */
/* - the minus sign (Message-Type) within the identifiers will be replaced by underscore (Message_Type)*/
/* - the ASN.1 identifiers matching a TTCN-3 keyword (objid) will be postfixed with an underscore (objid_)*/

// simple types

template SenderID localObjid := objid {itu_t(0) identified_organization(4) etsi(0)};

// complex types

/* ASN.1 Message-Type mapped to TTCN-3 Message_Type */
template Message receiveMsg(template (present) Message_Type p_messageType) := {
header := p_messageType,
body := ?
}

/* ASN.1 objid mapped to TTCN-3 objid_ */
template Message sendInviteMsg := {
header := inviteType,
body := {
/* optional fields may be assigned by omit or may be ignored/skipped */
description := "Invite Message",
data := 'FF'O,
objid_ := localObjid
}
}

template Message sendAcceptMsg modifies sendInviteMsg := {
header := acceptType,
body := {
description := "Accept Message"
}
};

template Message sendErrorMsg modifies sendInviteMsg := {
header := errorType,
body := {
description := "Error Message"
}
};

template Message expectedErrorMsg := {
header := errorType,
body := ?
};

template Message expectedInviteMsg modifies expectedErrorMsg := {
header := inviteType
};

template Message expectedAcceptMsg modifies expectedErrorMsg := {
header := acceptType
};

} with { encode "BER:1997" }
</textarea>
</div>

<script>
var ttcnEditor = CodeMirror.fromTextArea(document.getElementById("ttcn-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-ttcn"
});
ttcnEditor.setSize(600, 860);
var mac = CodeMirror.keyMap.default == CodeMirror.keyMap.macDefault;
CodeMirror.keyMap.default[(mac ? "Cmd" : "Ctrl") + "-Space"] = "autocomplete";
</script>
<br/>
<p><strong>Language:</strong> Testing and Test Control Notation
(<a href="http://en.wikipedia.org/wiki/TTCN">TTCN</a>)
</p>
<p><strong>MIME types defined:</strong> <code>text/x-ttcn,
text/x-ttcn3, text/x-ttcnpp</code>.</p>
<br/>
<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>

283 changes: 283 additions & 0 deletions mode/ttcn/ttcn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
// 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("ttcn", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = parserConfig.keywords || {},
builtin = parserConfig.builtin || {},
timerOps = parserConfig.timerOps || {},
portOps = parserConfig.portOps || {},
configOps = parserConfig.configOps || {},
verdictOps = parserConfig.verdictOps || {},
sutOps = parserConfig.sutOps || {},
functionOps = parserConfig.functionOps || {},

verdictConsts = parserConfig.verdictConsts || {},
booleanConsts = parserConfig.booleanConsts || {},
otherConsts = parserConfig.otherConsts || {},

types = parserConfig.types || {},
visibilityModifiers = parserConfig.visibilityModifiers || {},
templateMatch = parserConfig.templateMatch || {},
multiLineStrings = parserConfig.multiLineStrings,
indentStatements = parserConfig.indentStatements !== false;
var isOperatorChar = /[+\-*&@=<>!\/]/;
var curPunc;

function tokenBase(stream, state) {
var ch = stream.next();

if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]{}\(\),;\\:\?\.]/.test(ch)) {
curPunc = ch;
return "punctuation";
}
if (ch == "#"){
stream.skipToEnd();
return "atom preprocessor";
}
if (ch == "%"){
stream.eatWhile(/\b/);
return "atom ttcn3Macros";
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
if(ch == "@"){
if(stream.match("try") || stream.match("catch")
|| stream.match("lazy")){
return "keyword";
}
}
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
var cur = stream.current();

if (keywords.propertyIsEnumerable(cur)) return "keyword";
if (builtin.propertyIsEnumerable(cur)) return "builtin";

if (timerOps.propertyIsEnumerable(cur)) return "def timerOps";
if (configOps.propertyIsEnumerable(cur)) return "def configOps";
if (verdictOps.propertyIsEnumerable(cur)) return "def verdictOps";
if (portOps.propertyIsEnumerable(cur)) return "def portOps";
if (sutOps.propertyIsEnumerable(cur)) return "def sutOps";
if (functionOps.propertyIsEnumerable(cur)) return "def functionOps";

if (verdictConsts.propertyIsEnumerable(cur)) return "string verdictConsts";
if (booleanConsts.propertyIsEnumerable(cur)) return "string booleanConsts";
if (otherConsts.propertyIsEnumerable(cur)) return "string otherConsts";

if (types.propertyIsEnumerable(cur)) return "builtin types";
if (visibilityModifiers.propertyIsEnumerable(cur))
return "builtin visibilityModifiers";
if (templateMatch.propertyIsEnumerable(cur)) return "atom templateMatch";

return "variable";
}

function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped){
var afterQuote = stream.peek();
//look if the character after the quote is like the B in '10100010'B
if (afterQuote){
afterQuote = afterQuote.toLowerCase();
if(afterQuote == "b" || afterQuote == "h" || afterQuote == "o")
stream.next();
}
end = true; break;
}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}

function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}

function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}

function pushContext(state, col, type) {
var indent = state.indented;
if (state.context && state.context.type == "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}

function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}

//Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},

token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment") return style;
if (ctx.align == null) ctx.align = true;

if ((curPunc == ";" || curPunc == ":" || curPunc == ",")
&& ctx.type == "statement"){
popContext(state);
}
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (indentStatements &&
(((ctx.type == "}" || ctx.type == "top") && curPunc != ';') ||
(ctx.type == "statement" && curPunc == "newstatement")))
pushContext(state, stream.column(), "statement");

state.startOfLine = false;

return style;
},

electricChars: "{}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//",
fold: "brace"
};
});

function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}

function def(mimes, mode) {
if (typeof mimes == "string") mimes = [mimes];
var words = [];
function add(obj) {
if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
words.push(prop);
}

add(mode.keywords);
add(mode.builtin);
add(mode.timerOps);
add(mode.portOps);

if (words.length) {
mode.helperType = mimes[0];
CodeMirror.registerHelper("hintWords", mimes[0], words);
}

for (var i = 0; i < mimes.length; ++i)
CodeMirror.defineMIME(mimes[i], mode);
}

def(["text/x-ttcn", "text/x-ttcn3", "text/x-ttcnpp"], {
name: "ttcn",
keywords: words("activate address alive all alt altstep and and4b any" +
" break case component const continue control deactivate" +
" display do else encode enumerated except exception" +
" execute extends extension external for from function" +
" goto group if import in infinity inout interleave" +
" label language length log match message mixed mod" +
" modifies module modulepar mtc noblock not not4b nowait" +
" of on optional or or4b out override param pattern port" +
" procedure record recursive rem repeat return runs select" +
" self sender set signature system template testcase to" +
" type union value valueof var variant while with xor xor4b"),
builtin: words("bit2hex bit2int bit2oct bit2str char2int char2oct encvalue" +
" decomp decvalue float2int float2str hex2bit hex2int" +
" hex2oct hex2str int2bit int2char int2float int2hex" +
" int2oct int2str int2unichar isbound ischosen ispresent" +
" isvalue lengthof log2str oct2bit oct2char oct2hex oct2int" +
" oct2str regexp replace rnd sizeof str2bit str2float" +
" str2hex str2int str2oct substr unichar2int unichar2char" +
" enum2int"),
types: words("anytype bitstring boolean char charstring default float" +
" hexstring integer objid octetstring universal verdicttype timer"),
timerOps: words("read running start stop timeout"),
portOps: words("call catch check clear getcall getreply halt raise receive" +
" reply send trigger"),
configOps: words("create connect disconnect done kill killed map unmap"),
verdictOps: words("getverdict setverdict"),
sutOps: words("action"),
functionOps: words("apply derefers refers"),

verdictConsts: words("error fail inconc none pass"),
booleanConsts: words("true false"),
otherConsts: words("null NULL omit"),

visibilityModifiers: words("private public friend"),
templateMatch: words("complement ifpresent subset superset permutation"),
multiLineStrings: true
});
});
Loading