From d7ea9d6a5212a80739f153c9cc6cca92a2935f5f Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 24 Apr 2013 14:38:43 +0400 Subject: [PATCH 1/3] 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; From c2a50de10e1b78d580d40bff68d8d2fdb956b38f Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 24 Apr 2013 16:40:23 +0400 Subject: [PATCH 2/3] fix tests --- lib/ace/editor_text_edit_test.js | 5 ++++- lib/ace/mode/logiql_test.js | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/ace/editor_text_edit_test.js b/lib/ace/editor_text_edit_test.js index c145f474..77ec34ed 100644 --- a/lib/ace/editor_text_edit_test.js +++ b/lib/ace/editor_text_edit_test.js @@ -42,6 +42,7 @@ var JavaScriptMode = require("./mode/javascript").Mode; var UndoManager = require("./undomanager").UndoManager; var MockRenderer = require("./test/mockrenderer").MockRenderer; var assert = require("./test/assertions"); +var whitespace = require("./ext/whitespace"); module.exports = { "test: delete line from the middle" : function() { @@ -184,7 +185,8 @@ module.exports = { "test: comment lines should perserve selection" : function() { var session = new EditSession([" abc", "cde"].join("\n"), new JavaScriptMode()); var editor = new Editor(new MockRenderer(), session); - + whitespace.detectIndentation(session); + editor.moveCursorTo(0, 2); editor.getSelection().selectDown(); editor.toggleCommentLines(); @@ -199,6 +201,7 @@ module.exports = { "test: uncomment lines should perserve selection" : function() { var session = new EditSession(["// abc", "//cde"].join("\n"), new JavaScriptMode()); var editor = new Editor(new MockRenderer(), session); + session.setTabSize(2); editor.moveCursorTo(0, 1); editor.getSelection().selectDown(); diff --git a/lib/ace/mode/logiql_test.js b/lib/ace/mode/logiql_test.js index a37b7da2..3e661829 100644 --- a/lib/ace/mode/logiql_test.js +++ b/lib/ace/mode/logiql_test.js @@ -46,10 +46,10 @@ module.exports = { }, "test: toggle comment lines should prepend '//' to each line" : function() { - var session = new EditSession([" abc", "cde", "fg"]); + var session = new EditSession([" abc", "cde", "fg"]); this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal(["// abc", "// cde", "fg"].join("\n"), session.toString()); + assert.equal(["// abc", "// cde", "fg"].join("\n"), session.toString()); }, "test: auto indent after ->" : function() { From a5e7d5d1f1c55c515eceda3c8fe495ffed1c0a44 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 20 May 2013 19:38:42 +0400 Subject: [PATCH 3/3] fix comment toggling on lines with wrong indentation --- lib/ace/mode/javascript_test.js | 6 +++++- lib/ace/mode/text.js | 14 ++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/ace/mode/javascript_test.js b/lib/ace/mode/javascript_test.js index 7de4aec2..b413765a 100644 --- a/lib/ace/mode/javascript_test.js +++ b/lib/ace/mode/javascript_test.js @@ -127,9 +127,13 @@ module.exports = { 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()); + 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()); + + session.insert({row: 0, column: 0}, " "); + 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() { diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index d90cd4a4..e243ddbd 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -143,17 +143,19 @@ var Mode = function() { return regexpStart.test(line); }; - var shouldInsertSpace = function(line, pos1, pos2) { + var shouldInsertSpace = function(line, before, after) { var spaces = 0; - while (pos1-- && line.charAt(pos1) == " ") + while (before-- && line.charAt(before) == " ") spaces++; if (spaces % tabSize != 0) return false; var spaces = 0; - while (line.charAt(pos2++) == " ") + while (line.charAt(after++) == " ") spaces++; - if (spaces % tabSize != 0) - return false; + if (tabSize > 2) + return spaces % tabSize != tabSize - 1; + else + return spaces % tabSize == 0; return true; }; } @@ -184,7 +186,7 @@ var Mode = function() { } if (insertAtTabStop && minIndent % tabSize != 0) - minIndent = Math.floor(minIndent / tabSize); + minIndent = Math.floor(minIndent / tabSize) * tabSize; iter(shouldRemove ? uncomment : comment); };