Active Line Demo
- - - - -Styling the current cursor line.
- -diff --git a/plugins/codemirror/codemirror/bin/authors.sh b/plugins/codemirror/codemirror/bin/authors.sh deleted file mode 100644 index b3ee99c..0000000 --- a/plugins/codemirror/codemirror/bin/authors.sh +++ /dev/null @@ -1,6 +0,0 @@ -# Combine existing list of authors with everyone known in git, sort, add header. -tail --lines=+3 AUTHORS > AUTHORS.tmp -git log --format='%aN' >> AUTHORS.tmp -echo -e "List of CodeMirror contributors. Updated before every release.\n" > AUTHORS -sort -u AUTHORS.tmp >> AUTHORS -rm -f AUTHORS.tmp diff --git a/plugins/codemirror/codemirror/bin/compress b/plugins/codemirror/codemirror/bin/compress deleted file mode 100644 index 809fbe8..0000000 --- a/plugins/codemirror/codemirror/bin/compress +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env node - -// Compression helper for CodeMirror -// -// Example: -// -// bin/compress codemirror runmode javascript xml -// -// Will take lib/codemirror.js, addon/runmode/runmode.js, -// mode/javascript/javascript.js, and mode/xml/xml.js, run them though -// the online minifier at http://marijnhaverbeke.nl/uglifyjs, and spit -// out the result. -// -// bin/compress codemirror --local /path/to/bin/UglifyJS -// -// Will use a local minifier instead of the online default one. -// -// Script files are specified without .js ending. Prefixing them with -// their full (local) path is optional. So you may say lib/codemirror -// or mode/xml/xml to be more precise. In fact, even the .js suffix -// may be speficied, if wanted. - -"use strict"; - -var fs = require("fs"); - -function help(ok) { - console.log("usage: " + process.argv[1] + " [--local /path/to/uglifyjs] files..."); - process.exit(ok ? 0 : 1); -} - -var local = null, args = [], extraArgs = null, files = [], blob = ""; - -for (var i = 2; i < process.argv.length; ++i) { - var arg = process.argv[i]; - if (arg == "--local" && i + 1 < process.argv.length) { - var parts = process.argv[++i].split(/\s+/); - local = parts[0]; - extraArgs = parts.slice(1); - if (!extraArgs.length) extraArgs = ["-c", "-m"]; - } else if (arg == "--help") { - help(true); - } else if (arg[0] != "-") { - files.push({name: arg, re: new RegExp("(?:\\/|^)" + arg + (/\.js$/.test(arg) ? "$" : "\\.js$"))}); - } else help(false); -} - -function walk(dir) { - fs.readdirSync(dir).forEach(function(fname) { - if (/^[_\.]/.test(fname)) return; - var file = dir + fname; - if (fs.statSync(file).isDirectory()) return walk(file + "/"); - if (files.some(function(spec, i) { - var match = spec.re.test(file); - if (match) files.splice(i, 1); - return match; - })) { - if (local) args.push(file); - else blob += fs.readFileSync(file, "utf8"); - } - }); -} - -walk("lib/"); -walk("addon/"); -walk("mode/"); - -if (!local && !blob) help(false); - -if (files.length) { - console.log("Some speficied files were not found: " + - files.map(function(a){return a.name;}).join(", ")); - process.exit(1); -} - -if (local) { - require("child_process").spawn(local, args.concat(extraArgs), {stdio: ["ignore", process.stdout, process.stderr]}); -} else { - var data = new Buffer("js_code=" + require("querystring").escape(blob), "utf8"); - var req = require("http").request({ - host: "marijnhaverbeke.nl", - port: 80, - method: "POST", - path: "/uglifyjs", - headers: {"content-type": "application/x-www-form-urlencoded", - "content-length": data.length} - }); - req.on("response", function(resp) { - resp.on("data", function (chunk) { process.stdout.write(chunk); }); - }); - req.end(data); -} diff --git a/plugins/codemirror/codemirror/bin/lint b/plugins/codemirror/codemirror/bin/lint deleted file mode 100644 index 4f70994..0000000 --- a/plugins/codemirror/codemirror/bin/lint +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node - -var lint = require("../test/lint/lint"), - path = require("path"); - -if (process.argv.length > 2) { - lint.checkDir(process.argv[2]); -} else { - process.chdir(path.resolve(__dirname, "..")); - lint.checkDir("lib"); - lint.checkDir("mode"); - lint.checkDir("addon"); - lint.checkDir("keymap"); -} - -process.exit(lint.success() ? 0 : 1); diff --git a/plugins/codemirror/codemirror/bin/source-highlight b/plugins/codemirror/codemirror/bin/source-highlight deleted file mode 100644 index 7596ed7..0000000 --- a/plugins/codemirror/codemirror/bin/source-highlight +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env node - -// Simple command-line code highlighting tool. Reads code from stdin, -// spits html to stdout. For example: -// -// echo 'function foo(a) { return a; }' | bin/source-highlight -s javascript -// bin/source-highlight -s - -var fs = require("fs"); - -CodeMirror = require("../addon/runmode/runmode.node.js"); -require("../mode/meta.js"); - -var sPos = process.argv.indexOf("-s"); -if (sPos == -1 || sPos == process.argv.length - 1) { - console.error("Usage: source-highlight -s language"); - process.exit(1); -} -var lang = process.argv[sPos + 1].toLowerCase(), modeName = lang; -CodeMirror.modeInfo.forEach(function(info) { - if (info.mime == lang) { - modeName = info.mode; - } else if (info.name.toLowerCase() == lang) { - modeName = info.mode; - lang = info.mime; - } -}); - -function ensureMode(name) { - if (CodeMirror.modes[name] || name == "null") return; - try { - require("../mode/" + name + "/" + name + ".js"); - } catch(e) { - console.error("Could not load mode " + name + "."); - process.exit(1); - } - var obj = CodeMirror.modes[name]; - if (obj.dependencies) obj.dependencies.forEach(ensureMode); -} -ensureMode(modeName); - -function esc(str) { - return str.replace(/[<&]/, function(ch) { return ch == "&" ? "&" : "<"; }); -} - -var code = fs.readFileSync("/dev/stdin", "utf8"); -var curStyle = null, accum = ""; -function flush() { - if (curStyle) process.stdout.write("" + esc(accum) + ""); - else process.stdout.write(esc(accum)); -} - -CodeMirror.runMode(code, lang, function(text, style) { - if (style != curStyle) { - flush(); - curStyle = style; accum = text; - } else { - accum += text; - } -}); -flush(); diff --git a/plugins/codemirror/codemirror/demo/activeline.html b/plugins/codemirror/codemirror/demo/activeline.html deleted file mode 100644 index 14851c3..0000000 --- a/plugins/codemirror/codemirror/demo/activeline.html +++ /dev/null @@ -1,78 +0,0 @@ - - -
Styling the current cursor line.
- -Press ctrl-space to activate autocompletion. The -completion uses -the anyword-hint.js -module, which simply looks at nearby words in the buffer and completes -to those.
- - -Demonstration of bi-directional text support. See - the related - blog post for more background.
- -Note: There is - a known - bug with cursor motion and mouse clicks in bi-directional lines - that are line wrapped.
- -Demonstration of
- using linked documents
- to provide a split view on a document, and
- using swapDoc
- to use a single editor to display multiple documents.
On changes to the content of the above editor, a (crude) script -tries to auto-detect the language used, and switches the editor to -either JavaScript or Scheme mode based on that.
- - -Press ctrl-space to activate autocompletion. Built
-on top of the show-hint
-and javascript-hint
-addons.
The emacs keybindings are enabled by
-including keymap/emacs.js and setting
-the keyMap
option to "emacs"
. Because
-CodeMirror's internal API is quite different from Emacs, they are only
-a loose approximation of actual emacs bindings, though.
Also note that a lot of browsers disallow certain keys from being -captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the -result that idiomatic use of Emacs keys will constantly close your tab -or open a new window.
- - - -Demonstration of - the fullscreen - addon. Press F11 when cursor is in the editor to - toggle full screen editing. Esc can also be used - to exit full screen editing.
-Demonstration of
-the hardwrap addon.
-The above editor has its change event hooked up to
-the wrapParagraphsInRange
method, so that the paragraphs
-are reflown as you are typing.
Shows the XML completer - parameterized with information about the tags in HTML. - Press ctrl-space to activate completion.
- - - - -This page uses a hack on top of the "renderLine"
- event to make wrapped text line up with the base indentation of
- the line.
- - -
Click the line-number gutter to add or remove 'breakpoints'.
- - - -Simple addon to easily mark (and style) selected text.
- -Search and highlight occurences of the selected text.
- -Put the cursor on or inside a pair of tags to highlight them. - Press Ctrl-J to jump to the tag that matches the one under the - cursor.
-The merge
-addon provides an interface for displaying and merging diffs,
-either two-way
-or three-way. The left
-(or center) pane is editable, and the differences with the other
-pane(s) are optionally shown live as you edit it.
This addon depends on -the google-diff-match-patch -library to compute the diffs.
- - -Demonstration of a multiplexing mode, which, at certain
- boundary strings, switches to one or more inner modes. The out
- (HTML) mode does not get fed the content of the <<
- >>
blocks. See
- the manual and
- the source for more
- information.
Demonstration of a mode that parses HTML, highlighting
- the Mustache templating
- directives inside of it by using the code
- in overlay.js
. View
- source to see the 15 lines of code needed to accomplish this.
The placeholder
- plug-in adds an option placeholder
that can be set to
- make text appear in the editor when it is empty and not focused.
- If the source textarea has a placeholder
attribute,
- it will automatically be inherited.
By setting a few CSS properties, and giving
-the viewportMargin
-a value of Infinity
, CodeMirror can be made to
-automatically resize to fit its content.
Running a CodeMirror mode outside of the editor.
- The CodeMirror.runMode
function, defined
- in lib/runmode.js
takes the following arguments:
text (string)
mode (mode spec)
output (function or DOM node)
null
for unstyled tokens). If it is a DOM node,
- the tokens will be converted to span
elements as in
- an editor, and inserted into the node
- (through innerHTML
).Demonstration of primitive search/replace functionality. The - keybindings (which can be overridden by custom keymaps) are:
-Searching is enabled by - including addon/search/search.js - and addon/search/searchcursor.js. - For good-looking input dialogs, you also want to include - addon/dialog/dialog.js - and addon/dialog/dialog.css.
-This is a hack to automatically derive
- a spanAffectsWrapping
regexp for a browser. See the
- comments above that variable
- in lib/codemirror.js
- for some more details.
Select a theme: -
- - -Uses -the trailingspace -addon to highlight trailing whitespace.
- -The vim keybindings are enabled by
-including keymap/vim.js and setting
-the keyMap
option to "vim"
. Because
-CodeMirror's internal API is quite different from Vim, they are only
-a loose approximation of actual vim bindings, though.
Tabs inside the editor are spans with the
-class cm-tab
, and can be styled.
This demo runs JSHint over the code -in the editor (which is the script used on this page), and -inserts line widgets to -display the warnings that JSHint comes up with.
-Press ctrl-space, or type a '<' character to - activate autocompletion. This demo defines a simple schema that - guides completion. The schema can be customized—see - the manual.
- -Development of the xml-hint
addon was kindly
- sponsored
- by www.xperiment.mobi.
To optimize loading CodeMirror, especially when including a - bunch of different modes, it is recommended that you combine and - minify (and preferably also gzip) the scripts. This page makes - those first two steps very easy. Simply select the version and - scripts you need in the form below, and - click Compress to download the minified script - file.
- - - - - -
- Topic: JavaScript, code editor implementation
- Author: Marijn Haverbeke
- Date: March 2nd 2011 (updated November 13th 2011)
-
Caution: this text was written briefly after -version 2 was initially written. It no longer (even including the -update at the bottom) fully represents the current implementation. I'm -leaving it here as a historic document. For more up-to-date -information, look at the entries -tagged cm-internals -on my blog.
- -This is a followup to -my Brutal Odyssey to the -Dark Side of the DOM Tree story. That one describes the -mind-bending process of implementing (what would become) CodeMirror 1. -This one describes the internals of CodeMirror 2, a complete rewrite -and rethink of the old code base. I wanted to give this piece another -Hunter Thompson copycat subtitle, but somehow that would be out of -place—the process this time around was one of straightforward -engineering, requiring no serious mind-bending whatsoever.
- -So, what is wrong with CodeMirror 1? I'd estimate, by mailing list -activity and general search-engine presence, that it has been -integrated into about a thousand systems by now. The most prominent -one, since a few weeks, -being Google -code's project hosting. It works, and it's being used widely.
- -Still, I did not start replacing it because I was bored. CodeMirror
-1 was heavily reliant on designMode
-or contentEditable
(depending on the browser). Neither of
-these are well specified (HTML5 tries
-to specify
-their basics), and, more importantly, they tend to be one of the more
-obscure and buggy areas of browser functionality—CodeMirror, by using
-this functionality in a non-typical way, was constantly running up
-against browser bugs. WebKit wouldn't show an empty line at the end of
-the document, and in some releases would suddenly get unbearably slow.
-Firefox would show the cursor in the wrong place. Internet Explorer
-would insist on linkifying everything that looked like a URL or email
-address, a behaviour that can't be turned off. Some bugs I managed to
-work around (which was often a frustrating, painful process), others,
-such as the Firefox cursor placement, I gave up on, and had to tell
-user after user that they were known problems, but not something I
-could help.
Also, there is the fact that designMode
(which seemed
-to be less buggy than contentEditable
in Webkit and
-Firefox, and was thus used by CodeMirror 1 in those browsers) requires
-a frame. Frames are another tricky area. It takes some effort to
-prevent getting tripped up by domain restrictions, they don't
-initialize synchronously, behave strangely in response to the back
-button, and, on several browsers, can't be moved around the DOM
-without having them re-initialize. They did provide a very nice way to
-namespace the library, though—CodeMirror 1 could freely pollute the
-namespace inside the frame.
Finally, working with an editable document means working with
-selection in arbitrary DOM structures. Internet Explorer (8 and
-before) has an utterly different (and awkward) selection API than all
-of the other browsers, and even among the different implementations of
-document.selection
, details about how exactly a selection
-is represented vary quite a bit. Add to that the fact that Opera's
-selection support tended to be very buggy until recently, and you can
-imagine why CodeMirror 1 contains 700 lines of selection-handling
-code.
And that brings us to the main issue with the CodeMirror 1 -code base: The proportion of browser-bug-workarounds to real -application code was getting dangerously high. By building on top of a -few dodgy features, I put the system in a vulnerable position—any -incompatibility and bugginess in these features, I had to paper over -with my own code. Not only did I have to do some serious stunt-work to -get it to work on older browsers (as detailed in the -previous story), things -also kept breaking in newly released versions, requiring me to come up -with new scary hacks in order to keep up. This was starting -to lose its appeal.
- -What CodeMirror 2 does is try to sidestep most of the hairy hacks -that came up in version 1. I owe a lot to the -ACE editor for inspiration on how to -approach this.
- -I absolutely did not want to be completely reliant on key events to -generate my input. Every JavaScript programmer knows that key event -information is horrible and incomplete. Some people (most awesomely -Mihai Bazon with Ymacs) have been able -to build more or less functioning editors by directly reading key -events, but it takes a lot of work (the kind of never-ending, fragile -work I described earlier), and will never be able to properly support -things like multi-keystoke international character -input. [see below for caveat]
- -So what I do is focus a hidden textarea, and let the browser -believe that the user is typing into that. What we show to the user is -a DOM structure we built to represent his document. If this is updated -quickly enough, and shows some kind of believable cursor, it feels -like a real text-input control.
- -Another big win is that this DOM representation does not have to
-span the whole document. Some CodeMirror 1 users insisted that they
-needed to put a 30 thousand line XML document into CodeMirror. Putting
-all that into the DOM takes a while, especially since, for some
-reason, an editable DOM tree is slower than a normal one on most
-browsers. If we have full control over what we show, we must only
-ensure that the visible part of the document has been added, and can
-do the rest only when needed. (Fortunately, the onscroll
-event works almost the same on all browsers, and lends itself well to
-displaying things only as they are scrolled into view.)
ACE uses its hidden textarea only as a text input shim, and does -all cursor movement and things like text deletion itself by directly -handling key events. CodeMirror's way is to let the browser do its -thing as much as possible, and not, for example, define its own set of -key bindings. One way to do this would have been to have the whole -document inside the hidden textarea, and after each key event update -the display DOM to reflect what's in that textarea.
- -That'd be simple, but it is not realistic. For even medium-sized -document the editor would be constantly munging huge strings, and get -terribly slow. What CodeMirror 2 does is put the current selection, -along with an extra line on the top and on the bottom, into the -textarea.
- -This means that the arrow keys (and their ctrl-variations), home, -end, etcetera, do not have to be handled specially. We just read the -cursor position in the textarea, and update our cursor to match it. -Also, copy and paste work pretty much for free, and people get their -native key bindings, without any special work on my part. For example, -I have emacs key bindings configured for Chrome and Firefox. There is -no way for a script to detect this. [no longer the case]
- -Of course, since only a small part of the document sits in the -textarea, keys like page up and ctrl-end won't do the right thing. -CodeMirror is catching those events and handling them itself.
-Getting and setting the selection range of a textarea in modern
-browsers is trivial—you just use the selectionStart
-and selectionEnd
properties. On IE you have to do some
-insane stuff with temporary ranges and compensating for the fact that
-moving the selection by a 'character' will treat \r\n as a single
-character, but even there it is possible to build functions that
-reliably set and get the selection range.
But consider this typical case: When I'm somewhere in my document, -press shift, and press the up arrow, something gets selected. Then, if -I, still holding shift, press the up arrow again, the top of my -selection is adjusted. The selection remembers where its head -and its anchor are, and moves the head when we shift-move. -This is a generally accepted property of selections, and done right by -every editing component built in the past twenty years.
- -But not something that the browser selection APIs expose.
- -Great. So when someone creates an 'upside-down' selection, the next -time CodeMirror has to update the textarea, it'll re-create the -selection as an 'upside-up' selection, with the anchor at the top, and -the next cursor motion will behave in an unexpected way—our second -up-arrow press in the example above will not do anything, since it is -interpreted in exactly the same way as the first.
- -No problem. We'll just, ehm, detect that the selection is -upside-down (you can tell by the way it was created), and then, when -an upside-down selection is present, and a cursor-moving key is -pressed in combination with shift, we quickly collapse the selection -in the textarea to its start, allow the key to take effect, and then -combine its new head with its old anchor to get the real -selection.
- -In short, scary hacks could not be avoided entirely in CodeMirror -2.
- -And, the observant reader might ask, how do you even know that a -key combo is a cursor-moving combo, if you claim you support any -native key bindings? Well, we don't, but we can learn. The editor -keeps a set known cursor-movement combos (initialized to the -predictable defaults), and updates this set when it observes that -pressing a certain key had (only) the effect of moving the cursor. -This, of course, doesn't work if the first time the key is used was -for extending an inverted selection, but it works most of the -time.
-One thing that always comes up when you have a complicated internal -state that's reflected in some user-visible external representation -(in this case, the displayed code and the textarea's content) is -keeping the two in sync. The naive way is to just update the display -every time you change your state, but this is not only error prone -(you'll forget), it also easily leads to duplicate work on big, -composite operations. Then you start passing around flags indicating -whether the display should be updated in an attempt to be efficient -again and, well, at that point you might as well give up completely.
- -I did go down that road, but then switched to a much simpler model: -simply keep track of all the things that have been changed during an -action, and then, only at the end, use this information to update the -user-visible display.
- -CodeMirror uses a concept of operations, which start by
-calling a specific set-up function that clears the state and end by
-calling another function that reads this state and does the required
-updating. Most event handlers, and all the user-visible methods that
-change state are wrapped like this. There's a method
-called operation
that accepts a function, and returns
-another function that wraps the given function as an operation.
It's trivial to extend this (as CodeMirror does) to detect nesting, -and, when an operation is started inside an operation, simply -increment the nesting count, and only do the updating when this count -reaches zero again.
- -If we have a set of changed ranges and know the currently shown -range, we can (with some awkward code to deal with the fact that -changes can add and remove lines, so we're dealing with a changing -coordinate system) construct a map of the ranges that were left -intact. We can then compare this map with the part of the document -that's currently visible (based on scroll offset and editor height) to -determine whether something needs to be updated.
- -CodeMirror uses two update algorithms—a full refresh, where it just -discards the whole part of the DOM that contains the edited text and -rebuilds it, and a patch algorithm, where it uses the information -about changed and intact ranges to update only the out-of-date parts -of the DOM. When more than 30 percent (which is the current heuristic, -might change) of the lines need to be updated, the full refresh is -chosen (since it's faster to do than painstakingly finding and -updating all the changed lines), in the other case it does the -patching (so that, if you scroll a line or select another character, -the whole screen doesn't have to be -re-rendered). [the full-refresh -algorithm was dropped, it wasn't really faster than the patching -one]
- -All updating uses innerHTML
rather than direct DOM
-manipulation, since that still seems to be by far the fastest way to
-build documents. There's a per-line function that combines the
-highlighting, marking, and
-selection info for that line into a snippet of HTML. The patch updater
-uses this to reset individual lines, the refresh updater builds an
-HTML chunk for the whole visible document at once, and then uses a
-single innerHTML
update to do the refresh.
When I wrote CodeMirror 1, I -thought interruptable -parsers were a hugely scary and complicated thing, and I used a -bunch of heavyweight abstractions to keep this supposed complexity -under control: parsers -were iterators -that consumed input from another iterator, and used funny -closure-resetting tricks to copy and resume themselves.
- -This made for a rather nice system, in that parsers formed strictly -separate modules, and could be composed in predictable ways. -Unfortunately, it was quite slow (stacking three or four iterators on -top of each other), and extremely intimidating to people not used to a -functional programming style.
- -With a few small changes, however, we can keep all those -advantages, but simplify the API and make the whole thing less -indirect and inefficient. CodeMirror -2's mode API uses explicit state -objects, and makes the parser/tokenizer a function that simply takes a -state and a character stream abstraction, advances the stream one -token, and returns the way the token should be styled. This state may -be copied, optionally in a mode-defined way, in order to be able to -continue a parse at a given point. Even someone who's never touched a -lambda in his life can understand this approach. Additionally, far -fewer objects are allocated in the course of parsing now.
- -The biggest speedup comes from the fact that the parsing no longer -has to touch the DOM though. In CodeMirror 1, on an older browser, you -could see the parser work its way through the document, -managing some twenty lines in each 50-millisecond time slice it got. It -was reading its input from the DOM, and updating the DOM as it went -along, which any experienced JavaScript programmer will immediately -spot as a recipe for slowness. In CodeMirror 2, the parser usually -finishes the whole document in a single 100-millisecond time slice—it -manages some 1500 lines during that time on Chrome. All it has to do -is munge strings, so there is no real reason for it to be slow -anymore.
-Given all this, what can you expect from CodeMirror 2?
- -iframe
nodes aren't
-really known for respecting document flow. Now that an editor instance
-is a plain div
element, it is much easier to size it to
-fit the surrounding elements. You don't even have to make it scroll if
-you do not want to.On the downside, a CodeMirror 2 instance is not a native -editable component. Though it does its best to emulate such a -component as much as possible, there is functionality that browsers -just do not allow us to hook into. Doing select-all from the context -menu, for example, is not currently detected by CodeMirror.
- -[Updates from November 13th 2011] Recently, I've made -some changes to the codebase that cause some of the text above to no -longer be current. I've left the text intact, but added markers at the -passages that are now inaccurate. The new situation is described -below.
-The original implementation of CodeMirror 2 represented the
-document as a flat array of line objects. This worked well—splicing
-arrays will require the part of the array after the splice to be
-moved, but this is basically just a simple memmove
of a
-bunch of pointers, so it is cheap even for huge documents.
However, I recently added line wrapping and code folding (line -collapsing, basically). Once lines start taking up a non-constant -amount of vertical space, looking up a line by vertical position -(which is needed when someone clicks the document, and to determine -the visible part of the document during scrolling) can only be done -with a linear scan through the whole array, summing up line heights as -you go. Seeing how I've been going out of my way to make big documents -fast, this is not acceptable.
- -The new representation is based on a B-tree. The leaves of the tree -contain arrays of line objects, with a fixed minimum and maximum size, -and the non-leaf nodes simply hold arrays of child nodes. Each node -stores both the amount of lines that live below them and the vertical -space taken up by these lines. This allows the tree to be indexed both -by line number and by vertical position, and all access has -logarithmic complexity in relation to the document size.
- -I gave line objects and tree nodes parent pointers, to the node -above them. When a line has to update its height, it can simply walk -these pointers to the top of the tree, adding or subtracting the -difference in height from each node it encounters. The parent pointers -also make it cheaper (in complexity terms, the difference is probably -tiny in normal-sized documents) to find the current line number when -given a line object. In the old approach, the whole document array had -to be searched. Now, we can just walk up the tree and count the sizes -of the nodes coming before us at each level.
- -I chose B-trees, not regular binary trees, mostly because they -allow for very fast bulk insertions and deletions. When there is a big -change to a document, it typically involves adding, deleting, or -replacing a chunk of subsequent lines. In a regular balanced tree, all -these inserts or deletes would have to be done separately, which could -be really expensive. In a B-tree, to insert a chunk, you just walk -down the tree once to find where it should go, insert them all in one -shot, and then break up the node if needed. This breaking up might -involve breaking up nodes further up, but only requires a single pass -back up the tree. For deletion, I'm somewhat lax in keeping things -balanced—I just collapse nodes into a leaf when their child count goes -below a given number. This means that there are some weird editing -patterns that may result in a seriously unbalanced tree, but even such -an unbalanced tree will perform well, unless you spend a day making -strangely repeating edits to a really big document.
-Above, I claimed that directly catching key -events for things like cursor movement is impractical because it -requires some browser-specific kludges. I then proceeded to explain -some awful hacks that were needed to make it -possible for the selection changes to be detected through the -textarea. In fact, the second hack is about as bad as the first.
- -On top of that, in the presence of user-configurable tab sizes and -collapsed and wrapped lines, lining up cursor movement in the textarea -with what's visible on the screen becomes a nightmare. Thus, I've -decided to move to a model where the textarea's selection is no longer -depended on.
- -So I moved to a model where all cursor movement is handled by my -own code. This adds support for a goal column, proper interaction of -cursor movement with collapsed lines, and makes it possible for -vertical movement to move through wrapped lines properly, instead of -just treating them like non-wrapped lines.
- -The key event handlers now translate the key event into a string,
-something like Ctrl-Home
or Shift-Cmd-R
, and
-use that string to look up an action to perform. To make keybinding
-customizable, this lookup goes through
-a table, using a scheme that
-allows such tables to be chained together (for example, the default
-Mac bindings fall through to a table named 'emacsy', which defines
-basic Emacs-style bindings like Ctrl-F
, and which is also
-used by the custom Emacs bindings).
A new
-option extraKeys
-allows ad-hoc keybindings to be defined in a much nicer way than what
-was possible with the
-old onKeyEvent
-callback. You simply provide an object mapping key identifiers to
-functions, instead of painstakingly looking at raw key events.
Built-in commands map to strings, rather than functions, for
-example "goLineUp"
is the default action bound to the up
-arrow key. This allows new keymaps to refer to them without
-duplicating any code. New commands can be defined by assigning to
-the CodeMirror.commands
object, which maps such commands
-to functions.
The hidden textarea now only holds the current selection, with no -extra characters around it. This has a nice advantage: polling for -input becomes much, much faster. If there's a big selection, this text -does not have to be read from the textarea every time—when we poll, -just noticing that something is still selected is enough to tell us -that no new text was typed.
- -The reason that cheap polling is important is that many browsers do
-not fire useful events on IME (input method engine) input, which is
-the thing where people inputting a language like Japanese or Chinese
-use multiple keystrokes to create a character or sequence of
-characters. Most modern browsers fire input
when the
-composing is finished, but many don't fire anything when the character
-is updated during composition. So we poll, whenever the
-editor is focused, to provide immediate updates of the display.
CodeMirror is a code-editor component that can be embedded in - Web pages. The core library provides only the editor - component, no accompanying buttons, auto-completion, or other IDE - functionality. It does provide a rich API on top of which such - functionality can be straightforwardly implemented. See - the addons included in the distribution, - and the list - of externally hosted addons, for reusable - implementations of extra features.
- -CodeMirror works with language-specific modes. Modes are
- JavaScript programs that help color (and optionally indent) text
- written in a given language. The distribution comes with a number
- of modes (see the mode/
- directory), and it isn't hard to write new
- ones for other languages.
The easiest way to use CodeMirror is to simply load the script
- and style sheet found under lib/
in the distribution,
- plus a mode script from one of the mode/
directories.
- (See the compression helper for an
- easy way to combine scripts.) For example:
<script src="lib/codemirror.js"></script> -<link rel="stylesheet" href="../lib/codemirror.css"> -<script src="mode/javascript/javascript.js"></script>- -
Having done this, an editor instance can be created like - this:
- -var myCodeMirror = CodeMirror(document.body);- -
The editor will be appended to the document body, will start
- empty, and will use the mode that we loaded. To have more control
- over the new editor, a configuration object can be passed
- to CodeMirror
as a second
- argument:
var myCodeMirror = CodeMirror(document.body, { - value: "function myScript(){return 100;}\n", - mode: "javascript" -});- -
This will initialize the editor with a piece of code already in - it, and explicitly tell it to use the JavaScript mode (which is - useful when multiple modes are loaded). - See below for a full discussion of the - configuration options that CodeMirror accepts.
- -In cases where you don't want to append the editor to an
- element, and need more control over the way it is inserted, the
- first argument to the CodeMirror
function can also
- be a function that, when given a DOM element, inserts it into the
- document somewhere. This could be used to, for example, replace a
- textarea with a real editor:
var myCodeMirror = CodeMirror(function(elt) { - myTextArea.parentNode.replaceChild(elt, myTextArea); -}, {value: myTextArea.value});- -
However, for this use case, which is a common way to use - CodeMirror, the library provides a much more powerful - shortcut:
- -var myCodeMirror = CodeMirror.fromTextArea(myTextArea);- -
This will, among other things, ensure that the textarea's value - is updated with the editor's contents when the form (if it is part - of a form) is submitted. See the API - reference for a full description of this method.
- -Both the CodeMirror
- function and its fromTextArea
method take as second
- (optional) argument an object containing configuration options.
- Any option not supplied like this will be taken
- from CodeMirror.defaults
, an
- object containing the default options. You can update this object
- to change the defaults on your page.
Options are not checked in any way, so setting bogus option - values is bound to lead to odd errors.
- -These are the supported options:
- -value: string|CodeMirror.Doc
mode: string|object
name
property that names the mode (for
- example {name: "javascript", json: true}
). The demo
- pages for each mode contain information about what configuration
- parameters the mode supports. You can ask CodeMirror which modes
- and MIME types have been defined by inspecting
- the CodeMirror.modes
- and CodeMirror.mimeModes
objects. The first maps
- mode names to their constructors, and the second maps MIME types
- to mode specs.theme: string
.cm-s-[name]
- styles is loaded (see
- the theme
directory in the
- distribution). The default is "default"
, for which
- colors are included in codemirror.css
. It is
- possible to use multiple theming classes at once—for
- example "foo bar"
will assign both
- the cm-s-foo
and the cm-s-bar
classes
- to the editor.indentUnit: integer
smartIndent: boolean
tabSize: integer
indentWithTabs: boolean
tabSize
- spaces should be replaced by N tabs. Default is false.electricChars: boolean
specialChars: RegExp
/[\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/
.specialCharPlaceholder: function(char) → Element
specialChars
- option, produces a DOM node that is used to represent the
- character. By default, a red dot (•)
- is shown, with a title tooltip to indicate the character code.rtlMoveVisually: boolean
false
- on Windows, and true
on other platforms.keyMap: string
"default"
, which is the only keymap defined
- in codemirror.js
itself. Extra keymaps are found in
- the keymap
directory. See
- the section on keymaps for more
- information.extraKeys: object
keyMap
. Should be
- either null, or a valid keymap value.lineWrapping: boolean
false
(scroll).lineNumbers: boolean
firstLineNumber: integer
lineNumberFormatter: function(line: integer) → string
gutters: array<string>
width
(and optionally a
- background), and which will be used to draw the background of
- the gutters. May include
- the CodeMirror-linenumbers
class, in order to
- explicitly set the position of the line number gutter (it will
- default to be to the right of all other gutters). These class
- names are the keys passed
- to setGutterMarker
.fixedGutter: boolean
coverGutterNextToScrollbar: boolean
fixedGutter
- is on, and there is a horizontal scrollbar, by default the
- gutter will be visible to the left of this scrollbar. If this
- option is set to true, it will be covered by an element with
- class CodeMirror-gutter-filler
.readOnly: boolean|string
"nocursor"
is given (instead of
- simply true
), focusing of the editor is also
- disallowed.showCursorWhenSelecting: boolean
undoDepth: integer
historyEventDelay: integer
tabindex: integer
autofocus: boolean
fromTextArea
is
- used, and no explicit value is given for this option, it will be
- set to true when either the source textarea is focused, or it
- has an autofocus
attribute and no other element is
- focused.Below this a few more specialized, low-level options are - listed. These are only useful in very specific situations, you - might want to skip them the first time you read this manual.
- -dragDrop: boolean
onDragEvent: function(instance: CodeMirror, event: Event) → boolean
dragenter
, dragover
,
- or drop
event. It will be passed the editor
- instance and the event object as arguments. The callback can
- choose to handle the event itself, in which case it should
- return true
to indicate that CodeMirror should not
- do anything further.onKeyEvent: function(instance: CodeMirror, event: Event) → boolean
keydown
, keyup
,
- and keypress
event that CodeMirror captures. It
- will be passed two arguments, the editor instance and the key
- event. This key event is pretty much the raw key event, except
- that a stop()
method is always added to it. You
- could feed it to, for example, jQuery.Event
to
- further normalize it.keydown
does not stop
- the keypress
from firing, whereas on others it
- does. If you respond to an event, you should probably inspect
- its type
property and only do something when it
- is keydown
(or keypress
for actions
- that need character data).cursorBlinkRate: number
cursorScrollMargin: number
cursorHeight: number
0.85
),
- which causes the cursor to not reach all the way to the bottom
- of the line, looks betterresetSelectionOnContextMenu: boolean
true
.workTime, workDelay: number
workTime
milliseconds, and then use
- timeout to sleep for workDelay
milliseconds. The
- defaults are 200 and 300, you can change these options to make
- the highlighting more or less aggressive.workDelay: number
workTime
.pollInterval: number
flattenSpans: boolean
maxHighlightLength: number
Infinity
to turn off
- this behavior.crudeMeasuringFrom: number
viewportMargin: integer
Infinity
to make sure the whole document is
- always rendered, and thus the browser's text search works on it.
- This will have bad effects on performance of big
- documents.Various CodeMirror-related objects emit events, which allow
- client code to react to various situations. Handlers for such
- events can be registed with the on
- and off
methods on the objects
- that the event fires on. To fire your own events,
- use CodeMirror.signal(target, name, args...)
,
- where target
is a non-DOM-node object.
An editor instance fires the following events.
- The instance
argument always refers to the editor
- itself.
"change" (instance: CodeMirror, changeObj: object)
changeObj
is a {from, to, text, removed,
- next}
object containing information about the changes
- that occurred as second argument. from
- and to
are the positions (in the pre-change
- coordinate system) where the change started and ended (for
- example, it might be {ch:0, line:18}
if the
- position is at the beginning of line #19). text
is
- an array of strings representing the text that replaced the
- changed range (split by line). removed
is the text
- that used to be between from
and to
,
- which is overwritten by this change. If multiple changes
- happened during a single operation, the object will have
- a next
property pointing to another change object
- (which may point to another, etc)."beforeChange" (instance: CodeMirror, changeObj: object)
changeObj
object
- has from
, to
, and text
- properties, as with
- the "change"
event, but
- never a next
property, since this is fired for each
- individual change, and not batched per operation. It also has
- a cancel()
method, which can be called to cancel
- the change, and, if the change isn't coming
- from an undo or redo event, an update(from, to,
- text)
method, which may be used to modify the change.
- Undo or redo changes can't be modified, because they hold some
- metainformation for restoring old marked ranges that is only
- valid for that specific change. All three arguments
- to update
are optional, and can be left off to
- leave the existing value for that field
- intact. Note: you may not do anything from
- a "beforeChange"
handler that would cause changes
- to the document or its visualization. Doing so will, since this
- handler is called directly from the bowels of the CodeMirror
- implementation, probably cause the editor to become
- corrupted."cursorActivity" (instance: CodeMirror)
"keyHandled" (instance: CodeMirror, name: string, event: Event)
name
is the name of the handled key (for
- example "Ctrl-X"
or "'q'"
),
- and event
is the DOM keydown
- or keypress
event."inputRead" (instance: CodeMirror, changeObj: object)
"beforeSelectionChange" (instance: CodeMirror, selection: {head, anchor})
selection
parameter is an object
- with head
and anchor
properties
- holding {line, ch}
objects, which the handler can
- read and update. Handlers for this event have the same
- restriction
- as "beforeChange"
- handlers — they should not do anything to directly update the
- state of the editor."viewportChange" (instance: CodeMirror, from: number, to: number)
from
and to
arguments
- give the new start and end of the viewport."swapDoc" (instance: CodeMirror, oldDoc: Doc)
swapDoc
- method."gutterClick" (instance: CodeMirror, line: integer, gutter: string, clickEvent: Event)
mousedown
event object as
- fourth argument."gutterContextMenu" (instance: CodeMirror, line: integer, gutter: string, contextMenu: Event: Event)
contextmenu
event. Will pass the editor
- instance as first argument, the (zero-based) number of the line
- that was clicked as second argument, the CSS class of the
- gutter that was clicked as third argument, and the raw
- contextmenu
mouse event object as fourth argument.
- You can preventDefault
the event, to signal that
- CodeMirror should do no further handling."focus" (instance: CodeMirror)
"blur" (instance: CodeMirror)
"scroll" (instance: CodeMirror)
"update" (instance: CodeMirror)
"renderLine" (instance: CodeMirror, line: LineHandle, element: Element)
"mousedown",
- "dblclick", "contextmenu", "keydown", "keypress",
- "keyup", "dragstart", "dragenter",
- "dragover", "drop"
- (instance: CodeMirror, event: Event)
preventDefault
the event, or give it a
- truthy codemirrorIgnore
property, to signal that
- CodeMirror should do no further handling.Document objects (instances
- of CodeMirror.Doc
) emit the
- following events:
"change" (doc: CodeMirror.Doc, changeObj: object)
changeObj
has a similar type as the
- object passed to the
- editor's "change"
- event, but it never has a next
property, because
- document change events are not batched (whereas editor change
- events are)."beforeChange" (doc: CodeMirror.Doc, change: object)
"cursorActivity" (doc: CodeMirror.Doc)
"beforeSelectionChange" (doc: CodeMirror.Doc, selection: {head, anchor})
Line handles (as returned by, for
- example, getLineHandle
)
- support these events:
"delete" ()
"change" (line: LineHandle, changeObj: object)
change
- object is similar to the one passed
- to change event on the editor
- object.Marked range handles (CodeMirror.TextMarker
), as returned
- by markText
- and setBookmark
, emit the
- following events:
"beforeCursorEnter" ()
"clear" (from: {line, ch}, to: {line, ch})
clearOnEnter
- or through a call to its clear()
method. Will only
- be fired once per handle. Note that deleting the range through
- text editing does not fire this event, because an undo action
- might bring the range back into existence. from
- and to
give the part of the document that the range
- spanned when it was cleared."hide" ()
"unhide" ()
Line widgets (CodeMirror.LineWidget
), returned
- by addLineWidget
, fire
- these events:
"redraw" ()
Keymaps are ways to associate keys with functionality. A keymap - is an object mapping strings that identify the keys to functions - that implement their functionality.
- -Keys are identified either by name or by character.
- The CodeMirror.keyNames
object defines names for
- common keys and associates them with their key codes. Examples of
- names defined here are Enter
, F5
,
- and Q
. These can be prefixed
- with Shift-
, Cmd-
, Ctrl-
,
- and Alt-
(in that order!) to specify a modifier. So
- for example, Shift-Ctrl-Space
would be a valid key
- identifier.
Common example: map the Tab key to insert spaces instead of a tab - character.
- --{ - Tab: function(cm) { - var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); - cm.replaceSelection(spaces, "end", "+input"); - } -}- -
Alternatively, a character can be specified directly by
- surrounding it in single quotes, for example '$'
- or 'q'
. Due to limitations in the way browsers fire
- key events, these may not be prefixed with modifiers.
The CodeMirror.keyMap
object associates keymaps
- with names. User code and keymap definitions can assign extra
- properties to this object. Anywhere where a keymap is expected, a
- string can be given, which will be looked up in this object. It
- also contains the "default"
keymap holding the
- default bindings.
The values of properties in keymaps can be either functions of
- a single argument (the CodeMirror instance), strings, or
- false
. Such strings refer to properties of the
- CodeMirror.commands
object, which defines a number of
- common commands that are used by the default keybindings, and maps
- them to functions. If the property is set to false
,
- CodeMirror leaves handling of the key up to the browser. A key
- handler function may return CodeMirror.Pass
to indicate
- that it has decided not to handle the key, and other handlers (or
- the default behavior) should be given a turn.
Keys mapped to command names that start with the
- characters "go"
(which should be used for
- cursor-movement actions) will be fired even when an
- extra Shift
modifier is present (i.e. "Up":
- "goLineUp"
matches both up and shift-up). This is used to
- easily implement shift-selection.
Keymaps can defer to each other by defining
- a fallthrough
property. This indicates that when a
- key is not found in the map itself, one or more other maps should
- be searched. It can hold either a single keymap or an array of
- keymaps.
When a keymap contains a nofallthrough
property
- set to true
, keys matched against that map will be
- ignored if they don't match any of the bindings in the map (no
- further child maps will be tried). When
- the disableInput
property is set
- to true
, the default effect of inserting a character
- will be suppressed when the keymap is active as the top-level
- map.
Up to a certain extent, CodeMirror's look can be changed by
- modifying style sheet files. The style sheets supplied by modes
- simply provide the colors for that mode, and can be adapted in a
- very straightforward way. To style the editor itself, it is
- possible to alter or override the styles defined
- in codemirror.css
.
Some care must be taken there, since a lot of the rules in this - file are necessary to have CodeMirror function properly. Adjusting - colors should be safe, of course, and with some care a lot of - other things can be changed as well. The CSS classes defined in - this file serve the following roles:
- -CodeMirror
CodeMirror-scroll
overflow: auto
+
- fixed height). By default, it does. Setting
- the CodeMirror
class to have height:
- auto
and giving this class overflow-x: auto;
- overflow-y: hidden;
will cause the editor
- to resize to fit its
- content.CodeMirror-focused
CodeMirror-gutters
CodeMirror-linenumbers
CodeMirror-linenumber
CodeMirror-linenumbers
- (plural) element, but rather will be absolutely positioned to
- overlay it. Use this to set alignment and text properties for
- the line numbers.CodeMirror-lines
CodeMirror-cursor
CodeMirror-selected
span
elements
- with this class.CodeMirror-matchingbracket
,
- CodeMirror-nonmatchingbracket
If your page's style sheets do funky things to
- all div
or pre
elements (you probably
- shouldn't do that), you'll have to define rules to cancel these
- effects out again for elements under the CodeMirror
- class.
Themes are also simply CSS files, which define colors for
- various syntactic elements. See the files in
- the theme
directory.
A lot of CodeMirror features are only available through its - API. Thus, you need to write code (or - use addons) if you want to expose them to - your users.
- -Whenever points in the document are represented, the API uses
- objects with line
and ch
properties.
- Both are zero-based. CodeMirror makes sure to 'clip' any positions
- passed by client code so that they fit inside the document, so you
- shouldn't worry too much about sanitizing your coordinates. If you
- give ch
a value of null
, or don't
- specify it, it will be replaced with the length of the specified
- line.
Methods prefixed with doc.
can, unless otherwise
- specified, be called both on CodeMirror
(editor)
- instances and CodeMirror.Doc
instances. Methods
- prefixed with cm.
are only available
- on CodeMirror
instances.
Constructing an editor instance is done with
- the CodeMirror(place: Element|fn(Element),
- ?option: object)
constructor. If the place
- argument is a DOM element, the editor will be appended to it. If
- it is a function, it will be called, and is expected to place the
- editor into the document. options
may be an element
- mapping option names to values. The options
- that it doesn't explicitly specify (or all options, if it is not
- passed) will be taken
- from CodeMirror.defaults
.
Note that the options object passed to the constructor will be - mutated when the instance's options - are changed, so you shouldn't share such - objects between instances.
- -See CodeMirror.fromTextArea
- for another way to construct an editor instance.
doc.getValue(?separator: string) → string
"\n"
).doc.setValue(content: string)
doc.getRange(from: {line, ch}, to: {line, ch}, ?separator: string) → string
{line, ch}
objects. An optional third
- argument can be given to indicate the line separator string to
- use (defaults to "\n"
).doc.replaceRange(replacement: string, from: {line, ch}, to: {line, ch})
from
- and to
with the given string. from
- and to
must be {line, ch}
- objects. to
can be left off to simply insert the
- string at position from
.doc.getLine(n: integer) → string
n
.doc.setLine(n: integer, text: string)
n
.doc.removeLine(n: integer)
doc.lineCount() → integer
doc.firstLine() → integer
doc.lastLine() → integer
doc.lineCount() - 1
,
- but for linked sub-views,
- it might return other values.doc.getLineHandle(num: integer) → LineHandle
doc.getLineNumber(handle: LineHandle) → integer
null
when it is no longer in the
- document).doc.eachLine(f: (line: LineHandle))
doc.eachLine(start: integer, end: integer, f: (line: LineHandle))
start
- and end
line numbers are given, the range
- from start
up to (not including) end
,
- and call f
for each line, passing the line handle.
- This is a faster way to visit a range of line handlers than
- calling getLineHandle
- for each of them. Note that line handles have
- a text
property containing the line's content (as a
- string).doc.markClean()
changeGeneration
,
- which allows multiple subsystems to track different notions of
- cleanness without interfering.doc.changeGeneration() → integer
isClean
to test whether
- any edits were made (and not undone) in the meantime.doc.isClean(?generation: integer) → boolean
markClean
if no
- argument is passed, or since the matching call
- to changeGeneration
- if a generation value is given.doc.getSelection() → string
doc.replaceSelection(replacement: string, ?collapse: string)
collapse
argument can be used to change
- this—passing "start"
or "end"
will
- collapse the selection to the start or end of the inserted
- text.doc.getCursor(?start: string) → {line, ch}
start
is a an optional string indicating which
- end of the selection to return. It may
- be "start"
, "end"
, "head"
- (the side of the selection that moves when you press
- shift+arrow), or "anchor"
(the fixed side of the
- selection). Omitting the argument is the same as
- passing "head"
. A {line, ch}
object
- will be returned.doc.somethingSelected() → boolean
doc.setCursor(pos: {line, ch})
{line, ch}
object, or the line and the
- character as two separate parameters.doc.setSelection(anchor: {line, ch}, ?head: {line, ch})
anchor
- and head
should be {line, ch}
- objects. head
defaults to anchor
when
- not given.doc.extendSelection(from: {line, ch}, ?to: {line, ch})
setSelection
, but
- will, if shift is held or
- the extending flag is set, move the
- head of the selection while leaving the anchor at its current
- place. to
is optional, and can be passed to
- ensure a region (for example a word or paragraph) will end up
- selected (in addition to whatever lies between that region and
- the current anchor).doc.setExtending(value: boolean)
extendSelection
- to leave the selection anchor in place.cm.hasFocus() → boolean
cm.findPosH(start: {line, ch}, amount: integer, unit: string, visually: boolean) → {line, ch, ?hitSide: boolean}
start
is a {line, ch}
- object, amount
an integer (may be negative),
- and unit
one of the
- string "char"
, "column"
,
- or "word"
. Will return a position that is produced
- by moving amount
times the distance specified
- by unit
. When visually
is true, motion
- in right-to-left text will be visual rather than logical. When
- the motion was clipped by hitting the end or start of the
- document, the returned value will have a hitSide
- property set to true.cm.findPosV(start: {line, ch}, amount: integer, unit: string) → {line, ch, ?hitSide: boolean}
findPosH
,
- but used for vertical motion. unit
may
- be "line"
or "page"
. The other
- arguments and the returned value have the same interpretation as
- they have in findPosH
.cm.setOption(option: string, value: any)
option
- should the name of an option,
- and value
should be a valid value for that
- option.cm.getOption(option: string) → any
cm.addKeyMap(map: object, bottom: boolean)
extraKeys
- option. Maps added in this way have a higher precedence than
- the extraKeys
- and keyMap
options,
- and between them, the maps added earlier have a lower precedence
- than those added later, unless the bottom
argument
- was passed, in which case they end up below other keymaps added
- with this method.cm.removeKeyMap(map: object)
addKeyMap
. Either
- pass in the keymap object itself, or a string, which will be
- compared against the name
property of the active
- keymaps.cm.addOverlay(mode: string|object, ?options: object)
mode
can be a mode
- spec or a mode object (an object with
- a token
method).
- The options
parameter is optional. If given, it
- should be an object. Currently, only the opaque
- option is recognized. This defaults to off, but can be given to
- allow the overlay styling, when not null
, to
- override the styling of the base mode entirely, instead of the
- two being applied together.cm.removeOverlay(mode: string|object)
mode
- parameter to addOverlay
,
- or a string that corresponds to the name
propery of
- that value, to remove an overlay again.cm.on(type: string, func: (...args))
CodeMirror.on(object, type, func)
version
- that allows registering of events on any object.cm.off(type: string, func: (...args))
CodeMirror.off(object, type,
- func)
also exists.Each editor is associated with an instance
- of CodeMirror.Doc
, its document. A document
- represents the editor content, plus a selection, an undo history,
- and a mode. A document can only be
- associated with a single editor at a time. You can create new
- documents by calling the CodeMirror.Doc(text, mode,
- firstLineNumber)
constructor. The last two arguments are
- optional and can be used to set a mode for the document and make
- it start at a line number other than 0, respectively.
cm.getDoc() → Doc
doc.getEditor() → CodeMirror
null
.cm.swapDoc(doc: CodeMirror.Doc) → Doc
doc.copy(copyHistory: boolean) → Doc
copyHistory
is true, the history will also be
- copied. Can not be called directly on an editor.doc.linkedDoc(options: object) → Doc
from: integer
to: integer
mode: string|object
doc.unlinkDoc(doc: CodeMirror.Doc)
doc.iterLinkedDocs(function: (doc: CodeMirror.Doc, sharedHist: boolean))
doc.undo()
doc.redo()
doc.historySize() → {undo: integer, redo: integer}
{undo, redo}
properties,
- both of which hold integers, indicating the amount of stored
- undo and redo operations.doc.clearHistory()
doc.getHistory() → object
doc.setHistory(history: object)
getHistory
. Note that
- this will have entirely undefined results if the editor content
- isn't also the same as it was when getHistory
was
- called.doc.markText(from: {line, ch}, to: {line, ch}, ?options: object) → TextMarker
from
and to
should
- be {line, ch}
objects. The options
- parameter is optional. When given, it should be an object that
- may contain the following configuration options:
- className: string
inclusiveLeft: boolean
inclusiveRight: boolean
inclusiveLeft
,
- but for the right side.atomic: boolean
inclusiveLeft
- and inclusiveRight
have a different meaning—they
- will prevent the cursor from being placed respectively
- directly before and directly after the range.collapsed: boolean
clearOnEnter: boolean
"clear"
event
- fired on the range handle can be used to be notified when this
- happens.replacedWith: Element
handleMouseEvents: boolean
replacedWith
is given, this determines
- whether the editor will capture mouse and drag events
- occurring in this widget. Default is false—the events will be
- left alone for the default browser handler, or specific
- handlers on the widget, to capture.readOnly: boolean
setValue
to reset
- the whole document. Note: adding a read-only span
- currently clears the undo history of the editor, because
- existing undo events being partially nullified by read-only
- spans would corrupt the history (in the current
- implementation).addToHistory: boolean
startStyle: string
endStyle: string
startStyle
, but for the rightmost span.title:
- string
title
attribute with the
- given value.shared
to true to make the
- marker appear in all documents. By default, a marker appears
- only in its target document.CodeMirror.TextMarker
), which
- exposes three methods:
- clear()
, to remove the mark,
- find()
, which returns
- a {from, to}
object (both holding document
- positions), indicating the current position of the marked range,
- or undefined
if the marker is no longer in the
- document, and finally changed()
,
- which you can call if you've done something that might change
- the size of the marker (for example changing the content of
- a replacedWith
- node), and want to cheaply update the display.doc.setBookmark(pos: {line, ch}, ?options: object) → TextMarker
find()
and clear()
. The first
- returns the current position of the bookmark, if it is still in
- the document, and the second explicitly removes the bookmark.
- The options argument is optional. If given, the following
- properties are recognized:
- widget: Element
replacedWith
- option to markText
).insertLeft: boolean
doc.findMarksAt(pos: {line, ch}) → array<TextMarker>
doc.getAllMarks() → array<TextMarker>
cm.setGutterMarker(line: integer|LineHandle, gutterID: string, value: Element) → LineHandle
gutters
option)
- to the given value. Value can be either null
, to
- clear the marker, or a DOM element, to set it. The DOM element
- will be shown in the specified gutter next to the specified
- line.cm.clearGutter(gutterID: string)
cm.addLineClass(line: integer|LineHandle, where: string, class: string) → LineHandle
line
- can be a number or a line handle. where
determines
- to which element this class should be applied, can can be one
- of "text"
(the text element, which lies in front of
- the selection), "background"
(a background element
- that will be behind the selection), or "wrap"
(the
- wrapper node that wraps all of the line's elements, including
- gutter elements). class
should be the name of the
- class to apply.cm.removeLineClass(line: integer|LineHandle, where: string, class: string) → LineHandle
line
can be a
- line handle or number. where
should be one
- of "text"
, "background"
,
- or "wrap"
- (see addLineClass
). class
- can be left off to remove all classes for the specified node, or
- be a string to remove only a specific class.cm.lineInfo(line: integer|LineHandle) → object
{line, handle, text,
- gutterMarkers, textClass, bgClass, wrapClass, widgets}
,
- where gutterMarkers
is an object mapping gutter IDs
- to marker elements, and widgets
is an array
- of line widgets attached to this
- line, and the various class properties refer to classes added
- with addLineClass
.cm.addWidget(pos: {line, ch}, node: Element, scrollIntoView: boolean)
node
, which should be an absolutely
- positioned DOM node, into the editor, positioned right below the
- given {line, ch}
position.
- When scrollIntoView
is true, the editor will ensure
- that the entire node is visible (if possible). To remove the
- widget again, simply use DOM methods (move it somewhere else, or
- call removeChild
on its parent).cm.addLineWidget(line: integer|LineHandle, node: Element, ?options: object) → LineWidget
line
should be either an integer or a
- line handle, and node
should be a DOM node, which
- will be displayed below the given line. options
,
- when given, should be an object that configures the behavior of
- the widget. The following options are supported (all default to
- false):
- coverGutter: boolean
noHScroll: boolean
above: boolean
showIfHidden: boolean
handleMouseEvents: boolean
insertAt: integer
line
property
- pointing at the line handle that it is associated with, and the following methods:
- clear()
changed()
cm.setSize(width: number|string, height: number|string)
width
and height
- can be either numbers (interpreted as pixels) or CSS units
- ("100%"
, for example). You can
- pass null
for either of them to indicate that that
- dimension should not be changed.cm.scrollTo(x: number, y: number)
null
- or undefined
to have no effect.cm.getScrollInfo() → {left, top, width, height, clientWidth, clientHeight}
{left, top, width, height, clientWidth,
- clientHeight}
object that represents the current scroll
- position, the size of the scrollable area, and the size of the
- visible area (minus scrollbars).cm.scrollIntoView(what: {line, ch}|{left, top, right, bottom}|{from, to}|null, ?margin: number)
what
may
- be null
to scroll the cursor into view,
- a {line, ch}
position to scroll a character into
- view, a {left, top, right, bottom}
pixel range (in
- editor-local coordinates), or a range {from, to}
- containing either two character positions or two pixel squares.
- The margin
parameter is optional. When given, it
- indicates the amount of vertical pixels around the given area
- that should be made visible as well.cm.cursorCoords(where: boolean|{line, ch}, mode: string) → {left, top, bottom}
{left, top, bottom}
object
- containing the coordinates of the cursor position.
- If mode
is "local"
, they will be
- relative to the top-left corner of the editable document. If it
- is "page"
or not given, they are relative to the
- top-left corner of the page. where
can be a boolean
- indicating whether you want the start (true
) or the
- end (false
) of the selection, or, if a {line,
- ch}
object is given, it specifies the precise position at
- which you want to measure.cm.charCoords(pos: {line, ch}, ?mode: string) → {left, right, top, bottom}
pos
should be a {line, ch}
- object. This differs from cursorCoords
in that
- it'll give the size of the whole character, rather than just the
- position that the cursor would have when it would sit at that
- position.cm.coordsChar(object: {left, top}, ?mode: string) → {line, ch}
{left, top}
object, returns
- the {line, ch}
position that corresponds to it. The
- optional mode
parameter determines relative to what
- the coordinates are interpreted. It may
- be "window"
, "page"
(the default),
- or "local"
.cm.lineAtHeight(height: number, ?mode: string) → number
mode
can be one of the same strings
- that coordsChar
- accepts.cm.heightAtLine(line: number, ?mode: string) → number
mode
- (see coordsChar
), which
- defaults to "page"
. When a line below the bottom of
- the document is specified, the returned value is the bottom of
- the last line in the document.cm.defaultTextHeight() → number
cm.defaultCharWidth() → number
cm.getViewport() → {from: number, to: number}
{from, to}
object indicating the
- start (inclusive) and end (exclusive) of the currently rendered
- part of the document. In big documents, when most content is
- scrolled out of view, CodeMirror will only render the visible
- part, and a margin around it. See also
- the viewportChange
- event.cm.refresh()
When writing language-aware functionality, it can often be - useful to hook into the knowledge that the CodeMirror language - mode has. See the section on modes for a - more detailed description of how these work.
- -doc.getMode() → object
getOption("mode")
, which gives you
- the mode specification, rather than the resolved, instantiated
- mode object.doc.getModeAt(pos: {line, ch}) → object
getMode
for
- simple modes, but will return an inner mode for nesting modes
- (such as htmlmixed
).cm.getTokenAt(pos: {line, ch}, ?precise: boolean) → object
{line, ch}
object). The
- returned object has the following properties:
- start
end
string
type
"keyword"
- or "comment"
(may also be null).state
precise
is true, the token will be guaranteed to be accurate based on recent edits. If false or
- not specified, the token will use cached state information, which will be faster but might not be accurate if
- edits were recently made and highlighting has not yet completed.
- cm.getTokenTypeAt(pos: {line, ch}) → string
getTokenAt
useful for
- when you just need the type of the token at a given position,
- and no other information. Will return null
for
- unstyled tokens, and a string, potentially containing multiple
- space-separated style names, otherwise.cm.getHelper(pos: {line, ch}, type: string) → helper
type
argument provides the helper namespace
- (see
- also registerHelper
),
- in which the value will be looked up. The key that is used
- depends on the mode active at the given
- position. If the mode object contains a property with the same
- name as the type
argument, that is tried first.
- Next, the mode's helperType
, if any, is tried. And
- finally, the mode's name.cm.getStateAfter(?line: integer, ?precise: boolean) → object
precise
is defined
- as in getTokenAt()
.cm.operation(func: () → any) → any
cm.indentLine(line: integer, ?dir: string|integer)
"smart"
) may be one of:
- "prev"
"smart"
"prev"
otherwise."add"
"subtract"
<integer>
cm.toggleOverwrite(?value: bool)
cm.execCommand(name: string)
doc.posFromIndex(index: integer) → {line, ch}
{line, ch}
object for a
- zero-based index
who's value is relative to the start of the
- editor's text. If the index
is out of range of the text then
- the returned object is clipped to start or end of the text
- respectively.doc.indexFromPos(object: {line, ch}) → integer
posFromIndex
.cm.focus()
cm.getInputField() → TextAreaElement
cm.getWrapperElement() → Element
cm.getScrollerElement() → Element
cm.getGutterElement() → Element
The CodeMirror
object itself provides
- several useful properties.
CodeMirror.version: string
"major.minor.patch"
,
- where patch
is zero for releases, and something
- else (usually one) for dev snapshots.CodeMirror.fromTextArea(textArea: TextAreaElement, ?config: object)
cm.save()
cm.toTextArea()
cm.getTextArea() → TextAreaElement
CodeMirror.defaults: object
CodeMirror.defineExtension(name: string, value: any)
defineExtension
. This will cause the given
- value (usually a method) to be added to all CodeMirror instances
- created from then on.CodeMirror.defineDocExtension(name: string, value: any)
defineExtension
,
- but the method will be added to the interface
- for Doc
objects instead.CodeMirror.defineOption(name: string,
- default: any, updateFunc: function)
defineOption
can be used to define new options for
- CodeMirror. The updateFunc
will be called with the
- editor instance and the new value when an editor is initialized,
- and whenever the option is modified
- through setOption
.CodeMirror.defineInitHook(func: function)
CodeMirror.defineInitHook
. Give it a function as
- its only argument, and from then on, that function will be called
- (with the instance as argument) whenever a new CodeMirror instance
- is initialized.CodeMirror.registerHelper(type: string, name: string, value: helper)
name
in
- the given namespace (type
). This is used to define
- functionality that may be looked up by mode. Will create (if it
- doesn't already exist) a property on the CodeMirror
- object for the given type
, pointing to an object
- that maps names to values. I.e. after
- doing CodeMirror.registerHelper("hint", "foo",
- myFoo)
, the value CodeMirror.hint.foo
will
- point to myFoo
.CodeMirror.Pos(line: integer, ?ch: integer)
{line, ch}
objects that
- are used to represent positions in editor documents.CodeMirror.changeEnd(change: object) → {line, ch}
from
, to
,
- and text
properties, as passed to
- various event handlers). The
- returned position will be the end of the changed
- range, after the change is applied.The addon
directory in the distribution contains a
- number of reusable components that implement extra editor
- functionality. In brief, they are:
dialog/dialog.js
openDialog
method to
- CodeMirror instances, which can be called with an HTML fragment
- or a detached DOM node that provides the prompt (should include
- an input
tag), and a callback function that is called
- when text has been entered. Also adds
- an openNotification
function that
- simply shows an HTML fragment as a notification. Depends
- on addon/dialog/dialog.css
.search/searchcursor.js
getSearchCursor(query, start, caseFold) →
- cursor
method to CodeMirror instances, which can be used
- to implement search/replace functionality. query
- can be a regular expression or a string (only strings will match
- across lines—if they contain newlines). start
- provides the starting position of the search. It can be
- a {line, ch}
object, or can be left off to default
- to the start of the document. caseFold
is only
- relevant when matching a string. It will cause the search to be
- case-insensitive. A search cursor has the following methods:
- findNext() → boolean
findPrevious() → boolean
match
method, in case you
- want to extract matched groups.from() → {line, ch}
to() → {line, ch}
findNext
or findPrevious
did
- not return false. They will return {line, ch}
- objects pointing at the start and end of the match.replace(text: string)
search/search.js
searchcursor.js
, and will make use
- of openDialog
when
- available to make prompting for search queries less ugly.edit/matchbrackets.js
matchBrackets
which, when set
- to true, causes matching brackets to be highlighted whenever the
- cursor is next to them. It also adds a
- method matchBrackets
that forces this to happen
- once, and a method findMatchingBracket
that can be
- used to run the bracket-finding algorithm that this uses
- internally.edit/closebrackets.js
autoCloseBrackets
that will
- auto-close brackets and quotes when typed. By default, it'll
- auto-close ()[]{}''""
, but you can pass it a string
- similar to that (containing pairs of matching characters), or an
- object with pairs
and
- optionally explode
properties to customize
- it. explode
should be a similar string that gives
- the pairs of characters that, when enter is pressed between
- them, should have the second character also moved to its own
- line. Demo here.matchTags
that, when enabled,
- will cause the tags around the cursor to be highlighted (using
- the CodeMirror-matchingtag
class). Also
- defines
- a command toMatchingTag
,
- which you can bind a key to in order to jump to the tag mathing
- the one under the cursor. Depends on
- the addon/fold/xml-fold.js
- addon. Demo here.edit/trailingspace.js
showTrailingSpace
which, when
- enabled, adds the CSS class cm-trailingspace
to
- stretches of whitespace at the end of lines.
- The demo has a nice
- squiggly underline style for this class.edit/closetag.js
edit/continuelist.js
"newlineAndIndentContinueMarkdownList"
command
- command that can be bound to enter
to automatically
- insert the leading characters for continuing a list. See
- the Markdown mode
- demo.comment/comment.js
lineComment(from: {line, ch}, to: {line, ch}, ?options: object)
blockComment
when no line comment
- style is defined for the mode.blockComment(from: {line, ch}, to: {line, ch}, ?options: object)
lineComment
when no block comment
- style is defined for the mode.uncomment(from: {line, ch}, to: {line, ch}, ?options: object) → boolean
true
if a comment range was found and
- removed, false
otherwise.options
object accepted by these methods may
- have the following properties:
- blockCommentStart, blockCommentEnd, blockCommentLead, lineComment: string
padding: string
commentBlankLines: boolean
indent: boolean
fullLines: boolean
true
.toggleComment
command,
- which will try to uncomment the current selection, and if that
- fails, line-comments it.fold/foldcode.js
foldCode
method
- to editor instances, which will try to do a code fold starting
- at the given line, or unfold the fold that is already present.
- The method takes as first argument the position that should be
- folded (may be a line number or
- a Pos
), and as second optional
- argument either a range-finder function, or an options object,
- supporting the following properties:
- rangeFinder: fn(CodeMirror, Pos)
getHelper
with
- a "fold"
type to find one that's appropriate for
- the mode. There are files in
- the addon/fold/
- directory providing CodeMirror.fold.brace
, which
- finds blocks in brace languages (JavaScript, C, Java,
- etc), CodeMirror.fold.indent
, for languages where
- indentation determines block structure (Python, Haskell),
- and CodeMirror.fold.xml
, for XML-style languages,
- and CodeMirror.fold.comment
, for folding comment
- blocks.widget: string|Element
CodeMirror-foldmarker
, or a DOM node.scanUp: boolean
minFoldSize: integer
fold/foldgutter.js
foldGutter
, which can be
- used to create a gutter with markers indicating the blocks that
- can be folded. Create a gutter using
- the gutters
option,
- giving it the class CodeMirror-foldgutter
or
- something else if you configure the addon to use a different
- class, and this addon will show markers next to folded and
- foldable blocks, and handle clicks in this gutter. Note that
- CSS styles should be applied to make the gutter, and the fold
- markers within it, visible. A default set of CSS styles are
- available in:
-
- addon/fold/foldgutter.css
- .
- The option
- can be either set to true
, or an object containing
- the following optional option fields:
- gutter: string
"CodeMirror-foldgutter"
. You will have to
- style this yourself to give it a width (and possibly a
- background). See the default gutter style rules above.indicatorOpen: string | Element
"CodeMirror-foldgutter-open"
.indicatorFolded: string | Element
"CodeMirror-foldgutter-folded"
.rangeFinder: fn(CodeMirror, Pos)
getHelper
will be
- used to determine a default.runmode/runmode.js
runmode/colorize.js
runmode
addon (or
- its standalone variant). Provides
- a CodeMirror.colorize
function that can be called
- with an array (or other array-ish collection) of DOM nodes that
- represent the code snippets. By default, it'll get
- all pre
tags. Will read the data-lang
- attribute of these nodes to figure out their language, and
- syntax-color their content using the relevant CodeMirror mode
- (you'll have to load the scripts for the relevant modes
- yourself). A second argument may be provided to give a default
- mode, used when no language attribute is found for a node. Used
- in this manual to highlight example code.mode/overlay.js
CodeMirror.overlayMode
, which is used to
- create such a mode. See this
- demo for a detailed example.mode/multiplex.js
CodeMirror.multiplexingMode
which, when
- given as first argument a mode object, and as other arguments
- any number of {open, close, mode [, delimStyle, innerStyle]}
- objects, will return a mode object that starts parsing using the
- mode passed as first argument, but will switch to another mode
- as soon as it encounters a string that occurs in one of
- the open
fields of the passed objects. When in a
- sub-mode, it will go back to the top mode again when
- the close
string is encountered.
- Pass "\n"
for open
or close
- if you want to switch on a blank line.
- delimStyle
is specified, it will be the token
- style returned for the delimiter tokens.innerStyle
is specified, it will be the token
- style added for each inner mode token.hint/show-hint.js
CodeMirror.showHint
, which takes a
- CodeMirror instance, a hinting function, and optionally an
- options object, and pops up a widget that allows the user to
- select a completion. Hinting functions are function that take an
- editor instance and an optional options object, and return
- a {list, from, to}
object, where list
- is an array of strings or objects (the completions),
- and from
and to
give the start and end
- of the token that is being completed as {line, ch}
- objects. If no hinting function is given, the addon will try to
- use getHelper
with
- the "hint"
type to find one. When completions
- aren't simple strings, they should be objects with the folowing
- properties:
- text: string
displayText: string
className: string
render: fn(Element, self, data)
hint: fn(CodeMirror, self, data)
async: boolean
(cm, callback, ?options)
, and the completion
- interface will only be popped up when the hinting function
- calls the callback, passing it the object holding the
- completions.completeSingle: boolean
alignWithWord: boolean
closeOnUnfocus: boolean
customKeys: keymap
moveFocus(n)
, setFocus(n)
, pick()
,
- and close()
methods (see the source for details),
- that can be used to change the focused element, pick the
- current element or close the menu.extraKeys: keymap
customKeys
above, but the bindings will
- be added to the set of default bindings, instead of replacing
- them."shown" ()
"select" (completion, Element)
"close" ()
addon/hint/show-hint.css
. Check
- out the demo for an
- example.hint/javascript-hint.js
CodeMirror.hint.javascript
) and CoffeeScript
- (CodeMirror.hint.coffeescript
) code. This will
- simply use the JavaScript environment that the editor runs in as
- a source of information about objects and their properties.hint/xml-hint.js
CodeMirror.hint.xml
, which produces
- hints for XML tagnames, attribute names, and attribute values,
- guided by a schemaInfo
option (a property of the
- second argument passed to the hinting function, or the third
- argument passed to CodeMirror.showHint
)."!top"
property
- containing a list of the names of valid top-level tags. The
- values of the properties should be objects with optional
- properties children
(an array of valid child
- element names, omit to simply allow all tags to appear)
- and attrs
(an object mapping attribute names
- to null
for free-form attributes, and an array of
- valid values for restricted
- attributes). Demo
- here.hint/html-hint.js
CodeMirror.htmlSchema
that you can pass to
- as a schemaInfo
option, and
- a CodeMirror.hint.html
hinting function that
- automatically calls CodeMirror.hint.xml
with this
- schema data. See
- the demo.hint/css-hint.js
CodeMirror.hint.css
.hint/python-hint.js
CodeMirror.hint.python
.hint/anyword-hint.js
CodeMirror.hint.anyword
) that simply looks for
- words in the nearby code and completes to those. Takes two
- optional options, word
, a regular expression that
- matches words (sequences of one or more character),
- and range
, which defines how many lines the addon
- should scan when completing (defaults to 500).hint/sql-hint.js
CodeMirror.hint.sql
.hint/pig-hint.js
CodeMirror.hint.pig
.search/match-highlighter.js
highlightSelectionMatches
option that
- can be enabled to highlight all instances of a currently
- selected word. Can be set either to true or to an object
- containing the following options: minChars
, for the
- minimum amount of selected characters that triggers a highlight
- (default 2), style
, for the style to be used to
- highlight the matches (default "matchhighlight"
,
- which will correspond to CSS
- class cm-matchhighlight
),
- and showToken
which can be set to true
- or to a regexp matching the characters that make up a word. When
- enabled, it causes the current word to be highlighted when
- nothing is selected (defaults to off).
- Demo here.lint/lint.js
json-lint.js
,
- javascript-lint.js
,
- and css-lint.js
- in the same directory). Defines a lint
option that
- can be set to a warning source (for
- example CodeMirror.lint.javascript
), or
- to true
, in which
- case getHelper
with
- type "lint"
is used to determined a validator
- function. Depends on addon/lint/lint.css
. A demo
- can be found here.selection/mark-selection.js
CodeMirror-selectedtext
when the styleSelectedText
option
- is enabled. Useful to change the colour of the selection (in addition to the background),
- like in this demo.selection/active-line.js
styleActiveLine
option that, when enabled,
- gives the wrapper of the active line the class CodeMirror-activeline
,
- and adds a background with the class CodeMirror-activeline-background
.
- is enabled. See the demo.mode/loadmode.js
CodeMirror.requireMode(modename,
- callback)
function that will try to load a given mode and
- call the callback when it succeeded. You'll have to
- set CodeMirror.modeURL
to a string that mode paths
- can be constructed from, for
- example "mode/%N/%N.js"
—the %N
's will
- be replaced with the mode name. Also
- defines CodeMirror.autoLoadMode(instance, mode)
,
- which will ensure the given mode is loaded and cause the given
- editor instance to refresh its mode when the loading
- succeeded. See the demo.comment/continuecomment.js
continueComments
option, which can be
- set to true to have the editor prefix new lines inside C-like
- block comments with an asterisk when Enter is pressed. It can
- also be set to a string in order to bind this functionality to a
- specific key..display/placeholder.js
placeholder
option that can be used to
- make text appear in the editor when it is empty and not focused.
- Also gives the editor a CodeMirror-empty
CSS class
- whenever it doesn't contain any text.
- See the demo.display/fullscreen.js
fullScreen
that, when set
- to true
, will make the editor full-screen (as in,
- taking up the whole browser window). Depends
- on fullscreen.css
. Demo
- here.wrap/hardwrap.js
wrapParagraph(?pos: {line, ch}, ?options: object)
pos
is not given, it defaults to the cursor
- position.wrapRange(from: {line, ch}, to: {line, ch}, ?options: object)
wrapParagraphsInRange(from: {line, ch}, to: {line, ch}, ?options: object)
paragraphStart, paragraphEnd: RegExp
column: number
wrapOn: RegExp
killTrailingSpace: boolean
merge/merge.js
CodeMirror.MergeView
- constructor takes arguments similar to
- the CodeMirror
- constructor, first a node to append the interface to, and then
- an options object. Two extra optional options are
- recognized, origLeft
and origRight
,
- which may be strings that provide original versions of the
- document, which will be shown to the left and right of the
- editor in non-editable CodeMirror instances. The merge interface
- will highlight changes between the editable document and the
- original(s) (demo).tern/tern.js
Modes typically consist of a single JavaScript file. This file - defines, in the simplest case, a lexer (tokenizer) for your - language—a function that takes a character stream as input, - advances it past a token, and returns a style for that token. More - advanced modes can also handle indentation for the language.
- -The mode script should
- call CodeMirror.defineMode
to
- register itself with CodeMirror. This function takes two
- arguments. The first should be the name of the mode, for which you
- should use a lowercase string, preferably one that is also the
- name of the files that define the mode (i.e. "xml"
is
- defined in xml.js
). The second argument should be a
- function that, given a CodeMirror configuration object (the thing
- passed to the CodeMirror
function) and an optional
- mode configuration object (as in
- the mode
option), returns
- a mode object.
Typically, you should use this second argument
- to defineMode
as your module scope function (modes
- should not leak anything into the global scope!), i.e. write your
- whole mode inside this function.
The main responsibility of a mode script is parsing - the content of the editor. Depending on the language and the - amount of functionality desired, this can be done in really easy - or extremely complicated ways. Some parsers can be stateless, - meaning that they look at one element (token) of the code - at a time, with no memory of what came before. Most, however, will - need to remember something. This is done by using a state - object, which is an object that is always passed when - reading a token, and which can be mutated by the tokenizer.
- -Modes that use a state must define
- a startState
method on their mode
- object. This is a function of no arguments that produces a state
- object to be used at the start of a document.
The most important part of a mode object is
- its token(stream, state)
method. All
- modes must define this method. It should read one token from the
- stream it is given as an argument, optionally update its state,
- and return a style string, or null
for tokens that do
- not have to be styled. For your styles, you are encouraged to use
- the 'standard' names defined in the themes (without
- the cm-
prefix). If that fails, it is also possible
- to come up with your own and write your own CSS theme file.
- -
A typical token string would
- be "variable"
or "comment"
. Multiple
- styles can be returned (separated by spaces), for
- example "string error"
for a thing that looks like a
- string but is invalid somehow (say, missing its closing quote).
- When a style is prefixed by "line-"
- or "line-background-"
, the style will be applied to
- the whole line, analogous to what
- the addLineClass
method
- does—styling the "text"
in the simple case, and
- the "background"
element
- when "line-background-"
is prefixed.
The stream object that's passed
- to token
encapsulates a line of code (tokens may
- never span lines) and our current position in that line. It has
- the following API:
eol() → boolean
sol() → boolean
peek() → string
null
at the end of the
- line.next() → string
null
when no more characters are
- available.eat(match: string|regexp|function(char: string) → boolean) → string
match
can be a character, a regular expression,
- or a function that takes a character and returns a boolean. If
- the next character in the stream 'matches' the given argument,
- it is consumed and returned. Otherwise, undefined
- is returned.eatWhile(match: string|regexp|function(char: string) → boolean) → boolean
eat
with the given argument,
- until it fails. Returns true if any characters were eaten.eatSpace() → boolean
eatWhile
when matching
- white-space.skipToEnd()
skipTo(ch: string) → boolean
match(pattern: string, ?consume: boolean, ?caseFold: boolean) → boolean
match(pattern: regexp, ?consume: boolean) → array<string>
eat
—if consume
is true
- or not given—or a look-ahead that doesn't update the stream
- position—if it is false. pattern
can be either a
- string or a regular expression starting with ^
.
- When it is a string, caseFold
can be set to true to
- make the match case-insensitive. When successfully matching a
- regular expression, the returned value will be the array
- returned by match
, in case you need to extract
- matched groups.backUp(n: integer)
n
characters. Backing it up
- further than the start of the current token will cause things to
- break, so be careful.column() → integer
indentation() → integer
current() → string
By default, blank lines are simply skipped when
- tokenizing a document. For languages that have significant blank
- lines, you can define
- a blankLine(state)
method on your
- mode that will get called whenever a blank line is passed over, so
- that it can update the parser state.
Because state object are mutated, and CodeMirror
- needs to keep valid versions of a state around so that it can
- restart a parse at any line, copies must be made of state objects.
- The default algorithm used is that a new state object is created,
- which gets all the properties of the old object. Any properties
- which hold arrays get a copy of these arrays (since arrays tend to
- be used as mutable stacks). When this is not correct, for example
- because a mode mutates non-array properties of its state object, a
- mode object should define
- a copyState
method, which is given a
- state and should return a safe copy of that state.
If you want your mode to provide smart indentation
- (through the indentLine
- method and the indentAuto
- and newlineAndIndent
commands, to which keys can be
- bound), you must define
- an indent(state, textAfter)
method
- on your mode object.
The indentation method should inspect the given state object,
- and optionally the textAfter
string, which contains
- the text on the line that is being indented, and return an
- integer, the amount of spaces to indent. It should usually take
- the indentUnit
- option into account. An indentation method may
- return CodeMirror.Pass
to indicate that it
- could not come up with a precise indentation.
To work well with
- the commenting addon, a mode may
- define lineComment
(string that
- starts a line
- comment), blockCommentStart
, blockCommentEnd
- (strings that start and end block comments),
- and blockCommentLead
(a string to put at the start of
- continued lines in a block comment). All of these are
- optional.
Finally, a mode may define
- an electricChars
property, which should hold a string
- containing all the characters that should trigger the behaviour
- described for
- the electricChars
- option.
So, to summarize, a mode must provide
- a token
method, and it may
- provide startState
, copyState
,
- and indent
methods. For an example of a trivial mode,
- see the diff mode, for a more
- involved example, see the C-like
- mode.
Sometimes, it is useful for modes to nest—to have one
- mode delegate work to another mode. An example of this kind of
- mode is the mixed-mode HTML
- mode. To implement such nesting, it is usually necessary to
- create mode objects and copy states yourself. To create a mode
- object, there are CodeMirror.getMode(options,
- parserConfig)
, where the first argument is a configuration
- object as passed to the mode constructor function, and the second
- argument is a mode specification as in
- the mode
option. To copy a
- state object, call CodeMirror.copyState(mode, state)
,
- where mode
is the mode that created the given
- state.
In a nested mode, it is recommended to add an
- extra method, innerMode
which, given
- a state object, returns a {state, mode}
object with
- the inner mode and its state for the current position. These are
- used by utility scripts such as the tag
- closer to get context information. Use
- the CodeMirror.innerMode
helper function to, starting
- from a mode and a state, recursively walk down to the innermost
- mode and state.
To make indentation work properly in a nested parser, it is
- advisable to give the startState
method of modes that
- are intended to be nested an optional argument that provides the
- base indentation for the block of code. The JavaScript and CSS
- parser do this, for example, to allow JavaScript and CSS code
- inside the mixed-mode HTML mode to be properly indented.
It is possible, and encouraged, to associate
- your mode, or a certain configuration of your mode, with
- a MIME type. For
- example, the JavaScript mode associates itself
- with text/javascript
, and its JSON variant
- with application/json
. To do this,
- call CodeMirror.defineMIME(mime,
- modeSpec)
, where modeSpec
can be a string or
- object specifying a mode, as in
- the mode
option.
Sometimes, it is useful to add or override mode
- object properties from external code.
- The CodeMirror.extendMode
function
- can be used to add properties to mode objects produced for a
- specific mode. Its first argument is the name of the mode, its
- second an object that specifies the properties that should be
- added. This is mostly useful to add utilities that can later be
- looked up through getMode
.
Contact me if you'd like - your project to be added to this list.
- -21-11-2013: Version 3.20:
- -21-10-2013: Version 3.19:
- -23-09-2013: Version 3.18:
- -Emergency release to fix a problem in 3.17
- where .setOption("lineNumbers", false)
would raise an
- error.
23-09-2013: Version 3.17:
- -css-lint
, css-hint
.box-sizing
.21-08-2013: Version 3.16:
- -CodeMirror.fold.comment
.29-07-2013: Version 3.15:
- -getModeAt
.20-06-2013: Version 3.14:
- -markText
- and addLineWidget
- now take a handleMouseEvents
option.lineAtHeight
,
- getTokenTypeAt
.changeGeneration
- and isClean
."keyHandled"
- and "inputRead"
.20-05-2013: Version 3.13:
- -cursorScrollMargin
and coverGutterNextToScrollbar
.19-04-2013: Version 3.12:
- -maxHighlightLength
- and historyEventDelay
.addToHistory
- option for markText
.20-03-2013: Version 3.11:
- -collapserange
,
- formatting
, and simple-hint
- addons. plsql
and mysql
modes
- (use sql
mode).continuecomment
- addon now exposes an option, rather than a command.placeholder
, HTML completion.hasFocus
, defaultCharWidth
.beforeCursorEnter
, renderLine
.show-hint
completion
- dialog addon.21-02-2013: Version 3.1:
- -CodeMirror.Pass
to signal they
- didn't handle the key.simple-hint.js
.insertLeft
option
- to setBookmark
.eachLine
- method to iterate over a document."beforeChange"
- and "beforeSelectionChange"
- events."hide"
- and "unhide"
- events to marked ranges.coordsChar
's
- interpretation of its argument to match the documentation.25-01-2013: Version 3.02:
- -Single-bugfix release. Fixes a problem that - prevents CodeMirror instances from being garbage-collected after - they become unused.
- -21-01-2013: Version 3.01:
- -/addon
. You might have to adjust your
- paths.rtlMoveVisually
option.showIfHidden
option for line widgets.fixedGutter
option.10-12-2012: Version 3.0:
- -New major version. Only - partially backwards-compatible. See - the upgrading guide for more - information. Changes since release candidate 2:
- -20-11-2012: Version 3.0, release candidate 2:
- -addKeyMap
and removeKeyMap
methods.formatting
and closetag
add-ons.20-11-2012: Version 3.0, release candidate 1:
- -addLineClass
- and removeLineClass
,
- drop setLineClass
.isClean
/markClean
methods.compoundChange
method, use better undo-event-combining heuristic.22-10-2012: Version 3.0, beta 2:
- -gutterClick
event.cursorHeight
option.viewportMargin
option.flattenSpans
option.19-09-2012: Version 3.0, beta 1:
- -21-01-2013: Version 2.38:
- -Integrate some bugfixes, enhancements to the vim keymap, and new - modes - (D, Sass, APL) - from the v3 branch.
- -20-12-2012: Version 2.37:
- -20-11-2012: Version 2.36:
- -scrollIntoView
public.defaultTextHeight
method.22-10-2012: Version 2.35:
- -markText
/undo interaction.defineInitHook
function.19-09-2012: Version 2.34:
- -compareStates
is no longer needed.onHighlightComplete
no longer works.CodeMirror.version
property.23-08-2012: Version 2.33:
- -getViewPort
and onViewportChange
API.false
disabling handling (again).innerHTML
. Remove CodeMirror.htmlEscape
.23-07-2012: Version 2.32:
- -Emergency fix for a bug where an editor with - line wrapping on IE will break when there is no - scrollbar.
- -20-07-2012: Version 2.31:
- -setSize
method for programmatic resizing.getHistory
and setHistory
methods.getValue
and getRange
.22-06-2012: Version 2.3:
- -getScrollInfo
method.23-05-2012: Version 2.25:
- -23-04-2012: Version 2.24:
- -dragDrop
- and onDragEvent
- options.compoundChange
API method.catchall
in key maps,
- add nofallthrough
boolean field instead.26-03-2012: Version 2.23:
- -setLineClass
.charCoords
- and cursorCoords
with a mode
argument.autofocus
option.findMarksAt
method.27-02-2012: Version 2.22:
- -autoClearEmptyLines
option.27-01-2012: Version 2.21:
- -smartIndent
- option.readOnly
-mode.scrollTo
method.20-12-2011: Version 2.2:
- -coordsFromIndex
- to posFromIndex
,
- add indexFromPos
- method.21-11-2011: Version 2.18:
-Fixes TextMarker.clear
, which is broken in 2.17.
21-11-2011: Version 2.17:
-setBookmark
method.lib/util
.27-10-2011: Version 2.16:
-coordsFromIndex
method.setValue
now no longer clears history. Use clearHistory
for that.markText
now
- returns an object with clear
and find
- methods. Marked text is now more robust when edited.26-09-2011: Version 2.15:
-Fix bug that snuck into 2.14: Clicking the - character that currently has the cursor didn't re-focus the - editor.
- -26-09-2011: Version 2.14:
-fixedGutter
option.setValue
breaking cursor movement.23-08-2011: Version 2.13:
-getGutterElement
to API.smartHome
option.25-07-2011: Version 2.12:
-innerHTML
for HTML-escaping.04-07-2011: Version 2.11:
-replace
method to search cursors, for cursor-preserving replacements.getStateAfter
API and compareState
mode API methods for finer-grained mode magic.getScrollerElement
API method to manipulate the scrolling DIV.07-06-2011: Version 2.1:
-Add - a theme system - (demo). Note that this is not - backwards-compatible—you'll have to update your styles and - modes!
- -07-06-2011: Version 2.02:
-26-05-2011: Version 2.01:
-coordsChar
now worksonCursorActivity
interfered with onChange
.onChange
."nocursor"
mode for readOnly
option.onHighlightComplete
option.28-03-2011: Version 2.0:
-CodeMirror 2 is a complete rewrite that's - faster, smaller, simpler to use, and less dependent on browser - quirks. See this - and this - for more information.
- -22-02-2011: Version 2.0 beta 2:
-Somewhat more mature API, lots of bugs shaken out.
- -17-02-2011: Version 0.94:
-tabMode: "spaces"
was modified slightly (now indents when something is selected).08-02-2011: Version 2.0 beta 1:
-CodeMirror 2 is a complete rewrite of - CodeMirror, no longer depending on an editable frame.
- -19-01-2011: Version 0.93:
-save
method to instances created with fromTextArea
.28-03-2011: Version 1.0:
-17-12-2010: Version 0.92:
-styleNumbers
option is now officially
- supported and documented.onLineNumberClick
option added.onLoad
and
- onCursorActivity
callbacks. Old names still work, but
- are deprecated.11-11-2010: Version 0.91:
-toTextArea
to update the code in the textarea.noScriptCaching
option (hack to ease development).02-10-2010: Version 0.9:
-height: "dynamic"
more robust.enterMode
and electricChars
options to make indentation even more customizable.firstLineNumber
option.@media
rules by the CSS parser.22-07-2010: Version 0.8:
-cursorCoords
method to find the screen
- coordinates of the cursor.height: dynamic
mode, where the editor's
- height will adjust to the size of its content.toTextArea
method in instances created with
- fromTextArea
.27-04-2010: Version - 0.67:
-More consistent page-up/page-down behaviour
- across browsers. Fix some issues with hidden editors looping forever
- when line-numbers were enabled. Make PHP parser parse
- "\\"
correctly. Have jumpToLine
work on
- line handles, and add cursorLine
function to fetch the
- line handle where the cursor currently is. Add new
- setStylesheet
function to switch style-sheets in a
- running editor.
01-03-2010: Version - 0.66:
-Adds removeLine
method to API.
- Introduces the PLSQL parser.
- Marks XML errors by adding (rather than replacing) a CSS class, so
- that they can be disabled by modifying their style. Fixes several
- selection bugs, and a number of small glitches.
12-11-2009: Version - 0.65:
-Add support for having both line-wrapping and
- line-numbers turned on, make paren-highlighting style customisable
- (markParen
and unmarkParen
config
- options), work around a selection bug that Opera
- reintroduced in version 10.
23-10-2009: Version - 0.64:
-Solves some issues introduced by the
- paste-handling changes from the previous release. Adds
- setSpellcheck
, setTextWrapping
,
- setIndentUnit
, setUndoDepth
,
- setTabMode
, and setLineNumbers
to
- customise a running editor. Introduces an SQL parser. Fixes a few small
- problems in the Python
- parser. And, as usual, add workarounds for various newly discovered
- browser incompatibilities.
31-08-2009: Version 0.63:
-Overhaul of paste-handling (less fragile), fixes for several - serious IE8 issues (cursor jumping, end-of-document bugs) and a number - of small problems.
- -30-05-2009: Version 0.62:
-Introduces Python
- and Lua parsers. Add
- setParser
(on-the-fly mode changing) and
- clearHistory
methods. Make parsing passes time-based
- instead of lines-based (see the passTime
option).
So you found a problem in CodeMirror. By all means, report it! Bug -reports from users are the main drive behind improvements to -CodeMirror. But first, please read over these points:
- -There are a few things in the 2.2 release that require some care -when upgrading.
- -The default theme is now included
-in codemirror.css
, so
-you do not have to included it separately anymore. (It was tiny, so
-even if you're not using it, the extra data overhead is negligible.)
-
-
CodeMirror has moved to a system -where keymaps are used to -bind behavior to keys. This means custom -bindings are now possible.
- -Three options that influenced key
-behavior, tabMode
, enterMode
,
-and smartHome
, are no longer supported. Instead, you can
-provide custom bindings to influence the way these keys act. This is
-done through the
-new extraKeys
-option, which can hold an object mapping key names to functionality. A
-simple example would be:
extraKeys: { - "Ctrl-S": function(instance) { saveText(instance.getValue()); }, - "Ctrl-/": "undo" - }- -
Keys can be mapped either to functions, which will be given the
-editor instance as argument, or to strings, which are mapped through
-functions through the CodeMirror.commands
table, which
-contains all the built-in editing commands, and can be inspected and
-extended by external code.
By default, the Home
key is bound to
-the "goLineStartSmart"
command, which moves the cursor to
-the first non-whitespace character on the line. You can set do this to
-make it always go to the very start instead:
extraKeys: {"Home": "goLineStart"}- -
Similarly, Enter
is bound
-to "newlineAndIndent"
by default. You can bind it to
-something else to get different behavior. To disable special handling
-completely and only get a newline character inserted, you can bind it
-to false
:
extraKeys: {"Enter": false}- -
The same works for Tab
. If you don't want CodeMirror
-to handle it, bind it to false
. The default behaviour is
-to indent the current line more ("indentMore"
command),
-and indent it less when shift is held ("indentLess"
).
-There are also "indentAuto"
(smart indent)
-and "insertTab"
commands provided for alternate
-behaviors. Or you can write your own handler function to do something
-different altogether.
Handling of tabs changed completely. The display width of tabs can
-now be set with the tabSize
option, and tabs can
-be styled by setting CSS rules
-for the cm-tab
class.
The default width for tabs is now 4, as opposed to the 8 that is
-hard-wired into browsers. If you are relying on 8-space tabs, make
-sure you explicitly set tabSize: 8
in your options.
Version 3 does not depart too much from 2.x API, and sites that use -CodeMirror in a very simple way might be able to upgrade without -trouble. But it does introduce a number of incompatibilities. Please -at least skim this text before upgrading.
- -Note that version 3 drops full support for Internet -Explorer 7. The editor will mostly work on that browser, but -it'll be significantly glitchy.
- -This one is the most likely to cause problems. The internal -structure of the editor has changed quite a lot, mostly to implement a -new scrolling model.
- -Editor height is now set on the outer wrapper element (CSS
-class CodeMirror
), not on the scroller element
-(CodeMirror-scroll
).
Other nodes were moved, dropped, and added. If you have any code -that makes assumptions about the internal DOM structure of the editor, -you'll have to re-test it and probably update it to work with v3.
- -See the styling section of the -manual for more information.
-In CodeMirror 2.x, there was a single gutter, and line markers
-created with setMarker
would have to somehow coexist with
-the line numbers (if present). Version 3 allows you to specify an
-array of gutters, by class
-name,
-use setGutterMarker
-to add or remove markers in individual gutters, and clear whole
-gutters
-with clearGutter
.
-Gutter markers are now specified as DOM nodes, rather than HTML
-snippets.
The gutters no longer horizontally scrolls along with the content.
-The fixedGutter
option was removed (since it is now the
-only behavior).
-<style> - /* Define a gutter style */ - .note-gutter { width: 3em; background: cyan; } -</style> -<script> - // Create an instance with two gutters -- line numbers and notes - var cm = new CodeMirror(document.body, { - gutters: ["note-gutter", "CodeMirror-linenumbers"], - lineNumbers: true - }); - // Add a note to line 0 - cm.setGutterMarker(0, "note-gutter", document.createTextNode("hi")); -</script> --
Most of the onXYZ
options have been removed. The same
-effect is now obtained by calling
-the on
method with a string
-identifying the event type. Multiple handlers can now be registered
-(and individually unregistered) for an event, and objects such as line
-handlers now also expose events. See the
-full list here.
(The onKeyEvent
and onDragEvent
options,
-which act more as hooks than as event handlers, are still there in
-their old form.)
-cm.on("change", function(cm, change) { - console.log("something changed! (" + change.origin + ")"); -}); --
The markText
method
-(which has gained some interesting new features, such as creating
-atomic and read-only spans, or replacing spans with widgets) no longer
-takes the CSS class name as a separate argument, but makes it an
-optional field in the options object instead.
-// Style first ten lines, and forbid the cursor from entering them -cm.markText({line: 0, ch: 0}, {line: 10, ch: 0}, { - className: "magic-text", - inclusiveLeft: true, - atomic: true -}); --
The interface for hiding lines has been
-removed. markText
can
-now be used to do the same in a more flexible and powerful way.
The folding script has been -updated to use the new interface, and should now be more robust.
- --// Fold a range, replacing it with the text "??" -var range = cm.markText({line: 4, ch: 2}, {line: 8, ch: 1}, { - replacedWith: document.createTextNode("??"), - // Auto-unfold when cursor moves into the range - clearOnEnter: true -}); -// Get notified when auto-unfolding -CodeMirror.on(range, "clear", function() { - console.log("boom"); -}); --
The setLineClass
method has been replaced
-by addLineClass
-and removeLineClass
,
-which allow more modular control over the classes attached to a line.
-var marked = cm.addLineClass(10, "background", "highlighted-line"); -setTimeout(function() { - cm.removeLineClass(marked, "background", "highlighted-line"); -}); --
All methods that take or return objects that represent screen
-positions now use {left, top, bottom, right}
properties
-(not always all of them) instead of the {x, y, yBot}
used
-by some methods in v2.x.
Affected methods
-are cursorCoords
, charCoords
, coordsChar
,
-and getScrollInfo
.
The matchBrackets
-option is no longer defined in the core editor.
-Load addon/edit/matchbrackets.js
to enable it.
The CodeMirror.listModes
-and CodeMirror.listMIMEs
functions, used for listing
-defined modes, are gone. You are now encouraged to simply
-inspect CodeMirror.modes
(mapping mode names to mode
-constructors) and CodeMirror.mimeModes
(mapping MIME
-strings to mode specs).
Some more reasons to upgrade to version 3.
- -CodeMirror.defineOption
.A limited set of programmatic sanity tests for CodeMirror.
- -Please enable JavaScript...
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' + text.replace('&', '&').replace('<', '<') + ''; - s += '
' + text.replace('&', '&').replace('<', '<') + ''; - s += '
' + - '' + - val.replace(/ /g,'\xb7').replace('&', '&').replace('<', '<') + - '' + - ' | '; - } - s += '
' + (output[i] || null) + ' | '; - } - s += '