
32 changed files with 2882 additions and 3378 deletions
@ -1,9 +1,10 @@
|
||||
[ |
||||
"codemirror.css", |
||||
"codemirror.js", |
||||
"mode/css.js", |
||||
"mode/javascript.js", |
||||
"mode/xml.js", |
||||
"codemirror.css", |
||||
"mode/css/css.js", |
||||
"mode/javascript/javascript.js", |
||||
"mode/xml/xml.js", |
||||
"modes.js", |
||||
"init.js", |
||||
"init.css" |
||||
] |
@ -1,3 +0,0 @@
|
||||
language: node_js |
||||
node_js: |
||||
- 0.8 |
@ -1,76 +0,0 @@
|
||||
# How to contribute |
||||
|
||||
- [Getting help](#getting-help-) |
||||
- [Submitting bug reports](#submitting-bug-reports-) |
||||
- [Contributing code](#contributing-code-) |
||||
|
||||
## Getting help |
||||
|
||||
Community discussion, questions, and informal bug reporting is done on the |
||||
[discuss.CodeMirror forum](http://discuss.codemirror.net). |
||||
|
||||
## Submitting bug reports |
||||
|
||||
The preferred way to report bugs is to use the |
||||
[GitHub issue tracker](http://github.com/codemirror/CodeMirror/issues). Before |
||||
reporting a bug, read these pointers. |
||||
|
||||
**Note:** The issue tracker is for *bugs*, not requests for help. Questions |
||||
should be asked on the |
||||
[discuss.CodeMirror forum](http://discuss.codemirror.net) instead. |
||||
|
||||
### Reporting bugs effectively |
||||
|
||||
- CodeMirror is maintained by volunteers. They don't owe you anything, so be |
||||
polite. Reports with an indignant or belligerent tone tend to be moved to the |
||||
bottom of the pile. |
||||
|
||||
- Include information about **the browser in which the problem occurred**. Even |
||||
if you tested several browsers, and the problem occurred in all of them, |
||||
mention this fact in the bug report. Also include browser version numbers and |
||||
the operating system that you're on. |
||||
|
||||
- Mention which release of CodeMirror you're using. Preferably, try also with |
||||
the current development snapshot, to ensure the problem has not already been |
||||
fixed. |
||||
|
||||
- Mention very precisely what went wrong. "X is broken" is not a good bug |
||||
report. What did you expect to happen? What happened instead? Describe the |
||||
exact steps a maintainer has to take to make the problem occur. We can not |
||||
fix something that we can not observe. |
||||
|
||||
- If the problem can not be reproduced in any of the demos included in the |
||||
CodeMirror distribution, please provide an HTML document that demonstrates |
||||
the problem. The best way to do this is to go to |
||||
[jsbin.com](http://jsbin.com/ihunin/edit), enter it there, press save, and |
||||
include the resulting link in your bug report. |
||||
|
||||
## Contributing code |
||||
|
||||
- Make sure you have a [GitHub Account](https://github.com/signup/free) |
||||
- Fork [CodeMirror](https://github.com/codemirror/CodeMirror/) |
||||
([how to fork a repo](https://help.github.com/articles/fork-a-repo)) |
||||
- Make your changes |
||||
- If your changes are easy to test or likely to regress, add tests. |
||||
Tests for the core go into `test/test.js`, some modes have their own |
||||
test suite under `mode/XXX/test.js`. Feel free to add new test |
||||
suites to modes that don't have one yet (be sure to link the new |
||||
tests into `test/index.html`). |
||||
- Follow the general code style of the rest of the project (see |
||||
below). Run `bin/lint` to verify that the linter is happy. |
||||
- Make sure all tests pass. Visit `test/index.html` in your browser to |
||||
run them. |
||||
- Submit a pull request |
||||
([how to create a pull request](https://help.github.com/articles/fork-a-repo)) |
||||
|
||||
### Coding standards |
||||
|
||||
- 2 spaces per indentation level, no tabs. |
||||
- Include semicolons after statements. |
||||
- Note that the linter (`bin/lint`) which is run after each commit |
||||
complains about unused variables and functions. Prefix their names |
||||
with an underscore to muffle it. |
||||
|
||||
- CodeMirror does *not* follow JSHint or JSLint prescribed style. |
||||
Patches that try to 'fix' code to pass one of these linters will be |
||||
unceremoniously discarded. |
@ -1,19 +0,0 @@
|
||||
Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in |
||||
all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
THE SOFTWARE. |
@ -1,11 +0,0 @@
|
||||
# CodeMirror |
||||
[](https://travis-ci.org/codemirror/CodeMirror) |
||||
[](https://www.npmjs.org/package/codemirror) |
||||
|
||||
CodeMirror is a JavaScript component that provides a code editor in |
||||
the browser. When a mode is available for the language you are coding |
||||
in, it will color your code, and optionally help with indentation. |
||||
|
||||
The project page is http://codemirror.net |
||||
The manual is at http://codemirror.net/doc/manual.html |
||||
The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md) |
@ -1,16 +0,0 @@
|
||||
{ |
||||
"name": "codemirror", |
||||
"version":"4.8.0", |
||||
"main": ["lib/codemirror.js", "lib/codemirror.css"], |
||||
"ignore": [ |
||||
"**/.*", |
||||
"node_modules", |
||||
"components", |
||||
"bin", |
||||
"demo", |
||||
"doc", |
||||
"test", |
||||
"index.html", |
||||
"package.json" |
||||
] |
||||
} |
@ -1,199 +0,0 @@
|
||||
<!doctype html> |
||||
|
||||
<title>CodeMirror</title> |
||||
<meta charset="utf-8"/> |
||||
|
||||
<link rel=stylesheet href="lib/codemirror.css"> |
||||
<link rel=stylesheet href="doc/docs.css"> |
||||
<script src="lib/codemirror.js"></script> |
||||
<script src="mode/xml/xml.js"></script> |
||||
<script src="mode/javascript/javascript.js"></script> |
||||
<script src="mode/css/css.js"></script> |
||||
<script src="mode/htmlmixed/htmlmixed.js"></script> |
||||
<script src="addon/edit/matchbrackets.js"></script> |
||||
|
||||
<script src="doc/activebookmark.js"></script> |
||||
|
||||
<style> |
||||
.CodeMirror { height: auto; border: 1px solid #ddd; } |
||||
.CodeMirror-scroll { max-height: 200px; } |
||||
.CodeMirror pre { padding-left: 7px; line-height: 1.25; } |
||||
</style> |
||||
|
||||
<div id=nav> |
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="doc/logo.png"></a> |
||||
|
||||
<ul> |
||||
<li><a class=active data-default="true" href="#description">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="#features">Features</a> |
||||
<li><a href="#community">Community</a> |
||||
<li><a href="#browsersupport">Browser support</a> |
||||
</ul> |
||||
</div> |
||||
|
||||
<article> |
||||
|
||||
<section id=description class=first> |
||||
<p><strong>CodeMirror</strong> is a versatile text editor |
||||
implemented in JavaScript for the browser. It is specialized for |
||||
editing code, and comes with a number of <a href="mode/index.html">language modes</a> and <a href="doc/manual.html#addons">addons</a> |
||||
that implement more advanced editing functionality.</p> |
||||
|
||||
<p>A rich <a href="doc/manual.html#api">programming API</a> and a |
||||
CSS <a href="doc/manual.html#styling">theming</a> system are |
||||
available for customizing CodeMirror to fit your application, and |
||||
extending it with new functionality.</p> |
||||
</section> |
||||
|
||||
<section id=demo> |
||||
<h2>This is CodeMirror</h2> |
||||
<form style="position: relative; margin-top: .5em;"><textarea id=demotext> |
||||
<!-- Create a simple CodeMirror instance --> |
||||
<link rel="stylesheet" href="lib/codemirror.css"> |
||||
<script src="lib/codemirror.js"></script> |
||||
<script> |
||||
var editor = CodeMirror.fromTextArea(myTextarea, { |
||||
lineNumbers: true |
||||
}); |
||||
</script></textarea> |
||||
<select id="demolist" onchange="document.location = this.options[this.selectedIndex].value;"> |
||||
<option value="#">Other demos...</option> |
||||
<option value="demo/complete.html">Autocompletion</option> |
||||
<option value="demo/folding.html">Code folding</option> |
||||
<option value="demo/theme.html">Themes</option> |
||||
<option value="mode/htmlmixed/index.html">Mixed language modes</option> |
||||
<option value="demo/bidi.html">Bi-directional text</option> |
||||
<option value="demo/variableheight.html">Variable font sizes</option> |
||||
<option value="demo/search.html">Search interface</option> |
||||
<option value="demo/vim.html">Vim bindings</option> |
||||
<option value="demo/emacs.html">Emacs bindings</option> |
||||
<option value="demo/sublime.html">Sublime Text bindings</option> |
||||
<option value="demo/tern.html">Tern integration</option> |
||||
<option value="demo/merge.html">Merge/diff interface</option> |
||||
<option value="demo/fullscreen.html">Full-screen editor</option> |
||||
</select></form> |
||||
<script> |
||||
var editor = CodeMirror.fromTextArea(document.getElementById("demotext"), { |
||||
lineNumbers: true, |
||||
mode: "text/html", |
||||
matchBrackets: true |
||||
}); |
||||
</script> |
||||
<div style="position: relative; margin: 1em 0;"> |
||||
<a class="bigbutton left" href="http://codemirror.net/codemirror.zip">DOWNLOAD LATEST RELEASE</a> |
||||
<div><strong>version 4.8</strong> (<a href="doc/releases.html">Release notes</a>)</div> |
||||
<div>or use the <a href="doc/compress.html">minification helper</a></div> |
||||
<div style="position: absolute; top: 0; right: 0; text-align: right"> |
||||
<span class="bigbutton right" onclick="document.getElementById('paypal').submit();">DONATE WITH PAYPAL</span> |
||||
<div style="position: relative"> |
||||
or <span onclick="document.getElementById('bankinfo').style.display = 'block';" class=quasilink>Bank</span>, |
||||
<span onclick="document.getElementById('bcinfo').style.display = 'block';" class=quasilink>Bitcoin</span>, |
||||
<a href="https://www.gittip.com/marijnh">Gittip</a>, |
||||
<a href="https://flattr.com/profile/marijnh">Flattr</a><br> |
||||
<div id=bankinfo class=bankinfo> |
||||
<span class=bankinfo_close onclick="document.getElementById('bankinfo').style.display = '';">×</span> |
||||
Bank: <i>Rabobank</i><br/> |
||||
Country: <i>Netherlands</i><br/> |
||||
SWIFT: <i>RABONL2U</i><br/> |
||||
Account: <i>147850770</i><br/> |
||||
Name: <i>Marijn Haverbeke</i><br/> |
||||
IBAN: <i>NL26 RABO 0147 8507 70</i> |
||||
</div> |
||||
<div id=bcinfo class=bankinfo> |
||||
<span class=bankinfo_close onclick="document.getElementById('bcinfo').style.display = '';">×</span> |
||||
Bitcoin address: 1HVnnU8E9yLPeFyNgNtUPB5deXBvUmZ6Nx |
||||
</div> |
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="paypal"> |
||||
<input type="hidden" name="cmd" value="_s-xclick"/> |
||||
<input type="hidden" name="hosted_button_id" value="3FVHS5FGUY7CC"/> |
||||
</form> |
||||
</div> |
||||
<div> |
||||
Purchase <a href="http://codemirror.com">commercial support</a> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
|
||||
<section id=features> |
||||
<h2>Features</h2> |
||||
<ul> |
||||
<li>Support for <a href="mode/index.html">over 60 languages</a> out of the box |
||||
<li>A powerful, <a href="mode/htmlmixed/index.html">composable</a> language mode <a href="doc/manual.html#modeapi">system</a> |
||||
<li><a href="doc/manual.html#addon_show-hint">Autocompletion</a> (<a href="demo/xmlcomplete.html">XML</a>) |
||||
<li><a href="doc/manual.html#addon_foldcode">Code folding</a> |
||||
<li><a href="doc/manual.html#option_extraKeys">Configurable</a> keybindings |
||||
<li><a href="demo/vim.html">Vim</a>, <a href="demo/emacs.html">Emacs</a>, and <a href="demo/sublime.html">Sublime Text</a> bindings |
||||
<li><a href="doc/manual.html#addon_search">Search and replace</a> interface |
||||
<li><a href="doc/manual.html#addon_matchbrackets">Bracket</a> and <a href="doc/manual.html#addon_matchtags">tag</a> matching |
||||
<li>Support for <a href="demo/buffers.html">split views</a> |
||||
<li><a href="doc/manual.html#addon_lint">Linter integration</a> |
||||
<li><a href="demo/variableheight.html">Mixing font sizes and styles</a> |
||||
<li><a href="demo/theme.html">Various themes</a> |
||||
<li>Able to <a href="demo/resize.html">resize to fit content</a> |
||||
<li><a href="doc/manual.html#mark_replacedWith">Inline</a> and <a href="doc/manual.html#addLineWidget">block</a> widgets |
||||
<li>Programmable <a href="demo/marker.html">gutters</a> |
||||
<li>Making ranges of text <a href="doc/manual.html#markText">styled, read-only, or atomic</a> |
||||
<li><a href="demo/bidi.html">Bi-directional text</a> support |
||||
<li>Many other <a href="doc/manual.html#api">methods</a> and <a href="doc/manual.html#addons">addons</a>... |
||||
</ul> |
||||
</section> |
||||
|
||||
<section id=community> |
||||
<h2>Community</h2> |
||||
|
||||
<p>CodeMirror is an open-source project shared under |
||||
an <a href="LICENSE">MIT license</a>. It is the editor used in the |
||||
dev tools for |
||||
both <a href="https://hacks.mozilla.org/2013/11/firefox-developer-tools-episode-27-edit-as-html-codemirror-more/">Firefox</a> |
||||
and <a href="https://developers.google.com/chrome-developer-tools/">Chrome</a>, <a href="http://www.lighttable.com/">Light |
||||
Table</a>, <a href="http://brackets.io/">Adobe |
||||
Brackets</a>, <a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a>, |
||||
and <a href="doc/realworld.html">many other projects</a>.</p> |
||||
|
||||
<p>Development and bug tracking happens |
||||
on <a href="https://github.com/codemirror/CodeMirror/">github</a> |
||||
(<a href="http://marijnhaverbeke.nl/git/codemirror">alternate git |
||||
repository</a>). |
||||
Please <a href="http://codemirror.net/doc/reporting.html">read these |
||||
pointers</a> before submitting a bug. Use pull requests to submit |
||||
patches. All contributions must be released under the same MIT |
||||
license that CodeMirror uses.</p> |
||||
|
||||
<p>Discussion around the project is done on |
||||
a <a href="http://discuss.codemirror.net">discussion forum</a>. |
||||
There is also |
||||
the <a href="http://groups.google.com/group/codemirror-announce">codemirror-announce</a> |
||||
list, which is only used for major announcements (such as new |
||||
versions). If needed, you can |
||||
contact <a href="mailto:marijnh@gmail.com">the maintainer</a> |
||||
directly.</p> |
||||
|
||||
<p>A list of CodeMirror-related software that is not part of the |
||||
main distribution is maintained |
||||
on <a href="https://github.com/codemirror/CodeMirror/wiki/CodeMirror-addons">our |
||||
wiki</a>. Feel free to add your project.</p> |
||||
</section> |
||||
|
||||
<section id=browsersupport> |
||||
<h2>Browser support</h2> |
||||
<p>The <em>desktop</em> versions of the following browsers, |
||||
in <em>standards mode</em> (HTML5 <code><!doctype html></code> |
||||
recommended) are supported:</p> |
||||
<table style="margin-bottom: 1em"> |
||||
<tr><th>Firefox</th><td>version 4 and up</td></tr> |
||||
<tr><th>Chrome</th><td>any version</td></tr> |
||||
<tr><th>Safari</th><td>version 5.2 and up</td></tr> |
||||
<tr><th style="padding-right: 1em;">Internet Explorer</th><td>version 8 and up</td></tr> |
||||
<tr><th>Opera</th><td>version 9 and up</td></tr> |
||||
</table> |
||||
<p>Modern mobile browsers tend to partly work. Bug reports and |
||||
patches for mobile support are welcome, but the maintainer does not |
||||
have the time or budget to actually work on it himself.</p> |
||||
</section> |
||||
|
||||
</article> |
@ -1,884 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://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 Context(indented, column, type, info, align, prev) { |
||||
this.indented = indented; |
||||
this.column = column; |
||||
this.type = type; |
||||
this.info = info; |
||||
this.align = align; |
||||
this.prev = prev; |
||||
} |
||||
function pushContext(state, col, type, info) { |
||||
var indent = state.indented; |
||||
if (state.context && state.context.type == "statement" && type != "statement") |
||||
indent = state.context.indented; |
||||
return state.context = new Context(indent, col, type, info, null, state.context); |
||||
} |
||||
function popContext(state) { |
||||
var t = state.context.type; |
||||
if (t == ")" || t == "]" || t == "}") |
||||
state.indented = state.context.indented; |
||||
return state.context = state.context.prev; |
||||
} |
||||
|
||||
function typeBefore(stream, state, pos) { |
||||
if (state.prevToken == "variable" || state.prevToken == "type") return true; |
||||
if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true; |
||||
if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true; |
||||
} |
||||
|
||||
function isTopScope(context) { |
||||
for (;;) { |
||||
if (!context || context.type == "top") return true; |
||||
if (context.type == "}" && context.prev.info != "namespace") return false; |
||||
context = context.prev; |
||||
} |
||||
} |
||||
|
||||
CodeMirror.defineMode("clike", function(config, parserConfig) { |
||||
var indentUnit = config.indentUnit, |
||||
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, |
||||
dontAlignCalls = parserConfig.dontAlignCalls, |
||||
keywords = parserConfig.keywords || {}, |
||||
types = parserConfig.types || {}, |
||||
builtin = parserConfig.builtin || {}, |
||||
blockKeywords = parserConfig.blockKeywords || {}, |
||||
defKeywords = parserConfig.defKeywords || {}, |
||||
atoms = parserConfig.atoms || {}, |
||||
hooks = parserConfig.hooks || {}, |
||||
multiLineStrings = parserConfig.multiLineStrings, |
||||
indentStatements = parserConfig.indentStatements !== false, |
||||
indentSwitch = parserConfig.indentSwitch !== false, |
||||
namespaceSeparator = parserConfig.namespaceSeparator, |
||||
isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/, |
||||
numberStart = parserConfig.numberStart || /[\d\.]/, |
||||
number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i, |
||||
isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/, |
||||
isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/, |
||||
// An optional function that takes a {string} token and returns true if it
|
||||
// should be treated as a builtin.
|
||||
isReservedIdentifier = parserConfig.isReservedIdentifier || false; |
||||
|
||||
var curPunc, isDefKeyword; |
||||
|
||||
function tokenBase(stream, state) { |
||||
var ch = stream.next(); |
||||
if (hooks[ch]) { |
||||
var result = hooks[ch](stream, state); |
||||
if (result !== false) return result; |
||||
} |
||||
if (ch == '"' || ch == "'") { |
||||
state.tokenize = tokenString(ch); |
||||
return state.tokenize(stream, state); |
||||
} |
||||
if (isPunctuationChar.test(ch)) { |
||||
curPunc = ch; |
||||
return null; |
||||
} |
||||
if (numberStart.test(ch)) { |
||||
stream.backUp(1) |
||||
if (stream.match(number)) return "number" |
||||
stream.next() |
||||
} |
||||
if (ch == "/") { |
||||
if (stream.eat("*")) { |
||||
state.tokenize = tokenComment; |
||||
return tokenComment(stream, state); |
||||
} |
||||
if (stream.eat("/")) { |
||||
stream.skipToEnd(); |
||||
return "comment"; |
||||
} |
||||
} |
||||
if (isOperatorChar.test(ch)) { |
||||
while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {} |
||||
return "operator"; |
||||
} |
||||
stream.eatWhile(isIdentifierChar); |
||||
if (namespaceSeparator) while (stream.match(namespaceSeparator)) |
||||
stream.eatWhile(isIdentifierChar); |
||||
|
||||
var cur = stream.current(); |
||||
if (contains(keywords, cur)) { |
||||
if (contains(blockKeywords, cur)) curPunc = "newstatement"; |
||||
if (contains(defKeywords, cur)) isDefKeyword = true; |
||||
return "keyword"; |
||||
} |
||||
if (contains(types, cur)) return "type"; |
||||
if (contains(builtin, cur) |
||||
|| (isReservedIdentifier && isReservedIdentifier(cur))) { |
||||
if (contains(blockKeywords, cur)) curPunc = "newstatement"; |
||||
return "builtin"; |
||||
} |
||||
if (contains(atoms, cur)) return "atom"; |
||||
return "variable"; |
||||
} |
||||
|
||||
function tokenString(quote) { |
||||
return function(stream, state) { |
||||
var escaped = false, next, end = false; |
||||
while ((next = stream.next()) != null) { |
||||
if (next == quote && !escaped) {end = true; break;} |
||||
escaped = !escaped && next == "\\"; |
||||
} |
||||
if (end || !(escaped || multiLineStrings)) |
||||
state.tokenize = null; |
||||
return "string"; |
||||
}; |
||||
} |
||||
|
||||
function tokenComment(stream, state) { |
||||
var maybeEnd = false, ch; |
||||
while (ch = stream.next()) { |
||||
if (ch == "/" && maybeEnd) { |
||||
state.tokenize = null; |
||||
break; |
||||
} |
||||
maybeEnd = (ch == "*"); |
||||
} |
||||
return "comment"; |
||||
} |
||||
|
||||
function maybeEOL(stream, state) { |
||||
if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context)) |
||||
state.typeAtEndOfLine = typeBefore(stream, state, stream.pos) |
||||
} |
||||
|
||||
// Interface
|
||||
|
||||
return { |
||||
startState: function(basecolumn) { |
||||
return { |
||||
tokenize: null, |
||||
context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false), |
||||
indented: 0, |
||||
startOfLine: true, |
||||
prevToken: null |
||||
}; |
||||
}, |
||||
|
||||
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()) { maybeEOL(stream, state); return null; } |
||||
curPunc = isDefKeyword = null; |
||||
var style = (state.tokenize || tokenBase)(stream, state); |
||||
if (style == "comment" || style == "meta") return style; |
||||
if (ctx.align == null) ctx.align = true; |
||||
|
||||
if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false))) |
||||
while (state.context.type == "statement") popContext(state); |
||||
else if (curPunc == "{") pushContext(state, stream.column(), "}"); |
||||
else if (curPunc == "[") pushContext(state, stream.column(), "]"); |
||||
else if (curPunc == "(") pushContext(state, stream.column(), ")"); |
||||
else if (curPunc == "}") { |
||||
while (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", stream.current()); |
||||
} |
||||
|
||||
if (style == "variable" && |
||||
((state.prevToken == "def" || |
||||
(parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) && |
||||
isTopScope(state.context) && stream.match(/^\s*\(/, false))))) |
||||
style = "def"; |
||||
|
||||
if (hooks.token) { |
||||
var result = hooks.token(stream, state, style); |
||||
if (result !== undefined) style = result; |
||||
} |
||||
|
||||
if (style == "def" && parserConfig.styleDefs === false) style = "variable"; |
||||
|
||||
state.startOfLine = false; |
||||
state.prevToken = isDefKeyword ? "def" : style || curPunc; |
||||
maybeEOL(stream, state); |
||||
return style; |
||||
}, |
||||
|
||||
indent: function(state, textAfter) { |
||||
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass; |
||||
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); |
||||
var closing = firstChar == ctx.type; |
||||
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; |
||||
if (parserConfig.dontIndentStatements) |
||||
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info)) |
||||
ctx = ctx.prev |
||||
if (hooks.indent) { |
||||
var hook = hooks.indent(state, ctx, textAfter, indentUnit); |
||||
if (typeof hook == "number") return hook |
||||
} |
||||
var switchBlock = ctx.prev && ctx.prev.info == "switch"; |
||||
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) { |
||||
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev |
||||
return ctx.indented |
||||
} |
||||
if (ctx.type == "statement") |
||||
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); |
||||
if (ctx.align && (!dontAlignCalls || ctx.type != ")")) |
||||
return ctx.column + (closing ? 0 : 1); |
||||
if (ctx.type == ")" && !closing) |
||||
return ctx.indented + statementIndentUnit; |
||||
|
||||
return ctx.indented + (closing ? 0 : indentUnit) + |
||||
(!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0); |
||||
}, |
||||
|
||||
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/, |
||||
blockCommentStart: "/*", |
||||
blockCommentEnd: "*/", |
||||
blockCommentContinue: " * ", |
||||
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 contains(words, word) { |
||||
if (typeof words === "function") { |
||||
return words(word); |
||||
} else { |
||||
return words.propertyIsEnumerable(word); |
||||
} |
||||
} |
||||
var cKeywords = "auto if break case register continue return default do sizeof " + |
||||
"static else struct switch extern typedef union for goto while enum const " + |
||||
"volatile inline restrict asm fortran"; |
||||
|
||||
// Do not use this. Use the cTypes function below. This is global just to avoid
|
||||
// excessive calls when cTypes is being called multiple times during a parse.
|
||||
var basicCTypes = words("int long char short double float unsigned signed " + |
||||
"void bool"); |
||||
|
||||
// Do not use this. Use the objCTypes function below. This is global just to avoid
|
||||
// excessive calls when objCTypes is being called multiple times during a parse.
|
||||
var basicObjCTypes = words("SEL instancetype id Class Protocol BOOL"); |
||||
|
||||
// Returns true if identifier is a "C" type.
|
||||
// C type is defined as those that are reserved by the compiler (basicTypes),
|
||||
// and those that end in _t (Reserved by POSIX for types)
|
||||
// http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html
|
||||
function cTypes(identifier) { |
||||
return contains(basicCTypes, identifier) || /.+_t/.test(identifier); |
||||
} |
||||
|
||||
// Returns true if identifier is a "Objective C" type.
|
||||
function objCTypes(identifier) { |
||||
return cTypes(identifier) || contains(basicObjCTypes, identifier); |
||||
} |
||||
|
||||
var cBlockKeywords = "case do else for if switch while struct enum union"; |
||||
var cDefKeywords = "struct enum union"; |
||||
|
||||
function cppHook(stream, state) { |
||||
if (!state.startOfLine) return false |
||||
for (var ch, next = null; ch = stream.peek();) { |
||||
if (ch == "\\" && stream.match(/^.$/)) { |
||||
next = cppHook |
||||
break |
||||
} else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) { |
||||
break |
||||
} |
||||
stream.next() |
||||
} |
||||
state.tokenize = next |
||||
return "meta" |
||||
} |
||||
|
||||
function pointerHook(_stream, state) { |
||||
if (state.prevToken == "type") return "type"; |
||||
return false; |
||||
} |
||||
|
||||
// For C and C++ (and ObjC): identifiers starting with __
|
||||
// or _ followed by a capital letter are reserved for the compiler.
|
||||
function cIsReservedIdentifier(token) { |
||||
if (!token || token.length < 2) return false; |
||||
if (token[0] != '_') return false; |
||||
return (token[1] == '_') || (token[1] !== token[1].toLowerCase()); |
||||
} |
||||
|
||||
function cpp14Literal(stream) { |
||||
stream.eatWhile(/[\w\.']/); |
||||
return "number"; |
||||
} |
||||
|
||||
function cpp11StringHook(stream, state) { |
||||
stream.backUp(1); |
||||
// Raw strings.
|
||||
if (stream.match(/(R|u8R|uR|UR|LR)/)) { |
||||
var match = stream.match(/"([^\s\\()]{0,16})\(/); |
||||
if (!match) { |
||||
return false; |
||||
} |
||||
state.cpp11RawStringDelim = match[1]; |
||||
state.tokenize = tokenRawString; |
||||
return tokenRawString(stream, state); |
||||
} |
||||
// Unicode strings/chars.
|
||||
if (stream.match(/(u8|u|U|L)/)) { |
||||
if (stream.match(/["']/, /* eat */ false)) { |
||||
return "string"; |
||||
} |
||||
return false; |
||||
} |
||||
// Ignore this hook.
|
||||
stream.next(); |
||||
return false; |
||||
} |
||||
|
||||
function cppLooksLikeConstructor(word) { |
||||
var lastTwo = /(\w+)::~?(\w+)$/.exec(word); |
||||
return lastTwo && lastTwo[1] == lastTwo[2]; |
||||
} |
||||
|
||||
// C#-style strings where "" escapes a quote.
|
||||
function tokenAtString(stream, state) { |
||||
var next; |
||||
while ((next = stream.next()) != null) { |
||||
if (next == '"' && !stream.eat('"')) { |
||||
state.tokenize = null; |
||||
break; |
||||
} |
||||
} |
||||
return "string"; |
||||
} |
||||
|
||||
// C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
|
||||
// <delim> can be a string up to 16 characters long.
|
||||
function tokenRawString(stream, state) { |
||||
// Escape characters that have special regex meanings.
|
||||
var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&'); |
||||
var match = stream.match(new RegExp(".*?\\)" + delim + '"')); |
||||
if (match) |
||||
state.tokenize = null; |
||||
else |
||||
stream.skipToEnd(); |
||||
return "string"; |
||||
} |
||||
|
||||
function def(mimes, mode) { |
||||
if (typeof mimes == "string") mimes = [mimes]; |
||||
var words = []; |
||||
function add(obj) { |
||||
if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop)) |
||||
words.push(prop); |
||||
} |
||||
add(mode.keywords); |
||||
add(mode.types); |
||||
add(mode.builtin); |
||||
add(mode.atoms); |
||||
if (words.length) { |
||||
mode.helperType = mimes[0]; |
||||
CodeMirror.registerHelper("hintWords", mimes[0], words); |
||||
} |
||||
|
||||
for (var i = 0; i < mimes.length; ++i) |
||||
CodeMirror.defineMIME(mimes[i], mode); |
||||
} |
||||
|
||||
def(["text/x-csrc", "text/x-c", "text/x-chdr"], { |
||||
name: "clike", |
||||
keywords: words(cKeywords), |
||||
types: cTypes, |
||||
blockKeywords: words(cBlockKeywords), |
||||
defKeywords: words(cDefKeywords), |
||||
typeFirstDefinitions: true, |
||||
atoms: words("NULL true false"), |
||||
isReservedIdentifier: cIsReservedIdentifier, |
||||
hooks: { |
||||
"#": cppHook, |
||||
"*": pointerHook, |
||||
}, |
||||
modeProps: {fold: ["brace", "include"]} |
||||
}); |
||||
|
||||
def(["text/x-c++src", "text/x-c++hdr"], { |
||||
name: "clike", |
||||
// Keywords from https://en.cppreference.com/w/cpp/keyword includes C++20.
|
||||
keywords: words(cKeywords + "alignas alignof and and_eq audit axiom bitand bitor catch " + |
||||
"class compl concept constexpr const_cast decltype delete dynamic_cast " + |
||||
"explicit export final friend import module mutable namespace new noexcept " + |
||||
"not not_eq operator or or_eq override private protected public " + |
||||
"reinterpret_cast requires static_assert static_cast template this " + |
||||
"thread_local throw try typeid typename using virtual xor xor_eq"), |
||||
types: cTypes, |
||||
blockKeywords: words(cBlockKeywords + " class try catch"), |
||||
defKeywords: words(cDefKeywords + " class namespace"), |
||||
typeFirstDefinitions: true, |
||||
atoms: words("true false NULL nullptr"), |
||||
dontIndentStatements: /^template$/, |
||||
isIdentifierChar: /[\w\$_~\xa1-\uffff]/, |
||||
isReservedIdentifier: cIsReservedIdentifier, |
||||
hooks: { |
||||
"#": cppHook, |
||||
"*": pointerHook, |
||||
"u": cpp11StringHook, |
||||
"U": cpp11StringHook, |
||||
"L": cpp11StringHook, |
||||
"R": cpp11StringHook, |
||||
"0": cpp14Literal, |
||||
"1": cpp14Literal, |
||||
"2": cpp14Literal, |
||||
"3": cpp14Literal, |
||||
"4": cpp14Literal, |
||||
"5": cpp14Literal, |
||||
"6": cpp14Literal, |
||||
"7": cpp14Literal, |
||||
"8": cpp14Literal, |
||||
"9": cpp14Literal, |
||||
token: function(stream, state, style) { |
||||
if (style == "variable" && stream.peek() == "(" && |
||||
(state.prevToken == ";" || state.prevToken == null || |
||||
state.prevToken == "}") && |
||||
cppLooksLikeConstructor(stream.current())) |
||||
return "def"; |
||||
} |
||||
}, |
||||
namespaceSeparator: "::", |
||||
modeProps: {fold: ["brace", "include"]} |
||||
}); |
||||
|
||||
def("text/x-java", { |
||||
name: "clike", |
||||
keywords: words("abstract assert break case catch class const continue default " + |
||||
"do else enum extends final finally float for goto if implements import " + |
||||
"instanceof interface native new package private protected public " + |
||||
"return static strictfp super switch synchronized this throw throws transient " + |
||||
"try volatile while @interface"), |
||||
types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " + |
||||
"Integer Long Number Object Short String StringBuffer StringBuilder Void"), |
||||
blockKeywords: words("catch class do else finally for if switch try while"), |
||||
defKeywords: words("class interface enum @interface"), |
||||
typeFirstDefinitions: true, |
||||
atoms: words("true false null"), |
||||
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, |
||||
hooks: { |
||||
"@": function(stream) { |
||||
// Don't match the @interface keyword.
|
||||
if (stream.match('interface', false)) return false; |
||||
|
||||
stream.eatWhile(/[\w\$_]/); |
||||
return "meta"; |
||||
} |
||||
}, |
||||
modeProps: {fold: ["brace", "import"]} |
||||
}); |
||||
|
||||
def("text/x-csharp", { |
||||
name: "clike", |
||||
keywords: words("abstract as async await base break case catch checked class const continue" + |
||||
" default delegate do else enum event explicit extern finally fixed for" + |
||||
" foreach goto if implicit in interface internal is lock namespace new" + |
||||
" operator out override params private protected public readonly ref return sealed" + |
||||
" sizeof stackalloc static struct switch this throw try typeof unchecked" + |
||||
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" + |
||||
" global group into join let orderby partial remove select set value var yield"), |
||||
types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" + |
||||
" Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" + |
||||
" UInt64 bool byte char decimal double short int long object" + |
||||
" sbyte float string ushort uint ulong"), |
||||
blockKeywords: words("catch class do else finally for foreach if struct switch try while"), |
||||
defKeywords: words("class interface namespace struct var"), |
||||
typeFirstDefinitions: true, |
||||
atoms: words("true false null"), |
||||
hooks: { |
||||
"@": function(stream, state) { |
||||
if (stream.eat('"')) { |
||||
state.tokenize = tokenAtString; |
||||
return tokenAtString(stream, state); |
||||
} |
||||
stream.eatWhile(/[\w\$_]/); |
||||
return "meta"; |
||||
} |
||||
} |
||||
}); |
||||
|
||||
function tokenTripleString(stream, state) { |
||||
var escaped = false; |
||||
while (!stream.eol()) { |
||||
if (!escaped && stream.match('"""')) { |
||||
state.tokenize = null; |
||||
break; |
||||
} |
||||
escaped = stream.next() == "\\" && !escaped; |
||||
} |
||||
return "string"; |
||||
} |
||||
|
||||
function tokenNestedComment(depth) { |
||||
return function (stream, state) { |
||||
var ch |
||||
while (ch = stream.next()) { |
||||
if (ch == "*" && stream.eat("/")) { |
||||
if (depth == 1) { |
||||
state.tokenize = null |
||||
break |
||||
} else { |
||||
state.tokenize = tokenNestedComment(depth - 1) |
||||
return state.tokenize(stream, state) |
||||
} |
||||
} else if (ch == "/" && stream.eat("*")) { |
||||
state.tokenize = tokenNestedComment(depth + 1) |
||||
return state.tokenize(stream, state) |
||||
} |
||||
} |
||||
return "comment" |
||||
} |
||||
} |
||||
|
||||
def("text/x-scala", { |
||||
name: "clike", |
||||
keywords: words( |
||||
/* scala */ |
||||
"abstract case catch class def do else extends final finally for forSome if " + |
||||
"implicit import lazy match new null object override package private protected return " + |
||||
"sealed super this throw trait try type val var while with yield _ " + |
||||
|
||||
/* package scala */ |
||||
"assert assume require print println printf readLine readBoolean readByte readShort " + |
||||
"readChar readInt readLong readFloat readDouble" |
||||
), |
||||
types: words( |
||||
"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " + |
||||
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " + |
||||
"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " + |
||||
"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " + |
||||
"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " + |
||||
|
||||
/* package java.lang */ |
||||
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + |
||||
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + |
||||
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + |
||||
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" |
||||
), |
||||
multiLineStrings: true, |
||||
blockKeywords: words("catch class enum do else finally for forSome if match switch try while"), |
||||
defKeywords: words("class enum def object package trait type val var"), |
||||
atoms: words("true false null"), |
||||
indentStatements: false, |
||||
indentSwitch: false, |
||||
isOperatorChar: /[+\-*&%=<>!?|\/#:@]/, |
||||
hooks: { |
||||
"@": function(stream) { |
||||
stream.eatWhile(/[\w\$_]/); |
||||
return "meta"; |
||||
}, |
||||
'"': function(stream, state) { |
||||
if (!stream.match('""')) return false; |
||||
state.tokenize = tokenTripleString; |
||||
return state.tokenize(stream, state); |
||||
}, |
||||
"'": function(stream) { |
||||
stream.eatWhile(/[\w\$_\xa1-\uffff]/); |
||||