diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index c5d34aae..e941806b 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -97,24 +97,28 @@ exports.commands = [{ name: "fold", bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"), exec: function(editor) { editor.session.toggleFold(false); }, + multiSelectAction: "forEach", scrollIntoView: "center", readOnly: true }, { name: "unfold", bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"), exec: function(editor) { editor.session.toggleFold(true); }, + multiSelectAction: "forEach", scrollIntoView: "center", readOnly: true }, { name: "toggleFoldWidget", bindKey: bindKey("F2", "F2"), exec: function(editor) { editor.session.toggleFoldWidget(); }, + multiSelectAction: "forEach", scrollIntoView: "center", readOnly: true }, { name: "toggleParentFoldWidget", bindKey: bindKey("Alt-F2", "Alt-F2"), exec: function(editor) { editor.session.toggleFoldWidget(true); }, + multiSelectAction: "forEach", scrollIntoView: "center", readOnly: true }, { @@ -415,7 +419,7 @@ exports.commands = [{ readOnly: true }, { name: "passKeysToBrowser", - bindKey: bindKey("null", "null"), + bindKey: bindKey(null, null), exec: function() {}, passEvent: true, readOnly: true diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index be81f560..cef995c8 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -160,6 +160,8 @@ z-index: 1; position: absolute; overflow: hidden; + /* workaround for chrome bug https://github.com/ajaxorg/ace/issues/2312*/ + word-wrap: normal; white-space: pre; height: 100%; width: 100%; diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index b11ff05c..b35ea4e0 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -1580,13 +1580,11 @@ var EditSession = function(text, mode) { **/ this.setWrapLimitRange = function(min, max) { if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) { - this.$wrapLimitRange = { - min: min, - max: max - }; + this.$wrapLimitRange = { min: min, max: max }; this.$modified = true; // This will force a recalculation of the wrap limit - this._signal("changeWrapMode"); + if (this.$useWrapMode) + this._signal("changeWrapMode"); } }; @@ -2467,6 +2465,7 @@ config.defineOptions(EditSession.prototype, "session", { if (this.$wrap == value) return; + this.$wrap = value; if (!value) { this.setUseWrapMode(false); } else { @@ -2474,7 +2473,6 @@ config.defineOptions(EditSession.prototype, "session", { this.setWrapLimitRange(col, col); this.setUseWrapMode(true); } - this.$wrap = value; }, get: function() { if (this.getUseWrapMode()) { diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index a86c27ce..53071dda 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -794,7 +794,7 @@ function Folding() { this.foldAll(startRow, endRow, options.all ? 10000 : 0); } else if (options.children) { endRow = range ? range.end.row : this.getLength(); - this.foldAll(row + 1, range.end.row, options.all ? 10000 : 0); + this.foldAll(row + 1, endRow, options.all ? 10000 : 0); } else if (range) { if (options.all) range.collapseChildren = 10000; diff --git a/lib/ace/ext/error_marker.js b/lib/ace/ext/error_marker.js index 05d50498..5dbe3d2e 100644 --- a/lib/ace/ext/error_marker.js +++ b/lib/ace/ext/error_marker.js @@ -62,7 +62,7 @@ function findAnnotations(session, row, dir) { if (i < 0) i = -i - 1; - if (i >= annotations.length - 1) + if (i >= annotations.length) i = dir > 0 ? 0 : annotations.length - 1; else if (i === 0 && dir < 0) i = annotations.length - 1; diff --git a/lib/ace/keyboard/vim.js b/lib/ace/keyboard/vim.js index a8bba7ec..0641897f 100644 --- a/lib/ace/keyboard/vim.js +++ b/lib/ace/keyboard/vim.js @@ -66,23 +66,25 @@ define(function(require, exports, module) { var d = ""; function format(p) { if (typeof p != "object") - return p + "" + return p + ""; if ("line" in p) { - return p.line + ":" + p.ch + return p.line + ":" + p.ch; } if ("anchor" in p) { - return format(p.anchor) + "->" + format(p.head) + return format(p.anchor) + "->" + format(p.head); } if (Array.isArray(p)) - return "[" + p.map(function(x) {return format(x)})+"]" - return JSON.stringify(p) + return "[" + p.map(function(x) { + return format(x); + }) + "]"; + return JSON.stringify(p); } for (var i = 0; i < arguments.length; i++) { - var p = arguments[i] - var f = format(p) - d+= f+" " + var p = arguments[i]; + var f = format(p); + d += f + " "; } - console.log(d) + console.log(d); } var Range = require("../range").Range; var EventEmitter = require("../lib/event_emitter").EventEmitter; @@ -94,6 +96,7 @@ define(function(require, exports, module) { var useragent = require("../lib/useragent"); var SearchHighlight = require("../search_highlight").SearchHighlight; var multiSelectCommands = require("../commands/multi_select_commands"); + var TextModeTokenRe = require("../mode/text").Mode.prototype.tokenRe; require("../multi_select"); var CodeMirror = function(ace) { @@ -157,6 +160,11 @@ define(function(require, exports, module) { CodeMirror.signal = function(o, name, e) { return o._signal(name, e) }; CodeMirror.on = event.addListener; CodeMirror.off = event.removeListener; + CodeMirror.isWordChar = function(ch) { + TextModeTokenRe.lastIndex = 0; + return TextModeTokenRe.test(ch); + }; + (function() { oop.implement(CodeMirror.prototype, EventEmitter); @@ -383,13 +391,19 @@ define(function(require, exports, module) { sel.moveCursorBy(0, increment); } }; - this.findPosV = function(start, amaount, unit, goalColumn) { + this.findPosV = function(start, amount, unit, goalColumn) { + if (unit == 'page') { + var renderer = this.ace.renderer; + var config = renderer.layerConfig; + amount = amount * Math.floor(config.height / config.lineHeight); + unit = 'line'; + } if (unit == 'line') { var screenPos = this.ace.session.documentToScreenPosition(start.line, start.ch); if (goalColumn != null) screenPos.column = goalColumn; - screenPos.row += amaount; - // not what codemirror does but vim mode needs only it + screenPos.row += amount; + // not what codemirror does but vim mode needs only this screenPos.row = Math.min(Math.max(0, screenPos.row), this.ace.session.getScreenLength() - 1); var pos = this.ace.session.screenToDocumentPosition(screenPos.row, screenPos.column); return toCmPos(pos); @@ -1121,7 +1135,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ } var numberRegex = /[\d]/; - var wordRegexp = [(/\w/), (/[^\w\s]/)], bigWordRegexp = [(/\S/)]; + var wordRegexp = [{test: CodeMirror.isWordChar}, {test: function(ch) { + return !CodeMirror.isWordChar(ch) && !/\s/.test(ch); + }}], bigWordRegexp = [(/\S/)]; function makeKeyRange(start, size) { var keys = []; for (var i = start; i < start + size; i++) { @@ -2380,6 +2396,15 @@ dom.importCssString(".normal-mode .ace_cursor{\ (line > last && cur.line == last)) { return; } + // /ace patch + var fold = cm.ace.session.getFoldAt(line, endCh); + if (fold) { + if (motionArgs.forward) + line = fold.end.row + 1; + else + line = fold.start.row - 1; + } + // /ace patche if (motionArgs.toFirstChar){ endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line)); vim.lastHPos = endCh; @@ -4085,7 +4110,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ var min = cm.firstLine(); var max = cm.lastLine(); var start, end, i = line; - function isEmpty(i) { return !cm.getLine(i); } + function isEmpty(i) { return !/\S/.test(cm.getLine(i)); } function isBoundary(i, dir, any) { if (any) { return isEmpty(i) != isEmpty(i + dir); } return !isEmpty(i) && isEmpty(i + dir); @@ -5942,7 +5967,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } } } - } + }; var renderVirtualNumbers = { getText: function(session, row) { return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9? "\xb7" : "" ))) + "" @@ -5969,6 +5994,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ }, type: "boolean" }, false); + Vim.defineEx('write', 'w', function() { + console.log(':write is not implemented') + }); defaultKeymap.push( { keys: 'zc', type: 'action', action: 'fold', actionArgs: { open: false } }, { keys: 'zC', type: 'action', action: 'fold', actionArgs: { open: false, all: true } }, diff --git a/lib/ace/mode/behaviour/behaviour_test.js b/lib/ace/mode/behaviour/behaviour_test.js index ba0a5041..9dc27bf8 100644 --- a/lib/ace/mode/behaviour/behaviour_test.js +++ b/lib/ace/mode/behaviour/behaviour_test.js @@ -30,6 +30,7 @@ if (typeof process !== "undefined") { require("amd-loader"); + require("../../test/mockdom"); } define(function(require, exports, module) { @@ -42,6 +43,7 @@ var Editor = require("../../editor").Editor; var EditSession = require("../../edit_session").EditSession; var MockRenderer = require("../../test/mockrenderer").MockRenderer; var JavaScriptMode = require("../javascript").Mode; +var XMLMode = require("../xml").Mode; var editor; var exec = function(name, times, args) { do { @@ -117,9 +119,9 @@ module.exports = { editor.setValue(""); exec("insertstring", 1, "{"); - assert.equal(editor.getValue(), "{") + assert.equal(editor.getValue(), "{"); exec("insertstring", 1, "\n"); - assert.equal(editor.getValue(), "{\n \n}") + assert.equal(editor.getValue(), "{\n \n}"); editor.setValue(""); exec("insertstring", 1, "("); @@ -129,6 +131,34 @@ module.exports = { exec("backspace", 1); exec("insertstring", 1, '"'); assert.equal(editor.getValue(), '("")'); + + editor.setValue("('foo')", 1); + exec("gotoleft", 1); + exec("selectleft", 1); + exec("selectMoreBefore", 1); + exec("insertstring", 1, "'"); + assert.equal(editor.getValue(), "('foo')"); + exec("selectleft", 1); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '("foo")'); + exec("selectleft", 1); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '("foo")'); + }, + "test: xml": function() { + editor = new Editor(new MockRenderer()); + editor.setValue(["", + " " + ].join("\n")); + editor.session.setMode(new XMLMode); + exec("gotolinedown", 1); + exec("gotolineend", 1); + exec("insertstring", 1, '\n'); + assert.equal(editor.session.getLine(2), " "); + exec("gotolineup", 1); + exec("gotolineend", 1); + exec("insertstring", 1, '\n'); + assert.equal(editor.session.getLine(2), " "); } }; diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index 5abf08fd..c67f1130 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -256,7 +256,7 @@ var CstyleBehaviour = function() { text: quote + selected + quote, selection: false }; - } else { + } else if (!selected) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var leftChar = line.substring(cursor.column-1, cursor.column); @@ -278,7 +278,7 @@ var CstyleBehaviour = function() { if (stringBefore && !stringAfter) return null; // wrap string with different quote if (stringBefore && stringAfter) - return null; // do not pair quotes inside strings + return null; // do not pair quotes inside strings var wordRe = session.$mode.tokenRe; wordRe.lastIndex = 0; var isWordBefore = wordRe.test(leftChar); diff --git a/lib/ace/mode/behaviour/xml.js b/lib/ace/mode/behaviour/xml.js index fc46a240..068fdb31 100644 --- a/lib/ace/mode/behaviour/xml.js +++ b/lib/ace/mode/behaviour/xml.js @@ -155,6 +155,8 @@ var XmlBehaviour = function () { var token = iterator.getCurrentToken(); if (token && token.type.indexOf("tag-close") !== -1) { + if (token.value == "/>") + return; //get tag name while (token && token.type.indexOf("tag-name") === -1) { token = iterator.stepBackward(); diff --git a/lib/ace/mode/sh_highlight_rules.js b/lib/ace/mode/sh_highlight_rules.js index 9dd9aa33..9d32055a 100644 --- a/lib/ace/mode/sh_highlight_rules.js +++ b/lib/ace/mode/sh_highlight_rules.js @@ -104,7 +104,7 @@ var ShHighlightRules = function() { token : "keyword.operator" }, { stateName: "heredoc", - regex : "(<<)(\\s*)(['\"`]?)([\\w\\-]+)(['\"`]?)", + regex : "(<<-?)(\\s*)(['\"`]?)([\\w\\-]+)(['\"`]?)", onMatch : function(value, currentState, stack) { var next = value[2] == '-' ? "indentedHeredoc" : "heredoc"; var tokens = value.split(this.splitRegex);