Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge (whew) from upstream

  • Loading branch information...
commit 818d539476453f561357f746bf5db9b6562824d6 1 parent ea75add
@njx njx authored
Showing with 6,075 additions and 1,741 deletions.
  1. +1 −1  LICENSE
  2. +2 −2 demo/activeline.html
  3. +65 −0 demo/closetag.html
  4. +4 −1 demo/complete.html
  5. +39 −0 demo/loadmode.html
  6. +37 −0 demo/matchhighlighter.html
  7. +1 −0  demo/mustache.html
  8. +23 −7 demo/theme.html
  9. +2 −2 demo/vim.html
  10. +21 −5 doc/compress.html
  11. +150 −36 doc/manual.html
  12. +38 −1 doc/oldrelease.html
  13. +105 −52 index.html
  14. +2 −2 keymap/emacs.js
  15. +390 −237 keymap/vim.js
  16. +29 −13 lib/codemirror.css
  17. +553 −335 lib/codemirror.js
  18. +146 −0 lib/util/closetag.js
  19. +14 −9 lib/util/foldcode.js
  20. +11 −5 lib/util/formatting.js
  21. +4 −2 lib/util/javascript-hint.js
  22. +51 −0 lib/util/loadmode.js
  23. +44 −0 lib/util/match-highlighter.js
  24. +1 −1  lib/util/overlay.js
  25. +30 −8 lib/util/runmode.js
  26. +5 −5 lib/util/search.js
  27. +1 −1  lib/util/searchcursor.js
  28. +6 −0 lib/util/simple-hint.js
  29. +40 −3 mode/clike/clike.js
  30. +1 −1  mode/clike/index.html
  31. +764 −0 mode/clike/scala.html
  32. +13 −13 mode/clojure/clojure.js
  33. +6 −0 mode/coffeescript/coffeescript.js
  34. +6 −0 mode/coffeescript/index.html
  35. +1 −1  mode/css/css.js
  36. +0 −3  mode/diff/diff.css
  37. +24 −5 mode/diff/diff.js
  38. +9 −4 mode/diff/index.html
  39. +251 −0 mode/erlang/erlang.js
  40. +61 −0 mode/erlang/index.html
  41. +1 −1  mode/gfm/gfm.js
  42. +1 −1  mode/htmlembedded/htmlembedded.js
  43. +4 −2 mode/htmlmixed/htmlmixed.js
  44. +8 −7 mode/javascript/javascript.js
  45. +48 −7 mode/less/index.html
  46. +100 −54 mode/less/less.js
  47. +0 −1  mode/markdown/index.html
  48. +30 −61 mode/markdown/markdown.js
  49. +2 −46 mode/pascal/pascal.js
  50. +21 −25 mode/php/php.js
  51. +42 −0 mode/pig/index.html
  52. +172 −0 mode/pig/pig.js
  53. +2 −2 mode/properties/index.html
  54. +0 −3  mode/properties/properties.css
  55. +17 −11 mode/properties/properties.js
  56. +14 −16 mode/python/python.js
  57. +1 −1  mode/rst/rst.js
  58. +20 −44 mode/scheme/scheme.js
  59. +50 −0 mode/shell/index.html
  60. +103 −0 mode/shell/shell.js
  61. +82 −0 mode/smarty/index.html
  62. +148 −0 mode/smarty/smarty.js
  63. +15 −2 mode/stex/stex.js
  64. +251 −0 mode/stex/test.html
  65. +13 −56 mode/tiddlywiki/index.html
  66. +14 −21 mode/tiddlywiki/tiddlywiki.css
  67. +55 −45 mode/tiddlywiki/tiddlywiki.js
  68. +82 −0 mode/tiki/index.html
  69. +26 −0 mode/tiki/tiki.css
  70. +316 −0 mode/tiki/tiki.js
  71. +42 −0 mode/vbscript/index.html
  72. +26 −0 mode/vbscript/vbscript.js
  73. +78 −13 mode/xml/xml.js
  74. +0 −59 mode/xmlpure/index.html
  75. +0 −490 mode/xmlpure/xmlpure.js
  76. +20 −0 mode/xquery/LICENSE
  77. +222 −0 mode/xquery/index.html
  78. +27 −0 mode/xquery/test/index.html
  79. +42 −0 mode/xquery/test/testBase.js
  80. +16 −0 mode/xquery/test/testEmptySequenceKeyword.js
  81. +16 −0 mode/xquery/test/testMultiAttr.js
  82. +91 −0 mode/xquery/test/testNamespaces.js
  83. +16 −0 mode/xquery/test/testProcessingInstructions.js
  84. +19 −0 mode/xquery/test/testQuotes.js
  85. +448 −0 mode/xquery/xquery.js
  86. +22 −0 test/mode_test.css
  87. +164 −0 test/mode_test.js
  88. +13 −11 test/test.js
  89. +81 −0 theme/ambiance.css
  90. +25 −0 theme/blackboard.css
  91. +1 −1  theme/eclipse.css
  92. +2 −2 theme/elegant.css
  93. +21 −0 theme/erlang-dark.css
  94. +44 −0 theme/lesser-dark.css
  95. +3 −3 theme/neat.css
  96. +1 −1  theme/rubyblue.css
  97. +46 −0 theme/xq-dark.css
