From 10e35ef5074f797060a577509bffa9656cbc61fc Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Mon, 26 Apr 2010 15:51:58 +0200 Subject: [PATCH] add proper new line handling including new line character detection --- src/ace/Document.js | 46 +++++++++++++++++++++++++++++++++++++--- src/test/DocumentTest.js | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/ace/Document.js b/src/ace/Document.js index 231b8de8..b624176b 100644 --- a/src/ace/Document.js +++ b/src/ace/Document.js @@ -3,7 +3,7 @@ ace.provide("ace.Document"); ace.Document = function(text, mode) { this.$initEvents(); - this.lines = this.$split(text); + this.lines = []; this.modified = true; this.selection = new ace.Selection(this); @@ -11,6 +11,8 @@ ace.Document = function(text, mode) { if (mode) { this.setMode(mode); } + + this.insert({row: 0, column: 0}, text); }; (function() { @@ -22,7 +24,7 @@ ace.Document = function(text, mode) { }; this.toString = function() { - return this.lines.join("\n"); + return this.lines.join(this.$getNewLineCharacter()); }; this.getSelection = function() { @@ -68,6 +70,41 @@ ace.Document = function(text, mode) { return this.$tabSize; }; + this.$detectNewLine = function(text) { + var match = text.match(/^.*?(\r?\n)/m); + console.log(match); + if (match) { + this.$autoNewLine = match[1]; + } else { + this.$autoNewLine = "\n"; + } + }; + + this.$getNewLineCharacter = function() { + switch (this.$newLineMode) { + case "windows": + return "\r\n"; + + case "unix": + return "\n"; + + case "auto": + return this.$autoNewLine; + } + }, + + this.$autoNewLine = "\n"; + this.$newLineMode = "auto"; + this.setNewLineMode = function(newLineMode) { + if (this.$newLineMode === newLineMode) return; + + this.$newLineMode = newLineMode; + }; + + this.getNewLineMode = function() { + return this.$newLineMode; + }; + this.$mode = null; this.setMode = function(mode) { if (this.$mode === mode) return; @@ -127,7 +164,7 @@ ace.Document = function(text, mode) { lines.push(this.lines[range.start.row].substring(range.start.column)); lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1)); lines.push(this.lines[range.end.row].substring(0, range.end.column)); - return lines.join("\n"); + return lines.join(this.$getNewLineCharacter()); } }; @@ -242,6 +279,9 @@ ace.Document = function(text, mode) { this.$insert = function(position, text) { this.modified = true; + if (this.lines.length <= 1) { + this.$detectNewLine(text); + } var newLines = this.$split(text); diff --git a/src/test/DocumentTest.js b/src/test/DocumentTest.js index 4a8b8e62..ad66f640 100644 --- a/src/test/DocumentTest.js +++ b/src/test/DocumentTest.js @@ -84,5 +84,44 @@ var TextDocumentTest = new TestCase("TextDocumentTest", { doc.duplicateLines(0, 0); assertEquals(["1", "1", "2", "3"].join("\n"), doc.toString()); + }, + + "test: should handle unix style new lines" : function() { + var doc = new ace.Document(["1", "2", "3"].join("\n")); + assertEquals(["1", "2", "3"].join("\n"), doc.toString()); + }, + + "test: should handle windows style new lines" : function() { + var doc = new ace.Document(["1", "2", "3"].join("\r\n")); + doc.setNewLineMode("unix"); + assertEquals(["1", "2", "3"].join("\n"), doc.toString()); + }, + + "test: set new line mode to 'windows' should use '\r\n' as new lines": function() { + var doc = new ace.Document(["1", "2", "3"].join("\n")); + doc.setNewLineMode("windows"); + assertEquals(["1", "2", "3"].join("\r\n"), doc.toString()); + }, + + "test: set new line mode to 'unix' should use '\n' as new lines": function() { + var doc = new ace.Document(["1", "2", "3"].join("\r\n")); + doc.setNewLineMode("unix"); + assertEquals(["1", "2", "3"].join("\n"), doc.toString()); + }, + + "test: set new line mode to 'auto' should use detect the incoming nl type": function() { + var doc = new ace.Document(["1", "2", "3"].join("\n")); + doc.setNewLineMode("auto"); + assertEquals(["1", "2", "3"].join("\n"), doc.toString()); + + var doc = new ace.Document(["1", "2", "3"].join("\r\n")); + doc.setNewLineMode("auto"); + assertEquals(["1", "2", "3"].join("\r\n"), doc.toString()); + + doc.replace({ + start: {row: 0, column: 0}, + end: {row: 2, column: 1} + }, ["4", "5", "6"].join("\n")); + assertEquals(["4", "5", "6"].join("\n"), doc.toString()); } }); \ No newline at end of file