21 changes: 13 additions & 8 deletions addon/hint/sql-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,9 @@
function addMatches(result, search, wordlist, formatter) {
for (var word in wordlist) {
if (!wordlist.hasOwnProperty(word)) continue;
if (Array.isArray(wordlist)) {
word = wordlist[word];
}
if (match(search, word)) {
result.push(formatter(word));
}
if (wordlist.slice) word = wordlist[word];

if (match(search, word)) result.push(formatter(word));
}
}

Expand Down Expand Up @@ -120,7 +117,7 @@
table = findTableByAlias(table, editor);

var columns = getItem(tables, table);
if (columns && Array.isArray(tables) && columns.columns)
if (columns && columns.columns)
columns = columns.columns;

if (columns) {
Expand Down Expand Up @@ -208,9 +205,17 @@
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
tables = (options && options.tables) || {};
var defaultTableName = options && options.defaultTable;
defaultTable = (defaultTableName && getItem(tables, defaultTableName)) || [];
defaultTable = defaultTableName && getItem(tables, defaultTableName);
keywords = keywords || getKeywords(editor);

if (defaultTableName && !defaultTable)
defaultTable = findTableByAlias(defaultTableName, editor);

defaultTable = defaultTable || [];

if (defaultTable.columns)
defaultTable = defaultTable.columns;

var cur = editor.getCursor();
var result = [];
var token = editor.getTokenAt(cur), start, end, search;
Expand Down
2 changes: 2 additions & 0 deletions addon/lint/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@

function onChange(cm) {
var state = cm.state.lint;
if (!state) return;
clearTimeout(state.timeout);
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
}
Expand All @@ -188,6 +189,7 @@
clearMarks(cm);
cm.off("change", onChange);
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
clearTimeout(cm.state.lint.timeout);
delete cm.state.lint;
}

Expand Down
40 changes: 40 additions & 0 deletions addon/merge/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
constructor: DiffView,
init: function(pane, orig, options) {
this.edit = this.mv.edit;
(this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this);
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options)));
this.orig.state.diffViews = [this];

this.diff = getDiff(asString(orig), asString(options.value));
this.chunks = getChunks(this.diff);
Expand Down Expand Up @@ -732,4 +734,42 @@
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; }

function findPrevDiff(chunks, start, isOrig) {
for (var i = chunks.length - 1; i >= 0; i--) {
var chunk = chunks[i];
var to = (isOrig ? chunk.origTo : chunk.editTo) - 1;
if (to < start) return to;
}
}

function findNextDiff(chunks, start, isOrig) {
for (var i = 0; i < chunks.length; i++) {
var chunk = chunks[i];
var from = (isOrig ? chunk.origFrom : chunk.editFrom);
if (from > start) return from;
}
}

function goNearbyDiff(cm, dir) {
var found = null, views = cm.state.diffViews, line = cm.getCursor().line;
if (views) for (var i = 0; i < views.length; i++) {
var dv = views[i], isOrig = cm == dv.orig;
ensureDiff(dv);
var pos = dir < 0 ? findPrevDiff(dv.chunks, line, isOrig) : findNextDiff(dv.chunks, line, isOrig);
if (pos != null && (found == null || (dir < 0 ? pos > found : pos < found)))
found = pos;
}
if (found != null)
cm.setCursor(found, 0);
else
return CodeMirror.Pass;
}

CodeMirror.commands.goNextDiff = function(cm) {
return goNearbyDiff(cm, 1);
};
CodeMirror.commands.goPrevDiff = function(cm) {
return goNearbyDiff(cm, -1);
};
});
10 changes: 8 additions & 2 deletions addon/scroll/simplescrollbars.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,20 @@
if (update !== false) this.scroll(pos, this.orientation);
};

var minButtonSize = 10;

Bar.prototype.update = function(scrollSize, clientSize, barSize) {
this.screen = clientSize;
this.total = scrollSize;
this.size = barSize;

// FIXME clip to min size?
var buttonSize = this.screen * (this.size / this.total);
if (buttonSize < minButtonSize) {
this.size -= minButtonSize - buttonSize;
buttonSize = minButtonSize;
}
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
this.screen * (this.size / this.total) + "px";
buttonSize + "px";
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
this.pos * (this.size / this.total) + "px";
};
Expand Down
2 changes: 1 addition & 1 deletion addon/tern/tern.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@
function atInterestingExpression(cm) {
var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false;
return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
}

