Showing with 1,292 additions and 182 deletions.
  1. +9 −0 .npmignore
  2. +2 −1 .travis.yml
  3. +8 −0 AUTHORS
  4. +2 −1 CONTRIBUTING.md
  5. +21 −6 README.md
  6. +10 −7 addon/hint/show-hint.js
  7. +52 −17 addon/search/search.js
  8. +1 −0 addon/tern/tern.css
  9. +1 −1 addon/tern/tern.js
  10. +4 −2 demo/search.html
  11. +19 −3 demo/theme.html
  12. +3 −0 doc/compress.html
  13. +26 −4 doc/manual.html
  14. +26 −13 doc/releases.html
  15. +5 −2 index.html
  16. +1 −1 keymap/emacs.js
  17. +4 −2 keymap/sublime.js
  18. +1 −1 keymap/vim.js
  19. +19 −12 lib/codemirror.css
  20. +88 −35 lib/codemirror.js
  21. +85 −0 mode/brainfuck/brainfuck.js
  22. +85 −0 mode/brainfuck/index.html
  23. +13 −0 mode/clike/clike.js
  24. +2 −1 mode/clike/index.html
  25. +2 −0 mode/css/css.js
  26. +0 −4 mode/erlang/erlang.js
  27. +3 −2 mode/gfm/gfm.js
  28. +3 −0 mode/index.html
  29. +7 −7 mode/markdown/markdown.js
  30. +3 −1 mode/meta.js
  31. +1 −1 mode/ruby/ruby.js
  32. +1 −1 mode/rust/rust.js
  33. +95 −0 mode/vhdl/index.html
  34. +189 −0 mode/vhdl/vhdl.js
  35. +1 −0 mode/xml/xml.js
  36. +1 −1 package.json
  37. +6 −0 test/emacs_test.js
  38. +10 −0 test/scroll_test.js
  39. +16 −1 test/test.js
  40. +9 −6 test/vim_test.js
  41. +3 −2 theme/3024-day.css
  42. +2 −2 theme/3024-night.css
  43. +2 −2 theme/ambiance.css
  44. +2 −2 theme/base16-dark.css
  45. +2 −2 theme/base16-light.css
  46. +2 −2 theme/blackboard.css
  47. +2 −2 theme/cobalt.css
  48. +87 −0 theme/dracula.css
  49. +2 −2 theme/erlang-dark.css
  50. +42 −0 theme/icecoder.css
  51. +2 −2 theme/lesser-dark.css
  52. +105 −0 theme/material.css
  53. +2 −2 theme/mbo.css
  54. +2 −2 theme/mdn-like.css
  55. +2 −2 theme/midnight.css
  56. +2 −2 theme/monokai.css
  57. +2 −2 theme/night.css
  58. +2 −2 theme/paraiso-dark.css
  59. +2 −2 theme/paraiso-light.css
  60. +2 −2 theme/pastel-on-dark.css
  61. +2 −2 theme/rubyblue.css
  62. +88 −0 theme/seti.css
  63. +3 −3 theme/solarized.css
  64. +2 −2 theme/the-matrix.css
  65. +2 −2 theme/tomorrow-night-eighties.css
  66. +2 −2 theme/twilight.css
  67. +2 −2 theme/vibrant-ink.css
  68. +2 −2 theme/xq-dark.css
  69. +86 −0 theme/yeti.css
