From d07160c81d106731ef55dc04e7e8f3b83b22f117 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 22 Jan 2015 16:27:53 +0100 Subject: [PATCH 01/78] Bump version number post-4.12 --- 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 d378331c4c..7e30a06c6a 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"4.12.0", + "version":"4.12.1", "main": ["lib/codemirror.js", "lib/codemirror.css"], "ignore": [ "**/.*", diff --git a/doc/manual.html b/doc/manual.html index 909d1a6343..31a52dee12 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -63,7 +63,7 @@

User manual and reference guide - version 4.12.0 + version 4.12.1

CodeMirror is a code-editor component that can be embedded in diff --git a/lib/codemirror.js b/lib/codemirror.js index 03a34dbbfb..6723a1c42a 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -8039,7 +8039,7 @@ // THE END - CodeMirror.version = "4.12.0"; + CodeMirror.version = "4.12.1"; return CodeMirror; }); diff --git a/package.json b/package.json index 8f529cd925..89645861fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codemirror", - "version":"4.12.0", + "version":"4.12.1", "main": "lib/codemirror.js", "description": "In-browser code editing made bearable", "licenses": [{"type": "MIT", From 35830b92e7e4a5ce0b66f09c26d5bd4e96d19b40 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 22 Jan 2015 22:43:38 +0100 Subject: [PATCH 02/78] [selection-pointer addon] Also clear geometry on window scroll Closes #3040 --- addon/selection/selection-pointer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addon/selection/selection-pointer.js b/addon/selection/selection-pointer.js index 8cc0fc6860..ef5e404ad3 100644 --- a/addon/selection/selection-pointer.js +++ b/addon/selection/selection-pointer.js @@ -16,6 +16,7 @@ if (data) { CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove); CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout); + CodeMirror.off(window, "scroll", data.windowScroll); cm.off("cursorActivity", reset); cm.off("scroll", reset); cm.state.selectionPointer = null; @@ -26,12 +27,14 @@ value: typeof val == "string" ? val : "default", mousemove: function(event) { mousemove(cm, event); }, mouseout: function(event) { mouseout(cm, event); }, + windowScroll: function() { reset(cm); }, rects: null, mouseX: null, mouseY: null, willUpdate: false }; CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout); + CodeMirror.on(window, "scroll", data.windowScroll); cm.on("cursorActivity", reset); cm.on("scroll", reset); } From 076afcb14e8be635439e1689d8c3af2ffcfbce85 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 23 Jan 2015 11:05:23 +0100 Subject: [PATCH 03/78] [closetag addon] Properly pass through return value for / key handler So that the CodeMirror.Pass it will return actually ends up in the editor. --- addon/edit/closetag.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/edit/closetag.js b/addon/edit/closetag.js index 369bea30c4..e68d52d9dc 100644 --- a/addon/edit/closetag.js +++ b/addon/edit/closetag.js @@ -131,7 +131,7 @@ function autoCloseSlash(cm) { if (cm.getOption("disableInput")) return CodeMirror.Pass; - autoCloseCurrent(cm, true); + return autoCloseCurrent(cm, true); } CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); }; From b17c0b6adb91d44e6fb062619db409862a24f133 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Thu, 22 Jan 2015 20:43:42 -0800 Subject: [PATCH 04/78] [vim] fix join when 'head' before 'anchor' (closes #3042) --- keymap/vim.js | 5 +++++ test/vim_test.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/keymap/vim.js b/keymap/vim.js index 88a404a291..9f61fd7152 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -2183,6 +2183,11 @@ if (vim.visualMode) { curStart = cm.getCursor('anchor'); curEnd = cm.getCursor('head'); + if (cursorIsBefore(curEnd, curStart)) { + var tmp = curEnd; + curEnd = curStart; + curStart = tmp; + } curEnd.ch = lineLength(cm, curEnd.line) - 1; } else { // Repeat is the number of lines to join. Minimum 2 lines. diff --git a/test/vim_test.js b/test/vim_test.js index ea640efdac..1f5179a87d 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -1964,6 +1964,11 @@ testVim('visual_join', function(cm, vim, helpers) { 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_join_2', function(cm, vim, helpers) { + helpers.doKeys('G', 'V', 'g', 'g', 'J'); + eq('1 2 3 4 5 6 ', cm.getValue()); + is(!vim.visualMode); +}, { value: '1\n2\n3\n4\n5\n6\n'}); testVim('visual_blank', function(cm, vim, helpers) { helpers.doKeys('v', 'k'); eq(vim.visualMode, true); From c79549dd2f38c17c01654b19e0b98879249006cb Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Thu, 22 Jan 2015 22:48:59 -0800 Subject: [PATCH 05/78] [vim] set cursor position after exiting visual mode --- keymap/vim.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keymap/vim.js b/keymap/vim.js index 9f61fd7152..f5dabcd39b 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -2206,10 +2206,10 @@ cm.replaceRange(text, curStart, tmp); } var curFinalPos = Pos(curStart.line, finalCh); - cm.setCursor(curFinalPos); if (vim.visualMode) { exitVisualMode(cm); } + cm.setCursor(curFinalPos); }, newLineAndEnterInsertMode: function(cm, actionArgs, vim) { vim.insertMode = true; From 25fa71e7fd6b52a2cab8362e1f56774e44fe81f7 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Thu, 22 Jan 2015 22:57:14 -0800 Subject: [PATCH 06/78] [vim] don't move cursor on 'exitVisualMode' in many places --- keymap/vim.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index f5dabcd39b..dafd573831 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -1449,7 +1449,7 @@ var operatorMoveTo = operators[operator]( cm, operatorArgs, cmSel.ranges, oldAnchor, newHead); if (vim.visualMode) { - exitVisualMode(cm); + exitVisualMode(cm, operatorMoveTo); } if (operatorMoveTo) { cm.setCursor(operatorMoveTo); @@ -2207,7 +2207,7 @@ } var curFinalPos = Pos(curStart.line, finalCh); if (vim.visualMode) { - exitVisualMode(cm); + exitVisualMode(cm, false); } cm.setCursor(curFinalPos); }, @@ -2372,7 +2372,7 @@ } } if (vim.visualMode) { - exitVisualMode(cm); + exitVisualMode(cm, false); } cm.setCursor(curPosFinal); }, @@ -2430,7 +2430,7 @@ curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ? selections[0].anchor : selections[0].head; cm.setCursor(curStart); - exitVisualMode(cm); + exitVisualMode(cm, false); } else { cm.setCursor(offsetCursor(curEnd, 0, -1)); } From 790a7621a3ba46da868cfff272340beb49eba664 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Thu, 22 Jan 2015 23:00:54 -0800 Subject: [PATCH 07/78] [vim] better check re: operatorMoveTo truthiness --- keymap/vim.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keymap/vim.js b/keymap/vim.js index dafd573831..7a8704feef 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -1449,7 +1449,7 @@ var operatorMoveTo = operators[operator]( cm, operatorArgs, cmSel.ranges, oldAnchor, newHead); if (vim.visualMode) { - exitVisualMode(cm, operatorMoveTo); + exitVisualMode(cm, operatorMoveTo != null); } if (operatorMoveTo) { cm.setCursor(operatorMoveTo); From f1692af532b78b7aeacb9dfc1962e2443866f65b Mon Sep 17 00:00:00 2001 From: Yunchi Luo Date: Sat, 24 Jan 2015 10:56:30 -0500 Subject: [PATCH 08/78] [vim] Clip cursor position after delete --- keymap/vim.js | 2 +- test/vim_test.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index 7a8704feef..ee524fde74 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -1899,7 +1899,7 @@ vimGlobalState.registerController.pushText( args.registerName, 'delete', text, args.linewise, vim.visualBlock); - return finalHead; + return clipCursorToContent(cm, finalHead); }, indent: function(cm, args, ranges) { var vim = cm.state.vim; diff --git a/test/vim_test.js b/test/vim_test.js index 1f5179a87d..74013cbff4 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -597,7 +597,7 @@ testVim('dl_eol', function(cm, vim, helpers) { var register = helpers.getRegisterController().getRegister(); eq(' ', register.toString()); is(!register.linewise); - helpers.assertCursorAt(0, 6); + helpers.assertCursorAt(0, 5); }, { value: ' word1 ' }); testVim('dl_repeat', function(cm, vim, helpers) { var curStart = makeCursor(0, 0); @@ -688,7 +688,7 @@ testVim('dw_only_word', function(cm, vim, helpers) { var register = helpers.getRegisterController().getRegister(); eq('word1 ', register.toString()); is(!register.linewise); - helpers.assertCursorAt(0, 1); + helpers.assertCursorAt(0, 0); }, { value: ' word1 ' }); testVim('dw_eol', function(cm, vim, helpers) { // Assert that dw does not delete the newline if last word to delete is at end @@ -699,7 +699,7 @@ testVim('dw_eol', function(cm, vim, helpers) { var register = helpers.getRegisterController().getRegister(); eq('word1', register.toString()); is(!register.linewise); - helpers.assertCursorAt(0, 1); + helpers.assertCursorAt(0, 0); }, { value: ' word1\nword2' }); testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) { // Assert that dw does not delete the newline if last word to delete is at end @@ -710,7 +710,7 @@ testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) { var register = helpers.getRegisterController().getRegister(); eq('word1', register.toString()); is(!register.linewise); - helpers.assertCursorAt(0, 1); + helpers.assertCursorAt(0, 0); }, { value: ' word1\n\nword2' }); testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) { cm.setCursor(0, 0); @@ -756,7 +756,7 @@ testVim('dw_repeat', function(cm, vim, helpers) { var register = helpers.getRegisterController().getRegister(); eq('word1\nword2', register.toString()); is(!register.linewise); - helpers.assertCursorAt(0, 1); + helpers.assertCursorAt(0, 0); }, { value: ' word1\nword2' }); testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) { cm.setCursor(0, 0); @@ -1283,7 +1283,7 @@ testVim('D', function(cm, vim, helpers) { var register = helpers.getRegisterController().getRegister(); eq('rd1', register.toString()); is(!register.linewise); - helpers.assertCursorAt(0, 3); + helpers.assertCursorAt(0, 2); }, { value: ' word1\nword2\n word3' }); testVim('C', function(cm, vim, helpers) { var curStart = makeCursor(0, 3); From e94159ec9b214873dd818ce2ee90bb708a1edbb1 Mon Sep 17 00:00:00 2001 From: Aliaksei Chapyzhenka Date: Sun, 25 Jan 2015 15:20:31 -0800 Subject: [PATCH 09/78] [forth mode] Add --- mode/forth/forth.js | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 mode/forth/forth.js diff --git a/mode/forth/forth.js b/mode/forth/forth.js new file mode 100644 index 0000000000..d08c6f0bdc --- /dev/null +++ b/mode/forth/forth.js @@ -0,0 +1,180 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Author: Aliaksei Chapyzhenka + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function toWordList(words) { + var ret = []; + words.split(' ').forEach(function(e){ + ret.push({name: e}); + }); + return ret; + } + + var coreWordList = toWordList( +'INVERT AND OR XOR\ + 2* 2/ LSHIFT RSHIFT\ + 0= = 0< < > U< MIN MAX\ + 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP\ + >R R> R@\ + + - 1+ 1- ABS NEGATE\ + S>D * M* UM*\ + FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD\ + HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2!\ + ALIGN ALIGNED +! ALLOT\ + CHAR [CHAR] [ ] BL\ + FIND EXECUTE IMMEDIATE COUNT LITERAL STATE\ + ; DOES> >BODY\ + EVALUATE\ + SOURCE >IN\ + <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL\ + FILL MOVE\ + . CR EMIT SPACE SPACES TYPE U. .R U.R\ + ACCEPT\ + TRUE FALSE\ + <> U> 0<> 0>\ + NIP TUCK ROLL PICK\ + 2>R 2R@ 2R>\ + WITHIN UNUSED MARKER\ + I J\ + TO\ + COMPILE, [COMPILE]\ + SAVE-INPUT RESTORE-INPUT\ + PAD ERASE\ + 2LITERAL DNEGATE\ + D- D+ D0< D0= D2* D2/ D< D= DMAX DMIN D>S DABS\ + M+ M*/ D. D.R 2ROT DU<\ + CATCH THROW\ + FREE RESIZE ALLOCATE\ + CS-PICK CS-ROLL\ + GET-CURRENT SET-CURRENT FORTH-WORDLIST GET-ORDER SET-ORDER\ + PREVIOUS SEARCH-WORDLIST WORDLIST FIND ALSO ONLY FORTH DEFINITIONS ORDER\ + -TRAILING /STRING SEARCH COMPARE CMOVE CMOVE> BLANK SLITERAL'); + + var immediateWordList = toWordList('IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE [IF] [ELSE] [THEN] ?DO DO LOOP +LOOP UNLOOP LEAVE EXIT AGAIN CASE OF ENDOF ENDCASE'); + + CodeMirror.defineMode('forth', function() { + function searchWordList (wordList, word) { + var i; + for (i = wordList.length - 1; i >= 0; i--) { + if (wordList[i].name === word.toUpperCase()) { + return wordList[i]; + } + } + return undefined; + } + return { + startState: function() { + return { + state: '', + base: 10, + coreWordList: coreWordList, + immediateWordList: immediateWordList, + wordList: [] + }; + }, + token: function (stream, stt) { + var mat; + if (stream.eatSpace()) { + return null; + } + if (stt.state === '') { // interpretation + if (stream.match(/^(\]|:NONAME)(\s|$)/i)) { + stt.state = ' compilation'; + return 'builtin compilation'; + } + mat = stream.match(/^(\:)\s+(\S+)(\s|$)+/); + if (mat) { + stt.wordList.push({name: mat[2].toUpperCase()}); + stt.state = ' compilation'; + return 'def' + stt.state; + } + mat = stream.match(/^(VARIABLE|2VARIABLE|CONSTANT|2CONSTANT|CREATE|POSTPONE|VALUE|WORD)\s+(\S+)(\s|$)+/i); + if (mat) { + stt.wordList.push({name: mat[2].toUpperCase()}); + return 'def' + stt.state; + } + mat = stream.match(/^(\'|\[\'\])\s+(\S+)(\s|$)+/); + if (mat) { + return 'builtin' + stt.state; + } + } else { // compilation + // ; [ + if (stream.match(/^(\;|\[)(\s)/)) { + stt.state = ''; + stream.backUp(1); + return 'builtin compilation'; + } + if (stream.match(/^(\;|\[)($)/)) { + stt.state = ''; + return 'builtin compilation'; + } + if (stream.match(/^(POSTPONE)\s+\S+(\s|$)+/)) { + return 'builtin'; + } + } + + // dynamic wordlist + mat = stream.match(/^(\S+)(\s+|$)/); + if (mat) { + if (searchWordList(stt.wordList, mat[1]) !== undefined) { + return 'variable' + stt.state; + } + + // comments + if (mat[1] === '\\') { + stream.skipToEnd(); + return 'comment' + stt.state; + } + + // core words + if (searchWordList(stt.coreWordList, mat[1]) !== undefined) { + return 'builtin' + stt.state; + } + if (searchWordList(stt.immediateWordList, mat[1]) !== undefined) { + return 'keyword' + stt.state; + } + + if (mat[1] === '(') { + stream.eatWhile(function (s) { return s !== ')'; }); + stream.eat(')'); + return 'comment' + stt.state; + } + + // // strings + if (mat[1] === '.(') { + stream.eatWhile(function (s) { return s !== ')'; }); + stream.eat(')'); + return 'string' + stt.state; + } + if (mat[1] === 'S"' || mat[1] === '."' || mat[1] === 'C"') { + stream.eatWhile(function (s) { return s !== '"'; }); + stream.eat('"'); + return 'string' + stt.state; + } + + // numbers + if (mat[1] - 0xfffffffff) { + return 'number' + stt.state; + } + // if (mat[1].match(/^[-+]?[0-9]+\.[0-9]*/)) { + // return 'number' + stt.state; + // } + + return 'atom' + stt.state; + } + } + }; + }); + CodeMirror.defineMIME("text/forth", "forth"); +}); From 0c10c7a72c79610fad7a79601227897a9ab0df0c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 27 Jan 2015 23:04:04 +0100 Subject: [PATCH 10/78] [forth mode] Integrate --- doc/compress.html | 1 + mode/forth/forth.js | 2 +- mode/index.html | 1 + mode/meta.js | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/compress.html b/doc/compress.html index cf785ef75a..b572c09dac 100644 --- a/doc/compress.html +++ b/doc/compress.html @@ -119,6 +119,7 @@ + diff --git a/mode/forth/forth.js b/mode/forth/forth.js index d08c6f0bdc..1f519d8862 100644 --- a/mode/forth/forth.js +++ b/mode/forth/forth.js @@ -176,5 +176,5 @@ } }; }); - CodeMirror.defineMIME("text/forth", "forth"); + CodeMirror.defineMIME("text/x-forth", "forth"); }); diff --git a/mode/index.html b/mode/index.html index c933e1e943..d934f7e0e9 100644 --- a/mode/index.html +++ b/mode/index.html @@ -51,6 +51,7 @@

  • ECL
  • Eiffel
  • Erlang
  • +
  • Forth
  • Fortran
  • F#
  • Gas (AT&T-style assembly)
  • diff --git a/mode/meta.js b/mode/meta.js index 8d91df7d77..e110288afc 100644 --- a/mode/meta.js +++ b/mode/meta.js @@ -38,6 +38,7 @@ {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]}, {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]}, {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]}, + {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]}, {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]}, {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]}, {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]}, From 11a7c353077d9dac15a8d7de159165c2a3363805 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 29 Jan 2015 23:35:07 +0100 Subject: [PATCH 11/78] Wrap .focus() call in try/catch to avoid IE8 exception Issue #3052 --- lib/codemirror.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index 6723a1c42a..b89dc1c101 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -2611,8 +2611,10 @@ } function focusInput(cm) { - if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input)) - cm.display.input.focus(); + if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input)) { + try { cm.display.input.focus(); } + catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM + } } function ensureFocus(cm) { From bb8f072c7e5840159ba816bae8163b759822d3f5 Mon Sep 17 00:00:00 2001 From: Aliaksei Chapyzhenka Date: Thu, 29 Jan 2015 23:59:22 +0100 Subject: [PATCH 12/78] [forth mode] Add demo page --- mode/forth/index.html | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 mode/forth/index.html diff --git a/mode/forth/index.html b/mode/forth/index.html new file mode 100644 index 0000000000..711d387cd8 --- /dev/null +++ b/mode/forth/index.html @@ -0,0 +1,67 @@ + + +CodeMirror: Forth mode + + + + + + + + + +
    + +

    Forth mode

    + +
    + + + +

    Simple mode that handle Forth-Syntax (Forth on WikiPedia).

    + +

    MIME types defined: text/x-forth.

    + +
    From 893a12e7ea3983d6f7a99d6e16f4aa7f00a6e699 Mon Sep 17 00:00:00 2001 From: Christian Petrov Date: Mon, 26 Jan 2015 10:15:20 +0100 Subject: [PATCH 13/78] [tern addon] open [doc] link in a new tab/window Opening the documentation in the same window navigates away from the code editor. --- addon/tern/tern.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addon/tern/tern.js b/addon/tern/tern.js index 86729e2d3f..80bf87cd43 100644 --- a/addon/tern/tern.js +++ b/addon/tern/tern.js @@ -252,7 +252,9 @@ tip.appendChild(document.createTextNode(" — " + data.doc)); if (data.url) { tip.appendChild(document.createTextNode(" ")); - tip.appendChild(elt("a", null, "[docs]")).href = data.url; + var child = tip.appendChild(elt("a", null, "[docs]")); + child.href = data.url; + child.target = "_blank"; } } tempTooltip(cm, tip); From 41a740b19baf1db5409a09844bcb45bf2235e908 Mon Sep 17 00:00:00 2001 From: Aliaksei Chapyzhenka Date: Tue, 27 Jan 2015 20:06:47 -0800 Subject: [PATCH 14/78] [colorforth theme] Add --- mode/forth/index.html | 14 +++++++++++--- theme/colorforth.css | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 theme/colorforth.css diff --git a/mode/forth/index.html b/mode/forth/index.html index 711d387cd8..ae8cd34584 100644 --- a/mode/forth/index.html +++ b/mode/forth/index.html @@ -4,10 +4,17 @@ + + - +