From ece288b0c72e14196c3c8af3f212217c742f04bc Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Tue, 21 Dec 2010 16:34:52 +0100 Subject: [PATCH] add multi row document operations n preparation for rectangular selections --- lib/ace/document.js | 61 +++++++++++++++++++++++++++++++- lib/ace/test/document_test.js | 66 +++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/lib/ace/document.js b/lib/ace/document.js index dc2389fb..e60dbbd7 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -107,7 +107,6 @@ var Document = function(text, mode) { } if (undoManager) { - //undoManager.setDocument(this); var self = this; this.$informUndoManager = lang.deferredCall(function() { if (self.$deltas.length > 0) @@ -456,6 +455,45 @@ var Document = function(text, mode) { : undefined); return end; }; + + /** + * @param rows Array[Integer] sorted list of rows + */ + this.multiRowInsert = function(rows, column, text) { + var lines = this.lines; + + for (var i=rows.length-1; i>=0; i--) { + var row = rows[i]; + if (row >= lines.length) + continue; + + var diff = column - lines[row].length; + if ( diff > 0) { + var padded = lang.stringRepeat(" ", diff) + text; + var offset = -diff; + } + else { + padded = text; + offset = 0; + } + + var end = this.$insert({row: row, column: column+offset}, padded, false); + } + + if (end) { + this.fireChangeEvent(rows[0], rows[rows.length-1] + end.row - rows[0]); + return { + rows: end.row - rows[0], + columns: end.column - column + } + } + else { + return { + rows: 0, + columns: 0 + } + } + }; this.$insertLines = function(row, lines, fromUndo) { if (lines.length == 0) @@ -552,6 +590,27 @@ var Document = function(text, mode) { return range.start; }; + this.multiRowRemove = function(rows, range) { + if (range.start.row !== rows[0]) + throw new TypeError("range must start in the first row!"); + + var height = range.end.row - rows[0]; + for (var i=rows.length-1; i>=0; i--) { + var row = rows[i]; + if (row >= this.lines.length) + continue; + + var end = this.$remove(new Range(row, range.start.column, row+height, range.end.column), false); + } + + if (end) { + if (height < 0) + this.fireChangeEvent(rows[0]+height, undefined); + else + this.fireChangeEvent(rows[0], height == 0 ? rows[rows.length-1] : undefined); + } + }; + this.$remove = function(range, fromUndo) { if (range.isEmpty()) return; diff --git a/lib/ace/test/document_test.js b/lib/ace/test/document_test.js index 253ecbb8..c3bc3958 100644 --- a/lib/ace/test/document_test.js +++ b/lib/ace/test/document_test.js @@ -217,6 +217,72 @@ var Test = { assert.equal(doc.screenToDocumentColumn(0, 9), 6); assert.equal(doc.screenToDocumentColumn(0, 15), 12); assert.equal(doc.screenToDocumentColumn(0, 19), 13); + }, + + "test: insert text in multiple rows": function() { + var doc = new Document(["12", "", "abcd"]); + + var inserted = doc.multiRowInsert([0, 1, 2], 2, "juhu 1"); + assert.equal(inserted.rows, 0); + assert.equal(inserted.columns, 6); + + assert.equal(doc.toString(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n")); + }, + + "test: undo insert text in multiple rows": function() { + var doc = new Document(["12", "", "abcd"]); + + var undoManager = new UndoManager(); + doc.setUndoManager(undoManager); + + doc.multiRowInsert([0, 1, 2], 2, "juhu 1"); + doc.$informUndoManager.call(); + assert.equal(doc.toString(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n")); + + undoManager.undo(); + assert.equal(doc.toString(), ["12", "", "abcd"].join("\n")); + + undoManager.redo(); + assert.equal(doc.toString(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n")); + }, + + "test: insert new line in multiple rows": function() { + var doc = new Document(["12", "", "abcd"]); + + var inserted = doc.multiRowInsert([0, 1, 2], 2, "\n"); + assert.equal(inserted.rows, 1); + assert.equal(doc.toString(), ["12\n", " \n", "ab\ncd"].join("\n")); + }, + + "test: insert multi line text in multiple rows": function() { + var doc = new Document(["12", "", "abcd"]); + + var inserted = doc.multiRowInsert([0, 1, 2], 2, "juhu\n12"); + assert.equal(inserted.rows, 1); + assert.equal(doc.toString(), ["12juhu\n12", " juhu\n12", "abjuhu\n12cd"].join("\n")); + }, + + "test: remove right in multiple rows" : function() { + var doc = new Document(["12", "", "abcd"]); + + doc.multiRowRemove([0, 1, 2], new Range(0, 2, 0, 3)); + assert.equal(doc.toString(), ["12", "", "abd"].join("\n")); + }, + + "test: undo remove right in multiple rows" : function() { + var doc = new Document(["12", "", "abcd"]); + var undoManager = new UndoManager(); + doc.setUndoManager(undoManager); + + doc.multiRowRemove([0, 1, 2], new Range(0, 1, 0, 3)); + doc.$informUndoManager.call(); + assert.equal(doc.toString(), ["1", "", "ad"].join("\n")); + + undoManager.undo(); + assert.equal(doc.toString(), ["12", "", "abcd"].join("\n")); + + undoManager.redo(); + assert.equal(doc.toString(), ["1", "", "ad"].join("\n")); } };