Active Line Demo
Styling the current cursor line.
pax_global_header 0000666 0000000 0000000 00000000064 12770207757 0014530 g ustar 00root root 0000000 0000000 52 comment=a350d03f15df2892e41b094faa85a08459942845 CodeMirror-5.19.0/ 0000775 0000000 0000000 00000000000 12770207757 0013671 5 ustar 00root root 0000000 0000000 CodeMirror-5.19.0/.gitattributes 0000664 0000000 0000000 00000000150 12770207757 0016560 0 ustar 00root root 0000000 0000000 *.txt text *.js text *.html text *.md text *.json text *.yml text *.css text *.svg text CodeMirror-5.19.0/.gitignore 0000664 0000000 0000000 00000000106 12770207757 0015656 0 ustar 00root root 0000000 0000000 /node_modules /npm-debug.log /test*.html .tern-* *~ *.swp .idea *.iml CodeMirror-5.19.0/.npmignore 0000664 0000000 0000000 00000000153 12770207757 0015667 0 ustar 00root root 0000000 0000000 /node_modules /demo /doc /test /test*.html /index.html /mode/*/*test.js /mode/*/*.html /mode/index.html .* CodeMirror-5.19.0/.travis.yml 0000664 0000000 0000000 00000000062 12770207757 0016000 0 ustar 00root root 0000000 0000000 language: node_js node_js: - stable sudo: false CodeMirror-5.19.0/AUTHORS 0000664 0000000 0000000 00000017147 12770207757 0014753 0 ustar 00root root 0000000 0000000 List of CodeMirror contributors. Updated before every release. 4r2r Aaron Brooks Abdelouahab Abe Fettig Adam Ahmed Adam King adanlobato Adán Lobato Adrian Aichner aeroson Ahmad Amireh Ahmad M. Zawawi ahoward Akeksandr Motsjonov Alasdair Smith Alberto González Palomo Alberto Pose Albert Xing Alexander Pavlov Alexander Schepanovski Alexander Shvets Alexander Solovyov Alexandre Bique alexey-k Alex Piggott Aliaksei Chapyzhenka Allen Sarkisyan Amin Shali Amin Ullah Khan amshali@google.com Amsul amuntean Amy Ananya Sen anaran AndersMad Anders Nawroth Anderson Mesquita Anders Wåglund Andrea G Andreas Reischuck Andres Taylor Andre von Houck Andrey Fedorov Andrey Klyuchnikov Andrey Lushnikov Andrey Shchekin Andy Joslin Andy Kimball Andy Li Angelo angelozerr angelo.zerr@gmail.com Ankit Ankit Ahuja Ansel Santosa Anthony Dugois anthonygego Anthony Gégo Anthony Grimes Anton Kovalyov AQNOUCH Mohammed areos Arnab Bose as3boyan AtomicPages LLC Atul Bhouraskar Aurelian Oancea Barret Rennie Basarat Ali Syed Bastian Müller belhaj Bem Jones-Bey benbro Beni Cherniavsky-Paskin Benjamin DeCoste Ben Keen Ben Miller Ben Mosher Bernhard Sirlinger Bert Chang Bharad Billy Moon binny B Krishna Chaitanya Blaine G blukat29 boomyjee borawjm Brad Metcalf Brandon Frohs Brandon Wamboldt Brett Zamir Brian Grinstead Brian Sletten Bruce Mitchener Caitlin Potter Calin Barbat callodacity Camilo Roca Chad Jolly Chandra Sekhar Pydi Charles Skelton Cheah Chu Yeow Chris Coyier Chris Ford Chris Granger Chris Houseknecht Chris Lohfink Chris Morgan Chris Smith Christian Oyarzun Christian Petrov Christopher Brown Christopher Mitchell Christopher Pfohl Chunliang Lyu ciaranj CodeAnimal coderaiser Cole R Lawrence ComFreek Curtis Gagliardi dagsta daines Dale Jung Dan Bentley Dan Heberden Daniel, Dao Quang Minh Daniele Di Sarli Daniel Faust Daniel Huigens Daniel Kesler Daniel KJ Daniel Neel Daniel Parnell Danny Yoo darealshinji Darius Roberts Dave Brondsema Dave Myers David Barnett David H. Bronke David Mignot David Pathakjee David Vázquez David Whittington deebugger Deep Thought Devin Abbott Devon Carew dignifiedquire Dimage Sapelkin Dmitry Kiselyov domagoj412 Dominator008 Domizio Demichelis Doug Wikle Drew Bratcher Drew Hintz Drew Khoury Drini Cami Dror BG duralog eborden edsharp ekhaled Elisée Enam Mijbah Noor Eric Allam Erik Welander eustas Fabien O'Carroll Fabio Zendhi Nagao Faiza Alsaied Fauntleroy fbuchinger feizhang365 Felipe Lalanne Felix Raab Filip Noetzel Filip Stollár flack ForbesLindesay Forbes Lindesay Ford_Lawnmower Forrest Oliphant Frank Wiegand Gabriel Gheorghian Gabriel Horner Gabriel Nahmias galambalazs Gary Sheng Gautam Mehta Gavin Douglas gekkoe geowarin Gerard Braad Gergely Hegykozi Giovanni Calò Glebov Boris Glenn Jorde Glenn Ruehle Golevka Google Inc. Gordon Smith Grant Skinner greengiant Gregory Koberger Grzegorz Mazur Guillaume Massé Guillaume Massé guraga Gustavo Rodrigues Hakan Tunc Hans Engel Hardest Harshvardhan Gupta Hasan Karahan Hector Oswaldo Caballero Hendrik Wallbaum Herculano Campos Hiroyuki Makino hitsthings Hocdoc Hugues Malphettes Ian Beck Ian Dickinson Ian Wehrman Ian Wetherbee Ice White ICHIKAWA, Yuji idleberg ilvalle Ingo Richter Irakli Gozalishvili Ivan Kurnosov Ivoah Jacob Lee Jakob Miland Jakub Vrana Jakub Vrána James Campos James Howard James Thorne Jamie Hill Jan Jongboom jankeromnes Jan Keromnes Jan Odvarko Jan Schär Jan T. Sott Jared Dean Jared Forsyth Jared Jacobs Jason Jason Barnabe Jason Grout Jason Johnston Jason San Jose Jason Siefken Jaydeep Solanki Jean Boussier Jeff Blaisdell Jeff Jenkins jeffkenton Jeff Pickhardt jem (graphite) Jeremy Parmenter Jim JobJob jochenberger Jochen Berger Joel Einbinder joelpinheiro Johan Ask John Connor John Engler John Lees-Miller John Snelson John Van Der Loo Jon Ander Peñalba Jonas Döbertin Jonathan Malmaud jongalloway Jon Malmaud Jon Sangster Joost-Wim Boekesteijn Joseph Pecoraro Josh Cohen Josh Soref Joshua Newman Josh Watzman jots jsoojeon ju1ius Juan Benavides Romero Jucovschi Constantin Juho Vuori Julien Rebetez Justin Andresen Justin Hileman jwallers@gmail.com kaniga karevn Kayur Patel Ken Newman ken restivo Ken Rockot Kevin Earls Kevin Sawicki Kevin Ushey Klaus Silveira Koh Zi Han, Cliff komakino Konstantin Lopuhin koops Kris Ciccarello ks-ifware kubelsmieci KwanEsq Lanfei Lanny Laszlo Vidacs leaf corcoran Leonid Khachaturov Leon Sorokin Leonya Khachaturov Liam Newman Libo Cannici LloydMilligan LM lochel Lorenzo Stoakes Luciano Longo Lu Fangjian Luke Granger-Brown Luke Stagner lynschinzer M1cha Madhura Jayaratne Maksim Lin Maksym Taran Malay Majithia Manideep Manuel Rego Casasnovas Marat Dreizin Marcel Gerber Marco Aurélio Marco Munizaga Marcus Bointon Marek Rudnicki Marijn Haverbeke Mário Gonçalves Mario Pietsch Mark Anderson Mark Lentczner Marko Bonaci Markus Bordihn Martin Balek Martín Gaitán Martin Hasoň Martin Hunt Martin Laine Martin Zagora Mason Malone Mateusz Paprocki Mathias Bynens mats cronqvist Matt Gaide Matthew Bauer Matthew Beale matthewhayes Matthew Rathbone Matthias Bussonnier Matthias BUSSONNIER Matt McDonald Matt Pass Matt Sacks mauricio Maximilian Hils Maxim Kraev Max Kirsch Max Schaefer Max Xiantu mbarkhau McBrainy melpon Metatheos Micah Dubinko Michael Michael Goderbauer Michael Grey Michael Kaminsky Michael Lehenbauer Michael Zhou Michal Dorner Mighty Guava Miguel Castillo mihailik Mike Mike Brevoort Mike Diaz Mike Ivanov Mike Kadin Mike Kobit MinRK Miraculix87 misfo mkaminsky11 mloginov Moritz Schwörer mps ms mtaran-google Narciso Jaramillo Nathan Williams ndr nerbert nextrevision ngn nguillaumin Ng Zhi An Nicholas Bollweg Nicholas Bollweg (Nick) Nick Kreeger Nick Small Nicolò Ribaudo Niels van Groningen nightwing Nikita Beloglazov Nikita Vasilyev Nikolay Kostov nilp0inter Nisarg Jhaveri nlwillia noragrossman Norman Rzepka Oreoluwa Onatemowo pablo pabloferz Page Panupong Pasupat paris Paris Patil Arpith Patrick Stoica Patrick Strawderman Paul Garvin Paul Ivanov Paul Masson Pavel Pavel Feldman Pavel Petržela Pavel Strashkin Paweł Bartkiewicz peteguhl peter Peter Flynn peterkroon Peter Kroon Philipp A Philip Stadermann Pierre Gerold Piët Delport Pontus Melke prasanthj Prasanth J Prayag Verma Radek Piórkowski Rahul Rahul Anand ramwin1 Randall Mason Randy Burden Randy Edmunds Rasmus Erik Voel Jensen ray ratchup Ray Ratchup Remi Nyborg Richard Denton Richard van der Meer Richard Z.H. Wang Robert Crossfield Roberto Abdelkader Martínez Pérez robertop23 Robert Plummer Rrandom Ruslan Osmanov Ryan Prior sabaca Sam Lee Samuel Ainsworth Sam Wilson sandeepshetty Sander AKA Redsandro santec Sascha Peilicke satamas satchmorun sathyamoorthi S. Chris Colbert SCLINIC\jdecker Scott Aikin Scott Goodhew Sebastian Zaha Sergey Goder Sergey Tselovalnikov Se-Won Kim shaund shaun gilchrist Shawn A Shea Bunge sheopory Shiv Deepak Shmuel Englard Shubham Jain Siamak Mokhtari silverwind sinkuu snasa soliton4 sonson spastorelli srajanpaliwal Stanislav Oaserele Stas Kobzar Stefan Borsje Steffen Beyer Steffen Bruchmann Stephen Lavelle Steve Champagne Steve O'Hara stoskov Stu Kennedy Sungho Kim sverweij Taha Jahangir Tako Schotanus Takuji Shimokawa Tarmil TDaglis tel tfjgeorge Thaddee Tyl thanasis TheHowl think Thomas Dvornik Thomas Kluyver Thomas Schmid Tim Alby Tim Baumann Timothy Farrell Timothy Gu Timothy Hatcher TobiasBg Tomas-A Tomas Varaneckas Tom Erik Støwer Tom MacWright Tony Jian Travis Heppe Triangle717 Tristan Tarrant TSUYUSATO Kitsune twifkak VapidWorx Vestimir Markov vf Victor Bocharsky Vincent Woo Volker Mische Weiyan Shao wenli Wes Cossick Wesley Wiser Will Binns-Smith Will Dean William Jamieson William Stein Willy Wojtek Ptak Wu Cheng-Han Xavier Mendez Yassin N. Hassan YNH Webdev Yunchi Luo Yuvi Panda Zac Anger Zachary Dremann Zhang Hao zziuni 魏鹏刚 CodeMirror-5.19.0/CHANGELOG.md 0000664 0000000 0000000 00000164030 12770207757 0015506 0 ustar 00root root 0000000 0000000 ## 5.19.0 (2016-09-20) ### Bugfixes [erlang mode](http://codemirror.net/mode/erlang): Fix mode crash when trying to read an empty context. [comment addon](http://codemirror.net/doc/manual.html#addon_comment): Fix broken behavior when toggling comments inside a comment. xml-fold addon: Fix a null-dereference bug. Page up and page down now do something even in single-line documents. Fix an issue where the cursor position could be off in really long (~8000 character) tokens. ### New features [javascript mode](http://codemirror.net/mode/javascript): Better indentation when semicolons are missing. Better support for TypeScript classes, optional parameters, and the `type` keyword. The [`blur`](http://codemirror.net/doc/manual.html#event_blur) and [`focus`](http://codemirror.net/doc/manual.html#event_focus) events now pass the DOM event to their handlers. ## 5.18.2 (2016-08-23) ### Bugfixes [vue mode](http://codemirror.net/mode/vue): Fix outdated references to renamed Pug mode dependency. ## 5.18.0 (2016-08-22) ### Bugfixes Make sure [gutter backgrounds](http://codemirror.net/doc/manual.html#addLineClass) stick to the rest of the gutter during horizontal scrolling. The contenteditable [`inputStyle`](http://codemirror.net/doc/manual.html#option_inputStyle) now properly supports pasting on pre-Edge IE versions. [javascript mode](http://codemirror.net/mode/javascript): Fix some small parsing bugs and improve TypeScript support. [matchbrackets addon](http://codemirror.net/doc/manual.html#addon_matchbrackets): Fix bug where active highlighting was left in editor when the addon was disabled. [match-highlighter addon](http://codemirror.net/doc/manual.html#addon_match-highlighter): Only start highlighting things when the editor gains focus. [javascript-hint addon](http://codemirror.net/doc/manual.html#addon_javascript-hint): Also complete non-enumerable properties. ### New features The [`addOverlay`](http://codemirror.net/doc/manual.html#addOverlay) method now supports a `priority` option to control the order in which overlays are applied. MIME types that end in `+json` now default to the JSON mode when the MIME itself is not defined. ### Breaking changes The mode formerly known as Jade was renamed to [Pug](http://codemirror.net/mode/pug). The [Python mode](http://codemirror.net/mode/python) now defaults to Python 3 (rather than 2) syntax. ## 5.17.0 (2016-07-19) ### Bugfixes Fix problem with wrapped trailing whitespace displaying incorrectly. Prevent IME dialog from overlapping typed content in Chrome. Improve measuring of characters near a line wrap. [javascript mode](http://codemirror.net/mode/javascript): Improve support for `async`, allow trailing commas in `import` lists. [vim bindings](http://codemirror.net/demo/vim.html): Fix backspace in replace mode. [sublime bindings](http://codemirror.net/demo/sublime.html): Fix some key bindings on OS X to match Sublime Text. ### New features [markdown mode](http://codemirror.net/mode/markdown): Add more classes to image links in highlight-formatting mode. ## 5.16.0 (2016-06-20) ### Bugfixes Fix glitches when dragging content caused by the drop indicator receiving mouse events. Make Control-drag work on Firefox. Make clicking or selection-dragging at the end of a wrapped line select the right position. [show-hint addon](http://codemirror.net/doc/manual.html#addon_show-hint): Prevent widget scrollbar from hiding part of the hint text. [rulers addon](http://codemirror.net/doc/manual.html#addon_rulers): Prevent rulers from forcing a horizontal editor scrollbar. ### New features [search addon](http://codemirror.net/doc/manual.html#addon_search): Automatically bind search-related keys in persistent dialog. [sublime keymap](http://codemirror.net/demo/sublime.html): Add a multi-cursor aware smart backspace binding. ## 5.15.2 (2016-05-20) ### Bugfixes Fix a critical document corruption bug that occurs when a document is gradually grown. ## 5.15.0 (2016-05-20) ### Bugfixes Fix bug that caused the selection to reset when focusing the editor in contentEditable input mode. Fix issue where not all ASCII control characters were being replaced by placeholders. Remove the assumption that all modes have a `startState` method from several wrapping modes. Fix issue where the editor would complain about overlapping collapsed ranges when there weren't any. Optimize document tree building when loading or pasting huge chunks of content. [markdown mode](http://codemirror.net/mode/markdown/): Fix several issues in matching link targets. [clike mode](http://codemirror.net/mode/clike/): Improve indentation of C++ template declarations. ### New features Explicitly bind Ctrl-O on OS X to make that binding (“open line”) act as expected. Pasting [linewise-copied](http://codemirror.net/doc/manual.html#option_lineWiseCopyCut) content when there is no selection now inserts the lines above the current line. [javascript mode](http://codemirror.net/mode/javascript/): Support `async`/`await` and improve support for TypeScript type syntax. ## 5.14.2 (2016-04-20) ### Bugfixes Push a new package to NPM due to an [NPM bug](https://github.com/npm/npm/issues/5082) omitting the LICENSE file in 5.14.0. Set `dataTransfer.effectAllowed` in `dragstart` handler to help browsers use the right drag icon. Add the [mbox mode](http://codemirror.net/mode/mbox/index.html) to `mode/meta.js`. ## 5.14.0 (2016-04-20) ### Bugfixes [`posFromIndex`](http://codemirror.net/doc/manual.html#posFromIndex) and [`indexFromPos`](http://codemirror.net/doc/manual.html#indexFromPos) now take [`lineSeparator`](http://codemirror.net/doc/manual.html#option_lineSeparator) into account. [vim bindings](http://codemirror.net/demo/vim.html): Only call `.save()` when it is actually available. [comment addon](http://codemirror.net/doc/manual.html#addon_comment): Be careful not to mangle multi-line strings. [Python mode](http://codemirror.net/mode/python/index.html): Improve distinguishing of decorators from `@` operators. [`findMarks`](http://codemirror.net/doc/manual.html#findMarks): No longer return marks that touch but don't overlap given range. ### New features [vim bindings](http://codemirror.net/demo/vim.html): Add yank command. [match-highlighter addon](http://codemirror.net/doc/manual.html#addon_match-highlighter): Add `trim` option to disable ignoring of whitespace. [PowerShell mode](http://codemirror.net/mode/powershell/index.html): Added. [Yacas mode](http://codemirror.net/mode/yacas/index.html): Added. [Web IDL mode](http://codemirror.net/mode/webidl/index.html): Added. [SAS mode](http://codemirror.net/mode/sas/index.html): Added. [mbox mode](http://codemirror.net/mode/mbox/index.html): Added. ## 5.13.2 (2016-03-23) ### Bugfixes Solves a problem where the gutter would sometimes not extend all the way to the end of the document. ## 5.13.0 (2016-03-21) ### New features New DOM event forwarded: [`"dragleave"`](http://codemirror.net/doc/manual.html#event_dom). [protobuf mode](http://codemirror.net/mode/protobuf/index.html): Newly added. ### Bugfixes Fix problem where [`findMarks`](http://codemirror.net/doc/manual.html#findMarks) sometimes failed to find multi-line marks. Fix crash that showed up when atomic ranges and bidi text were combined. [show-hint addon](http://codemirror.net/demo/complete.html): Completion widgets no longer close when the line indented or dedented. [merge addon](http://codemirror.net/demo/merge.html): Fix bug when merging chunks at the end of the file. [placeholder addon](http://codemirror.net/doc/manual.html#addon_placeholder): No longer gets confused by [`swapDoc`](http://codemirror.net/doc/manual.html#swapDoc). [simplescrollbars addon](http://codemirror.net/doc/manual.html#addon_simplescrollbars): Fix invalid state when deleting at end of document. [clike mode](http://codemirror.net/mode/clike/index.html): No longer gets confused when a comment starts after an operator. [markdown mode](http://codemirror.net/mode/markdown/index.html): Now supports CommonMark-style flexible list indentation. [dylan mode](http://codemirror.net/mode/dylan/index.html): Several improvements and fixes. ## 5.12.0 (2016-02-19) ### New features [Vim bindings](http://codemirror.net/demo/vim.html): Ctrl-Q is now an alias for Ctrl-V. [Vim bindings](http://codemirror.net/demo/vim.html): The Vim API now exposes an `unmap` method to unmap bindings. [active-line addon](http://codemirror.net/demo/activeline.html): This addon can now style the active line's gutter. [FCL mode](http://codemirror.net/mode/fcl/): Newly added. [SQL mode](http://codemirror.net/mode/sql/): Now has a Postgresql dialect. ### Bugfixes Fix [issue](https://github.com/codemirror/CodeMirror/issues/3781) where trying to scroll to a horizontal position outside of the document's width could cause the gutter to be positioned incorrectly. Use absolute, rather than fixed positioning in the context-menu intercept hack, to work around a [problem](https://github.com/codemirror/CodeMirror/issues/3238) when the editor is inside a transformed parent container. Solve a [problem](https://github.com/codemirror/CodeMirror/issues/3821) where the horizontal scrollbar could hide text in Firefox. Fix a [bug](https://github.com/codemirror/CodeMirror/issues/3834) that caused phantom scroll space under the text in some situations. [Sublime Text bindings](http://codemirror.net/demo/sublime.html): Bind delete-line to Shift-Ctrl-K on OS X. [Markdown mode](http://codemirror.net/mode/markdown/): Fix [issue](https://github.com/codemirror/CodeMirror/issues/3787) where the mode would keep state related to fenced code blocks in an unsafe way, leading to occasional corrupted parses. [Markdown mode](http://codemirror.net/mode/markdown/): Ignore backslashes in code fragments. [Markdown mode](http://codemirror.net/mode/markdown/): Use whichever mode is registered as `text/html` to parse HTML. [Clike mode](http://codemirror.net/mode/clike/): Improve indentation of Scala `=>` functions. [Python mode](http://codemirror.net/mode/python/): Improve indentation of bracketed code. [HTMLMixed mode](http://codemirror.net/mode/htmlmixed/): Support multi-line opening tags for sub-languages (`
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.
Current mode: text/plain
Filename, mime, or mode name:
Click the line-number gutter to add or remove 'breakpoints'.
Simple addon to easily mark (and style) selected text. Docs.
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. In the two-way configuration, there are also options to pad changed
sections to align them, and to collapse unchanged
stretches of text.
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 panel
addon allows you to display panels above or below an editor.
Click the links below to add panels at the given position:
top after-top before-bottom bottom
You can also replace an existing panel:
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.
This demo does the same thing as the HTML5 completion demo, but loads its dependencies with Require.js, rather than explicitly. Press ctrl-space to activate completion.
By setting an editor's height
style
to auto
and giving
the viewportMargin
a value of Infinity
, CodeMirror can be made to
automatically resize to fit its content.
Demonstration of the rulers addon, which displays vertical lines at given column offsets.
Running a CodeMirror mode outside of the editor.
The CodeMirror.runMode
function, defined
in addon/runmode/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 configured with custom keymaps) are:
Searching is enabled by including addon/search/search.js and addon/search/searchcursor.js. Jump to line - including addon/search/jumpToLine.js.
For good-looking input dialogs, you also want to include addon/dialog/dialog.js and addon/dialog/dialog.css.
The mode/simple
addon allows CodeMirror modes to be specified using a relatively simple
declarative format. This format is not as powerful as writing code
directly against the mode
interface, but is a lot easier to get started with, and
sufficiently expressive for many simple language modes.
This interface is still in flux. It is unlikely to be scrapped or overhauled completely, so do start writing code against it, but details might change as it stabilizes, and you might have to tweak your code when upgrading.
Simple modes (loosely based on the Common JavaScript Syntax Highlighting Specification, which never took off), are state machines, where each state has a number of rules that match tokens. A rule describes a type of token that may occur in the current state, and possibly a transition to another state caused by that token.
The CodeMirror.defineSimpleMode(name, states)
method
takes a mode name and an object that describes the mode's states. The
editor below shows an example of such a mode (and is itself
highlighted by the mode shown in it).
Each state is an array of rules. A rule may have the following properties:
regex: string | RegExp
ignoreCase
flag
will be taken into account when matching the token. This regex
should only capture groups when the token
property is
an array.token
: string | nullregex
for
this rule captures groups, it must capture all of the
string (since JS provides no way to find out where a group matched),
and this property must hold an array of token styles that has one
style for each matched group.sol
: boolean^
regexp marker doesn't work as you'd expect in
this context because of limitations in JavaScript's RegExp
API.)next: string
next
property is present, the mode will
transfer to the state named by the property when the token is
encountered.push: string
next
, but instead replacing the current state
by the new state, the current state is kept on a stack, and can be
returned to with the pop
directive.pop: bool
mode: {spec, end, persistent}
spec
property that describes
the embedded mode, and an optional end
end property
that specifies the regexp that will end the extent of the mode. When
a persistent
property is set (and true), the nested
mode's state will be preserved between occurrences of the mode.indent: bool
dedent: bool
dedentIfLineStart: bool
dedent
property set, it will, by
default, cause lines where it appears at the start to be dedented.
Set this property to false to prevent that behavior.The meta
property of the states object is special, and
will not be interpreted as a state. Instead, properties set on it will
be set on the mode, which is useful for properties
like lineComment
,
which sets the comment style for a mode. The simple mode addon also
recognizes a few such properties:
dontIndentStates: array<string>
The simplescrollbars
addon defines two
styles of non-native scrollbars: "simple"
and "overlay"
(click to try), which can be passed to
the scrollbarStyle
option. These implement
the scrollbar using DOM elements, allowing more control over
its appearance.
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.
The sublime
keymap defines many Sublime Text-specific
bindings for CodeMirror. See the code below for an overview.
Enable the keymap by
loading keymap/sublime.js
and setting
the keyMap
option to "sublime"
.
(A lot of the search functionality is still missing.)
Demonstrates integration of Tern and CodeMirror. The following keys are bound:
Documentation is sparse for now. See the top of the script for a rough API overview.
Select a theme:
Uses the trailingspace addon to highlight trailing whitespace.
Note: The CodeMirror vim bindings do not have an active maintainer. That means that if you report bugs in it, they are likely to go unanswered. It also means that if you want to help, you are very welcome to look at the open issues and see which ones you can solve.
The vim keybindings are enabled by including keymap/vim.js
and setting the
keyMap
option to vim
.
Features
For the full list of key mappings and Ex commands, refer to the
defaultKeymap
and defaultExCommandMap
at the
top of keymap/vim.js
.
Note that while the vim mode tries to emulate the most useful features of vim as faithfully as possible, it does not strive to become a complete vim implementation
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.