From d7ea9d6a5212a80739f153c9cc6cca92a2935f5f Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 24 Apr 2013 14:38:43 +0400 Subject: [PATCH] try to not remove spaces from indentation when uncommenting --- lib/ace/mode/javascript_test.js | 26 +++++++++++++++++++- lib/ace/mode/text.js | 43 ++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/lib/ace/mode/javascript_test.js b/lib/ace/mode/javascript_test.js index bd74e2ee..7de4aec2 100644 --- a/lib/ace/mode/javascript_test.js +++ b/lib/ace/mode/javascript_test.js @@ -56,6 +56,7 @@ module.exports = { "test: toggle comment lines should prepend '//' to each line" : function() { var session = new EditSession([" abc", "cde", "fg"]); + session.setTabSize(1); this.mode.toggleCommentLines("start", session, 0, 1); assert.equal(["// abc", "// cde", "fg"].join("\n"), session.toString()); @@ -63,6 +64,7 @@ module.exports = { "test: toggle comment on commented lines should remove leading '//' chars" : function() { var session = new EditSession(["// abc", "//cde", "fg"]); + session.setTabSize(1); this.mode.toggleCommentLines("start", session, 0, 1); assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); @@ -70,6 +72,7 @@ module.exports = { "test: toggle comment on all empty lines" : function() { var session = new EditSession([" ", " ", " "]); + session.setTabSize(1); this.mode.toggleCommentLines("start", session, 0, 1); assert.equal([" // ", " // ", " "].join("\n"), session.toString()); @@ -105,7 +108,7 @@ module.exports = { "test: toggle comment on multiple lines with one commented line prepend '//' to each line" : function() { var session = new EditSession([" // abc", " //cde", " fg"]); - + session.setTabSize(1); this.mode.toggleCommentLines("start", session, 0, 2); assert.equal([" // // abc", " // //cde", " // fg"].join("\n"), session.toString()); }, @@ -117,6 +120,27 @@ module.exports = { assert.equal(["cde", " fg"].join("\n"), session.toString()); }, + "test: toggle comment lines should take tabsize into account" : function() { + var session = new EditSession([" // abc", " // cde", "// fg"]); + session.setTabSize(2); + this.mode.toggleCommentLines("start", session, 0, 2); + assert.equal([" abc", " cde", " fg"].join("\n"), session.toString()); + session.setTabSize(4); + this.mode.toggleCommentLines("start", session, 0, 2); + assert.equal(["// abc", "// cde", "// fg"].join("\n"), session.toString()); + this.mode.toggleCommentLines("start", session, 0, 2); + assert.equal([" abc", " cde", " fg"].join("\n"), session.toString()); + }, + //there doesn't seem to be any way to make this work + "!test: togglecomment on line with one space" : function() { + var session = new EditSession([" abc", " // cde", "// fg"]); + var initialValue = session + ""; + session.setTabSize(4); + this.mode.toggleCommentLines("start", session, 0, 0); + this.mode.toggleCommentLines("start", session, 0, 0); + assert.equal(initialValue, session.toString()); + }, + "test: auto indent after opening brace" : function() { assert.equal(" ", this.mode.getNextLineIndent("start", "if () {", " ")); }, diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index ca14fdec..d90cd4a4 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -73,6 +73,8 @@ var Mode = function() { var ignoreBlankLines = true; var shouldRemove = true; var minIndent = Infinity; + var tabSize = session.getTabSize(); + var insertAtTabStop = false; if (!this.lineCommentStart) { if (!this.blockComment) @@ -111,24 +113,49 @@ var Mode = function() { } else { if (Array.isArray(this.lineCommentStart)) { var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|"); - var lineCommentStart = this.lineCommentStart[0] + " "; + var lineCommentStart = this.lineCommentStart[0]; } else { var regexpStart = lang.escapeRegExp(this.lineCommentStart); - var lineCommentStart = this.lineCommentStart + " "; + var lineCommentStart = this.lineCommentStart; } regexpStart = new RegExp("^(\\s*)(?:" + regexpStart + ") ?"); + + insertAtTabStop = session.getUseSoftTabs(); var uncomment = function(line, i) { var m = line.match(regexpStart); - m && doc.removeInLine(i, m[1].length, m[0].length); + if (!m) return; + var start = m[1].length, end = m[0].length; + if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == " ") + end--; + doc.removeInLine(i, start, end); }; + var commentWithSpace = lineCommentStart + " "; var comment = function(line, i) { - if (!ignoreBlankLines || /\S/.test(line)) - doc.insertInLine({row: i, column: minIndent}, lineCommentStart); + if (!ignoreBlankLines || /\S/.test(line)) { + if (shouldInsertSpace(line, minIndent, minIndent)) + doc.insertInLine({row: i, column: minIndent}, commentWithSpace); + else + doc.insertInLine({row: i, column: minIndent}, lineCommentStart); + } }; var testRemove = function(line, i) { return regexpStart.test(line); }; + + var shouldInsertSpace = function(line, pos1, pos2) { + var spaces = 0; + while (pos1-- && line.charAt(pos1) == " ") + spaces++; + if (spaces % tabSize != 0) + return false; + var spaces = 0; + while (line.charAt(pos2++) == " ") + spaces++; + if (spaces % tabSize != 0) + return false; + return true; + }; } function iter(fun) { @@ -156,6 +183,9 @@ var Mode = function() { shouldRemove = false; } + if (insertAtTabStop && minIndent % tabSize != 0) + minIndent = Math.floor(minIndent / tabSize); + iter(shouldRemove ? uncomment : comment); }; @@ -264,7 +294,8 @@ var Mode = function() { this.$delegator = function(method, args, defaultHandler) { var state = args[0]; - + if (typeof state != "string") + state = state[0]; for (var i = 0; i < this.$embeds.length; i++) { if (!this.$modes[this.$embeds[i]]) continue;