9 changes: 9 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/node_modules
/demo
/doc
/test
/index.html
/mode/*/*test.js
/mode/*/*.html
/mode/index.html
.*
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
language: node_js
node_js:
- 0.10
- stable
sudo: false
8 changes: 8 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ AtomicPages LLC
Atul Bhouraskar
Aurelian Oancea
Bastian Müller
belhaj
Bem Jones-Bey
benbro
Beni Cherniavsky-Paskin
Expand Down Expand Up @@ -215,6 +216,7 @@ Jason San Jose
Jason Siefken
Jaydeep Solanki
Jean Boussier
Jeff Blaisdell
jeffkenton
Jeff Pickhardt
jem (graphite)
Expand Down Expand Up @@ -272,6 +274,7 @@ Lorenzo Stoakes
Luciano Longo
Luke Stagner
lynschinzer
M1cha
Madhura Jayaratne
Maksim Lin
Maksym Taran
Expand Down Expand Up @@ -307,6 +310,7 @@ mauricio
Maximilian Hils
Maxim Kraev
Max Kirsch
Max Schaefer
Max Xiantu
mbarkhau
Metatheos
Expand All @@ -327,6 +331,7 @@ Mike Kadin
MinRK
Miraculix87
misfo
mkaminsky11
mloginov
Moritz Schwörer
mps
Expand Down Expand Up @@ -354,6 +359,7 @@ Nisarg Jhaveri
nlwillia
noragrossman
Norman Rzepka
Oreoluwa Onatemowo
pablo
Page
Panupong Pasupat
Expand Down Expand Up @@ -387,6 +393,7 @@ Robert Crossfield
Roberto Abdelkader Martínez Pérez
robertop23
Robert Plummer
Rrandom
Ruslan Osmanov
Ryan Prior
sabaca
Expand Down Expand Up @@ -421,6 +428,7 @@ Stefan Borsje
Steffen Beyer
Steve O'Hara
stoskov
Sungho Kim
Taha Jahangir
Takuji Shimokawa
Tarmil
Expand Down
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ should be asked on the
- Make sure all tests pass. Visit `test/index.html` in your browser to
run them.
- Submit a pull request
([how to create a pull request](https://help.github.com/articles/fork-a-repo))
([how to create a pull request](https://help.github.com/articles/fork-a-repo)).
Don't put more than one feature/fix in a single pull request.

By contributing code to CodeMirror you

Expand Down
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,25 @@
[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?again)](https://marijnhaverbeke.nl/fund/)

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.
CodeMirror is a versatile text editor implemented in JavaScript for
the browser. It is specialized for editing code, and comes with over
100 language modes and various addons that implement more advanced
editing functionality.

The project page is http://codemirror.net
The manual is at http://codemirror.net/doc/manual.html
The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)
A rich programming API and a CSS theming system are available for
customizing CodeMirror to fit your application, and extending it with
new functionality.

You can find more information (and the
[manual](http://codemirror.net/doc/manual.html)) on the [project
page](http://codemirror.net). For questions and discussion, use the
[discussion forum](http://discuss.codemirror.net/).

See
[CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)
for contributing guidelines.

The CodeMirror community aims to be welcoming to everybody. We use the
[Contributor Covenant
(1.1)](http://contributor-covenant.org/version/1/1/0/) as our code of
conduct.
17 changes: 10 additions & 7 deletions addon/hint/show-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@

update: function(first) {
if (this.tick == null) return;
if (this.data) CodeMirror.signal(this.data, "update");
if (!this.options.hint.async) {
this.finishUpdate(this.options.hint(this.cm, this.options), first);
} else {
Expand All @@ -111,6 +110,8 @@
},

finishUpdate: function(data, first) {
if (this.data) CodeMirror.signal(this.data, "update");
if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
this.data = data;

var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
Expand Down Expand Up @@ -351,18 +352,20 @@

CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
var to = CodeMirror.Pos(cur.line, token.end);
if (token.string && /\w/.test(token.string[token.string.length - 1])) {
var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
} else {
var term = "", from = to;
}
var found = [];
for (var i = 0; i < options.words.length; i++) {
var word = options.words[i];
if (word.slice(0, token.string.length) == token.string)
if (word.slice(0, term.length) == term)
found.push(word);
}

if (found.length) return {
list: found,
from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)
};
if (found.length) return {list: found, from: from, to: to};
});

CodeMirror.commands.autocomplete = CodeMirror.showHint;
Expand Down
69 changes: 52 additions & 17 deletions addon/search/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

function searchOverlay(query, caseInsensitive) {
if (typeof query == "string")
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
Expand All @@ -42,24 +43,39 @@
this.posFrom = this.posTo = this.lastQuery = this.query = null;
this.overlay = null;
}

function getSearchState(cm) {
return cm.state.search || (cm.state.search = new SearchState());
}

function queryCaseInsensitive(query) {
return typeof query == "string" && query == query.toLowerCase();
}

function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search.
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
}

function persistentDialog(cm, text, deflt, f) {
cm.openDialog(text, f, {
value: deflt,
selectValueOnOpen: true,
closeOnEnter: false,
onClose: function() { clearSearch(cm); }
});
}

function dialog(cm, text, shortText, deflt, f) {
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
else f(prompt(shortText, deflt));
}

function confirmDialog(cm, text, shortText, fs) {
if (cm.openConfirm) cm.openConfirm(text, fs);
else if (confirm(shortText)) fs[0]();
}

function parseQuery(query) {
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
if (isRE) {
Expand All @@ -70,28 +86,44 @@
query = /x^/;
return query;
}

var queryDialog =
'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
function doSearch(cm, rev) {

function startSearch(cm, state, query) {
state.queryText = query;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
if (cm.showMatchesOnScrollbar) {
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
}
}

function doSearch(cm, rev, persistent) {
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
var q = cm.getSelection() || state.lastQuery;
dialog(cm, queryDialog, "Search for:", q, function(query) {
cm.operation(function() {
if (!query || state.query) return;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
if (cm.showMatchesOnScrollbar) {
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
}
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
if (persistent && cm.openDialog) {
persistentDialog(cm, queryDialog, q, function(query, event) {
CodeMirror.e_stop(event);
if (!query) return;
if (query != state.queryText) startSearch(cm, state, query);
findNext(cm, event.shiftKey);
});
});
} else {
dialog(cm, queryDialog, "Search for:", q, function(query) {
if (query && !state.query) cm.operation(function() {
startSearch(cm, state, query);
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
});
});
}
}

function findNext(cm, rev) {cm.operation(function() {
var state = getSearchState(cm);
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
Expand All @@ -100,14 +132,15 @@
if (!cursor.find(rev)) return;
}
cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
state.posFrom = cursor.from(); state.posTo = cursor.to();
});}

function clearSearch(cm) {cm.operation(function() {
var state = getSearchState(cm);
state.lastQuery = state.query;
if (!state.query) return;
state.query = null;
state.query = state.queryText = null;
cm.removeOverlay(state.overlay);
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
});}
Expand All @@ -116,6 +149,7 @@
'Replace: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";

function replace(cm, all) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
Expand Down Expand Up @@ -159,6 +193,7 @@
}

CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
CodeMirror.commands.findNext = doSearch;
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
CodeMirror.commands.clearSearch = clearSearch;
Expand Down
1 change: 1 addition & 0 deletions addon/tern/tern.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.CodeMirror-Tern-completion {
padding-left: 22px;
position: relative;
line-height: 1.5;
}
.CodeMirror-Tern-completion:before {
position: absolute;
Expand Down
2 changes: 1 addition & 1 deletion addon/tern/tern.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@
var completion = data.completions[i], className = typeToIcon(completion.type);
if (data.guess) className += " " + cls + "guess";
completions.push({text: completion.name + after,
displayText: completion.name,
displayText: completion.displayName || completion.name,
className: className,
data: completion});
}
Expand Down
6 changes: 4 additions & 2 deletions demo/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,20 @@ <h2>Search/Replace Demo</h2>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/html",
lineNumbers: true
lineNumbers: true,
extraKeys: {"Alt-F": "findPersistent"}
});
</script>

<p>Demonstration of primitive search/replace functionality. The
keybindings (which can be overridden by custom keymaps) are:</p>
keybindings (which can be configured with custom keymaps) are:</p>
<dl>
<dt>Ctrl-F / Cmd-F</dt><dd>Start searching</dd>
<dt>Ctrl-G / Cmd-G</dt><dd>Find next</dd>
<dt>Shift-Ctrl-G / Shift-Cmd-G</dt><dd>Find previous</dd>
<dt>Shift-Ctrl-F / Cmd-Option-F</dt><dd>Replace</dd>
<dt>Shift-Ctrl-R / Shift-Cmd-Option-F</dt><dd>Replace all</dd>
<dt>Alt-F</dt><dd>Persistent search (dialog doesn't autoclose, enter to find next, shift-enter to find previous)</dd>
</dl>
<p>Searching is enabled by
including <a href="../addon/search/search.js">addon/search/search.js</a>
Expand Down
Loading