View
2  LICENSE
@@ -1,4 +1,4 @@
-Copyright (C) 2011 by Marijn Haverbeke <marijnh@gmail.com>
+Copyright (C) 2012 by Marijn Haverbeke <marijnh@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
View
4 demo/activeline.html
@@ -59,8 +59,8 @@
lineNumbers: true,
lineWrapping: true,
onCursorActivity: function() {
- editor.setLineClass(hlLine, null);
- hlLine = editor.setLineClass(editor.getCursor().line, "activeline");
+ editor.setLineClass(hlLine, null, null);
+ hlLine = editor.setLineClass(editor.getCursor().line, null, "activeline");
}
});
var hlLine = editor.setLineClass(0, "activeline");
View
65 demo/closetag.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+ <head>
+ <title>CodeMirror: Close-Tag Demo</title>
+ <link rel="stylesheet" href="../lib/codemirror.css">
+ <script src="../lib/codemirror.js"></script>
+ <script src="../lib/util/closetag.js"></script>
+ <script src="../mode/xml/xml.js"></script>
+ <script src="../mode/javascript/javascript.js"></script>
+ <script src="../mode/css/css.js"></script>
+ <script src="../mode/htmlmixed/htmlmixed.js"></script>
+ <link rel="stylesheet" href="../doc/docs.css">
+ <style type="text/css">
+ .CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
+ </style>
+ </head>
+ <body>
+
+ <h1>Close-Tag Demo</h1>
+ <ul>
+ <li>Type an html tag. When you type '>' or '/', the tag will auto-close/complete. Block-level tags will indent.</li>
+ <li>There are options for disabling tag closing or customizing the list of tags to indent.</li>
+ <li>Works with "text/html" (based on htmlmixed.js or xml.js) mode.</li>
+ <li>View source for key binding details.</li>
+ </p>
+
+ <form><textarea id="code" name="code"></textarea></form>
+
+ <script type="text/javascript">
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+ mode: 'text/html',
+
+ //closeTagEnabled: false, // Set this option to disable tag closing behavior without having to remove the key bindings.
+ //closeTagIndent: false, // Pass false or an array of tag names to override the default indentation behavior.
+
+ extraKeys: {
+ "'>'": function(cm) { cm.closeTag(cm, '>'); },
+ "'/'": function(cm) { cm.closeTag(cm, '/'); }
+ },
+
+ /*
+ // extraKeys is the easier way to go, but if you need native key event processing, this should work too.
+ onKeyEvent: function(cm, e) {
+ if (e.type == 'keydown') {
+ var c = e.keyCode || e.which;
+ if (c == 190 || c == 191) {
+ try {
+ cm.closeTag(cm, c == 190 ? '>' : '/');
+ e.stop();
+ return true;
+ } catch (e) {
+ if (e != CodeMirror.Pass) throw e;
+ }
+ }
+ }
+ return false;
+ },
+ */
+
+ wordWrap: true
+ });
+ </script>
+
+ </body>
+</html>
View
5 demo/complete.html
@@ -58,9 +58,12 @@
how it works.</p>
<script>
+ CodeMirror.commands.autocomplete = function(cm) {
+ CodeMirror.simpleHint(cm, CodeMirror.javascriptHint);
+ }
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
- extraKeys: {"Ctrl-Space": function(cm) {CodeMirror.simpleHint(cm, CodeMirror.javascriptHint);}}
+ extraKeys: {"Ctrl-Space": "autocomplete"}
});
</script>
</body>
View
39 demo/loadmode.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<html>
+ <head>
+ <title>CodeMirror: Lazy Mode Loading Demo</title>
+ <link rel="stylesheet" href="../lib/codemirror.css">
+ <script src="../lib/codemirror.js"></script>
+ <script src="../lib/util/loadmode.js"></script>
+ <link rel="stylesheet" href="../doc/docs.css">
+
+ <style type="text/css">
+ .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+ </style>
+ </head>
+ <body>
+ <h1>CodeMirror: Lazy Mode Loading</h1>
+
+ <form><textarea id="code" name="code">This is the editor.
+// It starts out in plain text mode,
+# use the control below to load and apply a mode
+ "you'll see the highlighting of" this text /*change*/.
+</textarea></form>
+<p><input type=text value=javascript id=mode> <button type=button onclick="change()">change mode</button></p>
+
+ <script>
+CodeMirror.modeURL = "../mode/%N/%N.js";
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+ lineNumbers: true
+});
+var modeInput = document.getElementById("mode");
+CodeMirror.connect(modeInput, "keypress", function(e) {
+ if (e.keyCode == 13) change();
+});
+function change() {
+ editor.setOption("mode", modeInput.value);
+ CodeMirror.autoLoadMode(editor, modeInput.value);
+}
+</script>
+ </body>
+</html>
View
37 demo/matchhighlighter.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+ <head>
+ <title>CodeMirror: Match Highlighter Demo</title>
+ <link rel="stylesheet" href="../lib/codemirror.css">
+ <script src="../lib/codemirror.js"></script>
+ <script src="../lib/util/searchcursor.js"></script>
+ <script src="../lib/util/match-highlighter.js"></script>
+ <link rel="stylesheet" href="../doc/docs.css">
+
+ <style type="text/css">
+ .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+
+ span.CodeMirror-matchhighlight { background: #e9e9e9 }
+ .CodeMirror-focused span.CodeMirror-matchhighlight { background: #e7e4ff; !important }
+ </style>
+ </head>
+ <body>
+ <h1>CodeMirror: Match Highlighter Demo</h1>
+
+ <form><textarea id="code" name="code">Select this text: hardToSpotVar
+ And everywhere else in your code where hardToSpotVar appears will automatically illuminate.
+Give it a try! No more hardToSpotVars.</textarea></form>
+
+ <script>
+var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+ lineNumbers : true,
+ onCursorActivity: function() {
+ editor.matchHighlight("CodeMirror-matchhighlight");
+ }
+});
+</script>
+
+ <p>Highlight matches of selected text on select</p>
+
+ </body>
+</html>
View
1  demo/mustache.html
@@ -32,6 +32,7 @@
CodeMirror.defineMode("mustache", function(config, parserConfig) {
var mustacheOverlay = {
token: function(stream, state) {
+ var ch;
if (stream.match("{{")) {
while ((ch = stream.next()) != null)
if (ch == "}" && stream.next() == "}") break;
View
30 demo/theme.html
@@ -6,11 +6,16 @@
<script src="../lib/codemirror.js"></script>
<link rel="stylesheet" href="../theme/neat.css">
<link rel="stylesheet" href="../theme/elegant.css">
+ <link rel="stylesheet" href="../theme/erlang-dark.css">
<link rel="stylesheet" href="../theme/night.css">
<link rel="stylesheet" href="../theme/monokai.css">
<link rel="stylesheet" href="../theme/cobalt.css">
<link rel="stylesheet" href="../theme/eclipse.css">
<link rel="stylesheet" href="../theme/rubyblue.css">
+ <link rel="stylesheet" href="../theme/lesser-dark.css">
+ <link rel="stylesheet" href="../theme/xq-dark.css">
+ <link rel="stylesheet" href="../theme/ambiance.css">
+ <link rel="stylesheet" href="../theme/blackboard.css">
<script src="../mode/javascript/javascript.js"></script>
<link rel="stylesheet" href="../doc/docs.css">
@@ -35,15 +40,20 @@
return find(1, "1");
}</textarea></form>
-<p>Select a theme: <select onchange="selectTheme(this)">
+<p>Select a theme: <select onchange="selectTheme()" id=select>
<option selected>default</option>
- <option>night</option>
- <option>monokai</option>
- <option>neat</option>
- <option>elegant</option>
+ <option>ambiance</option>
+ <option>blackboard</option>
<option>cobalt</option>
<option>eclipse</option>
+ <option>elegant</option>
+ <option>erlang-dark</option>
+ <option>lesser-dark</option>
+ <option>monokai</option>
+ <option>neat</option>
+ <option>night</option>
<option>rubyblue</option>
+ <option>xq-dark</option>
</select>
</p>
@@ -51,10 +61,16 @@
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true
});
- function selectTheme(node) {
- var theme = node.options[node.selectedIndex].innerHTML;
+ var input = document.getElementById("select");
+ function selectTheme() {
+ var theme = input.options[input.selectedIndex].innerHTML;
editor.setOption("theme", theme);
}
+ var choice = document.location.search && document.location.search.slice(1);
+ if (choice) {
+ input.value = choice;
+ editor.setOption("theme", choice);
+ }
</script>
</body>
</html>
View
4 demo/vim.html
@@ -38,8 +38,8 @@
a loose approximation of actual vim bindings, though.</p>
<script>
- CodeMirror.commands.save = function(){alert("Saving");};
- CodeMirror.fromTextArea(document.getElementById("code"), {
+ CodeMirror.commands.save = function(){ alert("Saving"); };
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "text/x-csrc",
keyMap: "vim"
View
26 doc/compress.html
@@ -27,6 +27,10 @@
<input type="hidden" id="download" name="download" value="codemirror-compressed.js"/>
<p>Version: <select id="version" onchange="setVersion(this);" style="padding: 1px">
<option value="http://codemirror.net/">HEAD</option>
+ <option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=v2.25;f=">2.25</option>
+ <option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=v2.24;f=">2.24</option>
+ <option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=v2.23;f=">2.23</option>
+ <option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=v2.22;f=">2.22</option>
<option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=v2.21;f=">2.21</option>
<option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=v2.2;f=">2.2</option>
<option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=v2.18;f=">2.18</option>
@@ -43,7 +47,7 @@
<option value="http://marijnhaverbeke.nl/git/codemirror2?a=blob_plain;hb=beta1;f=">beta1</option>
</select></p>
- <select multiple="multiple" name="code_url" style="width: 40em;" class="field" id="files">
+ <select multiple="multiple" size="20" name="code_url" style="width: 40em;" class="field" id="files">
<optgroup label="CodeMirror Library">
<option value="http://codemirror.net/lib/codemirror.js" selected>codemirror.js</option>
</optgroup>
@@ -53,7 +57,8 @@
<option value="http://codemirror.net/mode/coffeescript/coffeescript.js">coffeescript.js</option>
<option value="http://codemirror.net/mode/css/css.js">css.js</option>
<option value="http://codemirror.net/mode/diff/diff.js">diff.js</option>
- <option value="http://codemirror.net/mode/ecl/ecl.js">diff.js</option>
+ <option value="http://codemirror.net/mode/ecl/ecl.js">ecl.js</option>
+ <option value="http://codemirror.net/mode/erlang/erlang.js">erlang.js</option>
<option value="http://codemirror.net/mode/gfm/gfm.js">gfm.js</option>
<option value="http://codemirror.net/mode/go/go.js">go.js</option>
<option value="http://codemirror.net/mode/groovy/groovy.js">groovy.js</option>
@@ -70,6 +75,7 @@
<option value="http://codemirror.net/mode/pascal/pascal.js">pascal.js</option>
<option value="http://codemirror.net/mode/perl/perl.js">perl.js</option>
<option value="http://codemirror.net/mode/php/php.js">php.js</option>
+ <option value="http://codemirror.net/mode/pig/pig.js">pig.js</option>
<option value="http://codemirror.net/mode/plsql/plsql.js">plsql.js</option>
<option value="http://codemirror.net/mode/properties/properties.js">properties.js</option>
<option value="http://codemirror.net/mode/python/python.js">python.js</option>
@@ -80,13 +86,18 @@
<option value="http://codemirror.net/mode/ruby/ruby.js">ruby.js</option>
<option value="http://codemirror.net/mode/rust/rust.js">rust.js</option>
<option value="http://codemirror.net/mode/scheme/scheme.js">scheme.js</option>
+ <option value="http://codemirror.net/mode/shell/shell.js">shell.js</option>
<option value="http://codemirror.net/mode/smalltalk/smalltalk.js">smalltalk.js</option>
+ <option value="http://codemirror.net/mode/smarty/smarty.js">smarty.js</option>
<option value="http://codemirror.net/mode/sparql/sparql.js">sparql.js</option>
<option value="http://codemirror.net/mode/stex/stex.js">stex.js</option>
<option value="http://codemirror.net/mode/tiddlywiki/tiddlywiki.js">tiddlywiki.js</option>
+ <option value="http://codemirror.net/mode/tiki/tiki.js">tiki.js</option>
+ <option value="http://codemirror.net/mode/vbscript/vbscript.js">vbscript.js</option>
<option value="http://codemirror.net/mode/velocity/velocity.js">velocity.js</option>
<option value="http://codemirror.net/mode/verilog/verilog.js">verilog.js</option>
<option value="http://codemirror.net/mode/xml/xml.js">xml.js</option>
+ <option value="http://codemirror.net/mode/xquery/xquery.js">xquery.js</option>
<option value="http://codemirror.net/mode/yaml/yaml.js">yaml.js</option>
</optgroup>
<optgroup label="Utilities and add-ons">
@@ -94,12 +105,18 @@
<option value="http://codemirror.net/lib/util/runmode.js">runmode.js</option>
<option value="http://codemirror.net/lib/util/simple-hint.js">simple-hint.js</option>
<option value="http://codemirror.net/lib/util/javascript-hint.js">javascript-hint.js</option>
- <option value="http://codemirror.net/lib/util/foldcode.js">codefold.js</option>
+ <option value="http://codemirror.net/lib/util/foldcode.js">foldcode.js</option>
<option value="http://codemirror.net/lib/util/dialog.js">dialog.js</option>
<option value="http://codemirror.net/lib/util/search.js">search.js</option>
+ <option value="http://codemirror.net/lib/util/searchcursor.js">searchcursor.js</option>
+ <option value="http://codemirror.net/lib/util/formatting.js">formatting.js</option>
+ <option value="http://codemirror.net/lib/util/match-highlighter.js">match-highlighter.js</option>
+ <option value="http://codemirror.net/lib/util/closetag.js">closetag.js</option>
+ <option value="http://codemirror.net/lib/util/loadmode.js">loadmode.js</option>
</optgroup>
<optgroup label="Keymaps">
<option value="http://codemirror.net/keymap/emacs.js">emacs.js</option>
+ <option value="http://codemirror.net/keymap/vim.js">vim.js</option>
</optgroup>
</select></p>
@@ -120,7 +137,7 @@
continue;
else if (m = opt.value.match(/^http:\/\/codemirror.net\/(.*)$/))
opt.value = urlprefix + m[1];
- else if (m = opt.value.match(/http:\/\/marijnhaverbeke.nl\/git\/codemirror\?a=blob_plain;hb=[^;]+;f=(.*)$/))
+ else if (m = opt.value.match(/http:\/\/marijnhaverbeke.nl\/git\/codemirror2\?a=blob_plain;hb=[^;]+;f=(.*)$/))
opt.value = urlprefix + m[1];
}
}
@@ -128,4 +145,3 @@
</body>
</html>
-
View
186 doc/manual.html
@@ -27,13 +27,13 @@ <h2 id="overview">Overview</h2>
functionality can be straightforwardly implemented. See
the <a href="#addons">add-ons</a> included in the distribution,
and
- the <a href="http://www.octolabs.com/javascripts/codemirror-ui/">CodeMirror
+ the <a href="https://github.com/jagthedrummer/codemirror-ui">CodeMirror
UI</a> project, for reusable implementations of extra features.</p>
<p>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 few
- modes (see the <code>mode/</code> directory), and it isn't hard
+ written in a given language. The distribution comes with a number
+ of modes (see the <code>mode/</code> directory), and it isn't hard
to <a href="#modeapi">write new ones</a> for other languages.</p>
<h2 id="usage">Basic Usage</h2>
@@ -160,24 +160,25 @@ <h2 id="config">Configuration</h2>
indentation (only works if the mode supports indentation).
Default is true.</dd>
+ <dt id="option_autoClearEmptyLines"><code>autoClearEmptyLines (boolean)</code></dt>
+ <dd>When turned on (default is off), this will clear
+ automatically clear lines consisting only of whitespace when the
+ cursor leaves them. This is mostly useful to prevent auto
+ indentation from introducing trailing whitespace in a file.</dd>
+
<dt id="option_keyMap"><code>keyMap (string)</code></dt>
<dd>Configures the keymap to use. The default
is <code>"default"</code>, which is the only keymap defined
in <code>codemirror.js</code> itself. Extra keymaps are found in
- the <a href="../keymap/"><code>keymap</code></a> directory.</dd>
+ the <a href="../keymap/"><code>keymap</code></a> directory. See
+ the <a href="#keymaps">section on keymaps</a> for more
+ information.</dd>
<dt id="option_extraKeys"><code>extraKeys (object)</code></dt>
- <dd>Can be used to specify extra keybindings for the editor.
- When given, should be an object with property names
- like <code>Ctrl-A</code>, <code>Home</code>,
- and <code>Ctrl-Alt-Left</code>. See
- the <code>CodeMirror.keyNames</code> object for the names of all
- the keys. The values in this object can either be functions,
- which will be called with the CodeMirror instance when the key
- is pressed, or strings, which should name commands defined
- in <code>CodeMirror.commands</code> (not documented properly,
- but looking at the source and the definition of the built-in
- keymaps, they should be rather obvious).</dd>
+ <dd>Can be used to specify extra keybindings for the editor,
+ alongside the ones defined
+ by <a href="#option_keyMap"><code>keyMap</code></a>. Should be
+ either null, or a valid <a href="#keymaps">keymap</a> value.</dd>
<dt id="option_lineWrapping"><code>lineWrapping (boolean)</code></dt>
<dd>Whether CodeMirror should scroll or wrap for long lines.
@@ -213,11 +214,11 @@ <h2 id="config">Configuration</h2>
and <code>to</code> are the positions (in the pre-change
coordinate system) where the change started and
ended (for example, it might be <code>{ch:0, line:18}</code> if the
- position is at line #19, at the first character. <code>text</code> is an
- array of strings representing the text that replaced the changed range
- (split by line). If multiple changes happened during a single operation,
- the object will have a <code>next</code> property pointing to another
- change object (which may point to another, etc).</dd>
+ position is at the beginning of line #19). <code>text</code>
+ is an array of strings representing the text that replaced the changed
+ range (split by line). If multiple changes happened during a single
+ operation, the object will have a <code>next</code> property pointing to
+ another change object (which may point to another, etc).</dd>
<dt id="option_onCursorActivity"><code>onCursorActivity (function)</code></dt>
<dd>Will be called when the cursor or selection moves, or any
@@ -273,10 +274,25 @@ <h2 id="config">Configuration</h2>
index</a> to assign to the editor. If not given, no tab index
will be assigned.</dd>
- <dt id="option_document"><code>document (DOM document)</code></dt>
- <dd>Use this if you want to display the editor in another DOM.
- By default it will use the global <code>document</code>
- object.</dd>
+ <dt id="option_autofocus"><code>autofocus (boolean)</code></dt>
+ <dd>Can be used to make CodeMirror focus itself on
+ initialization. Defaults to off.
+ When <a href="#fromTextArea"><code>fromTextArea</code></a> is
+ used, and no explicit value is given for this option, it will
+ inherit the setting from the textarea's <code>autofocus</code>
+ attribute.</dd>
+
+ <dt id="option_dragDrop"><code>dragDrop (boolean)</code></dt>
+ <dd>Controls whether drag-and-drop is enabled. On by default.</dd>
+
+ <dt id="option_onDragEvent"><code>onDragEvent (function)</code></dt>
+ <dd>When given, this will be called when the editor is handling
+ a <code>dragenter</code>, <code>dragover</code>,
+ or <code>drop</code> 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 <code>true</code> to indicate that CodeMirror should not
+ do anything further.</dd>
<dt id="option_onKeyEvent"><code>onKeyEvent (function)</code></dt>
<dd>This provides a rather low-level hook into CodeMirror's key
@@ -298,6 +314,63 @@ <h2 id="config">Configuration</h2>
that need character data).</dd>
</dl>
+ <h2 id="keymaps">Keymaps</h2>
+
+ <p>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.</p>
+
+ <p>Keys are identified either by name or by character.
+ The <code>CodeMirror.keyNames</code> object defines names for
+ common keys and associates them with their key codes. Examples of
+ names defined here are <code>Enter</code>, <code>F5</code>,
+ and <code>Q</code>. These can be prefixed
+ with <code>Shift-</code>, <code>Cmd-</code>, <code>Ctrl-</code>,
+ and <code>Alt-</code> (in that order!) to specify a modifier. So
+ for example, <code>Shift-Ctrl-Space</code> would be a valid key
+ identifier.</p>
+
+ <p>Alternatively, a character can be specified directly by
+ surrounding it in single quotes, for example <code>'$'</code>
+ or <code>'q'</code>. Due to limitations in the way browsers fire
+ key events, these may not be prefixed with modifiers.</p>
+
+ <p>The <code>CodeMirror.keyMap</code> 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 <code>"default"</code> keymap holding the
+ default bindings.</p>
+
+ <p>The values of properties in keymaps can be either functions of
+ a single argument (the CodeMirror instance), or strings. Such
+ strings refer to properties of the
+ <code>CodeMirror.commands</code> object, which defines a number of
+ common commands that are used by the default keybindings, and maps
+ them to functions. A key handler function may throw
+ <code>CodeMirror.Pass</code> to indicate that it has decided not
+ to handle the key, and other handlers (or the default behavior)
+ should be given a turn.</p>
+
+ <p>Keys mapped to command names that start with the
+ characters <code>"go"</code> (which should be used for
+ cursor-movement actions) will be fired even when an
+ extra <code>Shift</code> modifier is present (i.e. <code>"Up":
+ "goLineUp"</code> matches both up and shift-up). This is used to
+ easily implement shift-selection.</p>
+
+ <p>Keymaps can defer to each other by defining
+ a <code>fallthrough</code> 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.</p>
+
+ <p>When a keymap contains a <code>nofallthrough</code> property
+ set to <code>true</code>, 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, and the default effect of
+ inserting a character will not occur).</p>
+
<h2 id="styling">Customized Styling</h2>
<p>Up to a certain extent, CodeMirror's look can be changed by
@@ -424,13 +497,16 @@ <h2 id="api">Programming API</h2>
<dd>Retrieves the current value of the given option for this
editor instance.</dd>
- <dt id="cursorCoords"><code>cursorCoords(start) → object</code></dt>
+ <dt id="cursorCoords"><code>cursorCoords(start, mode) → object</code></dt>
<dd>Returns an <code>{x, y, yBot}</code> object containing the
- coordinates of the cursor relative to the top-left corner of the
+ coordinates of the cursor. If <code>mode</code>
+ is <code>"local"</code>, they will be relative to the top-left
+ corner of the editable document. If it is <code>"page"</code> or
+ not given, they are relative to the top-left corner of the
page. <code>yBot</code> is the coordinate of the bottom of the
cursor. <code>start</code> is a boolean indicating whether you
want the start or the end of the selection.</dd>
- <dt id="charCoords"><code>charCoords(pos) → object</code></dt>
+ <dt id="charCoords"><code>charCoords(pos, mode) → object</code></dt>
<dd>Like <code>cursorCoords</code>, but returns the position of
an arbitrary characters. <code>pos</code> should be
a <code>{line, ch}</code> object.</dd>
@@ -487,6 +563,10 @@ <h2 id="api">Programming API</h2>
the document, and the second explicitly removes the
bookmark.</dd>
+ <dt id="findMarksAt"><code>findMarksAt(pos) → array</code></dt>
+ <dd>Returns an array of all the bookmarks and marked ranges
+ present at the given position.</dd>
+
<dt id="setMarker"><code>setMarker(line, text, className) → lineHandle</code></dt>
<dd>Add a gutter marker for the given line. Gutter markers are
shown in the line-number area (instead of the number for this
@@ -506,11 +586,14 @@ <h2 id="api">Programming API</h2>
number or a handle returned by <code>setMarker</code> (since a
number may now refer to a different line if something was added
or deleted).</dd>
- <dt id="setLineClass"><code>setLineClass(line, className) → lineHandle</code></dt>
+ <dt id="setLineClass"><code>setLineClass(line, className, backgroundClassName) → lineHandle</code></dt>
<dd>Set a CSS class name for the given line. <code>line</code>
can be a number or a line handle (as returned
- by <code>setMarker</code> or this function).
- Pass <code>null</code> to clear the class for a line.</dd>
+ by <code>setMarker</code> or this
+ function). <code>className</code> will be used to style the text
+ for the line, and <code>backgroundClassName</code> to style its
+ background (which lies behind the selection).
+ Pass <code>null</code> to clear the classes for a line.</dd>
<dt id="hideLine"><code>hideLine(line) → lineHandle</code></dt>
<dd>Hide the given line (either by number or by handle). Hidden
lines don't show up in the editor, and their numbers are skipped
@@ -529,7 +612,8 @@ <h2 id="api">Programming API</h2>
<dd>Returns the line number, text content, and marker status of
the given line, which can be either a number or a handle
returned by <code>setMarker</code>. The returned object has the
- structure <code>{line, handle, text, markerText, markerClass}</code>.</dd>
+ structure <code>{line, handle, text, markerText, markerClass,
+ lineClass, bgClass}</code>.</dd>
<dt id="getLineHandle"><code>getLineHandle(num) → lineHandle</code></dt>
<dd>Fetches the line handle for the given line number.</dd>
@@ -581,7 +665,7 @@ <h2 id="api">Programming API</h2>
and <code>to</code> must be <code>{line, ch}</code>
objects. <code>to</code> can be left off to simply insert the
string at position <code>from</code>.</dd>
-
+
<dt id="posFromIndex"><code>posFromIndex(index) → object</code></dt>
<dd>Calculates and returns a <code>{line, ch}</code> object for a
zero-based <code>index</code> who's value is relative to the start of the
@@ -605,6 +689,11 @@ <h2 id="api">Programming API</h2>
lot faster. The return value from this method will be the return
value of your function.</dd>
+ <dt id="compoundChange"><code>compoundChange(func) → result</code></dt>
+ <dd>Will call the given function (and return its result),
+ combining all changes made while that function executes into a
+ single undo event.</dd>
+
<dt id="refresh"><code>refresh()</code></dt>
<dd>If your code does something to change the size of the editor
element (window resizes are already listened for), or unhides
@@ -612,7 +701,7 @@ <h2 id="api">Programming API</h2>
ensure CodeMirror is still looking as intended.</dd>
<dt id="getInputField"><code>getInputField() → textarea</code></dt>
- <dd>Returns the hiden textarea used to read input.</dd>
+ <dd>Returns the hidden textarea used to read input.</dd>
<dt id="getWrapperElement"><code>getWrapperElement() → node</code></dt>
<dd>Returns the DOM node that represents the editor. Remove this
from your tree to delete an editor instance.</dd>
@@ -718,7 +807,7 @@ <h2 id="addons">Add-ons</h2>
helper function to create a function that will, when applied to
a CodeMirror instance and a line number, attempt to fold or
unfold the block starting at the given line. A range-finder is a
- language-specific functoin that also takes an instance and a
+ language-specific function that also takes an instance and a
line number, and returns an end line for the block, or null if
no block is started on that line. This file
provides <code>CodeMirror.braceRangeFinder</code>, which finds
@@ -748,6 +837,31 @@ <h2 id="addons">Add-ons</h2>
and <code>CodeMirror.coffeescriptHint</code>, which are simple
hinting functions for the JavaScript and CoffeeScript
modes.</dd>
+ <dt id="util_match-highlighter"><a href="../lib/util/match-highlighter.js"><code>match-highlighter.js</code></a></dt>
+ <dd>Adds a <code>matchHighlight</code> method to CodeMirror
+ instances that can be called (typically from
+ a <a href="#option_onCursorActivity"><code>onCursorActivity</code></a>
+ handler) to highlight all instances of a currently selected word
+ with the a classname given as a first argument to the method.
+ Depends on
+ the <a href="#util_searchcursor"><code>searchcursor</code></a>
+ add-on. Demo <a href="../demo/matchhighlighter.html">here</a>.</dd>
+ <dt id="util_closetag"><a href="../lib/util/closetag.js"><code>closetag.js</code></a></dt>
+ <dd>Provides utility functions for adding automatic tag closing
+ to XML modes. See
+ the <a href="../demo/closetag.html">demo</a>.</dd>
+ <dt id="util_loadmode"><a href="../lib/util/loadmode.js"><code>loadmode.js</code></a></dt>
+ <dd>Defines a <code>CodeMirror.requireMode(modename,
+ callback)</code> function that will try to load a given mode and
+ call the callback when it succeeded. You'll have to
+ set <code>CodeMirror.modeURL</code> to a string that mode paths
+ can be constructed from, for
+ example <code>"mode/%N/%N.js"</code>—the <code>%N</code>'s will
+ be replaced with the mode name. Also
+ defines <code>CodeMirror.autoLoadMode(instance, mode)</code>,
+ which will ensure the given mode is loaded and cause the given
+ editor instance to refresh its mode when the loading
+ succeeded. See the <a href="../demo/loadmode.html">demo</a>.</dd>
</dl>
<h2 id="modeapi">Writing CodeMirror Modes</h2>
@@ -798,8 +912,7 @@ <h2 id="modeapi">Writing CodeMirror Modes</h2>
style string, or <code>null</code> for tokens that do not have to
be styled. For your styles, you can either use the 'standard' ones
defined in the themes (without the <code>cm-</code> prefix), or
- define your own (as the <a href="../mode/diff/index.html">diff</a>
- mode does) and have people include a custom CSS file for your
+ define your own and have people include a custom CSS file for your
mode.<p>
<p id="StringStream">The stream object encapsulates a line of code
@@ -972,6 +1085,7 @@ <h2 id="modeapi">Writing CodeMirror Modes</h2>
<li><a href="#overview">Overview</a></li>
<li><a href="#usage">Basic Usage</a></li>
<li><a href="#config">Configuration</a></li>
+ <li><a href="#keymaps">Keymaps</a></li>
<li><a href="#styling">Customized Styling</a></li>
<li><a href="#api">Programming API</a></li>
<li><a href="#addons">Add-ons</a></li>
View
39 doc/oldrelease.html
@@ -15,6 +15,43 @@
<img src="baboon.png" class="logo" alt="logo"/>/* Old release history */
</pre>
+
+ <p class="rel">23-08-2011: <a href="http://codemirror.net/codemirror-2.13.zip">Version 2.13</a>:</p>
+ <ul class="rel-note">
+ <li>Add <a href="../mode/ruby/index.html">Ruby</a>, <a href="../mode/r/index.html">R</a>, <a href="../mode/coffeescript/index.html">CoffeeScript</a>, and <a href="../mode/velocity/index.html">Velocity</a> modes.</li>
+ <li>Add <a href="manual.html#getGutterElement"><code>getGutterElement</code></a> to API.</li>
+ <li>Several fixes to scrolling and positioning.</li>
+ <li>Add <a href="manual.html#option_smartHome"><code>smartHome</code></a> option.</li>
+ <li>Add an experimental <a href="../mode/xmlpure/index.html">pure XML</a> mode.</li>
+ </ul>
+
+ <p class="rel">25-07-2011: <a href="http://codemirror.net/codemirror-2.12.zip">Version 2.12</a>:</p>
+ <ul class="rel-note">
+ <li>Add a <a href="../mode/sparql/index.html">SPARQL</a> mode.</li>
+ <li>Fix bug with cursor jumping around in an unfocused editor in IE.</li>
+ <li>Allow key and mouse events to bubble out of the editor. Ignore widget clicks.</li>
+ <li>Solve cursor flakiness after undo/redo.</li>
+ <li>Fix block-reindent ignoring the last few lines.</li>
+ <li>Fix parsing of multi-line attrs in XML mode.</li>
+ <li>Use <code>innerHTML</code> for HTML-escaping.</li>
+ <li>Some fixes to indentation in C-like mode.</li>
+ <li>Shrink horiz scrollbars when long lines removed.</li>
+ <li>Fix width feedback loop bug that caused the width of an inner DIV to shrink.</li>
+ </ul>
+
+ <p class="rel">04-07-2011: <a href="http://codemirror.net/codemirror-2.11.zip">Version 2.11</a>:</p>
+ <ul class="rel-note">
+ <li>Add a <a href="../mode/scheme/index.html">Scheme mode</a>.</li>
+ <li>Add a <code>replace</code> method to search cursors, for cursor-preserving replacements.</li>
+ <li>Make the <a href="../mode/clike/index.html">C-like mode</a> mode more customizable.</li>
+ <li>Update XML mode to spot mismatched tags.</li>
+ <li>Add <code>getStateAfter</code> API and <code>compareState</code> mode API methods for finer-grained mode magic.</li>
+ <li>Add a <code>getScrollerElement</code> API method to manipulate the scrolling DIV.</li>
+ <li>Fix drag-and-drop for Firefox.</li>
+ <li>Add a C# configuration for the <a href="../mode/clike/index.html">C-like mode</a>.</li>
+ <li>Add <a href="../demo/fullscreen.html">full-screen editing</a> and <a href="../demo/changemode.html">mode-changing</a> demos.</li>
+ </ul>
+
<p class="rel">07-06-2011: <a href="http://codemirror.net/codemirror-2.1.zip">Version 2.1</a>:</p>
<p class="rel-note">Add
a <a href="manual.html#option_theme">theme</a> system
@@ -67,7 +104,7 @@
</ul>
<p class="rel">22-02-2011: <a href="https://github.com/marijnh/codemirror2/tree/beta2">Version 2.0 beta 2</a>:</p>
- <p class="rel-note">Somewhate more mature API, lots of bugs shaken out.</a>
+ <p class="rel-note">Somewhat more mature API, lots of bugs shaken out.</a>
<p class="rel">17-02-2011: <a href="http://codemirror.net/codemirror-0.94.zip">Version 0.94</a>:</p>
<ul class="rel-note">
View
157 index.html
@@ -18,34 +18,33 @@
<div class="clear"><div class="left blk">
- <p style="margin-top: 0">CodeMirror is a JavaScript library that can
- be used to create a relatively pleasant editor interface for
- code-like content &#x2015; computer programs, HTML markup, and
- similar. If a mode has been written for the language you are
- editing, the code will be coloured, and the editor will optionally
- help you with indentation.</p>
-
- <p>This is the project page for CodeMirror 2, the currently more
- actively developed, and recommended
- version. <a href="1/index.html">CodeMirror 1</a> is still available
- from here.</p>
+ <p style="margin-top: 0">CodeMirror is a JavaScript component that
+ provides a code editor in the browser. When a mode is available for
+ the language you are coding in, it will color your code, and
+ optionally help with indentation.</p>
+
+ <p>A <a href="doc/manual.html">rich programming API</a> and a CSS
+ theming system are available for customizing CodeMirror to fit your
+ application, and extending it with new functionality.</p>
<div class="clear"><div class="left1 blk">
<h2 style="margin-top: 0">Supported modes:</h2>
<ul>
- <li><a href="mode/clike/index.html">C, C++, Java, and similar</a></li>
+ <li><a href="mode/clike/index.html">C, C++, C#</a></li>
<li><a href="mode/clojure/index.html">Clojure</a></li>
<li><a href="mode/coffeescript/index.html">CoffeeScript</a></li>
<li><a href="mode/css/index.html">CSS</a></li>
<li><a href="mode/diff/index.html">diff</a></li>
<li><a href="mode/ecl/index.html">ECL</a></li>
+ <li><a href="mode/erlang/index.html">Erlang</a></li>
<li><a href="mode/go/index.html">Go</a></li>
<li><a href="mode/groovy/index.html">Groovy</a></li>
<li><a href="mode/haskell/index.html">Haskell</a></li>
<li><a href="mode/htmlembedded/index.html">HTML embedded scripts</a></li>
<li><a href="mode/htmlmixed/index.html">HTML mixed-mode</a></li>
+ <li><a href="mode/clike/index.html">Java</a></li>
<li><a href="mode/javascript/index.html">JavaScript</a></li>
<li><a href="mode/jinja2/index.html">Jinja2</a></li>
<li><a href="mode/less/index.html">LESS</a></li>
@@ -56,6 +55,7 @@ <h2 style="margin-top: 0">Supported modes:</h2>
<li><a href="mode/pascal/index.html">Pascal</a></li>
<li><a href="mode/perl/index.html">Perl</a></li>
<li><a href="mode/php/index.html">PHP</a></li>
+ <li><a href="mode/pig/index.html">Pig Latin</a></li>
<li><a href="mode/plsql/index.html">PL/SQL</a></li>
<li><a href="mode/properties/index.html">Properties files</a></li>
<li><a href="mode/python/index.html">Python</a></li>
@@ -64,14 +64,20 @@ <h2 style="margin-top: 0">Supported modes:</h2>
<li><a href="mode/rst/index.html">reStructuredText</a></li>
<li><a href="mode/ruby/index.html">Ruby</a></li>
<li><a href="mode/rust/index.html">Rust</a></li>
+ <li><a href="mode/clike/scala.html">Scala</a></li>
<li><a href="mode/scheme/index.html">Scheme</a></li>
+ <li><a href="mode/shell/index.html">Shell</a></li>
<li><a href="mode/smalltalk/index.html">Smalltalk</a></li>
+ <li><a href="mode/smarty/index.html">Smarty</a></li>
<li><a href="mode/sparql/index.html">SPARQL</a></li>
<li><a href="mode/stex/index.html">sTeX, LaTeX</a></li>
<li><a href="mode/tiddlywiki/index.html">Tiddlywiki</a></li>
+ <li><a href="mode/tiki/index.html">Tiki wiki</a></li>
+ <li><a href="mode/vbscript/index.html">VBScript</a></li>
<li><a href="mode/velocity/index.html">Velocity</a></li>
<li><a href="mode/verilog/index.html">Verilog</a></li>
- <li><a href="mode/xml/index.html">XML/HTML</a> (<a href="mode/xmlpure/index.html">alternative XML</a>)</li>
+ <li><a href="mode/xml/index.html">XML/HTML</a></li>
+ <li><a href="mode/xquery/index.html">XQuery</a></li>
<li><a href="mode/yaml/index.html">YAML</a></li>
</ul>
@@ -88,6 +94,7 @@ <h2 style="margin-top: 0">Usage demos:</h2>
<li><a href="demo/resize.html">Auto-resizing editor</a></li>
<li><a href="demo/marker.html">Setting breakpoints</a></li>
<li><a href="demo/activeline.html">Highlighting the current line</a></li>
+ <li><a href="demo/matchhighlighter.html">Highlighting selection matches</a></li>
<li><a href="demo/theme.html">Theming</a></li>
<li><a href="demo/runmode.html">Stand-alone highlighting</a></li>
<li><a href="demo/fullscreen.html">Full-screen editing</a></li>
@@ -96,6 +103,8 @@ <h2 style="margin-top: 0">Usage demos:</h2>
<li><a href="demo/formatting.html">Autoformatting of code</a></li>
<li><a href="demo/emacs.html">Emacs keybindings</a></li>
<li><a href="demo/vim.html">Vim keybindings</a></li>
+ <li><a href="demo/closetag.html">Automatic xml tag closing</a></li>
+ <li><a href="demo/loadmode.html">Lazy mode loading</a></li>
</ul>
<h2>Real-world uses:</h2>
@@ -114,7 +123,14 @@ <h2 style="margin-top: 0">Usage demos:</h2>
<li><a href="http://bluegriffon.org/">BlueGriffon</a> (HTML editor)</li>
<li><a href="http://www.jshint.com/">JSHint</a> (JS linter)</li>
<li><a href="http://kl1p.com/cmtest/1">kl1p</a> (paste service)</li>
- </ul>
+ <li><a href="http://sqlfiddle.com">SQLFiddle</a> (SQL playground)</li>
+ <li><a href="http://tour.golang.org">Go language tour</a></li>
+ <li><a href="http://cssdeck.com/">CSSDeck</a> (CSS showcase)</li>
+ <li><a href="http://www.ckwnc.com/">CKWNC</a> (UML editor)</li>
+ <li><a href="http://www.sketchpatch.net/labs/livecodelabIntro.html">sketchPatch Livecodelab</a></li>
+ <li><a href="https://thefiletree.com">The File Tree</a> (collab editor)</li>
+ <li><a href="http://enjalot.com/tributary/2636296/sinwaves.js">Tributary</a> (augmented editing)</li>
+ </ul>
</div></div>
@@ -171,7 +187,7 @@ <h2 id="supported">Supported browsers</h2>
<li>Firefox 2 or higher</li>
<li>Chrome, any version</li>
<li>Safari 3 or higher</li>
- <li>Internet Explorer 6 or higher in standards (<strong>non-quirks</strong>) mode</li>
+ <li>Internet Explorer 7 or higher in standards (<strong>non-quirks</strong>) mode</li>
<li>Opera 9 or higher (with some key-handling problems on OS X)</li>
</ul>
@@ -225,7 +241,80 @@ <h2 id="commercial">Commercial support</h2>
IBAN: <i>NL26 RABO 0147 8507 70</i>
</p>
- <h2>Releases:</h2>
+ <h2>Reading material</h2>
+
+ <ul>
+ <li><a href="doc/manual.html">User manual</a></li>
+ <li><a href="http://github.com/marijnh/CodeMirror2">Browse the code</a></li>
+ </ul>
+
+ <h2>Releases</h2>
+
+ <p class="rel">23-05-2012: <a href="http://codemirror.net/codemirror-2.25.zip">Version 2.25</a>:</p>
+
+ <ul class="rel-note">
+ <li>New mode: <a href="mode/erlang/index.html">Erlang</a>.</li>
+ <li><strong>Remove xmlpure mode</strong> (use <a href="mode/xml/index.html">xml.js</a>).</li>
+ <li>Fix line-wrapping in Opera.</li>
+ <li>Fix X Windows middle-click paste in Chrome.</li>
+ <li>Fix bug that broke pasting of huge documents.</li>
+ <li>Fix backspace and tab key repeat in Opera.</li>
+ </ul>
+
+ <p class="rel">23-04-2012: <a href="http://codemirror.net/codemirror-2.24.zip">Version 2.24</a>:</p>
+
+ <ul class="rel-note">
+ <li><strong>Drop support for Internet Explorer 6</strong>.</li>
+ <li>New
+ modes: <a href="mode/shell/index.html">Shell</a>, <a href="mode/tiki/index.html">Tiki
+ wiki</a>, <a href="mode/pig/index.html">Pig Latin</a>.</li>
+ <li>New themes: <a href="demo/theme.html?ambiance">Ambiance</a>, <a href="demo/theme.html?blackboard">Blackboard</a>.</li>
+ <li>More control over drag/drop
+ with <a href="doc/manual.html#option_dragDrop"><code>dragDrop</code></a>
+ and <a href="doc/manual.html#option_onDragEvent"><code>onDragEvent</code></a>
+ options.</li>
+ <li>Make HTML mode a bit less pedantic.</li>
+ <li>Add <a href="doc/manual.html#compoundChange"><code>compoundChange</code></a> API method.</li>
+ <li>Several fixes in undo history and line hiding.</li>
+ <li>Remove (broken) support for <code>catchall</code> in key maps,
+ add <code>nofallthrough</code> boolean field instead.</li>
+ </ul>
+
+ <p class="rel">26-03-2012: <a href="http://codemirror.net/codemirror-2.23.zip">Version 2.23</a>:</p>
+
+ <ul class="rel-note">
+ <li>Change <strong>default binding for tab</strong> <a href="javascript:void(document.getElementById('tabbinding').style.display='')">[more]</a>
+ <div style="display: none" id=tabbinding>
+ Starting in 2.23, these bindings are default:
+ <ul><li>Tab: Insert tab character</li>
+ <li>Shift-tab: Reset line indentation to default</li>
+ <li>Ctrl/Cmd-[: Reduce line indentation (old tab behaviour)</li>
+ <li>Ctrl/Cmd-]: Increase line indentation (old shift-tab behaviour)</li>
+ </ul>
+ </div>
+ </li>
+ <li>New modes: <a href="mode/xquery/index.html">XQuery</a> and <a href="mode/vbscript/index.html">VBScript</a>.</li>
+ <li>Two new themes: <a href="mode/less/index.html">lesser-dark</a> and <a href="mode/xquery/index.html">xq-dark</a>.</li>
+ <li>Differentiate between background and text styles in <a href="doc/manual.html#setLineClass"><code>setLineClass</code></a>.</li>
+ <li>Fix drag-and-drop in IE9+.</li>
+ <li>Extend <a href="doc/manual.html#charCoords"><code>charCoords</code></a>
+ and <a href="doc/manual.html#cursorCoords"><code>cursorCoords</code></a> with a <code>mode</code> argument.</li>
+ <li>Add <a href="doc/manual.html#option_autofocus"><code>autofocus</code></a> option.</li>
+ <li>Add <a href="doc/manual.html#findMarksAt"><code>findMarksAt</code></a> method.</li>
+ </ul>
+
+ <p class="rel">27-02-2012: <a href="http://codemirror.net/codemirror-2.22.zip">Version 2.22</a>:</p>
+
+ <ul class="rel-note">
+ <li>Allow <a href="doc/manual.html#keymaps">key handlers</a> to pass up events, allow binding characters.</li>
+ <li>Add <a href="doc/manual.html#option_autoClearEmptyLines"><code>autoClearEmptyLines</code></a> option.</li>
+ <li>Properly use tab stops when rendering tabs.</li>
+ <li>Make PHP mode more robust.</li>
+ <li>Support indentation blocks in <a href="doc/manual.html#util_foldcode">code folder</a>.</li>
+ <li>Add a script for <a href="doc/manual.html#util_match-highlighter">highlighting instances of the selection</a>.</li>
+ <li>New <a href="mode/properties/index.html">.properties</a> mode.</li>
+ <li>Fix many bugs.</li>
+ </ul>
<p class="rel">27-01-2012: <a href="http://codemirror.net/codemirror-2.21.zip">Version 2.21</a>:</p>
@@ -315,42 +404,6 @@ <h2 id="commercial">Commercial support</h2>
<li>Allow dragging of text out of the editor (on modern browsers).</li>
</ul>
- <p class="rel">23-08-2011: <a href="http://codemirror.net/codemirror-2.13.zip">Version 2.13</a>:</p>
- <ul class="rel-note">
- <li>Add <a href="mode/ruby/index.html">Ruby</a>, <a href="mode/r/index.html">R</a>, <a href="mode/coffeescript/index.html">CoffeeScript</a>, and <a href="mode/velocity/index.html">Velocity</a> modes.</li>
- <li>Add <a href="doc/manual.html#getGutterElement"><code>getGutterElement</code></a> to API.</li>
- <li>Several fixes to scrolling and positioning.</li>
- <li>Add <a href="doc/manual.html#option_smartHome"><code>smartHome</code></a> option.</li>
- <li>Add an experimental <a href="mode/xmlpure/index.html">pure XML</a> mode.</li>
- </ul>
-
- <p class="rel">25-07-2011: <a href="http://codemirror.net/codemirror-2.12.zip">Version 2.12</a>:</p>
- <ul class="rel-note">
- <li>Add a <a href="mode/sparql/index.html">SPARQL</a> mode.</li>
- <li>Fix bug with cursor jumping around in an unfocused editor in IE.</li>
- <li>Allow key and mouse events to bubble out of the editor. Ignore widget clicks.</li>
- <li>Solve cursor flakiness after undo/redo.</li>
- <li>Fix block-reindent ignoring the last few lines.</li>
- <li>Fix parsing of multi-line attrs in XML mode.</li>
- <li>Use <code>innerHTML</code> for HTML-escaping.</li>
- <li>Some fixes to indentation in C-like mode.</li>
- <li>Shrink horiz scrollbars when long lines removed.</li>
- <li>Fix width feedback loop bug that caused the width of an inner DIV to shrink.</li>
- </ul>
-
- <p class="rel">04-07-2011: <a href="http://codemirror.net/codemirror-2.11.zip">Version 2.11</a>:</p>
- <ul class="rel-note">
- <li>Add a <a href="mode/scheme/index.html">Scheme mode</a>.</li>
- <li>Add a <code>replace</code> method to search cursors, for cursor-preserving replacements.</li>
- <li>Make the <a href="mode/clike/index.html">C-like mode</a> mode more customizeable.</li>
- <li>Update XML mode to spot mismatched tags.</li>
- <li>Add <code>getStateAfter</code> API and <code>compareState</code> mode API methods for finer-grained mode magic.</li>
- <li>Add a <code>getScrollerElement</code> API method to manipulate the scrolling DIV.</li>
- <li>Fix drag-and-drop for Firefox.</li>
- <li>Add a C# configuration for the <a href="mode/clike/index.html">C-like mode</a>.</li>
- <li>Add <a href="demo/fullscreen.html">full-screen editing</a> and <a href="demo/changemode.html">mode-changing</a> demos.</li>
- </ul>
-
<p><a href="doc/oldrelease.html">Older releases...</a></p>
</div></div>
View
4 keymap/emacs.js
@@ -18,12 +18,12 @@
"Alt-Y": function(cm) {cm.replaceSelection(popFromRing());},
"Ctrl-/": "undo", "Shift-Ctrl--": "undo", "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
- "Ctrl-Z": "undo", "Cmd-Z": "undo",
+ "Ctrl-Z": "undo", "Cmd-Z": "undo", "Alt-/": "autocomplete",
fallthrough: ["basic", "emacsy"]
};
CodeMirror.keyMap["emacs-Ctrl-X"] = {
"Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": "undo", "K": "close",
- auto: "emacs", catchall: function(cm) {/*ignore*/}
+ auto: "emacs", nofallthrough: true
};
})();
View
627 keymap/vim.js
@@ -1,3 +1,53 @@
+// Supported keybindings:
+//
+// Cursor movement:
+// h, j, k, l
+// e, E, w, W, b, B
+// Ctrl-f, Ctrl-b
+// Ctrl-n, Ctrl-p
+// $, ^, 0
+// G
+// ge, gE
+// gg
+// f<char>, F<char>, t<char>, T<char>
+// Ctrl-o, Ctrl-i TODO (FIXME - Ctrl-O wont work in Chrome)
+// /, ?, n, N TODO (does not work)
+// #, * TODO
+//
+// Entering insert mode:
+// i, I, a, A, o, O
+// s
+// ce, cb (without support for number of actions like c3e - TODO)
+// cc
+// S, C TODO
+// cf<char>, cF<char>, ct<char>, cT<char>
+//
+// Deleting text:
+// x, X
+// J
+// dd, D
+// de, db (without support for number of actions like d3e - TODO)
+// df<char>, dF<char>, dt<char>, dT<char>
+//
+// Yanking and pasting:
+// yy, Y
+// p, P
+// p'<char> TODO - test
+// y'<char> TODO - test
+// m<char> TODO - test
+//
+// Changing text in place:
+// ~
+// r<char>
+//
+// Visual mode:
+// v, V TODO
+//
+// Misc:
+// . TODO
+//
+
+
(function() {
var count = "";
var sdir = "f";
@@ -8,14 +58,39 @@
function pushInBuffer(str) { buf += str; };
function pushCountDigit(digit) { return function(cm) {count += digit;} }
function popCount() { var i = parseInt(count); count = ""; return i || 1; }
+ function iterTimes(func) {
+ for (var i = 0, c = popCount(); i < c; ++i) func(i, i == c - 1);
+ }
function countTimes(func) {
if (typeof func == "string") func = CodeMirror.commands[func];
- return function(cm) { for (var i = 0, c = popCount(); i < c; ++i) func(cm); }
+ return function(cm) { iterTimes(function () { func(cm); }) };
}
function iterObj(o, f) {
for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]);
}
+ function iterList(l, f) {
+ for (var i in l) f(l[i]);
+ }
+ function toLetter(ch) {
+ // T -> t, Shift-T -> T, '*' -> *, "Space" -> " "
+ if (ch.slice(0, 6) == "Shift-") {
+ return ch.slice(0, 1);
+ } else {
+ if (ch == "Space") return " ";
+ if (ch.length == 3 && ch[0] == "'" && ch[2] == "'") return ch[1];
+ return ch.toLowerCase();
+ }
+ }
+ var SPECIAL_SYMBOLS = "~`!@#$%^&*()_-+=[{}]\\|/?.,<>:;\"\'1234567890";
+ function toCombo(ch) {
+ // t -> T, T -> Shift-T, * -> '*', " " -> "Space"
+ if (ch == " ") return "Space";
+ var specialIdx = SPECIAL_SYMBOLS.indexOf(ch);
+ if (specialIdx != -1) return "'" + ch + "'";
+ if (ch.toLowerCase() == ch) return ch.toUpperCase();
+ return "Shift-" + ch.toUpperCase();
+ }
var word = [/\w/, /[^\w\s]/], bigWord = [/\S/];
function findWord(line, pos, dir, regexps) {
@@ -56,15 +131,13 @@
CodeMirror.commands.delCharRight(cm);
}
}
- function editCursor(mode) {
- if (mode == "vim-insert") {
- // put in your cursor css changing code
- } else if (mode == "vim") {
- // put in your cursor css changing code
- }
- }
function delTillMark(cm, cHar) {
- var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
+ var i = mark[cHar];
+ if (i === undefined) {
+ // console.log("Mark not set"); // TODO - show in status bar
+ return;
+ }
+ var l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
cm.setCursor(start);
for (var c = start; c <= end; c++) {
pushInBuffer("\n"+cm.getLine(start));
@@ -72,27 +145,125 @@
}
}
function yankTillMark(cm, cHar) {
- var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
+ var i = mark[cHar];
+ if (i === undefined) {
+ // console.log("Mark not set"); // TODO - show in status bar
+ return;
+ }
+ var l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
for (var c = start; c <= end; c++) {
pushInBuffer("\n"+cm.getLine(c));
}
cm.setCursor(start);
}
+ function goLineStartText(cm) {
+ // Go to the start of the line where the text begins, or the end for whitespace-only lines
+ var cur = cm.getCursor(), firstNonWS = cm.getLine(cur.line).search(/\S/);
+ cm.setCursor(cur.line, firstNonWS == -1 ? line.length : firstNonWS, true);
+ }
+ function charIdxInLine(cm, cHar, motion_options) {
+ // Search for cHar in line.
+ // motion_options: {forward, inclusive}
+ // If inclusive = true, include it too.
+ // If forward = true, search forward, else search backwards.
+ // If char is not found on this line, do nothing
+ var cur = cm.getCursor(), line = cm.getLine(cur.line), idx;
+ var ch = toLetter(cHar), mo = motion_options;
+ if (mo.forward) {
+ idx = line.indexOf(ch, cur.ch + 1);
+ if (idx != -1 && mo.inclusive) idx += 1;
+ } else {
+ idx = line.lastIndexOf(ch, cur.ch);
+ if (idx != -1 && !mo.inclusive) idx += 1;
+ }
+ return idx;
+ }
+
+ function moveTillChar(cm, cHar, motion_options) {
+ // Move to cHar in line, as found by charIdxInLine.
+ var idx = charIdxInLine(cm, cHar, motion_options), cur = cm.getCursor();
+ if (idx != -1) cm.setCursor({line: cur.line, ch: idx});
+ }
+
+ function delTillChar(cm, cHar, motion_options) {
+ // delete text in this line, untill cHar is met,
+ // as found by charIdxInLine.
+ // If char is not found on this line, do nothing
+ var idx = charIdxInLine(cm, cHar, motion_options);
+ var cur = cm.getCursor();
+ if (idx !== -1) {
+ if (motion_options.forward) {
+ cm.replaceRange("", {line: cur.line, ch: cur.ch}, {line: cur.line, ch: idx});
+ } else {
+ cm.replaceRange("", {line: cur.line, ch: idx}, {line: cur.line, ch: cur.ch});
+ }
+ }
+ }
+
+ function enterInsertMode(cm) {
+ // enter insert mode: switch mode and cursor
+ if (!cm) console.log("call enterInsertMode with 'cm' as an argument");
+ popCount();
+ cm.setOption("keyMap", "vim-insert");
+ }
+
+ // main keymap
var map = CodeMirror.keyMap.vim = {
- "0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);},
- "A": function(cm) {popCount(); cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
- "Shift-A": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
- "I": function(cm) {popCount(); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
- "Shift-I": function(cm) {popCount(); CodeMirror.commands.goLineStartSmart(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
- "O": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.replaceSelection("\n", "end"); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
- "Shift-O": function(cm) {popCount(); CodeMirror.commands.goLineStart(cm); cm.replaceSelection("\n", "start"); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
- "G": function(cm) {cm.setOption("keyMap", "vim-prefix-g");},
- "D": function(cm) {cm.setOption("keyMap", "vim-prefix-d"); emptyBuffer();},
+ // Pipe (|); TODO: should be *screen* chars, so need a util function to turn tabs into spaces?
+ "'|'": function(cm) {
+ cm.setCursor(cm.getCursor().line, popCount() - 1, true);
+ },
+ "'^'": function(cm) { popCount(); goLineStartText(cm);},
+ "A": function(cm) {
+ cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true);
+ enterInsertMode(cm);
+ },
+ "Shift-A": function(cm) { CodeMirror.commands.goLineEnd(cm); enterInsertMode(cm);},
+ "I": function(cm) { enterInsertMode(cm);},
+ "Shift-I": function(cm) { goLineStartText(cm); enterInsertMode(cm);},
+ "O": function(cm) {
+ CodeMirror.commands.goLineEnd(cm);
+ CodeMirror.commands.newlineAndIndent(cm);
+ enterInsertMode(cm);
+ },
+ "Shift-O": function(cm) {
+ CodeMirror.commands.goLineStart(cm);
+ cm.replaceSelection("\n", "start");
+ cm.indentLine(cm.getCursor().line);
+ enterInsertMode(cm);
+ },
+ "G": function(cm) { cm.setOption("keyMap", "vim-prefix-g");},
+ "Shift-D": function(cm) {
+ // commented out verions works, but I left original, cause maybe
+ // I don't know vim enouth to see what it does
+ /* var cur = cm.getCursor();
+ var f = {line: cur.line, ch: cur.ch}, t = {line: cur.line};
+ pushInBuffer(cm.getRange(f, t));
+ cm.replaceRange("", f, t);
+ */
+ emptyBuffer();
+ mark["Shift-D"] = cm.getCursor(false).line;
+ cm.setCursor(cm.getCursor(true).line);
+ delTillMark(cm,"Shift-D"); mark = [];
+ },
+
+ "S": function (cm) {
+ countTimes(function (_cm) {
+ CodeMirror.commands.delCharRight(_cm);
+ })(cm);
+ enterInsertMode(cm);
+ },
"M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
"Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
- "/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f"},
- "Shift-/": function(cm) {
+ "Shift-Y": function(cm) {
+ emptyBuffer();
+ mark["Shift-D"] = cm.getCursor(false).line;
+ cm.setCursor(cm.getCursor(true).line);
+ yankTillMark(cm,"Shift-D"); mark = [];
+ },
+ "/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f";},
+ "'?'": function(cm) {
var f = CodeMirror.commands.find;
if (f) { f(cm); CodeMirror.commands.findPrev(cm); sdir = "r"; }
},
@@ -104,244 +275,226 @@
var fn = CodeMirror.commands.findNext;
if (fn) sdir != "r" ? CodeMirror.commands.findPrev(cm) : fn.findNext(cm);
},
- "Shift-G": function(cm) {count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count)-1); popCount(); CodeMirror.commands.goLineStart(cm);},
- catchall: function(cm) {/*ignore*/}
+ "Shift-G": function(cm) {
+ count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count)-1);
+ popCount();
+ CodeMirror.commands.goLineStart(cm);
+ },
+ "'$'": function (cm) {
+ countTimes("goLineEnd")(cm);
+ if (cm.getCursor().ch) CodeMirror.commands.goColumnLeft(cm);
+ },
+ nofallthrough: true, style: "fat-cursor"
};
- // Add bindings for number keys
- for (var i = 1; i < 10; ++i) map[i] = pushCountDigit(i);
+
+ // standard mode switching
+ iterList(["d", "t", "T", "f", "F", "c", "r"],
+ function (ch) {
+ CodeMirror.keyMap.vim[toCombo(ch)] = function (cm) {
+ cm.setOption("keyMap", "vim-prefix-" + ch);
+ emptyBuffer();
+ };
+ });
+
+ function addCountBindings(keyMap) {
+ // Add bindings for number keys
+ keyMap["0"] = function(cm) {
+ count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);
+ };
+ for (var i = 1; i < 10; ++i) keyMap[i] = pushCountDigit(i);
+ }
+ addCountBindings(CodeMirror.keyMap.vim);
+
+ // main num keymap
// Add bindings that are influenced by number keys
- iterObj({"H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown", "K": "goLineUp",
- "Left": "goColumnLeft", "Right": "goColumnRight", "Down": "goLineDown", "Up": "goLineUp",
- "Backspace": "goCharLeft", "Space": "goCharRight",
- "B": function(cm) {moveToWord(cm, word, -1, "end");},
- "E": function(cm) {moveToWord(cm, word, 1, "end");},
- "W": function(cm) {moveToWord(cm, word, 1, "start");},
- "Shift-B": function(cm) {moveToWord(cm, bigWord, -1, "end");},
- "Shift-E": function(cm) {moveToWord(cm, bigWord, 1, "end");},
- "Shift-W": function(cm) {moveToWord(cm, bigWord, 1, "start");},
- "X": function(cm) {CodeMirror.commands.delCharRight(cm)},
- "P": function(cm) {
- var cur = cm.getCursor().line;
- if (buf!= "") {
- CodeMirror.commands.goLineEnd(cm);
- cm.replaceSelection(buf, "end");
- }
- cm.setCursor(cur+1);
- },
- "Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm)},
- "Shift-J": function(cm) {joinLineNext(cm)},
- "Shift-`": function(cm) {
- var cur = cm.getCursor(), cHar = cm.getRange({line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
- cHar = cHar != cHar.toLowerCase() ? cHar.toLowerCase() : cHar.toUpperCase();
- cm.replaceRange(cHar, {line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
- cm.setCursor(cur.line, cur.ch+1);
- },
- "Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm)},
- "Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm)},
- "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
- "U": "undo", "Ctrl-R": "redo", "Shift-4": "goLineEnd"},
- function(key, cmd) { map[key] = countTimes(cmd); });
+ iterObj({
+ "H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown",
+ "K": "goLineUp", "Left": "goColumnLeft", "Right": "goColumnRight",
+ "Down": "goLineDown", "Up": "goLineUp", "Backspace": "goCharLeft",
+ "Space": "goCharRight",
+ "B": function(cm) {moveToWord(cm, word, -1, "end");},
+ "E": function(cm) {moveToWord(cm, word, 1, "end");},
+ "W": function(cm) {moveToWord(cm, word, 1, "start");},
+ "Shift-B": function(cm) {moveToWord(cm, bigWord, -1, "end");},
+ "Shift-E": function(cm) {moveToWord(cm, bigWord, 1, "end");},
+ "Shift-W": function(cm) {moveToWord(cm, bigWord, 1, "start");},
+ "X": function(cm) {CodeMirror.commands.delCharRight(cm);},
+ "P": function(cm) {
+ var cur = cm.getCursor().line;
+ if (buf!= "") {
+ CodeMirror.commands.goLineEnd(cm);
+ cm.replaceSelection(buf, "end");
+ }
+ cm.setCursor(cur+1);
+ },
+ "Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm);},
+ "Shift-J": function(cm) {joinLineNext(cm);},
+ "Shift-P": function(cm) {
+ var cur = cm.getCursor().line;
+ if (buf!= "") {
+ CodeMirror.commands.goLineUp(cm);
+ CodeMirror.commands.goLineEnd(cm);
+ cm.replaceSelection(buf, "end");
+ }
+ cm.setCursor(cur+1);
+ },
+ "'~'": function(cm) {
+ var cur = cm.getCursor(), cHar = cm.getRange({line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
+ cHar = cHar != cHar.toLowerCase() ? cHar.toLowerCase() : cHar.toUpperCase();
+ cm.replaceRange(cHar, {line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
+ cm.setCursor(cur.line, cur.ch+1);
+ },
+ "Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm);},
+ "Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm);},
+ "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
+ "U": "undo", "Ctrl-R": "redo"
+ }, function(key, cmd) { map[key] = countTimes(cmd); });
+
+ // empty key maps
+ iterList([
+ "vim-prefix-d'",
+ "vim-prefix-y'",
+ "vim-prefix-df",
+ "vim-prefix-dF",
+ "vim-prefix-dt",
+ "vim-prefix-dT",
+ "vim-prefix-c",
+ "vim-prefix-cf",
+ "vim-prefix-cF",
+ "vim-prefix-ct",
+ "vim-prefix-cT",
+ "vim-prefix-",
+ "vim-prefix-f",
+ "vim-prefix-F",
+ "vim-prefix-t",
+ "vim-prefix-T",
+ "vim-prefix-r",
+ "vim-prefix-m"
+ ],
+ function (prefix) {
+ CodeMirror.keyMap[prefix] = {
+ auto: "vim",
+ nofallthrough: true
+ };
+ });
CodeMirror.keyMap["vim-prefix-g"] = {
"E": countTimes(function(cm) { moveToWord(cm, word, -1, "start");}),
"Shift-E": countTimes(function(cm) { moveToWord(cm, bigWord, -1, "start");}),
- auto: "vim",
- catchall: function(cm) {/*ignore*/}
+ "G": function (cm) { cm.setCursor({line: 0, ch: cm.getCursor().ch});},
+ auto: "vim", nofallthrough: true, style: "fat-cursor"
};
- CodeMirror.keyMap["vim-prefix-m"] = {
- "A": function(cm) {mark["A"] = cm.getCursor().line;},
- "Shift-A": function(cm) {mark["Shift-A"] = cm.getCursor().line;},
- "B": function(cm) {mark["B"] = cm.getCursor().line;},
- "Shift-B": function(cm) {mark["Shift-B"] = cm.getCursor().line;},
- "C": function(cm) {mark["C"] = cm.getCursor().line;},
- "Shift-C": function(cm) {mark["Shift-C"] = cm.getCursor().line;},
- "D": function(cm) {mark["D"] = cm.getCursor().line;},
- "Shift-D": function(cm) {mark["Shift-D"] = cm.getCursor().line;},
- "E": function(cm) {mark["E"] = cm.getCursor().line;},
- "Shift-E": function(cm) {mark["Shift-E"] = cm.getCursor().line;},
- "F": function(cm) {mark["F"] = cm.getCursor().line;},
- "Shift-F": function(cm) {mark["Shift-F"] = cm.getCursor().line;},
- "G": function(cm) {mark["G"] = cm.getCursor().line;},
- "Shift-G": function(cm) {mark["Shift-G"] = cm.getCursor().line;},
- "H": function(cm) {mark["H"] = cm.getCursor().line;},
- "Shift-H": function(cm) {mark["Shift-H"] = cm.getCursor().line;},
- "I": function(cm) {mark["I"] = cm.getCursor().line;},
- "Shift-I": function(cm) {mark["Shift-I"] = cm.getCursor().line;},
- "J": function(cm) {mark["J"] = cm.getCursor().line;},
- "Shift-J": function(cm) {mark["Shift-J"] = cm.getCursor().line;},
- "K": function(cm) {mark["K"] = cm.getCursor().line;},
- "Shift-K": function(cm) {mark["Shift-K"] = cm.getCursor().line;},
- "L": function(cm) {mark["L"] = cm.getCursor().line;},
- "Shift-L": function(cm) {mark["Shift-L"] = cm.getCursor().line;},
- "M": function(cm) {mark["M"] = cm.getCursor().line;},
- "Shift-M": function(cm) {mark["Shift-M"] = cm.getCursor().line;},
- "N": function(cm) {mark["N"] = cm.getCursor().line;},
- "Shift-N": function(cm) {mark["Shift-N"] = cm.getCursor().line;},
- "O": function(cm) {mark["O"] = cm.getCursor().line;},
- "Shift-O": function(cm) {mark["Shift-O"] = cm.getCursor().line;},
- "P": function(cm) {mark["P"] = cm.getCursor().line;},
- "Shift-P": function(cm) {mark["Shift-P"] = cm.getCursor().line;},
- "Q": function(cm) {mark["Q"] = cm.getCursor().line;},
- "Shift-Q": function(cm) {mark["Shift-Q"] = cm.getCursor().line;},
- "R": function(cm) {mark["R"] = cm.getCursor().line;},
- "Shift-R": function(cm) {mark["Shift-R"] = cm.getCursor().line;},
- "S": function(cm) {mark["S"] = cm.getCursor().line;},
- "Shift-S": function(cm) {mark["Shift-S"] = cm.getCursor().line;},
- "T": function(cm) {mark["T"] = cm.getCursor().line;},
- "Shift-T": function(cm) {mark["Shift-T"] = cm.getCursor().line;},
- "U": function(cm) {mark["U"] = cm.getCursor().line;},
- "Shift-U": function(cm) {mark["Shift-U"] = cm.getCursor().line;},
- "V": function(cm) {mark["V"] = cm.getCursor().line;},
- "Shift-V": function(cm) {mark["Shift-V"] = cm.getCursor().line;},
- "W": function(cm) {mark["W"] = cm.getCursor().line;},
- "Shift-W": function(cm) {mark["Shift-W"] = cm.getCursor().line;},
- "X": function(cm) {mark["X"] = cm.getCursor().line;},
- "Shift-X": function(cm) {mark["Shift-X"] = cm.getCursor().line;},
- "Y": function(cm) {mark["Y"] = cm.getCursor().line;},
- "Shift-Y": function(cm) {mark["Shift-Y"] = cm.getCursor().line;},
- "Z": function(cm) {mark["Z"] = cm.getCursor().line;},
- "Shift-Z": function(cm) {mark["Shift-Z"] = cm.getCursor().line;},
- auto: "vim",
- catchall: function(cm) {/*ignore*/}
- }
-
CodeMirror.keyMap["vim-prefix-d"] = {
- "D": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line)); cm.removeLine(cm.getCursor().line); }),
- "'": function(cm) {cm.setOption("keyMap", "vim-prefix-d'"); emptyBuffer();},
- auto: "vim",
- catchall: function(cm) {/*ignore*/}
+ "D": countTimes(function(cm) {
+ pushInBuffer("\n"+cm.getLine(cm.getCursor().line));
+ cm.removeLine(cm.getCursor().line);
+ }),
+ "'": function(cm) {
+ cm.setOption("keyMap", "vim-prefix-d'");
+ emptyBuffer();
+ },
+ "E": countTimes("delWordRight"),
+ "B": countTimes("delWordLeft"),
+ auto: "vim", nofallthrough: true, style: "fat-cursor"
+ };
+ // FIXME - does not work for bindings like "d3e"
+ addCountBindings(CodeMirror.keyMap["vim-prefix-d"]);
+
+ CodeMirror.keyMap["vim-prefix-c"] = {
+ "E": function (cm) {
+ countTimes("delWordRight")(cm);
+ enterInsertMode(cm);
+ },
+ "B": function (cm) {
+ countTimes("delWordLeft")(cm);
+ enterInsertMode(cm);
+ },
+ "C": function (cm) {
+ iterTimes(function (i, last) {
+ CodeMirror.commands.deleteLine(cm);
+ if (i) {
+ CodeMirror.commands.delCharRight(cm);
+ if (last) CodeMirror.commands.deleteLine(cm);
+ }
+ });
+ enterInsertMode(cm);
+ },
+ auto: "vim", nofallthrough: true, style: "fat-cursor"
};
- CodeMirror.keyMap["vim-prefix-d'"] = {
- "A": function(cm) {delTillMark(cm,"A");},
- "Shift-A": function(cm) {delTillMark(cm,"Shift-A");},
- "B": function(cm) {delTillMark(cm,"B");},
- "Shift-B": function(cm) {delTillMark(cm,"Shift-B");},
- "C": function(cm) {delTillMark(cm,"C");},
- "Shift-C": function(cm) {delTillMark(cm,"Shift-C");},
- "D": function(cm) {delTillMark(cm,"D");},
- "Shift-D": function(cm) {delTillMark(cm,"Shift-D");},
- "E": function(cm) {delTillMark(cm,"E");},
- "Shift-E": function(cm) {delTillMark(cm,"Shift-E");},
- "F": function(cm) {delTillMark(cm,"F");},
- "Shift-F": function(cm) {delTillMark(cm,"Shift-F");},
- "G": function(cm) {delTillMark(cm,"G");},
- "Shift-G": function(cm) {delTillMark(cm,"Shift-G");},
- "H": function(cm) {delTillMark(cm,"H");},
- "Shift-H": function(cm) {delTillMark(cm,"Shift-H");},
- "I": function(cm) {delTillMark(cm,"I");},
- "Shift-I": function(cm) {delTillMark(cm,"Shift-I");},
- "J": function(cm) {delTillMark(cm,"J");},
- "Shift-J": function(cm) {delTillMark(cm,"Shift-J");},
- "K": function(cm) {delTillMark(cm,"K");},
- "Shift-K": function(cm) {delTillMark(cm,"Shift-K");},
- "L": function(cm) {delTillMark(cm,"L");},
- "Shift-L": function(cm) {delTillMark(cm,"Shift-L");},
- "M": function(cm) {delTillMark(cm,"M");},
- "Shift-M": function(cm) {delTillMark(cm,"Shift-M");},
- "N": function(cm) {delTillMark(cm,"N");},
- "Shift-N": function(cm) {delTillMark(cm,"Shift-N");},
- "O": function(cm) {delTillMark(cm,"O");},
- "Shift-O": function(cm) {delTillMark(cm,"Shift-O");},
- "P": function(cm) {delTillMark(cm,"P");},
- "Shift-P": function(cm) {delTillMark(cm,"Shift-P");},
- "Q": function(cm) {delTillMark(cm,"Q");},
- "Shift-Q": function(cm) {delTillMark(cm,"Shift-Q");},
- "R": function(cm) {delTillMark(cm,"R");},
- "Shift-R": function(cm) {delTillMark(cm,"Shift-R");},
- "S": function(cm) {delTillMark(cm,"S");},
- "Shift-S": function(cm) {delTillMark(cm,"Shift-S");},
- "T": function(cm) {delTillMark(cm,"T");},
- "Shift-T": function(cm) {delTillMark(cm,"Shift-T");},
- "U": function(cm) {delTillMark(cm,"U");},
- "Shift-U": function(cm) {delTillMark(cm,"Shift-U");},
- "V": function(cm) {delTillMark(cm,"V");},
- "Shift-V": function(cm) {delTillMark(cm,"Shift-V");},
- "W": function(cm) {delTillMark(cm,"W");},
- "Shift-W": function(cm) {delTillMark(cm,"Shift-W");},
- "X": function(cm) {delTillMark(cm,"X");},
- "Shift-X": function(cm) {delTillMark(cm,"Shift-X");},
- "Y": function(cm) {delTillMark(cm,"Y");},
- "Shift-Y": function(cm) {delTillMark(cm,"Shift-Y");},
- "Z": function(cm) {delTillMark(cm,"Z");},
- "Shift-Z": function(cm) {delTillMark(cm,"Shift-Z");},
- auto: "vim",
- catchall: function(cm) {/*ignore*/}
+ iterList(["vim-prefix-d", "vim-prefix-c", "vim-prefix-"], function (prefix) {
+ iterList(["f", "F", "T", "t"],
+ function (ch) {
+ CodeMirror.keyMap[prefix][toCombo(ch)] = function (cm) {
+ cm.setOption("keyMap", prefix + ch);
+ emptyBuffer();
+ };
+ });
+ });
+
+ var MOTION_OPTIONS = {
+ "t": {inclusive: false, forward: true},
+ "f": {inclusive: true, forward: true},
+ "T": {inclusive: false, forward: false},
+ "F": {inclusive: true, forward: false}
};
- CodeMirror.keyMap["vim-prefix-y'"] = {
- "A": function(cm) {yankTillMark(cm,"A");},
- "Shift-A": function(cm) {yankTillMark(cm,"Shift-A");},
- "B": function(cm) {yankTillMark(cm,"B");},
- "Shift-B": function(cm) {yankTillMark(cm,"Shift-B");},
- "C": function(cm) {yankTillMark(cm,"C");},
- "Shift-C": function(cm) {yankTillMark(cm,"Shift-C");},
- "D": function(cm) {yankTillMark(cm,"D");},
- "Shift-D": function(cm) {yankTillMark(cm,"Shift-D");},
- "E": function(cm) {yankTillMark(cm,"E");},
- "Shift-E": function(cm) {yankTillMark(cm,"Shift-E");},
- "F": function(cm) {yankTillMark(cm,"F");},
- "Shift-F": function(cm) {yankTillMark(cm,"Shift-F");},
- "G": function(cm) {yankTillMark(cm,"G");},
- "Shift-G": function(cm) {yankTillMark(cm,"Shift-G");},
- "H": function(cm) {yankTillMark(cm,"H");},
- "Shift-H": function(cm) {yankTillMark(cm,"Shift-H");},
- "I": function(cm) {yankTillMark(cm,"I");},
- "Shift-I": function(cm) {yankTillMark(cm,"Shift-I");},
- "J": function(cm) {yankTillMark(cm,"J");},
- "Shift-J": function(cm) {yankTillMark(cm,"Shift-J");},
- "K": function(cm) {yankTillMark(cm,"K");},
- "Shift-K": function(cm) {yankTillMark(cm,"Shift-K");},
- "L": function(cm) {yankTillMark(cm,"L");},
- "Shift-L": function(cm) {yankTillMark(cm,"Shift-L");},
- "M": function(cm) {yankTillMark(cm,"M");},
- "Shift-M": function(cm) {yankTillMark(cm,"Shift-M");},
- "N": function(cm) {yankTillMark(cm,"N");},
- "Shift-N": function(cm) {yankTillMark(cm,"Shift-N");},
- "O": function(cm) {yankTillMark(cm,"O");},
- "Shift-O": function(cm) {yankTillMark(cm,"Shift-O");},
- "P": function(cm) {yankTillMark(cm,"P");},
- "Shift-P": function(cm) {yankTillMark(cm,"Shift-P");},
- "Q": function(cm) {yankTillMark(cm,"Q");},
- "Shift-Q": function(cm) {yankTillMark(cm,"Shift-Q");},
- "R": function(cm) {yankTillMark(cm,"R");},
- "Shift-R": function(cm) {yankTillMark(cm,"Shift-R");},
- "S": function(cm) {yankTillMark(cm,"S");},
- "Shift-S": function(cm) {yankTillMark(cm,"Shift-S");},
- "T": function(cm) {yankTillMark(cm,"T");},
- "Shift-T": function(cm) {yankTillMark(cm,"Shift-T");},
- "U": function(cm) {yankTillMark(cm,"U");},
- "Shift-U": function(cm) {yankTillMark(cm,"Shift-U");},
- "V": function(cm) {yankTillMark(cm,"V");},
- "Shift-V": function(cm) {yankTillMark(cm,"Shift-V");},
- "W": function(cm) {yankTillMark(cm,"W");},
- "Shift-W": function(cm) {yankTillMark(cm,"Shift-W");},
- "X": function(cm) {yankTillMark(cm,"X");},
- "Shift-X": function(cm) {yankTillMark(cm,"Shift-X");},
- "Y": function(cm) {yankTillMark(cm,"Y");},
- "Shift-Y": function(cm) {yankTillMark(cm,"Shift-Y");},
- "Z": function(cm) {yankTillMark(cm,"Z");},
- "Shift-Z": function(cm) {yankTillMark(cm,"Shift-Z");},
- auto: "vim",
- catchall: function(cm) {/*ignore*/}
+ function setupPrefixBindingForKey(m) {
+ CodeMirror.keyMap["vim-prefix-m"][m] = function(cm) {
+ mark[m] = cm.getCursor().line;
+ };
+ CodeMirror.keyMap["vim-prefix-d'"][m] = function(cm) {
+ delTillMark(cm,m);
+ };
+ CodeMirror.keyMap["vim-prefix-y'"][m] = function(cm) {
+ yankTillMark(cm,m);
+ };
+ CodeMirror.keyMap["vim-prefix-r"][m] = function (cm) {
+ var cur = cm.getCursor();
+ cm.replaceRange(toLetter(m),
+ {line: cur.line, ch: cur.ch},
+ {line: cur.line, ch: cur.ch + 1});
+ CodeMirror.commands.goColumnLeft(cm);
+ };
+ // all commands, related to motions till char in line
+ iterObj(MOTION_OPTIONS, function (ch, options) {
+ CodeMirror.keyMap["vim-prefix-" + ch][m] = function(cm) {
+ moveTillChar(cm, m, options);
+ };
+ CodeMirror.keyMap["vim-prefix-d" + ch][m] = function(cm) {
+ delTillChar(cm, m, options);
+ };
+ CodeMirror.keyMap["vim-prefix-c" + ch][m] = function(cm) {
+ delTillChar(cm, m, options);
+ enterInsertMode(cm);
+ };
+ });
};
+ for (var i = 65; i < 65 + 26; i++) { // uppercase alphabet char codes
+ var ch = String.fromCharCode(i);
+ setupPrefixBindingForKey(toCombo(ch));
+ setupPrefixBindingForKey(toCombo(ch.toLowerCase()));
+ }
+ iterList(SPECIAL_SYMBOLS, function (ch) {
+ setupPrefixBindingForKey(toCombo(ch));
+ });
+ setupPrefixBindingForKey("Space");
CodeMirror.keyMap["vim-prefix-y"] = {
"Y": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line+yank)); yank++; }),
"'": function(cm) {cm.setOption("keyMap", "vim-prefix-y'"); emptyBuffer();},
- auto: "vim",
- catchall: function(cm) {/*ignore*/}
+ auto: "vim", nofallthrough: true, style: "fat-cursor"
};
CodeMirror.keyMap["vim-insert"] = {
+ // TODO: override navigation keys so that Esc will cancel automatic indentation from o, O, i_<CR>
"Esc": function(cm) {
- cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
- cm.setOption("keyMap", "vim");
- editCursor("vim");
- },
- "Ctrl-N": function(cm) {/* Code to bring up autocomplete hint */},
- "Ctrl-P": function(cm) {/* Code to bring up autocomplete hint */},
+ cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
+ cm.setOption("keyMap", "vim");
+ },
+ "Ctrl-N": "autocomplete",
+ "Ctrl-P": "autocomplete",
fallthrough: ["default"]
};
})();
View
42 lib/codemirror.css
@@ -1,8 +1,11 @@
.CodeMirror {
line-height: 1em;