// Variable renaming
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version":"5.0.0",
"version":"5.1.0",
"main": ["lib/codemirror.js", "lib/codemirror.css"],
"ignore": [
"**/.*",
Expand Down
5 changes: 4 additions & 1 deletion doc/compress.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ <h2>Script compression helper</h2>
<input type="hidden" id="download" name="download" value="codemirror-compressed.js"/>
<p>Version: <select id="version" onchange="setVersion(this);" style="padding: 1px;">
<option value="http://codemirror.net/">HEAD</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=5.1.0;f=">5.1</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=5.0.0;f=">5.0</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.13.0;f=">4.13</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.12.0;f=">4.12</option>
Expand Down Expand Up @@ -103,8 +104,10 @@ <h2>Script compression helper</h2>
</optgroup>
<optgroup label="Modes">
<option value="http://codemirror.net/mode/apl/apl.js">apl.js</option>
<option value="http://codemirror.net/mode/asciiarmor/asciiarmor.js">asciiarmor.js</option>
<option value="http://codemirror.net/mode/clike/clike.js">clike.js</option>
<option value="http://codemirror.net/mode/clojure/clojure.js">clojure.js</option>
<option value="http://codemirror.net/mode/cmake/cmake.js">cmake.js</option>
<option value="http://codemirror.net/mode/cobol/cobol.js">cobol.js</option>
<option value="http://codemirror.net/mode/coffeescript/coffeescript.js">coffeescript.js</option>
<option value="http://codemirror.net/mode/commonlisp/commonlisp.js">commonlisp.js</option>
Expand Down Expand Up @@ -171,7 +174,6 @@ <h2>Script compression helper</h2>
<option value="http://codemirror.net/mode/slim/slim.js">slim.js</option>
<option value="http://codemirror.net/mode/smalltalk/smalltalk.js">smalltalk.js</option>
<option value="http://codemirror.net/mode/smarty/smarty.js">smarty.js</option>
<option value="http://codemirror.net/mode/smartymixed/smartymixed.js">smartymixed.js</option>
<option value="http://codemirror.net/mode/solr/solr.js">solr.js</option>
<option value="http://codemirror.net/mode/soy/soy.js">soy.js</option>
<option value="http://codemirror.net/mode/sparql/sparql.js">sparql.js</option>
Expand All @@ -185,6 +187,7 @@ <h2>Script compression helper</h2>
<option value="http://codemirror.net/mode/tiki/tiki.js">tiki.js</option>
<option value="http://codemirror.net/mode/toml/toml.js">toml.js</option>
<option value="http://codemirror.net/mode/tornado/tornado.js">tornado.js</option>
<option value="http://codemirror.net/mode/troff/troff.js">troff.js</option>
<option value="http://codemirror.net/mode/turtle/turtle.js">turtle.js</option>
<option value="http://codemirror.net/mode/vb/vb.js">vb.js</option>
<option value="http://codemirror.net/mode/vbscript/vbscript.js">vbscript.js</option>
Expand Down
26 changes: 20 additions & 6 deletions doc/manual.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,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.0.0</span>
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.1.0</span>
</h2>

<p>CodeMirror is a code-editor component that can be embedded in
Expand Down Expand Up @@ -256,7 +256,7 @@ <h2>Configuration</h2>
should be replaced by a
special <a href="#option_specialCharPlaceholder">placeholder</a>.
Mostly useful for non-printing special characters. The default
is <code>/[\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/</code>.</dd>
is <code>/[\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/</code>.</dd>
<dt id="option_specialCharPlaceholder"><code><strong>specialCharPlaceholder</strong>: function(char) → Element</code></dt>
<dd>A function that, given a special character identified by
the <a href="#option_specialChars"><code>specialChars</code></a>
Expand Down Expand Up @@ -1622,6 +1622,11 @@ <h3 id="api_marker">Text-marking methods</h3>
<dt><code><strong>shared</strong>: boolean</code></dt><dd>See
the corresponding <a href="#mark_shared">option</a>
to <code>markText</code>.</dd>
<dt><code><strong>handleMouseEvents</strong>: boolean</code></dt>
<dd>As with <a href="#markText"><code>markText</code></a>,
this determines whether mouse events on the widget inserted
for this bookmark are handled by CodeMirror. The default is
false.</dd>
</dl></dd>

<dt id="findMarks"><code><strong>doc.findMarks</strong>(from: {line, ch}, to: {line, ch}) → array&lt;TextMarker&gt;</code></dt>
Expand Down Expand Up @@ -1691,7 +1696,7 @@ <h3 id="api_decoration">Widget, gutter, and decoration methods</h3>
widget again, simply use DOM methods (move it somewhere else, or
call <code>removeChild</code> on its parent).</dd>

<dt id="addLineWidget"><code><strong>cm.addLineWidget</strong>(line: integer|LineHandle, node: Element, ?options: object) → LineWidget</code></dt>
<dt id="addLineWidget"><code><strong>doc.addLineWidget</strong>(line: integer|LineHandle, node: Element, ?options: object) → LineWidget</code></dt>
<dd>Adds a line widget, an element shown below a line, spanning
the whole of the editor's width, and moving the lines below it
downwards. <code>line</code> should be either an integer or a
Expand Down Expand Up @@ -2634,8 +2639,14 @@ <h2 id="addons">Addons</h2>
to <code>true</code>, in which
case <a href="#getHelper"><code>getHelper</code></a> with
type <code>"lint"</code> is used to determined a validator
function. Depends on <code>addon/lint/lint.css</code>. A demo
can be found <a href="../demo/lint.html">here</a>.</dd>
function. Such a function should, when given a document string,
an options object, and an editor instance, return an array of <code>{message,
severity, from, to}</code> objects representing problems. When
the function has an <code>async</code> property with a truthy
value, it will be called with an additional second argument,
which is a callback to pass the array to. Depends
on <code>addon/lint/lint.css</code>. A demo can be
found <a href="../demo/lint.html">here</a>.</dd>

<dt id="addon_mark-selection"><a href="../addon/selection/mark-selection.js"><code>selection/mark-selection.js</code></a></dt>
<dd>Causes the selected text to be marked with the CSS class
Expand Down Expand Up @@ -2830,7 +2841,10 @@ <h2 id="addons">Addons</h2>
<dd>When true (the default), changed pieces of text are
highlighted.</dd>
</dl>
<a href="../demo/merge.html">Demo here</a>.</dd>
The addon also defines commands <code>"goNextDiff"</code>
and <code>"goPrevDiff"</code> to quickly jump to the next
changed chunk. <a href="../demo/merge.html">Demo
here</a>.</dd>

<dt id="addon_tern"><a href="../addon/tern/tern.js"><code>tern/tern.js</code></a></dt>
<dd>Provides integration with
Expand Down
32 changes: 26 additions & 6 deletions doc/releases.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a class=active data-default="true" href="#v4">Version 4.x</a>
<li><a class=active data-default="true" href="#v5">Version 5.x</a>
<li><a href="#v4">Version 4.x</a>
<li><a href="#v3">Version 3.x</a>
<li><a href="#v2">Version 2.x</a>
<li><a href="#v1">Version 0.x</a>
Expand All @@ -25,9 +26,22 @@

<h2>Release notes and version history</h2>

<section id=v4 class=first>
<section id=v5 class=first>

<h2>Version 4.x</h2>
<h2>Version 5.x</h2>

<p class="rel">23-03-2015: <a href="http://codemirror.net/codemirror-5.1.zip">Version 5.1</a>:</p>

<ul class="rel-note">
<li>New modes: <a href="../mode/asciiarmor/index.html">ASCII armor</a> (PGP data), <a href="../mode/troff/index.html">Troff</a>, and <a href="../mode/cmake/index.html">CMake</a>.</li>
<li>Remove SmartyMixed mode, rewrite <a href="../mode/smarty/index.html">Smarty</a> mode to supersede it.</li>
<li>New commands in the <a href="manual.html#addon_merge">merge
addon</a>: <code>goNextDiff</code> and <code>goPrevDiff</code>.</li>
<li>The <a href="manual.html#addon_closebrackets">closebrackets addon</a> can now be configured per mode.</li>
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/5.0.0...5.1.0">list of patches</a>.</li>
</ul>

<h2>Version 5.x</h2>

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

Expand All @@ -36,9 +50,15 @@ <h2>Version 4.x</h2>
<li>New option <a href="manual.html#option_inputStyle"><code>inputStyle</code></a> to switch between hidden textarea and contenteditable input.</li>
<li>The <a href="manual.html#getInputField"><code>getInputField</code></a>
method is no longer guaranteed to return a textarea.</li>
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.12.0...4.13.0">list of patches</a>.</li>
<li>Full <a href="https://github.com/codemirror/CodeMirror/compare/4.13.0...5.0.0">list of patches</a>.</li>
</ul>

</section>

<section id=v4 class=first>

<h2>Version 4.x</h2>

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

<ul class="rel-note">
Expand Down Expand Up @@ -1033,12 +1053,12 @@ <h2>Version 0.x</h2>
parser. And, as usual, add workarounds for various newly discovered
browser incompatibilities.</p>

<p class="rel"><em>31-08-2009</em>: <a href="http://codemirror.net/codemirror-0.63.zip">Version 0.63</a>:</p>
<p class="rel">31-08-2009: <a href="http://codemirror.net/codemirror-0.63.zip">Version 0.63</a>:</p>
<p class="rel-note"> Overhaul of paste-handling (less fragile), fixes for several
serious IE8 issues (cursor jumping, end-of-document bugs) and a number
of small problems.</p>

<p class="rel"><em>30-05-2009</em>: <a href="http://codemirror.net/codemirror-0.62.zip">Version 0.62</a>:</p>
<p class="rel">30-05-2009: <a href="http://codemirror.net/codemirror-0.62.zip">Version 0.62</a>:</p>
<p class="rel-note">Introduces <a href="contrib/python/index.html">Python</a>
and <a href="contrib/lua/index.html">Lua</a> parsers. Add
<code>setParser</code> (on-the-fly mode changing) and
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.0</a>.<br>
Get the current version: <a href="http://codemirror.net/codemirror.zip">5.1</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
13 changes: 13 additions & 0 deletions keymap/sublime.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,19 @@

map[cK + ctrl + "Backspace"] = "delLineLeft";

cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
if (cm.somethingSelected()) return CodeMirror.Pass;

var cursor = cm.getCursor();
var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor);
var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize"));

if (!/\S/.test(toStartOfLine) && column % cm.getOption("indentUnit") == 0)
return cm.indentSelection("subtract");
else
return CodeMirror.Pass;
};

cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
Expand Down
97 changes: 43 additions & 54 deletions keymap/vim.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,11 @@
}

