From 8f52819bdc799ece0981d2b1308ce966ff060070 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 20 Oct 2014 22:04:39 +0200 Subject: [PATCH 01/71] Bump version number post-4.7 --- bower.json | 2 +- doc/manual.html | 2 +- lib/codemirror.js | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index 81352b6d70..2704354d73 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"4.7.0", + "version":"4.7.1", "main": ["lib/codemirror.js", "lib/codemirror.css"], "ignore": [ "**/.*", diff --git a/doc/manual.html b/doc/manual.html index cdbb107dd5..051a2178ae 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -63,7 +63,7 @@

User manual and reference guide - version 4.7.0 + version 4.7.1

CodeMirror is a code-editor component that can be embedded in diff --git a/lib/codemirror.js b/lib/codemirror.js index 4f8a23bde8..054548d9d4 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -7824,7 +7824,7 @@ // THE END - CodeMirror.version = "4.7.0"; + CodeMirror.version = "4.7.1"; return CodeMirror; }); diff --git a/package.json b/package.json index e7d5bd962b..c306fa531b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"4.7.0", + "version":"4.7.1", "main": "lib/codemirror.js", "description": "In-browser code editing made bearable", "licenses": [{"type": "MIT", From e1289d85c1518478a845d50d1a4797b16c1240b9 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 20 Oct 2014 22:51:30 +0200 Subject: [PATCH 02/71] Saturate logo a little --- doc/docs.css | 2 +- doc/logo.png | Bin 9709 -> 9310 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/docs.css b/doc/docs.css index 7747895d9f..837ba69782 100644 --- a/doc/docs.css +++ b/doc/docs.css @@ -29,7 +29,7 @@ article > h2:first-child, section:first-child > h2 { margin-top: 0; } margin-right: 12px; margin-top: 0; margin-bottom: 2px; - color: #E30808; + color: #d30707; letter-spacing: .5px; } diff --git a/doc/logo.png b/doc/logo.png index bdfc75df7db0db8c5d9336dba3070a9c1618c950..9aabda1d709f565bb115fa083cc16b6d52db64cf 100644 GIT binary patch literal 9310 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 literal 9709 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 SjscElK`F?nO4m!8Mf?vl%E>qY From 9ca51f30dbcbf7b97e194514d87f76cf450368cf Mon Sep 17 00:00:00 2001 From: Randy Burden Date: Tue, 21 Oct 2014 18:30:00 -0500 Subject: [PATCH 03/71] [overlay mode demo] Fixed bug which highlighted the rest of the line If "{{" was found, the code would highlight the rest of the line regardless if a matching "}}" or "}}}" was found. --- demo/mustache.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/demo/mustache.html b/demo/mustache.html index ecc68555ef..ae4e6a891b 100644 --- a/demo/mustache.html +++ b/demo/mustache.html @@ -46,9 +46,10 @@ var ch; if (stream.match("{{")) { while ((ch = stream.next()) != null) - if (ch == "}" && stream.next() == "}") break; - stream.eat("}"); - return "mustache"; + if (ch == "}" && stream.next() == "}") { + stream.eat("}"); + return "mustache"; + } } while (stream.next() != null && !stream.match("{{", false)) {} return null; From 08183e426e4a743b8dce274bc51a6aa584b6a4c0 Mon Sep 17 00:00:00 2001 From: Jeremy Parmenter Date: Sun, 19 Oct 2014 15:05:10 -0700 Subject: [PATCH 04/71] [gfm mode] Added strikethrough implementation --- lib/codemirror.css | 1 + mode/gfm/gfm.js | 3 ++- mode/gfm/index.html | 10 ++++++++++ mode/gfm/test.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++ mode/markdown/markdown.js | 39 ++++++++++++++++++++++++++++++++++--- 5 files changed, 98 insertions(+), 4 deletions(-) diff --git a/lib/codemirror.css b/lib/codemirror.css index 68c67b170a..af9e0f26e6 100644 --- a/lib/codemirror.css +++ b/lib/codemirror.css @@ -125,6 +125,7 @@ div.CodeMirror-overwrite div.CodeMirror-cursor {} .cm-header, .cm-strong {font-weight: bold;} .cm-em {font-style: italic;} .cm-link {text-decoration: underline;} +.cm-strikethrough {text-decoration: line-through;} .cm-s-default .cm-error {color: #f00;} .cm-invalidchar {color: #f00;} diff --git a/mode/gfm/gfm.js b/mode/gfm/gfm.js index eb0b7c193b..80a8e2c84d 100644 --- a/mode/gfm/gfm.js +++ b/mode/gfm/gfm.js @@ -109,7 +109,8 @@ CodeMirror.defineMode("gfm", function(config, modeConfig) { var markdownConfig = { underscoresBreakWords: false, taskLists: true, - fencedCodeBlocks: true + fencedCodeBlocks: true, + strikethrough: true }; for (var attr in modeConfig) { markdownConfig[attr] = modeConfig[attr]; diff --git a/mode/gfm/index.html b/mode/gfm/index.html index a35e56866c..60d108c1ca 100644 --- a/mode/gfm/index.html +++ b/mode/gfm/index.html @@ -41,6 +41,16 @@ Underscores_are_allowed_between_words. +## Strikethrough text + +GFM adds syntax to strikethrough text, which is missing from standard Markdown. + +~~Mistaken text.~~ +~~**works with other fomatting**~~ + +~~spans across +lines~~ + ## Fenced code blocks (and syntax highlighting) ```javascript diff --git a/mode/gfm/test.js b/mode/gfm/test.js index b9af5e894c..c2bc38fd57 100644 --- a/mode/gfm/test.js +++ b/mode/gfm/test.js @@ -22,6 +22,12 @@ "[variable-2&formatting&formatting-list&formatting-list-ul - ][meta&formatting&formatting-task [ ]]][variable-2 foo]", "[variable-2&formatting&formatting-list&formatting-list-ul - ][property&formatting&formatting-task [x]]][variable-2 foo]"); + FT("formatting_strikethrough", + "[strikethrough&formatting&formatting-strikethrough ~~][strikethrough foo][strikethrough&formatting&formatting-strikethrough ~~]"); + + FT("formatting_strikethrough", + "foo [strikethrough&formatting&formatting-strikethrough ~~][strikethrough bar][strikethrough&formatting&formatting-strikethrough ~~]"); + MT("emInWordAsterisk", "foo[em *bar*]hello"); @@ -161,4 +167,47 @@ "Commit: [link be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2]", "Issue: [link #1]", "Link: [link http://www.example.com/]"); + + MT("strikethrough", + "[strikethrough ~~foo~~]"); + + MT("strikethroughWithStartingSpace", + "~~ foo~~"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo~~~]"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo ~~]"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo ~~ bar]"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo ~~ bar~~]hello"); + + MT("strikethroughOneLetter", + "[strikethrough ~~a~~]"); + + MT("strikethroughWrapped", + "[strikethrough ~~foo]", + "[strikethrough foo~~]"); + + MT("strikethroughParagraph", + "[strikethrough ~~foo]", + "", + "foo[strikethrough ~~bar]"); + + MT("strikethroughEm", + "[strikethrough ~~foo][em&strikethrough *bar*][strikethrough ~~]"); + + MT("strikethroughEm", + "[em *][em&strikethrough ~~foo~~][em *]"); + + MT("strikethroughStrong", + "[strikethrough ~~][strong&strikethrough **foo**][strikethrough ~~]"); + + MT("strikethroughStrong", + "[strong **][strong&strikethrough ~~foo~~][strong **]"); + })(); diff --git a/mode/markdown/markdown.js b/mode/markdown/markdown.js index 3eb7747e60..48464645bb 100644 --- a/mode/markdown/markdown.js +++ b/mode/markdown/markdown.js @@ -75,6 +75,10 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { // Turn on task lists? ("- [ ] " and "- [x] ") if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; + // Turn on strikethrough syntax + if (modeCfg.strikethrough === undefined) + modeCfg.strikethrough = false; + var codeDepth = 0; var header = 'header' @@ -91,7 +95,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { , linktext = 'link' , linkhref = 'string' , em = 'em' - , strong = 'strong'; + , strong = 'strong' + , strikethrough = 'strikethrough'; var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/ , ulRE = /^[*\-+]\s+/ @@ -99,7 +104,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE , atxHeaderRE = /^#+/ , setextHeaderRE = /^(?:\={1,}|-{1,})$/ - , textRE = /^[^#!\[\]*_\\<>` "'(]+/; + , textRE = /^[^#!\[\]*_\\<>` "'(~]+/; function switchInline(stream, state, f) { state.f = state.inline = f; @@ -121,6 +126,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { state.em = false; // Reset STRONG state state.strong = false; + // Reset strikethrough state + state.strikethrough = false; // Reset state.quote state.quote = 0; if (!htmlFound && state.f == htmlBlock) { @@ -283,6 +290,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { if (state.strong) { styles.push(strong); } if (state.em) { styles.push(em); } + if (state.strikethrough) { styles.push(strikethrough); } if (state.linkText) { styles.push(linktext); } @@ -511,6 +519,29 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { } } + if (modeCfg.strikethrough) { + if (ch === '~' && stream.eatWhile(ch)) { + if (state.strikethrough) {// Remove strikethrough + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + var t = getType(state); + state.strikethrough = false; + return t; + } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough + state.strikethrough = true; + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + return getType(state); + } + } else if (ch === ' ') { + if (stream.match(/^~~/, true)) { // Probably surrounded by space + if (stream.peek() === ' ') { // Surrounded by spaces, ignore + return getType(state); + } else { // Not surrounded by spaces, back up pointer + stream.backUp(2); + } + } + } + } + if (ch === ' ') { if (stream.match(/ +$/, false)) { state.trailingSpace++; @@ -659,7 +690,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { listDepth: 0, quote: 0, trailingSpace: 0, - trailingSpaceNewLine: false + trailingSpaceNewLine: false, + strikethrough: false }; }, @@ -683,6 +715,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { linkTitle: s.linkTitle, em: s.em, strong: s.strong, + strikethrough: s.strikethrough, header: s.header, taskList: s.taskList, list: s.list, From 7e9080a2f3fa37cd6da43aaeaba5c82e7361c140 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 22 Oct 2014 17:41:27 +0200 Subject: [PATCH 05/71] Don't re-highlight lines that were highlighted during drawing --- lib/codemirror.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 054548d9d4..9d6902ba96 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -5878,12 +5878,13 @@ return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; } - function getLineStyles(cm, line) { + function getLineStyles(cm, line, updateFrontier) { if (!line.styles || line.styles[0] != cm.state.modeGen) { var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); line.styles = result.styles; if (result.classes) line.styleClasses = result.classes; else if (line.styleClasses) line.styleClasses = null; + if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; } return line.styles; } @@ -5938,7 +5939,8 @@ if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) builder.addToken = buildTokenBadBidi(builder.addToken, order); builder.map = []; - insertLineContent(line, builder, getLineStyles(cm, line)); + var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); if (line.styleClasses) { if (line.styleClasses.bgClass) builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); From fb8692435b3dda5c417fa1e9a1fd8efd49e9f0ce Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 23 Oct 2014 09:59:13 +0200 Subject: [PATCH 06/71] [solarized theme] Remove tab background character It doesn't belong in a theme. --- theme/solarized.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/theme/solarized.css b/theme/solarized.css index 36d5f79048..07ef406804 100644 --- a/theme/solarized.css +++ b/theme/solarized.css @@ -88,11 +88,6 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png text-decoration-style: dotted; } .cm-s-solarized .cm-strong { color: #eee; } -.cm-s-solarized .cm-tab:before { - content: "➤"; /*visualize tab character*/ - color: #586e75; - position:absolute; -} .cm-s-solarized .cm-error, .cm-s-solarized .cm-invalidchar { color: #586e75; From 7206ccce08a565905570e963e3a98b84e75f677b Mon Sep 17 00:00:00 2001 From: Yunchi Luo Date: Thu, 23 Oct 2014 21:26:23 -0400 Subject: [PATCH 07/71] [vim] Fix bug that vim mode could not be disabled --- keymap/vim.js | 85 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index a0a01e06c6..e1ff9469b6 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -226,51 +226,52 @@ var specialKey = {Enter:'CR',Backspace:'BS',Delete:'Del'}; var mac = /Mac/.test(navigator.platform); var Vim = function() { - CodeMirror.defineOption('vimMode', false, function(cm, val) { - function lookupKey(e) { - var keyCode = e.keyCode; - if (modifierCodes.indexOf(keyCode) != -1) { return; } - var hasModifier = e.ctrlKey || e.metaKey; - var key = CodeMirror.keyNames[keyCode]; - key = specialKey[key] || key; - var name = ''; - if (e.ctrlKey) { name += 'C-'; } - if (e.altKey) { name += 'A-'; } - if (mac && e.metaKey || (!hasModifier && e.shiftKey) && key.length < 2) { - // Shift key bindings can only specified for special characters. - return; - } else if (e.shiftKey && !/^[A-Za-z]$/.test(key)) { - name += 'S-'; - } - if (key.length == 1) { key = key.toLowerCase(); } - name += key; - if (name.length > 1) { name = '<' + name + '>'; } - return name; + function lookupKey(e) { + var keyCode = e.keyCode; + if (modifierCodes.indexOf(keyCode) != -1) { return; } + var hasModifier = e.ctrlKey || e.metaKey; + var key = CodeMirror.keyNames[keyCode]; + key = specialKey[key] || key; + var name = ''; + if (e.ctrlKey) { name += 'C-'; } + if (e.altKey) { name += 'A-'; } + if (mac && e.metaKey || (!hasModifier && e.shiftKey) && key.length < 2) { + // Shift key bindings can only specified for special characters. + return; + } else if (e.shiftKey && !/^[A-Za-z]$/.test(key)) { + name += 'S-'; } - // Keys with modifiers are handled using keydown due to limitations of - // keypress event. - function handleKeyDown(cm, e) { - var name = lookupKey(e); - if (!name) { return; } - - CodeMirror.signal(cm, 'vim-keypress', name); - if (CodeMirror.Vim.handleKey(cm, name, 'user')) { - CodeMirror.e_stop(e); - } + if (key.length == 1) { key = key.toLowerCase(); } + name += key; + if (name.length > 1) { name = '<' + name + '>'; } + return name; + } + // Keys with modifiers are handled using keydown due to limitations of + // keypress event. + function handleKeyDown(cm, e) { + var name = lookupKey(e); + if (!name) { return; } + + CodeMirror.signal(cm, 'vim-keypress', name); + if (CodeMirror.Vim.handleKey(cm, name, 'user')) { + CodeMirror.e_stop(e); } - // Keys without modifiers are handled using keypress to work best with - // non-standard keyboard layouts. - function handleKeyPress(cm, e) { - var code = e.charCode || e.keyCode; - if (e.ctrlKey || e.metaKey || e.altKey || - e.shiftKey && code < 32) { return; } - var name = String.fromCharCode(code); - - CodeMirror.signal(cm, 'vim-keypress', name); - if (CodeMirror.Vim.handleKey(cm, name, 'user')) { - CodeMirror.e_stop(e); - } + } + // Keys without modifiers are handled using keypress to work best with + // non-standard keyboard layouts. + function handleKeyPress(cm, e) { + var code = e.charCode || e.keyCode; + if (e.ctrlKey || e.metaKey || e.altKey || + e.shiftKey && code < 32) { return; } + var name = String.fromCharCode(code); + + CodeMirror.signal(cm, 'vim-keypress', name); + if (CodeMirror.Vim.handleKey(cm, name, 'user')) { + CodeMirror.e_stop(e); } + } + + CodeMirror.defineOption('vimMode', false, function(cm, val) { if (val) { cm.setOption('keyMap', 'vim'); cm.setOption('disableInput', true); From b216b2ae780b87028c7cce3e3425182cbc0e9e4c Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 16 Oct 2014 09:32:54 +0400 Subject: [PATCH 08/71] [vim] simplify selectBlock function --- keymap/vim.js | 142 ++++++++++++++----------------------------------------- test/vim_test.js | 11 ++++- 2 files changed, 46 insertions(+), 107 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index e1ff9469b6..ee682e3cf0 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -2669,121 +2669,51 @@ // Distance between selectionEnd.ch and any(first considered here) selection.ch function selectBlock(cm, selectionEnd) { var selections = [], ranges = cm.listSelections(); - var firstRange = ranges[0].anchor, lastRange = ranges[ranges.length-1].anchor; - var start, end, direction, selectionStart; - var curEnd = cm.getCursor('head'); - var originalSelectionEnd = copyCursor(selectionEnd); - start = firstRange.line; - end = lastRange.line; - if (selectionEnd.line < curEnd.line) { - direction = 'up'; - } else if (selectionEnd.line > curEnd.line) { - direction = 'down'; - } else { - if (selectionEnd.ch != curEnd.ch) { - direction = selectionEnd.ch > curEnd.ch ? 'right' : 'left'; - } - selectionStart = cm.getCursor('anchor'); - } - var primIndex = getIndex(ranges, curEnd); - // sets to true when selectionEnd already lies inside the existing selections - selectionEnd = cm.clipPos(selectionEnd); - var contains = getIndex(ranges, selectionEnd) < 0 ? false : true; - var isClipped = !cursorEqual(originalSelectionEnd, selectionEnd); - // This function helps to check selection crossing - // in case of short lines. - var processSelectionCrossing = function() { - if (isClipped) { - if (curEnd.ch >= selectionStart.ch) { - selectionStart.ch++; - } - } else if (curEnd.ch == lineLength(cm, curEnd.line)) { - if (cursorEqual(ranges[primIndex].anchor, ranges[primIndex].head) && ranges.length>1) { - if (direction == 'up') { - if (contains || primIndex>0) { - start = firstRange.line; - end = selectionEnd.line; - selectionStart = ranges[primIndex-1].anchor; - } - } else { - if (contains || primIndex == 0) { - end = lastRange.line; - start = selectionEnd.line; - selectionStart = ranges[primIndex+1].anchor; - } - } - if (selectionEnd.ch >= selectionStart.ch) { - selectionStart.ch--; - } - } - } - }; - switch(direction) { - case 'up': - start = contains ? firstRange.line : selectionEnd.line; - end = contains ? selectionEnd.line : lastRange.line; - selectionStart = lastRange; - processSelectionCrossing(); - break; - case 'down': - start = contains ? selectionEnd.line : firstRange.line; - end = contains ? lastRange.line : selectionEnd.line; - selectionStart = firstRange; - processSelectionCrossing(); - break; - case 'left': - if ((selectionEnd.ch <= selectionStart.ch) && (curEnd.ch > selectionStart.ch)) { - selectionStart.ch++; - selectionEnd.ch--; - } - break; - case 'right': - if ((selectionStart.ch <= selectionEnd.ch) && (curEnd.ch < selectionStart.ch)) { - selectionStart.ch--; - selectionEnd.ch++; - } - break; - default: - start = selectionStart.line; - end = selectionEnd.line; - } - while (start <= end) { - var anchor = {line: start, ch: selectionStart.ch}; - var head = {line: start, ch: selectionEnd.ch}; - var range = {anchor: anchor, head: head}; + var head = copyCursor(cm.clipPos(selectionEnd)); + var isClipped = !cursorEqual(selectionEnd, head); + var curHead = cm.getCursor('head'); + var primIndex = getIndex(ranges, curHead); + var wasClipped = cursorEqual(ranges[primIndex].head, ranges[primIndex].anchor); + var max = ranges.length - 1; + var index = max - primIndex > primIndex ? max : 0; + var base = ranges[index].anchor; + + var firstLine = Math.min(base.line, head.line); + var lastLine = Math.max(base.line, head.line); + var baseCh = base.ch, headCh = head.ch; + + var dir = ranges[index].head.ch - baseCh; + var newDir = headCh - baseCh; + if (dir > 0 && newDir <= 0) { + baseCh++; + if (!isClipped) { headCh--; } + } else if (dir < 0 && newDir >= 0) { + baseCh--; + if (!wasClipped) { headCh++; } + } else if (dir < 0 && newDir == -1) { + baseCh--; + headCh++; + } + for (var line = firstLine; line <= lastLine; line++) { + var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)}; selections.push(range); - if (cursorEqual(head, selectionEnd)) { - primIndex = selections.indexOf(range); - } - start++; - } - // Update selectionEnd and selectionStart - // after selection crossing - selectionEnd.ch = selections[0].head.ch; - selectionStart.ch = selections[0].anchor.ch; - if (cursorEqual(selectionEnd, selections[0].head)) { - selectionStart.line = selections[selections.length-1].anchor.line; - } else { - selectionStart.line = selections[0].anchor.line; } + primIndex = head.line == lastLine ? selections.length - 1 : 0; cm.setSelections(selections, primIndex); - return selectionStart; + selectionEnd.ch = headCh; + base.ch = baseCh; + return base; } // getIndex returns the index of the cursor in the selections. function getIndex(ranges, cursor, end) { - var pos = -1; for (var i = 0; i < ranges.length; i++) { - var atAnchor = cursorEqual(ranges[i].anchor, cursor); - var atHead = cursorEqual(ranges[i].head, cursor); - if (end == 'head') { - pos = atHead ? i : pos; - } else if (end == 'anchor') { - pos = atAnchor ? i : pos; - } else { - pos = (atAnchor || atHead) ? i : pos; + var atAnchor = end != 'head' && cursorEqual(ranges[i].anchor, cursor); + var atHead = end != 'anchor' && cursorEqual(ranges[i].head, cursor); + if (atAnchor || atHead) { + return i; } } - return pos; + return -1; } function getSelectedAreaRange(cm, vim) { var lastSelection = vim.lastSelection; diff --git a/test/vim_test.js b/test/vim_test.js index 401172b649..5a2912bef4 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -1757,11 +1757,20 @@ testVim('visual_block_crossing_short_line', function(cm, vim, helpers) { helpers.doKeys('3', 'k'); selections = cm.getSelections().join(); eq('4', selections); -}, {value: '123456\n78\nabcdefg\nfoobar'}); + helpers.doKeys('5', 'j', 'k'); + selections = cm.getSelections().join(""); + eq(10, selections.length); +}, {value: '123456\n78\nabcdefg\nfoobar\n}\n'}); testVim('visual_block_curPos_on_exit', function(cm, vim, helpers) { cm.setCursor(0, 0); helpers.doKeys('', '3' , 'l', ''); eqPos(makeCursor(0, 3), cm.getCursor()); + helpers.doKeys('h', '', '2' , 'j' ,'3' , 'l'); + eq(cm.getSelections().join(), "3456,,cdef"); + helpers.doKeys('4' , 'h'); + eq(cm.getSelections().join(), "23,8,bc"); + helpers.doKeys('2' , 'l'); + eq(cm.getSelections().join(), "34,,cd"); }, {value: '123456\n78\nabcdefg\nfoobar'}); testVim('visual_marks', function(cm, vim, helpers) { From 56dc38e94072122d5bdc86940eec8b7b8e04f076 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 24 Oct 2014 21:10:48 +0200 Subject: [PATCH 09/71] Link to new discussion forum --- CONTRIBUTING.md | 4 ++-- index.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47006a17f4..c4296ce4d2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ ## Getting help Community discussion, questions, and informal bug reporting is done on the -[CodeMirror Google group](http://groups.google.com/group/codemirror). +[discuss.CodeMirror forum](http://discuss.codemirror.net). ## Submitting bug reports @@ -17,7 +17,7 @@ reporting a bug, read these pointers. **Note:** The issue tracker is for *bugs*, not requests for help. Questions should be asked on the -[CodeMirror Google group](http://groups.google.com/group/codemirror) instead. +[discuss.CodeMirror forum](http://discuss.codemirror.net) instead. ### Reporting bugs effectively diff --git a/index.html b/index.html index 0a9f1338fd..8dcd378332 100644 --- a/index.html +++ b/index.html @@ -165,7 +165,7 @@ license that CodeMirror uses.

Discussion around the project is done on - a mailing list. + a discussion forum. There is also the codemirror-announce list, which is only used for major announcements (such as new From eac6c9b34aab86cc10a10b2cd4377dd5f5431ffd Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 22 Oct 2014 21:40:55 +0400 Subject: [PATCH 10/71] [vim] improve handling of external selections --- keymap/vim.js | 31 ++++++++++++++++++------------- test/vim_test.js | 3 ++- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index ee682e3cf0..c58de9d44d 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -706,8 +706,11 @@ return true; } - if (vim.insertMode) { return handleKeyInsertMode(); } - else { return handleKeyNonInsertMode(); } + return cm.operation(function() { + cm.curOp.isVimOp = true; + if (vim.insertMode) { return handleKeyInsertMode(); } + else { return handleKeyNonInsertMode(); } + }); }, handleEx: function(cm, input) { exCommandDispatcher.processCommand(cm, input); @@ -2100,7 +2103,6 @@ // equal to the repeat times the size of the previous visual // operation. if (!vim.visualMode) { - cm.on('mousedown', exitVisualMode); vim.visualMode = true; vim.visualLine = !!actionArgs.linewise; vim.visualBlock = !!actionArgs.blockwise; @@ -2820,7 +2822,6 @@ } function exitVisualMode(cm) { - cm.off('mousedown', exitVisualMode); var vim = cm.state.vim; var selectionStart = cm.getCursor('anchor'); var selectionEnd = cm.getCursor('head'); @@ -4655,9 +4656,7 @@ // Cursor moved outside the context of an edit. Reset the change. lastChange.changes = []; } - } else if (cm.doc.history.lastSelOrigin == '*mouse') { - // Reset lastHPos if mouse click was done in normal mode. - vim.lastHPos = cm.doc.getCursor().ch; + } else { handleExternalSelection(cm, vim); } if (vim.visualMode) { @@ -4680,16 +4679,22 @@ function handleExternalSelection(cm, vim) { var anchor = cm.getCursor('anchor'); var head = cm.getCursor('head'); - // Enter visual mode when the mouse selects text. - if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) { + // Enter or exit visual mode to match mouse selection. + if (vim.visualMode && cursorEqual(head, anchor) && lineLength(cm, head.line) > head.ch) { + exitVisualMode(cm); + } else if (!cm.curOp.isVimOp && !vim.visualMode && !vim.insertMode && cm.somethingSelected()) { vim.visualMode = true; vim.visualLine = false; CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"}); - cm.on('mousedown', exitVisualMode); } - if (vim.visualMode) { - updateMark(cm, vim, '<', cursorMin(head, anchor)); - updateMark(cm, vim, '>', cursorMax(head, anchor)); + if (!cm.curOp.isVimOp) { + if (vim.visualMode) { + updateMark(cm, vim, '<', cursorMin(head, anchor)); + updateMark(cm, vim, '>', cursorMax(head, anchor)); + } else if (!vim.insertMode) { + // Reset lastHPos if selection was modified by something outside of vim mode e.g. by mouse. + vim.lastHPos = cm.getCursor().ch; + } } } diff --git a/test/vim_test.js b/test/vim_test.js index 5a2912bef4..a88d02725e 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -1736,7 +1736,7 @@ testVim('visual_block', function(cm, vim, helpers) { // switch between visual modes cm.setCursor(1, 1); // blockwise to characterwise visual - helpers.doKeys('', '', 'j', 'l', 'v'); + helpers.doKeys('', 'j', 'l', 'v'); selections = cm.getSelections(); eq('7891\nabc', selections.join('')); // characterwise to blockwise @@ -1785,6 +1785,7 @@ testVim('visual_marks', function(cm, vim, helpers) { testVim('visual_join', function(cm, vim, helpers) { helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J'); eq(' 1 2 3\n 4\n 5', cm.getValue()); + is(!vim.visualMode); }, { value: ' 1\n 2\n 3\n 4\n 5' }); testVim('visual_blank', function(cm, vim, helpers) { helpers.doKeys('v', 'k'); From 5a78462df6b4f70664fd6a6df0933c527cf2df3c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 27 Oct 2014 10:30:12 +0100 Subject: [PATCH 11/71] [real-world uses] Add three links --- doc/realworld.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/realworld.html b/doc/realworld.html index 362408f72b..e9b6d45cce 100644 --- a/doc/realworld.html +++ b/doc/realworld.html @@ -121,6 +121,7 @@

  • Paper.js (graphics scripting)
  • PrinBit (collaborative coding tool)
  • Prose.io (github content editor)
  • +
  • PubliForge (online publishing system)
  • Puzzlescript (puzzle game engine)
  • ql.io (http API query helper)
  • QiYun web app platform
  • @@ -133,6 +134,7 @@
  • Shadertoy (shader sharing)
  • sketchPatch Livecodelab
  • Skulpt (in-browser Python environment)
  • +
  • Snap Tomato (HTML editing/testing page)
  • Snippets.pro (code snippet sharing)
  • SolidShops (hosted e-commerce platform)
  • SQLFiddle (SQL playground)
  • @@ -153,6 +155,7 @@
  • WebGL playground
  • WebKit Web inspector
  • WeScheme (learning tool)
  • +
  • Wide (golang web IDE)
  • WordPress plugin
  • writeLaTeX (Collaborative LaTeX Editor)
  • XOSide (online editor)
  • From 514b5bfc007a4339d86300ee271ab662ed0599a7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 27 Oct 2014 11:50:13 +0100 Subject: [PATCH 12/71] Allow calling the constructor with null as place Issue #2893 --- lib/codemirror.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 9d6902ba96..6bfbbf5cda 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -184,8 +184,10 @@ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). if (ie && ie_version < 8) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px"; - if (place.appendChild) place.appendChild(d.wrapper); - else place(d.wrapper); + if (place) { + if (place.appendChild) place.appendChild(d.wrapper); + else place(d.wrapper); + } // Current rendered range (may be bigger than the view window). d.viewFrom = d.viewTo = doc.first; From 4902d070c9ba400d2b312733861c32a51ec8cfd1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 27 Oct 2014 14:12:00 +0100 Subject: [PATCH 13/71] [vim mode] Don't directly access .options --- keymap/vim.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index c58de9d44d..832710ca0c 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -2271,11 +2271,12 @@ return; } if (actionArgs.matchIndent) { - // length that considers tabs and cm.options.tabSize + var tabSize = cm.getOption("tabSize"); + // length that considers tabs and tabSize var whitespaceLength = function(str) { var tabs = (str.split("\t").length - 1); var spaces = (str.split(" ").length - 1); - return tabs * cm.options.tabSize + spaces * 1; + return tabs * tabSize + spaces * 1; }; var currentLine = cm.getLine(cm.getCursor().line); var indent = whitespaceLength(currentLine.match(/^\s*/)[0]); @@ -2288,8 +2289,8 @@ if (newIndent < 0) { return ""; } - else if (cm.options.indentWithTabs) { - var quotient = Math.floor(newIndent / cm.options.tabSize); + else if (cm.getOption("indentWithTabs")) { + var quotient = Math.floor(newIndent / tabSize); return Array(quotient + 1).join('\t'); } else { @@ -2451,7 +2452,7 @@ replaceWithStr = replaceWithStr.replace(/[^\n]/g, replaceWith); if (vim.visualBlock) { // Tabs are split in visua block before replacing - var spaces = new Array(cm.options.tabSize+1).join(' '); + var spaces = new Array(cm.getOption("tabSize")+1).join(' '); replaceWithStr = cm.getSelection(); replaceWithStr = replaceWithStr.replace(/\t/g, spaces).replace(/[^\n]/g, replaceWith).split('\n'); cm.replaceSelections(replaceWithStr); From f2459b2867e982a30e56ea32925f674e693072b8 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 27 Oct 2014 22:04:51 +0400 Subject: [PATCH 14/71] [vim] implement gu and gU --- keymap/vim.js | 49 ++++++++++++++++++------------------------------- test/vim_test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index 832710ca0c..0d6007246d 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -156,7 +156,9 @@ { keys: 'c', type: 'operator', operator: 'change' }, { keys: '>', type: 'operator', operator: 'indent', operatorArgs: { indentRight: true }}, { keys: '<', type: 'operator', operator: 'indent', operatorArgs: { indentRight: false }}, - { keys: 'g~', type: 'operator', operator: 'swapcase' }, + { keys: 'g~', type: 'operator', operator: 'changeCase' }, + { keys: 'gu', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, isEdit: true }, + { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true }, { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }}, { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }}, // Operator-Motion dual commands @@ -165,7 +167,7 @@ { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, operatorMotionArgs: { visualLine: true }}, { keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'moveToEol', motionArgs: { inclusive: true }, operatorMotionArgs: { visualLine: true }}, { keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, operatorMotionArgs: { visualLine: true }}, - { keys: '~', type: 'operatorMotion', operator: 'swapcase', operatorArgs: { shouldMoveCursor: true }, motion: 'moveByCharacters', motionArgs: { forward: true }}, + { keys: '~', type: 'operatorMotion', operator: 'changeCase', operatorArgs: { shouldMoveCursor: true }, motion: 'moveByCharacters', motionArgs: { forward: true }}, { keys: '', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' }, // Actions { keys: '', type: 'action', action: 'jumpListWalk', actionArgs: { forward: true }}, @@ -192,8 +194,8 @@ // Handle Replace-mode as a special case of insert mode. { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }}, { keys: 'u', type: 'action', action: 'undo', context: 'normal' }, - { keys: 'u', type: 'action', action: 'changeCase', actionArgs: {toLower: true}, context: 'visual', isEdit: true }, - { keys: 'U',type: 'action', action: 'changeCase', actionArgs: {toLower: false}, context: 'visual', isEdit: true }, + { keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true }, + { keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true }, { keys: '', type: 'action', action: 'redo' }, { keys: 'm', type: 'action', action: 'setMark' }, { keys: '"', type: 'action', action: 'setRegister' }, @@ -1915,17 +1917,24 @@ cm.setCursor(curStart); cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm)); }, - swapcase: function(cm, operatorArgs, _vim, _curStart, _curEnd, _curOriginal) { + changeCase: function(cm, operatorArgs, _vim, _curStart, _curEnd, _curOriginal) { var selections = cm.getSelections(); var ranges = cm.listSelections(); var swapped = []; + var toLower = operatorArgs.toLower; for (var j = 0; j < selections.length; j++) { var toSwap = selections[j]; var text = ''; - for (var i = 0; i < toSwap.length; i++) { - var character = toSwap.charAt(i); - text += isUpperCase(character) ? character.toLowerCase() : - character.toUpperCase(); + if (toLower === true) { + text = toSwap.toLowerCase(); + } else if (toLower === false) { + text = toSwap.toUpperCase(); + } else { + for (var i = 0; i < toSwap.length; i++) { + var character = toSwap.charAt(i); + text += isUpperCase(character) ? character.toLowerCase() : + character.toUpperCase(); + } } swapped.push(text); } @@ -2508,28 +2517,6 @@ } repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */); }, - changeCase: function(cm, actionArgs, vim) { - var selectionStart = getSelectedAreaRange(cm, vim)[0]; - var text = cm.getSelection(); - var lastSelectionCurEnd; - var blockSelection; - if (vim.lastSelection) { - // save the curEnd marker to avoid its removal due to cm.replaceRange - lastSelectionCurEnd = vim.lastSelection.curEndMark.find(); - blockSelection = vim.lastSelection.visualBlock; - } - var toLower = actionArgs.toLower; - text = toLower ? text.toLowerCase() : text.toUpperCase(); - cm.replaceSelections(vim.visualBlock || blockSelection ? text.split('\n') : [text]); - // restore the last selection curEnd marker - if (lastSelectionCurEnd) { - vim.lastSelection.curEndMark = cm.setBookmark(lastSelectionCurEnd); - } - cm.setCursor(selectionStart); - if (vim.visualMode) { - exitVisualMode(cm); - } - }, exitInsertMode: exitInsertMode }; diff --git a/test/vim_test.js b/test/vim_test.js index a88d02725e..12cafa1193 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -957,6 +957,32 @@ testVim('g~g~', function(cm, vim, helpers) { is(!register.linewise); eqPos({line: curStart.line, ch:0}, cm.getCursor()); }, { value: ' word1\nword2\nword3\nword4\nword5\nword6' }); +testVim('gu_and_gU', function(cm, vim, helpers) { + var curStart = makeCursor(0, 7); + var value = cm.getValue(); + cm.setCursor(curStart); + helpers.doKeys('2', 'g', 'U', 'w'); + eq(cm.getValue(), 'wa wb xX WC wd'); + eqPos(curStart, cm.getCursor()); + helpers.doKeys('2', 'g', 'u', 'w'); + eq(cm.getValue(), value); + + helpers.doKeys('2', 'g', 'U', 'B'); + eq(cm.getValue(), 'wa WB Xx wc wd'); + eqPos(makeCursor(0, 3), cm.getCursor()); + + cm.setCursor(makeCursor(0, 4)); + helpers.doKeys('g', 'u', 'i', 'w'); + eq(cm.getValue(), 'wa wb Xx wc wd'); + eqPos(makeCursor(0, 3), cm.getCursor()); + + // TODO: support gUgU guu + // eqPos(makeCursor(0, 0), cm.getCursor()); + + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); +}, { value: 'wa wb xx wc wd' }); testVim('visual_block_~', function(cm, vim, helpers) { cm.setCursor(1, 1); helpers.doKeys('', 'l', 'l', 'j', '~'); From f1870d8e72fbcdfdd8c079461488c5e3d3bff3b1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 28 Oct 2014 12:11:10 +0100 Subject: [PATCH 15/71] Support attach and detach methods for key maps And adjust vim mode to use these. --- demo/vim.html | 2 +- keymap/vim.js | 81 ++++++++++++++++++++++++++++++++++++------------------ lib/codemirror.css | 4 +-- lib/codemirror.js | 24 +++++++++------- 4 files changed, 72 insertions(+), 39 deletions(-) diff --git a/demo/vim.html b/demo/vim.html index d637c5c869..6a33a6c075 100644 --- a/demo/vim.html +++ b/demo/vim.html @@ -80,7 +80,7 @@ var editor = CodeMirror.fromTextArea(document.getElementById("code"), { lineNumbers: true, mode: "text/x-csrc", - vimMode: true, + keyMap: "vim", matchBrackets: true, showCursorWhenSelecting: true }); diff --git a/keymap/vim.js b/keymap/vim.js index 0d6007246d..14affb1ae9 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -273,26 +273,48 @@ } } - CodeMirror.defineOption('vimMode', false, function(cm, val) { - if (val) { - cm.setOption('keyMap', 'vim'); - cm.setOption('disableInput', true); - cm.setOption('showCursorWhenSelecting', false); - CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); - cm.on('cursorActivity', onCursorActivity); - maybeInitVimState(cm); - CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm)); - cm.on('keypress', handleKeyPress); - cm.on('keydown', handleKeyDown); - } else if (cm.state.vim) { - cm.setOption('keyMap', 'default'); - cm.setOption('disableInput', false); - cm.off('cursorActivity', onCursorActivity); - CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); - cm.state.vim = null; - cm.off('keypress', handleKeyPress); - cm.off('keydown', handleKeyDown); - } + function enterVimMode(cm) { + cm.setOption('disableInput', true); + cm.setOption('showCursorWhenSelecting', false); + CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); + cm.on('cursorActivity', onCursorActivity); + maybeInitVimState(cm); + CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm)); + cm.on('keypress', handleKeyPress); + cm.on('keydown', handleKeyDown); + CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor"); + } + + function leaveVimMode(cm) { + cm.setOption('disableInput', false); + cm.off('cursorActivity', onCursorActivity); + CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); + cm.state.vim = null; + cm.off('keypress', handleKeyPress); + cm.off('keydown', handleKeyDown); + } + + function detachVimMap(cm, next) { + if (this == CodeMirror.keyMap.vim) + CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor"); + + if (!next || next.attach != attachVimMap) + leaveVimMode(cm, false); + } + function attachVimMap(cm, prev) { + if (this == CodeMirror.keyMap.vim) + CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor"); + + if (!prev || prev.attach != attachVimMap) + enterVimMode(cm); + } + + // Deprecated, simply setting the keymap works again. + CodeMirror.defineOption('vimMode', false, function(cm, val, prev) { + if (val && cm.getOption("keyMap") != "vim") + cm.setOption("keyMap", "vim"); + else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption("keyMap"))) + cm.setOption("keyMap", "default"); }); function getOnPasteFn(cm) { var vim = cm.state.vim; @@ -4468,9 +4490,10 @@ } CodeMirror.keyMap.vim = { - 'nofallthrough': true, - 'style': 'fat-cursor' - }; + nofallthrough: true, + attach: attachVimMap, + detach: detachVimMap + }; function exitInsertMode(cm) { var vim = cm.state.vim; @@ -4540,16 +4563,22 @@ CodeMirror.commands.newlineAndIndent; fn(cm); }, - fallthrough: ['default'] + fallthrough: ['default'], + attach: attachVimMap, + detach: detachVimMap }; CodeMirror.keyMap['await-second'] = { - fallthrough: ['vim-insert'] + fallthrough: ['vim-insert'], + attach: attachVimMap, + detach: detachVimMap }; CodeMirror.keyMap['vim-replace'] = { 'Backspace': 'goCharLeft', - fallthrough: ['vim-insert'] + fallthrough: ['vim-insert'], + attach: attachVimMap, + detach: detachVimMap }; function executeMacroRegister(cm, vim, macroModeState, registerName) { diff --git a/lib/codemirror.css b/lib/codemirror.css index af9e0f26e6..074dd41b12 100644 --- a/lib/codemirror.css +++ b/lib/codemirror.css @@ -52,12 +52,12 @@ .CodeMirror div.CodeMirror-secondarycursor { border-left: 1px solid silver; } -.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { +.CodeMirror.cm-fat-cursor div.CodeMirror-cursor { width: auto; border: 0; background: #7e7; } -.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursors { +.CodeMirror.cm-fat-cursor div.CodeMirror-cursors { z-index: 1; } diff --git a/lib/codemirror.js b/lib/codemirror.js index 6bfbbf5cda..4ec22f66de 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -303,10 +303,13 @@ }); } - function keyMapChanged(cm) { - var map = keyMap[cm.options.keyMap], style = map.style; - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") + - (style ? " cm-keymap-" + style : ""); + function keyMapChanged(cm, old) { + if (old == cm.options.keyMap) return; + + old = (old == CodeMirror.Init) ? null : getKeyMap(old); + var map = getKeyMap(cm.options.keyMap); + if (old && old.detach) old.detach(cm, map); + if (map.attach) map.attach(cm, old); } function themeChanged(cm) { @@ -3185,8 +3188,9 @@ clearTimeout(maybeTransition); if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() { if (getKeyMap(cm.options.keyMap) == startMap) { + var old = cm.options.keyMap; cm.options.keyMap = (next.call ? next.call(null, cm) : next); - keyMapChanged(cm); + keyMapChanged(cm, old); } }, 50); @@ -4504,7 +4508,7 @@ themeChanged(cm); guttersChanged(cm); }, true); - option("keyMap", "default", keyMapChanged); + option("keyMap", "default", function(cm, val, old) { keyMapChanged(cm, old); }); option("extraKeys", null); option("lineWrapping", false, wrappingChanged, true); @@ -7375,13 +7379,13 @@ }; function classTest(cls) { return new RegExp("\\b" + cls + "\\b\\s*"); } - function rmClass(node, cls) { + var rmClass = CodeMirror.rmClass = function(node, cls) { var test = classTest(cls); if (test.test(node.className)) node.className = node.className.replace(test, ""); - } - function addClass(node, cls) { + }; + var addClass = CodeMirror.addClass = function(node, cls) { if (!classTest(cls).test(node.className)) node.className += " " + cls; - } + }; function joinClasses(a, b) { var as = a.split(" "); for (var i = 0; i < as.length; i++) From b077d68ae1a731f0685f615db1664f3507751079 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 28 Oct 2014 16:22:18 +0100 Subject: [PATCH 16/71] Allow non-normalized keys and multi-stroke keys in keymaps As long as CodeMirror.normalizeKeyMap is called on them before they are used. This interface is a little weird, but backwards-compatible. --- demo/sublime.html | 11 +-- keymap/emacs.js | 47 +++++------ keymap/sublime.js | 29 ++++--- keymap/vim.js | 5 +- lib/codemirror.js | 239 ++++++++++++++++++++++++++++++++---------------------- test/vim_test.js | 4 +- 6 files changed, 182 insertions(+), 153 deletions(-) diff --git a/demo/sublime.html b/demo/sublime.html index 4cedbcd623..b3b5342c97 100644 --- a/demo/sublime.html +++ b/demo/sublime.html @@ -53,14 +53,11 @@ - + From ebc66a348e4f3449ac6470eb02b2e07989492a62 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 29 Oct 2014 22:08:16 +0100 Subject: [PATCH 21/71] [closebrackets addon] Count quotes as okay to autoclose in front of --- addon/edit/closebrackets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/edit/closebrackets.js b/addon/edit/closebrackets.js index 32eca014c5..f6b42f02d3 100644 --- a/addon/edit/closebrackets.js +++ b/addon/edit/closebrackets.js @@ -71,7 +71,7 @@ }; var closingBrackets = ""; for (var i = 0; i < pairs.length; i += 2) (function(left, right) { - if (left != right) closingBrackets += right; + closingBrackets += right; map["'" + left + "'"] = function(cm) { if (cm.getOption("disableInput")) return CodeMirror.Pass; var ranges = cm.listSelections(), type, next; From aaec99e351229c71db938720e2e6c4e0e7c9c1ad Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 30 Oct 2014 10:41:27 +0100 Subject: [PATCH 22/71] Work around Webkit wrapping issue Issue #2901 --- lib/codemirror.css | 3 +++ lib/codemirror.js | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/lib/codemirror.css b/lib/codemirror.css index 074dd41b12..eba9a5d8b5 100644 --- a/lib/codemirror.css +++ b/lib/codemirror.css @@ -306,5 +306,8 @@ div.CodeMirror-cursors { } } +/* See issue #2901 */ +.cm-tab-wrap-hack:after { content: ''; } + /* Help users use markselection to safely style text background */ span.CodeMirror-selectedtext { background: none; } diff --git a/lib/codemirror.js b/lib/codemirror.js index 98ba04d994..a3079206ef 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -6015,9 +6015,14 @@ } } + // See issue #2901 + if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className)) + builder.content.className = "cm-tab-wrap-hack"; + signal(cm, "renderLine", cm, lineView.line, builder.pre); if (builder.pre.className) builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); + return builder; } From 117e25294d91b947099d46a01b71f79773bb567e Mon Sep 17 00:00:00 2001 From: Travis Heppe Date: Fri, 31 Oct 2014 13:37:38 -0700 Subject: [PATCH 23/71] Workaround for an error in getting to insert mode. It was very difficult to reproduce, and I don't know what led to it, but the ">" mark was set but returned undefined when find() was called. This should work around the problem if it happens again. --- keymap/vim.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/keymap/vim.js b/keymap/vim.js index ff71568847..6da449a5c1 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -1816,7 +1816,10 @@ lastInsertModeChanges.inVisualBlock = visualBlock; var replacement = new Array(selections.length).join('1').split('1'); // save the selectionEnd mark - var selectionEnd = vim.marks['>'] ? vim.marks['>'].find() : cm.getCursor('head'); + var selectionEnd = vim.marks[">"] && vim.marks[">"].find(); + if (!selectionEnd) { + selectionEnd = cm.getCursor("head"); + } vimGlobalState.registerController.pushText( operatorArgs.registerName, 'change', text, operatorArgs.linewise); From 2b8106f669c016e9d110d225f63fd23247b54f9b Mon Sep 17 00:00:00 2001 From: Yunchi Luo Date: Sun, 2 Nov 2014 18:52:53 -0500 Subject: [PATCH 24/71] [vim] Make vim fail more gracefully --- keymap/vim.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index 6da449a5c1..558e4c82a3 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -732,8 +732,14 @@ return cm.operation(function() { cm.curOp.isVimOp = true; - if (vim.insertMode) { return handleKeyInsertMode(); } - else { return handleKeyNonInsertMode(); } + try { + if (vim.insertMode) { return handleKeyInsertMode(); } + else { return handleKeyNonInsertMode(); } + } catch (e) { + // clear VIM state in case it's in a bad state. + cm.state.vim = undefined; + throw e; + } }); }, handleEx: function(cm, input) { From 8173af6f05fa18455399698afc1b99aa6a5cd7bd Mon Sep 17 00:00:00 2001 From: Andrea G Date: Sat, 1 Nov 2014 12:52:34 +0000 Subject: [PATCH 25/71] [3024-day theme] Change color of matching bracket The color white is not visible on the current backgroung --- theme/3024-day.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theme/3024-day.css b/theme/3024-day.css index ebf46fb4a5..3c01c2bf58 100644 --- a/theme/3024-day.css +++ b/theme/3024-day.css @@ -35,4 +35,4 @@ .cm-s-3024-day span.cm-error {background: #db2d20; color: #5c5855;} .cm-s-3024-day .CodeMirror-activeline-background {background: #e8f2ff !important;} -.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: #a16a94 !important;} From ef690441922a5ebf3e1e680e1e39011fe2ccaae7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 3 Nov 2014 11:58:33 +0100 Subject: [PATCH 26/71] [markdown mode] Don't call tokenizer of code-block mode at end of line Issue #2904 --- mode/markdown/markdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mode/markdown/markdown.js b/mode/markdown/markdown.js index 48464645bb..5aeb8cf320 100644 --- a/mode/markdown/markdown.js +++ b/mode/markdown/markdown.js @@ -208,7 +208,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { // try switching mode state.localMode = getMode(RegExp.$1); if (state.localMode) state.localState = state.localMode.startState(); - switchBlock(stream, state, local); + state.f = state.block = local; if (modeCfg.highlightFormatting) state.formatting = "code-block"; state.code = true; return getType(state); From 1e7cdbf82dc08d06f995cdbb3e265547fb114e3a Mon Sep 17 00:00:00 2001 From: Marcel Gerber Date: Fri, 31 Oct 2014 02:10:37 +0100 Subject: [PATCH 27/71] [markdown mode] Support leading whitespace in fencedCodeBlocks mode name --- mode/markdown/markdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mode/markdown/markdown.js b/mode/markdown/markdown.js index 5aeb8cf320..3d1673bee0 100644 --- a/mode/markdown/markdown.js +++ b/mode/markdown/markdown.js @@ -204,7 +204,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { state.f = state.inline; if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; return getType(state); - } else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) { + } else if (modeCfg.fencedCodeBlocks && stream.match(/^```[ \t]*([\w+#]*)/, true)) { // try switching mode state.localMode = getMode(RegExp.$1); if (state.localMode) state.localState = state.localMode.startState(); From 72cd628aad83ff2a8250ba7241d7613b67bd99f4 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 3 Nov 2014 13:35:41 +0100 Subject: [PATCH 28/71] [real-world uses] Add interactive SICP link --- doc/realworld.html | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/realworld.html b/doc/realworld.html index e9b6d45cce..8a87a0485b 100644 --- a/doc/realworld.html +++ b/doc/realworld.html @@ -138,6 +138,7 @@
  • Snippets.pro (code snippet sharing)
  • SolidShops (hosted e-commerce platform)
  • SQLFiddle (SQL playground)
  • +
  • Structure and Interpretation of Computer Programs, Interactive Version
  • SyBox (PHP playground)
  • TagSpaces (personal data manager)
  • The File Tree (collab editor)
  • From 0c60c433efb8e37fad42251c49e08ef5b63d9f62 Mon Sep 17 00:00:00 2001 From: Marcel Gerber Date: Fri, 31 Oct 2014 19:04:26 +0100 Subject: [PATCH 29/71] [markdown mode, mode meta info] Add mode aliases to meta.js, add more aliases Issue #2903 --- mode/gfm/index.html | 1 + mode/markdown/markdown.js | 30 +++++++++++++++++------------- mode/meta.js | 42 +++++++++++++++++++++--------------------- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/mode/gfm/index.html b/mode/gfm/index.html index 60d108c1ca..7e38c52d60 100644 --- a/mode/gfm/index.html +++ b/mode/gfm/index.html @@ -14,6 +14,7 @@ + +

    Objective-C example

    + +
    +

    Java example

    -

    MIME types defined: application/x-sparql-query.

    +

    MIME types defined: application/sparql-query.

    diff --git a/mode/sparql/sparql.js b/mode/sparql/sparql.js index 64dbb612c2..0d006dcd34 100644 --- a/mode/sparql/sparql.js +++ b/mode/sparql/sparql.js @@ -19,11 +19,18 @@ CodeMirror.defineMode("sparql", function(config) { return new RegExp("^(?:" + words.join("|") + ")$", "i"); } var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri", + "iri", "uri", "bnode", "count", "sum", "min", "max", "avg", "sample", + "group_concat", "rand", "abs", "ceil", "floor", "round", "concat", "substr", "strlen", + "replace", "ucase", "lcase", "encode_for_uri", "contains", "strstarts", "strends", + "strbefore", "strafter", "year", "month", "day", "hours", "minutes", "seconds", + "timezone", "tz", "now", "uuid", "struuid", "md5", "sha1", "sha256", "sha384", + "sha512", "coalesce", "if", "strlang", "strdt", "isnumeric", "regex", "exists", "isblank", "isliteral", "a"]); var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe", "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional", "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group", "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union", + "true", "false", "with", "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]); var operatorChars = /[*+\-<>=&|]/; @@ -44,7 +51,7 @@ CodeMirror.defineMode("sparql", function(config) { } else if (/[{}\(\),\.;\[\]]/.test(ch)) { curPunc = ch; - return null; + return "bracket"; } else if (ch == "#") { stream.skipToEnd(); @@ -52,12 +59,20 @@ CodeMirror.defineMode("sparql", function(config) { } else if (operatorChars.test(ch)) { stream.eatWhile(operatorChars); - return null; + return "operator"; } else if (ch == ":") { stream.eatWhile(/[\w\d\._\-]/); return "atom"; } + else if (ch == "@") { + stream.eatWhile(/[a-z\d\-]/i); + return "meta"; + } + else if (ch == "^") { + stream.eatWhile(/\^/); + return "meta"; + } else { stream.eatWhile(/[_\w\d]/); if (stream.eat(":")) { @@ -66,7 +81,7 @@ CodeMirror.defineMode("sparql", function(config) { } var word = stream.current(); if (ops.test(word)) - return null; + return "builtin"; else if (keywords.test(word)) return "keyword"; else @@ -155,6 +170,6 @@ CodeMirror.defineMode("sparql", function(config) { }; }); -CodeMirror.defineMIME("application/x-sparql-query", "sparql"); +CodeMirror.defineMIME("application/sparql-query", "sparql"); }); From 096a20aa459eceebd1c0e960b80d395998b46a47 Mon Sep 17 00:00:00 2001 From: "Nicholas Bollweg (Nick)" Date: Fri, 21 Nov 2014 22:05:12 -0500 Subject: [PATCH 70/71] [sparql mode] Property paths --- mode/sparql/index.html | 16 ++++++++++++---- mode/sparql/sparql.js | 9 ++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/mode/sparql/index.html b/mode/sparql/index.html index 02837ab346..84ef4d3639 100644 --- a/mode/sparql/index.html +++ b/mode/sparql/index.html @@ -29,15 +29,23 @@ PREFIX a: <http://www.w3.org/2000/10/annotation-ns#> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> +PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> # Comment! SELECT ?given ?family WHERE { - ?annot a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . - ?annot dc:creator ?c . - OPTIONAL {?c foaf:given ?given ; - foaf:family ?family } . + { + ?annot a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . + ?annot dc:creator ?c . + OPTIONAL {?c foaf:givenName ?given ; + foaf:familyName ?family } + } UNION { + ?c !foaf:knows/foaf:knows? ?thing. + ?thing rdfs + } MINUS { + ?thing rdfs:label "剛柔流"@jp + } FILTER isBlank(?c) } diff --git a/mode/sparql/sparql.js b/mode/sparql/sparql.js index 0d006dcd34..bbf8a76a0d 100644 --- a/mode/sparql/sparql.js +++ b/mode/sparql/sparql.js @@ -32,12 +32,15 @@ CodeMirror.defineMode("sparql", function(config) { "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union", "true", "false", "with", "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]); - var operatorChars = /[*+\-<>=&|]/; + var operatorChars = /[*+\-<>=&|\^\/!\?]/; function tokenBase(stream, state) { var ch = stream.next(); curPunc = null; if (ch == "$" || ch == "?") { + if(ch == "?" && stream.match(/\s/, false)){ + return "operator"; + } stream.match(/^[\w\d]*/); return "variable-2"; } @@ -69,10 +72,6 @@ CodeMirror.defineMode("sparql", function(config) { stream.eatWhile(/[a-z\d\-]/i); return "meta"; } - else if (ch == "^") { - stream.eatWhile(/\^/); - return "meta"; - } else { stream.eatWhile(/[_\w\d]/); if (stream.eat(":")) { From be9e01eedbf33282fe85ebec69d026e12a6e2959 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 22 Nov 2014 09:53:54 +0100 Subject: [PATCH 71/71] Mark version 4.8.0 --- AUTHORS | 10 ++++++++++ bower.json | 2 +- doc/compress.html | 1 + doc/manual.html | 2 +- doc/releases.html | 12 ++++++++++++ index.html | 2 +- lib/codemirror.js | 2 +- package.json | 2 +- 8 files changed, 28 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index c6e7505f2f..455d7e68a5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -32,6 +32,7 @@ anaran AndersMad Anders Nawroth Anderson Mesquita +Andrea G Andreas Reischuck Andre von Houck Andrey Fedorov @@ -87,6 +88,7 @@ ComFreek Curtis Gagliardi dagsta daines +Dale Jung Dan Heberden Daniel, Dao Quang Minh Daniele Di Sarli @@ -145,6 +147,7 @@ Golevka Gordon Smith Grant Skinner greengiant +Gregory Koberger Guillaume Massé Guillaume Massé Gustavo Rodrigues @@ -177,6 +180,7 @@ jankeromnes Jan Keromnes Jan Odvarko Jan T. Sott +Jared Forsyth Jason Jason Grout Jason Johnston @@ -187,6 +191,7 @@ Jean Boussier jeffkenton Jeff Pickhardt jem (graphite) +Jeremy Parmenter Jochen Berger Johan Ask John Connor @@ -230,6 +235,7 @@ LM lochel Lorenzo Stoakes Luciano Longo +Luke Stagner lynschinzer Maksim Lin Maksym Taran @@ -289,8 +295,10 @@ nextrevision nguillaumin Ng Zhi An Nicholas Bollweg +Nicholas Bollweg (Nick) Nick Small Niels van Groningen +nightwing Nikita Beloglazov Nikita Vasilyev Nikolay Kostov @@ -317,6 +325,7 @@ prasanthj Prasanth J Radek Piórkowski Rahul +Randy Burden Randy Edmunds Rasmus Erik Voel Jensen Richard van der Meer @@ -336,6 +345,7 @@ satchmorun sathyamoorthi SCLINIC\jdecker Scott Aikin +Scott Goodhew Sebastian Zaha shaund shaun gilchrist diff --git a/bower.json b/bower.json index 2704354d73..bf28a95f87 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"4.7.1", + "version":"4.8.0", "main": ["lib/codemirror.js", "lib/codemirror.css"], "ignore": [ "**/.*", diff --git a/doc/compress.html b/doc/compress.html index a727e45328..bab6255bb1 100644 --- a/doc/compress.html +++ b/doc/compress.html @@ -36,6 +36,7 @@

    Version: