diff --git a/lib/ace/multi_select.js b/lib/ace/multi_select.js index 3b5a8bd0..4890e79c 100644 --- a/lib/ace/multi_select.js +++ b/lib/ace/multi_select.js @@ -41,11 +41,10 @@ define(function(require, exports, module) { var RangeList = require("./range_list").RangeList; var Range = require("./range").Range; var Selection = require("./selection").Selection; -var Range = require("./range").Range; var onMouseDown = require("./mouse/multi_select_mouse_handler").onMouseDown; exports.commands = require("./commands/multi_select_commands"); - +// Todo var Search = require("ace/search").Search var search = new Search @@ -82,6 +81,8 @@ var EditSession = require("./edit_session").EditSession; if (this.rangeCount > 1 && !this.inMultiSelectMode) { this._emit("multiSelect"); this.inMultiSelectMode = true; + this.$undoSelect = false; + this.rangeList.attach(this.session); } this.fromOrientedRange(range); @@ -102,7 +103,9 @@ var EditSession = require("./edit_session").EditSession; if (this.rangeCount <= 1 && this.inMultiSelectMode) { this.inMultiSelectMode = false; this._emit("singleSelect"); - + this.$undoSelect = true; + this.rangeList.detach(this.session); + if (this.rangeCount == 1) this.single(); } @@ -135,22 +138,7 @@ var EditSession = require("./edit_session").EditSession; this.rangeList.on("remove", this.$onRemoveRange.bind(this)); }; this.getAllRanges = function() { - return this.rangeList.ranges.concat(this.secondarySelections) - }; - - - this.splitIntoLines = function () { - if (this.rangeCount > 1) { - var ranges = this.rangeList.ranges; - var lastRange = ranges[ranges.length - 1] - var range = Range.fromPoints(ranges[0].start, lastRange.end) - - this.single() - this.setSelectionRange(range, lastRange.cursor == lastRange.start) - } else { - var cursor = this.getRange().toScreenRange(); - range - } + return this.rangeList.ranges.concat() }; this.splitIntoLines = function () { @@ -284,9 +272,6 @@ var Editor = require("./editor").Editor; this.commands.exec = exports.exec; this.renderer.updateCursor(); this.renderer.updateBackMarkers(); - - this.session.$undoSelect = false; - this.selection.rangeList.attach(this.session); }; this.$onSingleSelect = function(e) { @@ -300,10 +285,6 @@ var Editor = require("./editor").Editor; this.commands.exec = this.commands.__SingleSelectionExec; this.renderer.updateCursor(); this.renderer.updateBackMarkers(); - - this.session.$undoSelect = true; - - this.selection.rangeList.detach(this.session); }; this.forEachSelection = function(cmd, args) { @@ -537,6 +518,13 @@ exports.onSessionChange = function(e) { session.multiSelect.on("removeRange", this.$onRemoveRange); session.multiSelect.on("multiSelect", this.$onMultiSelect); session.multiSelect.on("singleSelect", this.$onSingleSelect); + + if (this.inMultiSelectMode != session.selection.inMultiSelectMode) { + if (session.selection.inMultiSelectMode) + this.$onMultiSelect(); + else + this.$onSingleSelect(); + } } // adds multicursor support to editor instance diff --git a/lib/ace/multi_select_test.js b/lib/ace/multi_select_test.js new file mode 100644 index 00000000..5c9d0dfe --- /dev/null +++ b/lib/ace/multi_select_test.js @@ -0,0 +1,144 @@ +/* vim:ts=4:sts=4:sw=4: + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Harutyun Amirjanyan + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var Range = require("./range").Range; +var assert = require("./test/assertions"); +var MultiSelect = require("ace/multi_select").MultiSelect; + +var editor +var exec = function(name, times, args) { + do { + editor.commands.exec(name, editor, args); + } while(times --> 1) +}; +var testRanges = function(str) { + assert.equal(editor.selection.getAllRanges()+"", str); +} + +module.exports = { + + name: "ACE multi_select.js", + + "test: multiselect editing": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.w" + ]); + editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + + editor.navigateFileEnd(); + exec("selectMoreBefore", 3); + assert.ok(editor.inMultiSelectMode); + assert.equal(editor.selection.getAllRanges().length, 4); + + assert.equal(editor.getCopyText(), "wwww"); + exec("insertstring", 1, "a"); + exec("backspace", 2); + assert.equal(editor.session.getValue(), "w1.w2\ntt\ntt"); + assert.equal(editor.selection.getAllRanges().length, 4); + + exec("selectall"); + assert.ok(!editor.inMultiSelectMode); + //assert.equal(editor.selection.getAllRanges().length, 1); + }, + + "test: multiselect navigation": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.we" + ]); + editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + + editor.selectMoreLines(1); + testRanges("Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]"); + assert.ok(editor.inMultiSelectMode); + + exec("golinedown"); + exec("gotolineend"); + testRanges("Range: [1/9] -> [1/9],Range: [2/10] -> [2/10]"); + exec("selectwordleft"); + + testRanges("Range: [1/8] -> [1/9],Range: [2/8] -> [2/10]"); + exec("golinedown", 2); + assert.ok(!editor.inMultiSelectMode); + }, + + "test: multiselect session change": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.w" + ]); + var editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + + editor.selectMoreLines(1) + assert.equal( + editor.selection.getAllRanges()+"", + "Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]" + ); + assert.ok(editor.inMultiSelectMode); + + var doc2 = new EditSession(["w1"]); + editor.setSession(doc2); + assert.ok(!editor.inMultiSelectMode); + + editor.setSession(doc); + assert.ok(editor.inMultiSelectMode); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} \ No newline at end of file diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js index b9484a86..d36d2a9c 100644 --- a/lib/ace/test/all_browser.js +++ b/lib/ace/test/all_browser.js @@ -41,6 +41,7 @@ var testNames = [ "ace/mode/folding/html_test", "ace/mode/folding/pythonic_test", "ace/mode/folding/xml_test", + "ace/multi_select_test", "ace/range_test", "ace/range_list_test", "ace/search_test", diff --git a/lib/ace/test/mockrenderer.js b/lib/ace/test/mockrenderer.js index 5efac2a9..67708735 100644 --- a/lib/ace/test/mockrenderer.js +++ b/lib/ace/test/mockrenderer.js @@ -1,185 +1,191 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { -"use strict"; - -var MockRenderer = exports.MockRenderer = function(visibleRowCount) { - this.container = document.createElement("div"); - this.visibleRowCount = visibleRowCount || 20; - - this.layerConfig = { - firstVisibleRow : 0, - lastVisibleRow : this.visibleRowCount - }; - - this.isMockRenderer = true; - - this.$gutter = {}; -}; - - -MockRenderer.prototype.getFirstVisibleRow = function() { - return this.layerConfig.firstVisibleRow; -}; - -MockRenderer.prototype.getLastVisibleRow = function() { - return this.layerConfig.lastVisibleRow; -}; - -MockRenderer.prototype.getFirstFullyVisibleRow = function() { - return this.layerConfig.firstVisibleRow; -}; - -MockRenderer.prototype.getLastFullyVisibleRow = function() { - return this.layerConfig.lastVisibleRow; -}; - -MockRenderer.prototype.getContainerElement = function() { - return this.container; -}; - -MockRenderer.prototype.getMouseEventTarget = function() { - return this.container; -}; - -MockRenderer.prototype.getTextAreaContainer = function() { - return this.container; -}; - -MockRenderer.prototype.moveTextAreaToCursor = function() { -}; - -MockRenderer.prototype.setSession = function(session) { - this.session = session; -}; - -MockRenderer.prototype.getSession = function(session) { - return this.session; -}; - -MockRenderer.prototype.setTokenizer = function() { -}; - -MockRenderer.prototype.on = function() { -}; - -MockRenderer.prototype.updateCursor = function() { -}; - -MockRenderer.prototype.scrollToX = function(scrollTop) {}; -MockRenderer.prototype.scrollToY = function(scrollLeft) {}; - -MockRenderer.prototype.scrollToLine = function(line, center) { - var lineHeight = { lineHeight: 16 }; - var row = 0; - for (var l = 1; l < line; l++) { - row += this.session.getRowHeight(lineHeight, l-1) / lineHeight.lineHeight; - } - - if (center) { - row -= this.visibleRowCount / 2; - } - this.scrollToRow(row); -}; - -MockRenderer.prototype.scrollCursorIntoView = function() { - var cursor = this.session.getSelection().getCursor(); - if (cursor.row < this.layerConfig.firstVisibleRow) { - this.scrollToRow(cursor.row); - } - else if (cursor.row > this.layerConfig.lastVisibleRow) { - this.scrollToRow(cursor.row); - } -}; - -MockRenderer.prototype.scrollToRow = function(row) { - var row = Math.min(this.session.getLength() - this.visibleRowCount, Math.max(0, - row)); - this.layerConfig.firstVisibleRow = row; - this.layerConfig.lastVisibleRow = row + this.visibleRowCount; -}; - -MockRenderer.prototype.getScrollTopRow = function() { - return this.layerConfig.firstVisibleRow; -}; - -MockRenderer.prototype.draw = function() { -}; - -MockRenderer.prototype.updateLines = function(startRow, endRow) { -}; - -MockRenderer.prototype.updateBackMarkers = function() { -}; - -MockRenderer.prototype.updateFrontMarkers = function() { -}; - -MockRenderer.prototype.setBreakpoints = function() { -}; - -MockRenderer.prototype.onResize = function() { -}; - -MockRenderer.prototype.updateFull = function() { -}; - -MockRenderer.prototype.updateText = function() { -}; - -MockRenderer.prototype.showCursor = function() { -}; - -MockRenderer.prototype.visualizeFocus = function() { -}; - -MockRenderer.prototype.setAnnotations = function() { -}; - -MockRenderer.prototype.textToScreenCoordinates = function() { - return { - pageX: 0, - pageY: 0 - } -}; - -MockRenderer.prototype.adjustWrapLimit = function () { - -}; - -}); +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var MockRenderer = exports.MockRenderer = function(visibleRowCount) { + this.container = document.createElement("div"); + this.visibleRowCount = visibleRowCount || 20; + + this.layerConfig = { + firstVisibleRow : 0, + lastVisibleRow : this.visibleRowCount + }; + + this.isMockRenderer = true; + + this.$gutter = {}; +}; + + +MockRenderer.prototype.getFirstVisibleRow = function() { + return this.layerConfig.firstVisibleRow; +}; + +MockRenderer.prototype.getLastVisibleRow = function() { + return this.layerConfig.lastVisibleRow; +}; + +MockRenderer.prototype.getFirstFullyVisibleRow = function() { + return this.layerConfig.firstVisibleRow; +}; + +MockRenderer.prototype.getLastFullyVisibleRow = function() { + return this.layerConfig.lastVisibleRow; +}; + +MockRenderer.prototype.getContainerElement = function() { + return this.container; +}; + +MockRenderer.prototype.getMouseEventTarget = function() { + return this.container; +}; + +MockRenderer.prototype.getTextAreaContainer = function() { + return this.container; +}; + +MockRenderer.prototype.moveTextAreaToCursor = function() { +}; + +MockRenderer.prototype.setSession = function(session) { + this.session = session; +}; + +MockRenderer.prototype.getSession = function(session) { + return this.session; +}; + +MockRenderer.prototype.setTokenizer = function() { +}; + +MockRenderer.prototype.on = function() { +}; + +MockRenderer.prototype.updateCursor = function() { +}; + +MockRenderer.prototype.scrollToX = function(scrollTop) {}; +MockRenderer.prototype.scrollToY = function(scrollLeft) {}; + +MockRenderer.prototype.scrollToLine = function(line, center) { + var lineHeight = { lineHeight: 16 }; + var row = 0; + for (var l = 1; l < line; l++) { + row += this.session.getRowHeight(lineHeight, l-1) / lineHeight.lineHeight; + } + + if (center) { + row -= this.visibleRowCount / 2; + } + this.scrollToRow(row); +}; + +MockRenderer.prototype.scrollCursorIntoView = function() { + var cursor = this.session.getSelection().getCursor(); + if (cursor.row < this.layerConfig.firstVisibleRow) { + this.scrollToRow(cursor.row); + } + else if (cursor.row > this.layerConfig.lastVisibleRow) { + this.scrollToRow(cursor.row); + } +}; + +MockRenderer.prototype.scrollToRow = function(row) { + var row = Math.min(this.session.getLength() - this.visibleRowCount, Math.max(0, + row)); + this.layerConfig.firstVisibleRow = row; + this.layerConfig.lastVisibleRow = row + this.visibleRowCount; +}; + +MockRenderer.prototype.getScrollTopRow = function() { + return this.layerConfig.firstVisibleRow; +}; + +MockRenderer.prototype.draw = function() { +}; + +MockRenderer.prototype.updateLines = function(startRow, endRow) { +}; + +MockRenderer.prototype.updateBackMarkers = function() { +}; + +MockRenderer.prototype.updateFrontMarkers = function() { +}; + +MockRenderer.prototype.setBreakpoints = function() { +}; + +MockRenderer.prototype.onResize = function() { +}; + +MockRenderer.prototype.updateFull = function() { +}; + +MockRenderer.prototype.updateText = function() { +}; + +MockRenderer.prototype.showCursor = function() { +}; + +MockRenderer.prototype.visualizeFocus = function() { +}; + +MockRenderer.prototype.setAnnotations = function() { +}; + +MockRenderer.prototype.setStyle = function() { +}; + +MockRenderer.prototype.unsetStyle = function() { +}; + +MockRenderer.prototype.textToScreenCoordinates = function() { + return { + pageX: 0, + pageY: 0 + } +}; + +MockRenderer.prototype.adjustWrapLimit = function () { + +}; + +});