var numberRegex = /[\d]/;
var wordRegexp = [(/\w/), (/[^\w\s]/)], bigWordRegexp = [(/\S/)];
var wordCharTest = [CodeMirror.isWordChar, function(ch) {
return ch && !CodeMirror.isWordChar(ch) && !/\s/.test(ch);
}], bigWordCharTest = [function(ch) {
return /\S/.test(ch);
}];
function makeKeyRange(start, size) {
var keys = [];
for (var i = start; i < start + size; i++) {
Expand Down Expand Up @@ -1035,12 +1039,10 @@
break;
case 'search':
this.processSearch(cm, vim, command);
clearInputState(cm);
break;
case 'ex':
case 'keyToEx':
this.processEx(cm, vim, command);
clearInputState(cm);
break;
default:
break;
Expand Down Expand Up @@ -1133,6 +1135,7 @@
updateSearchQuery(cm, query, ignoreCase, smartCase);
} catch (e) {
showConfirm(cm, 'Invalid regex: ' + query);
clearInputState(cm);
return;
}
commandDispatcher.processMotion(cm, vim, {
Expand Down Expand Up @@ -1182,6 +1185,7 @@
clearSearchHighlight(cm);
cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
CodeMirror.e_stop(e);
clearInputState(cm);
close();
cm.focus();
}
Expand Down Expand Up @@ -1248,6 +1252,7 @@
vimGlobalState.exCommandHistoryController.pushInput(input);
vimGlobalState.exCommandHistoryController.reset();
CodeMirror.e_stop(e);
clearInputState(cm);
close();
cm.focus();
}
Expand Down Expand Up @@ -2628,9 +2633,6 @@
function lineLength(cm, lineNum) {
return cm.getLine(lineNum).length;
}
function reverse(s){
return s.split('').reverse().join('');
}
function trim(s) {
if (s.trim) {
return s.trim();
Expand Down Expand Up @@ -2944,59 +2946,38 @@

// Seek to first word or non-whitespace character, depending on if
// noSymbol is true.
var textAfterIdx = line.substring(idx);
var firstMatchedChar;
if (noSymbol) {
firstMatchedChar = textAfterIdx.search(/\w/);
} else {
firstMatchedChar = textAfterIdx.search(/\S/);
var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0];
while (!test(line.charAt(idx))) {
idx++;
if (idx >= line.length) { return null; }
}
if (firstMatchedChar == -1) {
return null;
}
idx += firstMatchedChar;
textAfterIdx = line.substring(idx);
var textBeforeIdx = line.substring(0, idx);

var matchRegex;
// Greedy matchers for the "word" we are trying to expand.
if (bigWord) {
matchRegex = /^\S+/;
test = bigWordCharTest[0];
} else {
if ((/\w/).test(line.charAt(idx))) {
matchRegex = /^\w+/;
} else {
matchRegex = /^[^\w\s]+/;
test = wordCharTest[0];
if (!test(line.charAt(idx))) {
test = wordCharTest[1];
}
}

var wordAfterRegex = matchRegex.exec(textAfterIdx);
var wordStart = idx;
var wordEnd = idx + wordAfterRegex[0].length;
// TODO: Find a better way to do this. It will be slow on very long lines.
var revTextBeforeIdx = reverse(textBeforeIdx);
var wordBeforeRegex = matchRegex.exec(revTextBeforeIdx);
if (wordBeforeRegex) {
wordStart -= wordBeforeRegex[0].length;
}
var end = idx, start = idx;
while (test(line.charAt(end)) && end < line.length) { end++; }
while (test(line.charAt(start)) && start >= 0) { start--; }
start++;

if (inclusive) {
// If present, trim all whitespace after word.
// Otherwise, trim all whitespace before word.
var textAfterWordEnd = line.substring(wordEnd);
var whitespacesAfterWord = textAfterWordEnd.match(/^\s*/)[0].length;
if (whitespacesAfterWord > 0) {
wordEnd += whitespacesAfterWord;
} else {
var revTrim = revTextBeforeIdx.length - wordStart;
var textBeforeWordStart = revTextBeforeIdx.substring(revTrim);
var whitespacesBeforeWord = textBeforeWordStart.match(/^\s*/)[0].length;
wordStart -= whitespacesBeforeWord;
// If present, include all whitespace after word.
// Otherwise, include all whitespace before word, except indentation.
var wordEnd = end;
while (/\s/.test(line.charAt(end)) && end < line.length) { end++; }
if (wordEnd == end) {
var wordStart = start;
while (/\s/.test(line.charAt(start - 1)) && start > 0) { start--; }
if (!start) { start = wordStart; }
}
}

return { start: Pos(cur.line, wordStart),
end: Pos(cur.line, wordEnd) };
return { start: Pos(cur.line, start), end: Pos(cur.line, end) };
}

function recordJumpPosition(cm, oldCur, newCur) {
Expand Down Expand Up @@ -3154,7 +3135,7 @@
var pos = cur.ch;
var line = cm.getLine(lineNum);
var dir = forward ? 1 : -1;
var regexps = bigWord ? bigWordRegexp : wordRegexp;
var charTests = bigWord ? bigWordCharTest: wordCharTest;

if (emptyLineIsWord && line == '') {
lineNum += dir;
Expand All @@ -3174,11 +3155,11 @@
// Find bounds of next word.
while (pos != stop) {
var foundWord = false;
for (var i = 0; i < regexps.length && !foundWord; ++i) {
if (regexps[i].test(line.charAt(pos))) {
for (var i = 0; i < charTests.length && !foundWord; ++i) {
if (charTests[i](line.charAt(pos))) {
wordStart = pos;
// Advance to end of word.
while (pos != stop && regexps[i].test(line.charAt(pos))) {
while (pos != stop && charTests[i](line.charAt(pos))) {
pos += dir;
}
wordEnd = pos;
Expand Down Expand Up @@ -3510,7 +3491,8 @@
function dialog(cm, template, shortText, onClose, options) {
if (cm.openDialog) {
cm.openDialog(template, onClose, { bottom: true, value: options.value,
onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp });
onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp,
selectValueOnOpen: false});
}
else {
onClose(prompt(shortText, ''));
Expand Down Expand Up @@ -3888,6 +3870,13 @@
};
ExCommandDispatcher.prototype = {
processCommand: function(cm, input, opt_params) {
var that = this;
cm.operation(function () {
cm.curOp.isVimOp = true;
that._processCommand(cm, input, opt_params);
});
},
_processCommand: function(cm, input, opt_params) {
var vim = cm.state.vim;
var commandHistoryRegister = vimGlobalState.registerController.getRegister(':');
var previousCommand = commandHistoryRegister.toString();
Expand Down Expand Up @@ -4806,7 +4795,7 @@
var anchor = cm.getCursor('anchor');
var head = cm.getCursor('head');
// Enter or exit visual mode to match mouse selection.
if (vim.visualMode && cursorEqual(head, anchor) && lineLength(cm, head.line) > head.ch) {
if (vim.visualMode && !cm.somethingSelected()) {
exitVisualMode(cm, false);
} else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) {
vim.visualMode = true;
Expand Down
19 changes: 11 additions & 8 deletions lib/codemirror.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@
min-width: 20px;
text-align: right;
color: #999;
-moz-box-sizing: content-box;
box-sizing: content-box;
white-space: nowrap;
}

.CodeMirror-guttermarker { color: black; }
Expand Down Expand Up @@ -154,14 +153,10 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
-moz-box-sizing: content-box;
box-sizing: content-box;
}

/* The fake, visible scrollbars. Used to force redraw during scrolling
Expand Down Expand Up @@ -196,8 +191,6 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
-moz-box-sizing: content-box;
box-sizing: content-box;
display: inline-block;
margin-bottom: -30px;
/* Hack to make IE7 behave */
Expand Down Expand Up @@ -265,6 +258,16 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
outline: none;
}

/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}

.CodeMirror-measure {
position: absolute;
width: 100%;
Expand Down
168 changes: 104 additions & 64 deletions lib/codemirror.js

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions mode/asciiarmor/asciiarmor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// 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";

function errorIfNotEmpty(stream) {
var nonWS = stream.match(/^\s*\S/);
stream.skipToEnd();
return nonWS ? "error" : null;
}

CodeMirror.defineMode("asciiarmor", function() {
return {
token: function(stream, state) {
var m;
if (state.state == "top") {
if (stream.sol() && (m = stream.match(/^-----BEGIN (.*)?-----\s*$/))) {
state.state = "headers";
state.type = m[1];
return "tag";
}
return errorIfNotEmpty(stream);
} else if (state.state == "headers") {
if (stream.sol() && stream.match(/^\w+:/)) {
state.state = "header";
return "atom";
} else {
var result = errorIfNotEmpty(stream);
if (result) state.state = "body";
return result;
}
} else if (state.state == "header") {
stream.skipToEnd();
state.state = "headers";
return "string";
} else if (state.state == "body") {
if (stream.sol() && (m = stream.match(/^-----END (.*)?-----\s*$/))) {
if (m[1] != state.type) return "error";
state.state = "end";
return "tag";
} else {
if (stream.eatWhile(/[A-Za-z0-9+\/=]/)) {
return null;
} else {
stream.next();
return "error";
}
}
} else if (state.state == "end") {
return errorIfNotEmpty(stream);
}
},
blankLine: function(state) {
if (state.state == "headers") state.state = "body";
},
startState: function() {
return {state: "top", type: null};
}
};
});

CodeMirror.defineMIME("application/pgp", "asciiarmor");
CodeMirror.defineMIME("application/pgp-keys", "asciiarmor");
CodeMirror.defineMIME("application/pgp-signature", "asciiarmor");
});
46 changes: 46 additions & 0 deletions mode/asciiarmor/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!doctype html>

<title>CodeMirror: ASCII Armor (PGP) 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="asciiarmor.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>

<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">ASCII Armor</a>
</ul>
</div>

<article>
<h2>ASCII Armor (PGP) mode</h2>
<form><textarea id="code" name="code">
-----BEGIN PGP MESSAGE-----
Version: OpenPrivacy 0.99

yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS
vBSFjNSiVHsuAA==
=njUN
-----END PGP MESSAGE-----
</textarea></form>

<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true
});
</script>

<p><strong>MIME types
defined:</strong> <code>application/pgp</code>, <code>application/pgp-keys</code>, <code>application/pgp-signature</code></p>

</article>
3 changes: 2 additions & 1 deletion mode/clike/clike.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
return "atom";
}
}
},
modeProps: {closeBrackets: {triples: '"'}}
});

def(["x-shader/x-vertex", "x-shader/x-fragment"], {
Expand Down
1 change: 1 addition & 0 deletions mode/clojure/clojure.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ CodeMirror.defineMode("clojure", function (options) {
return state.indentStack.indent;
},

closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;"
};
});
Expand Down
97 changes: 97 additions & 0 deletions mode/cmake/cmake.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// 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")
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd)
define(["../../lib/codemirror"], mod);
else
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("cmake", function () {
var variable_regex = /({)?[a-zA-Z0-9_]+(})?/;

function tokenString(stream, state) {
var current, prev, found_var = false;
while (!stream.eol() && (current = stream.next()) != state.pending) {
if (current === '$' && prev != '\\' && state.pending == '"') {
found_var = true;
break;
}
prev = current;
}
if (found_var) {
stream.backUp(1);
}
if (current == state.pending) {
state.continueString = false;
} else {
state.continueString = true;
}
return "string";
}

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

// Have we found a variable?
if (ch === '$') {
if (stream.match(variable_regex)) {
return 'variable-2';
}
return 'variable';
}
// Should we still be looking for the end of a string?
if (state.continueString) {
// If so, go through the loop again
stream.backUp(1);
return tokenString(stream, state);
}
// Do we just have a function on our hands?
// In 'cmake_minimum_required (VERSION 2.8.8)', 'cmake_minimum_required' is matched
if (stream.match(/(\s+)?\w+\(/) || stream.match(/(\s+)?\w+\ \(/)) {
stream.backUp(1);
return 'def';
}
if (ch == "#") {
stream.skipToEnd();
return "comment";
}
// Have we found a string?
if (ch == "'" || ch == '"') {
// Store the type (single or double)
state.pending = ch;
// Perform the looping function to find the end
return tokenString(stream, state);
}
if (ch == '(' || ch == ')') {
return 'bracket';
}
if (ch.match(/[0-9]/)) {
return 'number';
}
stream.eatWhile(/[\w-]/);
return null;
}
return {
startState: function () {
var state = {};
state.inDefinition = false;
state.inInclude = false;
state.continueString = false;
state.pending = false;
return state;
},
token: function (stream, state) {
if (stream.eatSpace()) return null;
return tokenize(stream, state);
}
};
});

CodeMirror.defineMIME("text/x-cmake", "cmake");

});
129 changes: 129 additions & 0 deletions mode/cmake/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<!doctype html>

<title>CodeMirror: CMake 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="cmake.js"></script>
<style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default span.cm-arrow { color: red; }
</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>

<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">CMake</a>
</ul>
</div>

<article>
<h2>CMake mode</h2>
<form><textarea id="code" name="code">
# vim: syntax=cmake
if(NOT CMAKE_BUILD_TYPE)
# default to Release build for GCC builds
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif()
message(STATUS "cmake version ${CMAKE_VERSION}")
if(POLICY CMP0025)
cmake_policy(SET CMP0025 OLD) # report Apple's Clang as just Clang
endif()
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW) # MACOSX_RPATH
endif()

project (x265)
cmake_minimum_required (VERSION 2.8.8) # OBJECT libraries require 2.8.8
include(CheckIncludeFiles)
include(CheckFunctionExists)
include(CheckSymbolExists)
include(CheckCXXCompilerFlag)

# X265_BUILD must be incremented each time the public API is changed
set(X265_BUILD 48)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
"${PROJECT_BINARY_DIR}/x265_config.h")

SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")

# System architecture detection
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSPROC)
set(X86_ALIASES x86 i386 i686 x86_64 amd64)
list(FIND X86_ALIASES "${SYSPROC}" X86MATCH)
if("${SYSPROC}" STREQUAL "" OR X86MATCH GREATER "-1")
message(STATUS "Detected x86 target processor")
set(X86 1)
add_definitions(-DX265_ARCH_X86=1)
if("${CMAKE_SIZEOF_VOID_P}" MATCHES 8)
set(X64 1)
add_definitions(-DX86_64=1)
endif()
elseif(${SYSPROC} STREQUAL "armv6l")
message(STATUS "Detected ARM target processor")
set(ARM 1)
add_definitions(-DX265_ARCH_ARM=1 -DHAVE_ARMV6=1)
else()
message(STATUS "CMAKE_SYSTEM_PROCESSOR value `${CMAKE_SYSTEM_PROCESSOR}` is unknown")
message(STATUS "Please add this value near ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE}")
endif()

if(UNIX)
list(APPEND PLATFORM_LIBS pthread)
find_library(LIBRT rt)
if(LIBRT)
list(APPEND PLATFORM_LIBS rt)
endif()
find_package(Numa)
if(NUMA_FOUND)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${NUMA_LIBRARY})
check_symbol_exists(numa_node_of_cpu numa.h NUMA_V2)
if(NUMA_V2)
add_definitions(-DHAVE_LIBNUMA)
message(STATUS "libnuma found, building with support for NUMA nodes")
list(APPEND PLATFORM_LIBS ${NUMA_LIBRARY})
link_directories(${NUMA_LIBRARY_DIR})
include_directories(${NUMA_INCLUDE_DIR})
endif()
endif()
mark_as_advanced(LIBRT NUMA_FOUND)
endif(UNIX)

if(X64 AND NOT WIN32)
option(ENABLE_PIC "Enable Position Independent Code" ON)
else()
option(ENABLE_PIC "Enable Position Independent Code" OFF)
endif(X64 AND NOT WIN32)

# Compiler detection
if(CMAKE_GENERATOR STREQUAL "Xcode")
set(XCODE 1)
endif()
if (APPLE)
add_definitions(-DMACOS)
endif()
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/x-cmake",
matchBrackets: true,
indentUnit: 4
});
</script>

<p><strong>MIME types defined:</strong> <code>text/x-cmake</code>.</p>

</article>
1 change: 1 addition & 0 deletions mode/commonlisp/commonlisp.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ CodeMirror.defineMode("commonlisp", function (config) {
return typeof i == "number" ? i : state.ctx.start + 1;
},

closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;",
blockCommentStart: "#|",
blockCommentEnd: "|#"
Expand Down
1 change: 1 addition & 0 deletions mode/css/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == ")") return popContext(state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") wordAsValue(stream);
return "parens";
};
Expand Down
2 changes: 1 addition & 1 deletion mode/css/less.html
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ <h2>LESS mode</h2>
});
</script>

<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>

<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>, <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
</article>
2 changes: 1 addition & 1 deletion mode/css/scss.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ <h2>SCSS mode</h2>
});
</script>

<p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
<p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>

<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>, <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>

Expand Down
1 change: 1 addition & 0 deletions mode/groovy/groovy.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ CodeMirror.defineMode("groovy", function(config) {
},

electricChars: "{}",
closeBrackets: {triples: "'\""},
fold: "brace"
};
});
Expand Down
94 changes: 18 additions & 76 deletions mode/htmlembedded/htmlembedded.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,26 @@

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"));
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
require("../../addon/mode/multiplex"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../htmlmixed/htmlmixed"], mod);
define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
"../../addon/mode/multiplex"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {

//config settings
var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i,
scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i;

//inner modes
var scriptingMode, htmlMixedMode;

//tokenizer when in html mode
function htmlDispatch(stream, state) {
if (stream.match(scriptStartRegex, false)) {
state.token=scriptingDispatch;
return scriptingMode.token(stream, state.scriptState);
}
else
return htmlMixedMode.token(stream, state.htmlState);
}

//tokenizer when in scripting mode
function scriptingDispatch(stream, state) {
if (stream.match(scriptEndRegex, false)) {
state.token=htmlDispatch;
return htmlMixedMode.token(stream, state.htmlState);
}
else
return scriptingMode.token(stream, state.scriptState);
}


return {
startState: function() {
scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec);
htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
return {
token : parserConfig.startOpen ? scriptingDispatch : htmlDispatch,
htmlState : CodeMirror.startState(htmlMixedMode),
scriptState : CodeMirror.startState(scriptingMode)
};
},

token: function(stream, state) {
return state.token(stream, state);
},

indent: function(state, textAfter) {
if (state.token == htmlDispatch)
return htmlMixedMode.indent(state.htmlState, textAfter);
else if (scriptingMode.indent)
return scriptingMode.indent(state.scriptState, textAfter);
},

copyState: function(state) {
return {
token : state.token,
htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
scriptState : CodeMirror.copyState(scriptingMode, state.scriptState)
};
},

innerMode: function(state) {
if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
else return {state: state.htmlState, mode: htmlMixedMode};
}
};
}, "htmlmixed");

CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"});
CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"});
CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"});

"use strict";

CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
});
}, "htmlmixed");

CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"});
CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"});
CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"});
});
1 change: 1 addition & 0 deletions mode/htmlembedded/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../../addon/mode/multiplex.js"></script>
<script src="htmlembedded.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
Expand Down
5 changes: 3 additions & 2 deletions mode/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ <h2>Language modes</h2>
<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>
<li><a href="cmake/index.html">CMake</a></li>
<li><a href="cobol/index.html">COBOL</a></li>
<li><a href="coffeescript/index.html">CoffeeScript</a></li>
<li><a href="commonlisp/index.html">Common Lisp</a></li>
Expand Down Expand Up @@ -61,7 +62,6 @@ <h2>Language modes</h2>
<li><a href="haml/index.html">HAML</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 scripts</a></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 @@ -85,6 +85,7 @@ <h2>Language modes</h2>
<li><a href="pascal/index.html">Pascal</a></li>
<li><a href="pegjs/index.html">PEG.js</a></li>
<li><a href="perl/index.html">Perl</a></li>
<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="properties/index.html">Properties files</a></li>
Expand All @@ -106,7 +107,6 @@ <h2>Language modes</h2>
<li><a href="slim/index.html">Slim</a></li>
<li><a href="smalltalk/index.html">Smalltalk</a></li>
<li><a href="smarty/index.html">Smarty</a></li>
<li><a href="smartymixed/index.html">Smarty/HTML mixed</a></li>
<li><a href="solr/index.html">Solr</a></li>
<li><a href="soy/index.html">Soy</a></li>
<li><a href="stylus/index.html">Stylus</a></li>
Expand All @@ -119,6 +119,7 @@ <h2>Language modes</h2>
<li><a href="tiki/index.html">Tiki wiki</a></li>
<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="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
5 changes: 5 additions & 0 deletions mode/javascript/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function classBody(type, value) {
if (type == "variable" || cx.style == "keyword") {
if (value == "static") {
cx.marked = "keyword";
return cont(classBody);
}
cx.marked = "property";
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
return cont(functiondef, classBody);
Expand Down Expand Up @@ -669,6 +673,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",

helperType: jsonMode ? "json" : "javascript",
jsonldMode: jsonldMode,
Expand Down
1 change: 1 addition & 0 deletions mode/kotlin/kotlin.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ CodeMirror.defineMode("kotlin", function (config, parserConfig) {
else return ctx.indented + (closing ? 0 : config.indentUnit);
},

closeBrackets: {triples: "'\""},
electricChars: "{}"
};
});
Expand Down
6 changes: 4 additions & 2 deletions mode/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@

CodeMirror.modeInfo = [
{name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
{name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]},
{name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
{name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
{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: "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"]},
{name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
{name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
Expand Down Expand Up @@ -104,7 +106,6 @@
{name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
{name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
{name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
{name: "SmartyMixed", mime: "text/x-smarty", mode: "smartymixed"},
{name: "Solr", mime: "text/x-solr", mode: "solr"},
{name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
{name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
Expand All @@ -120,6 +121,7 @@
{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: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
{name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
{name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
Expand All @@ -128,7 +130,7 @@
{name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
{name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
{name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
{name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml"], alias: ["yml"]},
{name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
{name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}
];
// Ensure all modes have a mime property for backwards compatibility
Expand Down
2 changes: 1 addition & 1 deletion mode/mllike/mllike.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ CodeMirror.defineMode('mllike', function(_config, parserConfig) {
}
stream.eatWhile(/\w/);
var cur = stream.current();
return words[cur] || 'variable';
return words.hasOwnProperty(cur) ? words[cur] : 'variable';
}

function tokenString(stream, state) {
Expand Down
2 changes: 1 addition & 1 deletion mode/properties/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ CodeMirror.defineMode("properties", function() {
state.position = "quote";
return null;
} else if (ch === "\\" && state.position === "quote") {
if (stream.next() !== "u") { // u = Unicode sequence \u1234
if (stream.eol()) { // end of line?
// Multiline value
state.nextMultiline = true;
}
Expand Down
1 change: 1 addition & 0 deletions mode/python/python.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@
return scope.offset;
},

closeBrackets: {triples: "'\""},
lineComment: "#",
fold: "indent"
};
Expand Down
2 changes: 1 addition & 1 deletion mode/sass/sass.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ CodeMirror.defineMode("sass", function(config) {

if (stream.eatWhile(/[\w-]/)){
if(stream.match(/ *: *[\w-\+\$#!\("']/,false)){
return "propery";
return "property";
}
else if(stream.match(/ *:/,false)){
indent(state);
Expand Down
1 change: 1 addition & 0 deletions mode/scheme/scheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ CodeMirror.defineMode("scheme", function () {
return state.indentStack.indent;
},

closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;"
};
});
Expand Down
76 changes: 39 additions & 37 deletions mode/smarty/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../xml/xml.js"></script>
<script src="smarty.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
Expand Down Expand Up @@ -46,17 +47,24 @@ <h2>Smarty mode</h2>
{/function}
{/if}</textarea></form>

<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "smarty"
});
</script>
<p>Mode for Smarty version 2 or 3, which allows for custom delimiter tags.</p>

<br />
<p>Several configuration parameters are supported:</p>

<h3>Smarty 2, custom delimiters</h3>
<form><textarea id="code2" name="code2">
<ul>
<li><code>leftDelimiter</code> and <code>rightDelimiter</code>,
which should be strings that determine where the Smarty syntax
starts and ends.</li>
<li><code>version</code>, which should be 2 or 3.</li>
<li><code>baseMode</code>, which can be a mode spec
like <code>"text/html"</code> to set a different background mode.</li>
</ul>

<p><strong>MIME types defined:</strong> <code>text/x-smarty</code></p>

<h3>Smarty 2, custom delimiters</h3>

<form><textarea id="code2" name="code2">
{--extends file="parent.tpl"--}
{--include file="template.tpl"--}

Expand All @@ -78,27 +86,14 @@ <h3>Smarty 2, custom delimiters</h3>
{--/function--}
{--/if--}</textarea></form>

<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
lineNumbers: true,
mode: {
name: "smarty",
leftDelimiter: "{--",
rightDelimiter: "--}"
}
});
</script>

<br />

<h3>Smarty 3</h3>
<h3>Smarty 3</h3>

<textarea id="code3" name="code3">
<textarea id="code3" name="code3">
Nested tags {$foo={counter one=1 two={inception}}+3} are now valid in Smarty 3.

<script>
function test() {
console.log("Smarty 3 permits single curly braces followed by whitespace to NOT slip into Smarty mode.");
console.log("Smarty 3 permits single curly braces followed by whitespace to NOT slip into Smarty mode.");
}
</script>

Expand All @@ -121,16 +116,23 @@ <h3>Smarty 3</h3>

{$object->method1($x)->method2($y)}</textarea>

<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code3"), {
lineNumbers: true,
mode: "smarty",
smartyVersion: 3
});
</script>


<p>A plain text/Smarty version 2 or 3 mode, which allows for custom delimiter tags.</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "smarty"
});
var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
lineNumbers: true,
mode: {
name: "smarty",
leftDelimiter: "{--",
rightDelimiter: "--}"
}
});
var editor = CodeMirror.fromTextArea(document.getElementById("code3"), {
lineNumbers: true,
mode: {name: "smarty", version: 3, baseMode: "text/html"}
});
</script>

<p><strong>MIME types defined:</strong> <code>text/x-smarty</code></p>
</article>
</article>
207 changes: 100 additions & 107 deletions mode/smarty/smarty.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,134 +13,118 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("smarty", function(config) {
"use strict";

// our default settings; check to see if they're overridden
var settings = {
rightDelimiter: '}',
leftDelimiter: '{',
smartyVersion: 2 // for backward compatibility
};
if (config.hasOwnProperty("leftDelimiter")) {
settings.leftDelimiter = config.leftDelimiter;
}
if (config.hasOwnProperty("rightDelimiter")) {
settings.rightDelimiter = config.rightDelimiter;
}
if (config.hasOwnProperty("smartyVersion") && config.smartyVersion === 3) {
settings.smartyVersion = 3;
}

var keyFunctions = ["debug", "extends", "function", "include", "literal"];
var last;
var regs = {
operatorChars: /[+\-*&%=<>!?]/,
validIdentifier: /[a-zA-Z0-9_]/,
stringChar: /['"]/
};

var helpers = {
cont: function(style, lastType) {
CodeMirror.defineMode("smarty", function(config, parserConf) {
var rightDelimiter = parserConf.rightDelimiter || "}";
var leftDelimiter = parserConf.leftDelimiter || "{";
var version = parserConf.version || 2;
var baseMode = CodeMirror.getMode(config, parserConf.baseMode || "null");

var keyFunctions = ["debug", "extends", "function", "include", "literal"];
var regs = {
operatorChars: /[+\-*&%=<>!?]/,
validIdentifier: /[a-zA-Z0-9_]/,
stringChar: /['"]/
};

var last;
function cont(style, lastType) {
last = lastType;
return style;
},
chain: function(stream, state, parser) {
}

function chain(stream, state, parser) {
state.tokenize = parser;
return parser(stream, state);
}
};

// Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
function doesNotCount(stream, pos) {
if (pos == null) pos = stream.pos;
return version === 3 && leftDelimiter == "{" &&
(pos == stream.string.length || /\s/.test(stream.string.charAt(pos)));
}

// our various parsers
var parsers = {

// the main tokenizer
tokenizer: function(stream, state) {
if (stream.match(settings.leftDelimiter, true)) {
function tokenTop(stream, state) {
if (stream.match(leftDelimiter, true)) {
if (stream.eat("*")) {
return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
} else {
// Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
return chain(stream, state, tokenBlock("comment", "*" + rightDelimiter));
} else if (!doesNotCount(stream)) {
state.depth++;
var isEol = stream.eol();
var isFollowedByWhitespace = /\s/.test(stream.peek());
if (settings.smartyVersion === 3 && settings.leftDelimiter === "{" && (isEol || isFollowedByWhitespace)) {
state.depth--;
return null;
} else {
state.tokenize = parsers.smarty;
last = "startTag";
return "tag";
}
state.tokenize = tokenSmarty;
last = "startTag";
return "tag";
}
} else {
stream.next();
return null;
}
},

var token = baseMode.token(stream, state.base);
var text = stream.current();
var found = text.indexOf(leftDelimiter);
if (found > -1 && !doesNotCount(stream, stream.start + found + 1))
stream.backUp(text.length - found);
return token;
}

// parsing Smarty content
smarty: function(stream, state) {
if (stream.match(settings.rightDelimiter, true)) {
if (settings.smartyVersion === 3) {
function tokenSmarty(stream, state) {
if (stream.match(rightDelimiter, true)) {
if (version === 3) {
state.depth--;
if (state.depth <= 0) {
state.tokenize = parsers.tokenizer;
state.tokenize = tokenTop;
}
} else {
state.tokenize = parsers.tokenizer;
state.tokenize = tokenTop;
}
return helpers.cont("tag", null);
return cont("tag", null);
}

if (stream.match(settings.leftDelimiter, true)) {
if (stream.match(leftDelimiter, true)) {
state.depth++;
return helpers.cont("tag", "startTag");
return cont("tag", "startTag");
}

var ch = stream.next();
if (ch == "$") {
stream.eatWhile(regs.validIdentifier);
return helpers.cont("variable-2", "variable");
return cont("variable-2", "variable");
} else if (ch == "|") {
return helpers.cont("operator", "pipe");
return cont("operator", "pipe");
} else if (ch == ".") {
return helpers.cont("operator", "property");
return cont("operator", "property");
} else if (regs.stringChar.test(ch)) {
state.tokenize = parsers.inAttribute(ch);
return helpers.cont("string", "string");
state.tokenize = tokenAttribute(ch);
return cont("string", "string");
} else if (regs.operatorChars.test(ch)) {
stream.eatWhile(regs.operatorChars);
return helpers.cont("operator", "operator");
return cont("operator", "operator");
} else if (ch == "[" || ch == "]") {
return helpers.cont("bracket", "bracket");
return cont("bracket", "bracket");
} else if (ch == "(" || ch == ")") {
return helpers.cont("bracket", "operator");
return cont("bracket", "operator");
} else if (/\d/.test(ch)) {
stream.eatWhile(/\d/);
return helpers.cont("number", "number");
return cont("number", "number");
} else {

if (state.last == "variable") {
if (ch == "@") {
stream.eatWhile(regs.validIdentifier);
return helpers.cont("property", "property");
return cont("property", "property");
} else if (ch == "|") {
stream.eatWhile(regs.validIdentifier);
return helpers.cont("qualifier", "modifier");
return cont("qualifier", "modifier");
}
} else if (state.last == "pipe") {
stream.eatWhile(regs.validIdentifier);
return helpers.cont("qualifier", "modifier");
return cont("qualifier", "modifier");
} else if (state.last == "whitespace") {
stream.eatWhile(regs.validIdentifier);
return helpers.cont("attribute", "modifier");
return cont("attribute", "modifier");
} if (state.last == "property") {
stream.eatWhile(regs.validIdentifier);
return helpers.cont("property", null);
return cont("property", null);
} else if (/\s/.test(ch)) {
last = "whitespace";
return null;
Expand All @@ -156,66 +140,75 @@ CodeMirror.defineMode("smarty", function(config) {
}
for (var i=0, j=keyFunctions.length; i<j; i++) {
if (keyFunctions[i] == str) {
return helpers.cont("keyword", "keyword");
return cont("keyword", "keyword");
}
}
if (/\s/.test(ch)) {
return null;
}
return helpers.cont("tag", "tag");
return cont("tag", "tag");
}
},
}

inAttribute: function(quote) {
function tokenAttribute(quote) {
return function(stream, state) {
var prevChar = null;
var currChar = null;
while (!stream.eol()) {
currChar = stream.peek();
if (stream.next() == quote && prevChar !== '\\') {
state.tokenize = parsers.smarty;
state.tokenize = tokenSmarty;
break;
}
prevChar = currChar;
}
return "string";
};
},
}

inBlock: function(style, terminator) {
function tokenBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = parsers.tokenizer;
state.tokenize = tokenTop;
break;
}
stream.next();
}
return style;
};
}
};

return {
startState: function() {
return {
base: CodeMirror.startState(baseMode),
tokenize: tokenTop,
last: null,
depth: 0
};
},
copyState: function(state) {
return {
base: CodeMirror.copyState(baseMode, state.base),
tokenize: state.tokenize,
last: state.last,
depth: state.depth
};
},
innerMode: function(state) {
if (state.tokenize == tokenTop)
return {mode: baseMode, state: state.base};
},
token: function(stream, state) {
var style = state.tokenize(stream, state);
state.last = last;
return style;
},
blockCommentStart: leftDelimiter + "*",
blockCommentEnd: "*" + rightDelimiter
};
});

// the public API for CodeMirror
return {
startState: function() {
return {
tokenize: parsers.tokenizer,
mode: "smarty",
last: null,
depth: 0
};
},
token: function(stream, state) {
var style = state.tokenize(stream, state);
state.last = last;
return style;
},
electricChars: ""
};
});

CodeMirror.defineMIME("text/x-smarty", "smarty");

CodeMirror.defineMIME("text/x-smarty", "smarty");
});
114 changes: 0 additions & 114 deletions mode/smartymixed/index.html

This file was deleted.

197 changes: 0 additions & 197 deletions mode/smartymixed/smartymixed.js

This file was deleted.

8 changes: 5 additions & 3 deletions mode/stylus/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
<h2>Stylus mode</h2>
<form><textarea id="code" name="code">
/* Stylus mode */
#id
.class

#id,
.class,
article
font-family Arial, sans-serif

Expand Down Expand Up @@ -96,9 +97,10 @@ <h2>Stylus mode</h2>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
extraKeys: {"Ctrl-Space": "autocomplete"},
tabSize: 2
});
</script>

<p><strong>MIME types defined:</strong> <code>text/x-styl</code>.</p>

<p>Created by <a href="https://github.com/dmitrykiselyov">Dmitry Kiselyov</a></p>
</article>
983 changes: 651 additions & 332 deletions mode/stylus/stylus.js

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions mode/troff/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<!doctype html>

<title>CodeMirror: troff 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=troff.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="#">troff</a>
</ul>
</div>

<article>
<h2>troff</h2>


<textarea id=code>
'\" t
.\" Title: mkvextract
.TH "MKVEXTRACT" "1" "2015\-02\-28" "MKVToolNix 7\&.7\&.0" "User Commands"
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.SH "NAME"
mkvextract \- extract tracks from Matroska(TM) files into other files
.SH "SYNOPSIS"
.HP \w'\fBmkvextract\fR\ 'u
\fBmkvextract\fR {mode} {source\-filename} [options] [extraction\-spec]
.SH "DESCRIPTION"
.PP
.B mkvextract
extracts specific parts from a
.I Matroska(TM)
file to other useful formats\&. The first argument,
\fBmode\fR, tells
\fBmkvextract\fR(1)
what to extract\&. Currently supported is the extraction of
tracks,
tags,
attachments,
chapters,
CUE sheets,
timecodes
and
cues\&. The second argument is the name of the source file\&. It must be a
Matroska(TM)
file\&. All following arguments are options and extraction specifications; both of which depend on the selected mode\&.
.SS "Common options"
.PP
The following options are available in all modes and only described once in this section\&.
.PP
\fB\-f\fR, \fB\-\-parse\-fully\fR
.RS 4
Sets the parse mode to \*(Aqfull\*(Aq\&. The default mode does not parse the whole file but uses the meta seek elements for locating the required elements of a source file\&. In 99% of all cases this is enough\&. But for files that do not contain meta seek elements or which are damaged the user might have to use this mode\&. A full scan of a file can take a couple of minutes while a fast scan only takes seconds\&.
.RE
.PP
\fB\-\-command\-line\-charset\fR \fIcharacter\-set\fR
.RS 4
Sets the character set to convert strings given on the command line from\&. It defaults to the character set given by system\*(Aqs current locale\&.
.RE
.PP
\fB\-\-output\-charset\fR \fIcharacter\-set\fR
.RS 4
Sets the character set to which strings are converted that are to be output\&. It defaults to the character set given by system\*(Aqs current locale\&.
.RE
.PP
\fB\-r\fR, \fB\-\-redirect\-output\fR \fIfile\-name\fR
.RS 4
Writes all messages to the file
\fIfile\-name\fR
instead of to the console\&. While this can be done easily with output redirection there are cases in which this option is needed: when the terminal reinterprets the output before writing it to a file\&. The character set set with
\fB\-\-output\-charset\fR
is honored\&.
.RE
.PP
\fB\-\-ui\-language\fR \fIcode\fR
.RS 4
Forces the translations for the language
\fIcode\fR
to be used (e\&.g\&. \*(Aqde_DE\*(Aq for the German translations)\&. It is preferable to use the environment variables
\fILANG\fR,
\fILC_MESSAGES\fR
and
\fILC_ALL\fR
though\&. Entering \*(Aqlist\*(Aq as the
\fIcode\fR
will cause
\fBmkvextract\fR(1)
to output a list of available translations\&.

.\" [...]

.SH "SEE ALSO"
.PP
\fBmkvmerge\fR(1),
\fBmkvinfo\fR(1),
\fBmkvpropedit\fR(1),
\fBmmg\fR(1)
.SH "WWW"
.PP
The latest version can always be found at
\m[blue]\fBthe MKVToolNix homepage\fR\m[]\&\s-2\u[1]\d\s+2\&.
.SH "AUTHOR"
.PP
\(co \fBMoritz Bunkus\fR <\&moritz@bunkus\&.org\&>
.RS 4
Developer
.RE
.SH "NOTES"
.IP " 1." 4
the MKVToolNix homepage
.RS 4
\%https://www.bunkus.org/videotools/mkvtoolnix/
.RE
</textarea>

<script>
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
mode: 'troff',
lineNumbers: true,
matchBrackets: false
});
</script>

<p><strong>MIME types defined:</strong> <code>troff</code>.</p>
</article>
82 changes: 82 additions & 0 deletions mode/troff/troff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// 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")
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd)
define(["../../lib/codemirror"], mod);
else
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode('troff', function() {

var words = {};

function tokenBase(stream) {
if (stream.eatSpace()) return null;

var sol = stream.sol();
var ch = stream.next();

if (ch === '\\') {
if (stream.match('fB') || stream.match('fR') || stream.match('fI') ||
stream.match('u') || stream.match('d') ||
stream.match('%') || stream.match('&')) {
return 'string';
}
if (stream.match('m[')) {
stream.skipTo(']');
stream.next();
return 'string';
}
if (stream.match('s+') || stream.match('s-')) {
stream.eatWhile(/[\d-]/);
return 'string';
}
if (stream.match('\(') || stream.match('*\(')) {
stream.eatWhile(/[\w-]/);
return 'string';
}
return 'string';
}
if (sol && (ch === '.' || ch === '\'')) {
if (stream.eat('\\') && stream.eat('\"')) {
stream.skipToEnd();
return 'comment';
}
}
if (sol && ch === '.') {
if (stream.match('B ') || stream.match('I ') || stream.match('R ')) {
return 'attribute';
}
if (stream.match('TH ') || stream.match('SH ') || stream.match('SS ') || stream.match('HP ')) {
stream.skipToEnd();
return 'quote';
}
if ((stream.match(/[A-Z]/) && stream.match(/[A-Z]/)) || (stream.match(/[a-z]/) && stream.match(/[a-z]/))) {
return 'attribute';
}
}
stream.eatWhile(/[\w-]/);
var cur = stream.current();
return words.hasOwnProperty(cur) ? words[cur] : null;
}

function tokenize(stream, state) {
return (state.tokens[0] || tokenBase) (stream, state);
};

return {
startState: function() {return {tokens:[]};},
token: function(stream, state) {
return tokenize(stream, state);
}
};
});

CodeMirror.defineMIME('troff', 'troff');

});
11 changes: 6 additions & 5 deletions mode/vb/vb.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ CodeMirror.defineMode("vb", function(conf, parserConf) {
var middleKeywords = ['else','elseif','case', 'catch'];
var endKeywords = ['next','loop'];

var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'in']);
var commonkeywords = ['as', 'dim', 'break', 'continue','optional', 'then', 'until',
var operatorKeywords = ['and', 'or', 'not', 'xor', 'in'];
var wordOperators = wordRegexp(operatorKeywords);
var commonKeywords = ['as', 'dim', 'break', 'continue','optional', 'then', 'until',
'goto', 'byval','byref','new','handles','property', 'return',
'const','private', 'protected', 'friend', 'public', 'shared', 'static', 'true','false'];
var commontypes = ['integer','string','double','decimal','boolean','short','char', 'float','single'];

var keywords = wordRegexp(commonkeywords);
var keywords = wordRegexp(commonKeywords);
var types = wordRegexp(commontypes);
var stringPrefixes = '"';

Expand All @@ -47,8 +48,8 @@ CodeMirror.defineMode("vb", function(conf, parserConf) {

var indentInfo = null;



CodeMirror.registerHelper("hintWords", "vb", openingKeywords.concat(middleKeywords).concat(endKeywords)
.concat(operatorKeywords).concat(commonKeywords).concat(commontypes));

function indent(_stream, state) {
state.currentIndent++;
Expand Down
106 changes: 53 additions & 53 deletions mode/verilog/verilog.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,86 +375,86 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
name: "verilog"
});

// SVXVerilog mode
// TLVVerilog mode

var svxchScopePrefixes = {
var tlvchScopePrefixes = {
">": "property", "->": "property", "-": "hr", "|": "link", "?$": "qualifier", "?*": "qualifier",
"@-": "variable-3", "@": "variable-3", "?": "qualifier"
};

function svxGenIndent(stream, state) {
var svxindentUnit = 2;
function tlvGenIndent(stream, state) {
var tlvindentUnit = 2;
var rtnIndent = -1, indentUnitRq = 0, curIndent = stream.indentation();
switch (state.svxCurCtlFlowChar) {
switch (state.tlvCurCtlFlowChar) {
case "\\":
curIndent = 0;
break;
case "|":
if (state.svxPrevPrevCtlFlowChar == "@") {
if (state.tlvPrevPrevCtlFlowChar == "@") {
indentUnitRq = -2; //-2 new pipe rq after cur pipe
break;
}
if (svxchScopePrefixes[state.svxPrevCtlFlowChar])
if (tlvchScopePrefixes[state.tlvPrevCtlFlowChar])
indentUnitRq = 1; // +1 new scope
break;
case "M": // m4
if (state.svxPrevPrevCtlFlowChar == "@") {
if (state.tlvPrevPrevCtlFlowChar == "@") {
indentUnitRq = -2; //-2 new inst rq after pipe
break;
}
if (svxchScopePrefixes[state.svxPrevCtlFlowChar])
if (tlvchScopePrefixes[state.tlvPrevCtlFlowChar])
indentUnitRq = 1; // +1 new scope
break;
case "@":
if (state.svxPrevCtlFlowChar == "S")
if (state.tlvPrevCtlFlowChar == "S")
indentUnitRq = -1; // new pipe stage after stmts
if (state.svxPrevCtlFlowChar == "|")
if (state.tlvPrevCtlFlowChar == "|")
indentUnitRq = 1; // 1st pipe stage
break;
case "S":
if (state.svxPrevCtlFlowChar == "@")
if (state.tlvPrevCtlFlowChar == "@")
indentUnitRq = 1; // flow in pipe stage
if (svxchScopePrefixes[state.svxPrevCtlFlowChar])
if (tlvchScopePrefixes[state.tlvPrevCtlFlowChar])
indentUnitRq = 1; // +1 new scope
break;
}
var statementIndentUnit = svxindentUnit;
var statementIndentUnit = tlvindentUnit;
rtnIndent = curIndent + (indentUnitRq*statementIndentUnit);
return rtnIndent >= 0 ? rtnIndent : curIndent;
}

CodeMirror.defineMIME("text/x-svx", {
CodeMirror.defineMIME("text/x-tlv", {
name: "verilog",
hooks: {
"\\": function(stream, state) {
var vxIndent = 0, style = false;
var curPunc = stream.string;
if ((stream.sol()) && (/\\SV/.test(stream.string))) {
curPunc = (/\\SVX_version/.test(stream.string))
? "\\SVX_version" : stream.string;
if ((stream.sol()) && ((/\\SV/.test(stream.string)) || (/\\TLV/.test(stream.string)))) {
curPunc = (/\\TLV_version/.test(stream.string))
? "\\TLV_version" : stream.string;
stream.skipToEnd();
if (curPunc == "\\SV" && state.vxCodeActive) {state.vxCodeActive = false;};
if ((/\\SVX/.test(curPunc) && !state.vxCodeActive)
|| (curPunc=="\\SVX_version" && state.vxCodeActive)) {state.vxCodeActive = true;};
if ((/\\TLV/.test(curPunc) && !state.vxCodeActive)
|| (curPunc=="\\TLV_version" && state.vxCodeActive)) {state.vxCodeActive = true;};
style = "keyword";
state.svxCurCtlFlowChar = state.svxPrevPrevCtlFlowChar
= state.svxPrevCtlFlowChar = "";
state.tlvCurCtlFlowChar = state.tlvPrevPrevCtlFlowChar
= state.tlvPrevCtlFlowChar = "";
if (state.vxCodeActive == true) {
state.svxCurCtlFlowChar = "\\";
vxIndent = svxGenIndent(stream, state);
state.tlvCurCtlFlowChar = "\\";
vxIndent = tlvGenIndent(stream, state);
}
state.vxIndentRq = vxIndent;
}
return style;
},
tokenBase: function(stream, state) {
var vxIndent = 0, style = false;
var svxisOperatorChar = /[\[\]=:]/;
var svxkpScopePrefixs = {
var tlvisOperatorChar = /[\[\]=:]/;
var tlvkpScopePrefixs = {
"**":"variable-2", "*":"variable-2", "$$":"variable", "$":"variable",
"^^":"attribute", "^":"attribute"};
var ch = stream.peek();
var vxCurCtlFlowCharValueAtStart = state.svxCurCtlFlowChar;
var vxCurCtlFlowCharValueAtStart = state.tlvCurCtlFlowChar;
if (state.vxCodeActive == true) {
if (/[\[\]{}\(\);\:]/.test(ch)) {
// bypass nesting and 1 char punc
Expand All @@ -465,70 +465,70 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
if (stream.eat("/")) {
stream.skipToEnd();
style = "comment";
state.svxCurCtlFlowChar = "S";
state.tlvCurCtlFlowChar = "S";
} else {
stream.backUp(1);
}
} else if (ch == "@") {
// pipeline stage
style = svxchScopePrefixes[ch];
state.svxCurCtlFlowChar = "@";
style = tlvchScopePrefixes[ch];
state.tlvCurCtlFlowChar = "@";
stream.next();
stream.eatWhile(/[\w\$_]/);
} else if (stream.match(/\b[mM]4+/, true)) { // match: function(pattern, consume, caseInsensitive)
// m4 pre proc
stream.skipTo("(");
style = "def";
state.svxCurCtlFlowChar = "M";
state.tlvCurCtlFlowChar = "M";
} else if (ch == "!" && stream.sol()) {
// v stmt in svx region
// state.svxCurCtlFlowChar = "S";
// v stmt in tlv region
// state.tlvCurCtlFlowChar = "S";
style = "comment";
stream.next();
} else if (svxisOperatorChar.test(ch)) {
} else if (tlvisOperatorChar.test(ch)) {
// operators
stream.eatWhile(svxisOperatorChar);
stream.eatWhile(tlvisOperatorChar);
style = "operator";
} else if (ch == "#") {
// phy hier
state.svxCurCtlFlowChar = (state.svxCurCtlFlowChar == "")
? ch : state.svxCurCtlFlowChar;
state.tlvCurCtlFlowChar = (state.tlvCurCtlFlowChar == "")
? ch : state.tlvCurCtlFlowChar;
stream.next();
stream.eatWhile(/[+-]\d/);
style = "tag";
} else if (svxkpScopePrefixs.propertyIsEnumerable(ch)) {
// special SVX operators
style = svxkpScopePrefixs[ch];
state.svxCurCtlFlowChar = state.svxCurCtlFlowChar == "" ? "S" : state.svxCurCtlFlowChar; // stmt
} else if (tlvkpScopePrefixs.propertyIsEnumerable(ch)) {
// special TLV operators
style = tlvkpScopePrefixs[ch];
state.tlvCurCtlFlowChar = state.tlvCurCtlFlowChar == "" ? "S" : state.tlvCurCtlFlowChar; // stmt
stream.next();
stream.match(/[a-zA-Z_0-9]+/);
} else if (style = svxchScopePrefixes[ch] || false) {
// special SVX operators
state.svxCurCtlFlowChar = state.svxCurCtlFlowChar == "" ? ch : state.svxCurCtlFlowChar;
} else if (style = tlvchScopePrefixes[ch] || false) {
// special TLV operators
state.tlvCurCtlFlowChar = state.tlvCurCtlFlowChar == "" ? ch : state.tlvCurCtlFlowChar;
stream.next();
stream.match(/[a-zA-Z_0-9]+/);
}
if (state.svxCurCtlFlowChar != vxCurCtlFlowCharValueAtStart) { // flow change
vxIndent = svxGenIndent(stream, state);
if (state.tlvCurCtlFlowChar != vxCurCtlFlowCharValueAtStart) { // flow change
vxIndent = tlvGenIndent(stream, state);
state.vxIndentRq = vxIndent;
}
}
return style;
},
token: function(stream, state) {
if (state.vxCodeActive == true && stream.sol() && state.svxCurCtlFlowChar != "") {
state.svxPrevPrevCtlFlowChar = state.svxPrevCtlFlowChar;
state.svxPrevCtlFlowChar = state.svxCurCtlFlowChar;
state.svxCurCtlFlowChar = "";
if (state.vxCodeActive == true && stream.sol() && state.tlvCurCtlFlowChar != "") {
state.tlvPrevPrevCtlFlowChar = state.tlvPrevCtlFlowChar;
state.tlvPrevCtlFlowChar = state.tlvCurCtlFlowChar;
state.tlvCurCtlFlowChar = "";
}
},
indent: function(state) {
return (state.vxCodeActive == true) ? state.vxIndentRq : -1;
},
startState: function(state) {
state.svxCurCtlFlowChar = "";
state.svxPrevCtlFlowChar = "";
state.svxPrevPrevCtlFlowChar = "";
state.tlvCurCtlFlowChar = "";
state.tlvPrevCtlFlowChar = "";
state.tlvPrevPrevCtlFlowChar = "";
state.vxCodeActive = true;
state.vxIndentRq = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version":"5.0.0",
"version":"5.1.0",
"main": "lib/codemirror.js",
"description": "In-browser code editing made bearable",
"licenses": [{"type": "MIT",
Expand Down
7 changes: 7 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,13 @@ testCM("eventOrder", function(cm) {
eq(seen.join(","), "change,change,activity,change");
});

testCM("splitSpaces_nonspecial", function(cm) {
eq(byClassName(cm.getWrapperElement(), "cm-invalidchar").length, 0);
}, {
specialChars: /[\u00a0]/,
value: "spaces -> <- between"
});

test("core_rmClass", function() {
var node = document.createElement("div");
node.className = "foo-bar baz-quux yadda";
Expand Down
19 changes: 19 additions & 0 deletions test/vim_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,16 @@ testVim('dw_word', function(cm, vim, helpers) {
is(!register.linewise);
eqPos(curStart, cm.getCursor());
}, { value: ' word1 word2' });
testVim('dw_unicode_word', function(cm, vim, helpers) {
helpers.doKeys('d', 'w');
eq(cm.getValue().length, 10);
helpers.doKeys('d', 'w');
eq(cm.getValue().length, 6);
helpers.doKeys('d', 'w');
eq(cm.getValue().length, 5);
helpers.doKeys('d', 'e');
eq(cm.getValue().length, 2);
}, { value: ' \u0562\u0561\u0580\u0587\xbbe\xb5g ' });
testVim('dw_only_word', function(cm, vim, helpers) {
// Test that if there is only 1 word left, dw deletes till the end of the
// line.
Expand Down Expand Up @@ -2176,6 +2186,15 @@ testVim('S_visual', function(cm, vim, helpers) {
eq('\ncc', cm.getValue());
}, { value: 'aa\nbb\ncc'});

testVim('d_/', function(cm, vim, helpers) {
cm.openDialog = helpers.fakeOpenDialog('match');
helpers.doKeys('2', 'd', '/');
helpers.assertCursorAt(0, 0);
eq('match \n next', cm.getValue());
cm.openDialog = helpers.fakeOpenDialog('2');
helpers.doKeys('d', ':');
// TODO eq(' next', cm.getValue());
}, { value: 'text match match \n next' });
testVim('/ and n/N', function(cm, vim, helpers) {
cm.openDialog = helpers.fakeOpenDialog('match');
helpers.doKeys('/');
Expand Down
2 changes: 1 addition & 1 deletion theme/mdn-like.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
.cm-s-mdn-like.CodeMirror ::-moz-selection { background: #cfc; }

.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; }
.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; margin-left: 3px; }
.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; padding-left: 8px; }
div.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; }

.cm-s-mdn-like .cm-keyword { color: #6262FF; }
Expand Down