Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 32176e2

Browse files
committed
Fixes after review
1 parent ede8d8a commit 32176e2

File tree

2 files changed

+92
-27
lines changed

2 files changed

+92
-27
lines changed

src/editor/EditorCommandHandlers.js

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ define(function (require, exports, module) {
6161

6262
for (i = lineSyntax.length; i < blockSyntax.length; i++) {
6363
character = blockSyntax.charAt(i);
64-
subExps.push(prevChars + "[^" + character + "]");
64+
subExps.push(prevChars + "[^" + StringUtils.regexEscape(character) + "]");
6565
if (prevChars) {
6666
subExps.push(prevChars + "$");
6767
}
6868
prevChars += character;
6969
}
70-
return new RegExp("^\\s*" + lineSyntax + "($|" + subExps.join("|") + ")");
70+
return new RegExp("^\\s*" + StringUtils.regexEscape(lineSyntax) + "($|" + subExps.join("|") + ")");
7171
}
7272

7373
/**
@@ -79,27 +79,32 @@ define(function (require, exports, module) {
7979
* @return {Array.<RegExp>}
8080
*/
8181
function _createLineExpressions(prefixes, blockPrefix, blockSuffix) {
82-
var lineExp = [], escapedPrefix, regExp;
82+
var lineExp = [], escapedPrefix, nothingPushed;
8383

8484
prefixes.forEach(function (prefix) {
8585
escapedPrefix = StringUtils.regexEscape(prefix);
86+
nothingPushed = true;
87+
8688
if (blockPrefix && blockPrefix.indexOf(prefix) === 0) {
87-
regExp = _createSpecialLineExp(prefix, blockPrefix);
88-
} else if (blockSuffix && blockSuffix.indexOf(prefix) === 0) {
89-
regExp = _createSpecialLineExp(prefix, blockSuffix);
90-
} else {
91-
regExp = new RegExp("^\\s*" + escapedPrefix);
89+
lineExp.push(_createSpecialLineExp(prefix, blockPrefix));
90+
nothingPushed = false;
91+
}
92+
if (blockSuffix && blockPrefix !== blockSuffix && blockSuffix.indexOf(prefix) === 0) {
93+
lineExp.push(_createSpecialLineExp(prefix, blockSuffix));
94+
nothingPushed = false;
95+
}
96+
if (nothingPushed) {
97+
lineExp.push(new RegExp("^\\s*" + escapedPrefix));
9298
}
93-
lineExp.push(regExp);
9499
});
95100
return lineExp;
96101
}
97102

98103
/**
99104
* @private
100105
* Returns true if any regular expression matches the given string
101-
* @param {!string} string - where to look
102-
* @param {!Array.<RegExp>} expressions - what to look
106+
* @param {!string} string where to look
107+
* @param {!Array.<RegExp>} expressions what to look
103108
* @return {boolean}
104109
*/
105110
function _matchExpressions(string, expressions) {
@@ -130,7 +135,8 @@ define(function (require, exports, module) {
130135

131136
/**
132137
* @private
133-
* Searchs for an uncommented line between startLine and endLine
138+
* Searches between startLine and endLine to check if there is at least one line commented with a line comment, and
139+
* skips all the block comments.
134140
* @param {!Editor} editor
135141
* @param {!number} startLine valid line inside the document
136142
* @param {!number} endLine valid line inside the document
@@ -144,7 +150,7 @@ define(function (require, exports, module) {
144150
for (i = startLine; i <= endLine; i++) {
145151
line = editor.document.getLine(i);
146152
// A line is commented out if it starts with 0-N whitespace chars, then a line comment prefix
147-
if (line.match(/\S/) && !_matchExpressions(line, lineExp)) {
153+
if (!line.length || (line.match(/\S/) && !_matchExpressions(line, lineExp))) {
148154
containsNotLineComment = true;
149155
break;
150156
}
@@ -277,15 +283,15 @@ define(function (require, exports, module) {
277283
* Generates an edit that adds or removes block-comment tokens to the selection, preserving selection
278284
* and cursor position. Applies to the currently focused Editor.
279285
*
280-
* If the selection is inside a block-comment or one block-comment is inside or partially
281-
* inside the selection we uncomment; otherwise we comment out.
286+
* If the selection is inside a block-comment or one block-comment is inside or partially inside the selection
287+
* it will uncomment, otherwise it will comment out, unless if there are multiple block comments inside the selection,
288+
* where it does nothing.
282289
* Commenting out adds the prefix before the selection and the suffix after.
283290
* Uncommenting removes them.
284291
*
285-
* As a special case, if slashComment is true and the start or end of the selection is inside a
286-
* line-comment it needs to do a line uncomment if is not actually inside a bigger block comment and all
287-
* the lines in the selection are line-commented. In this case, we return null to indicate to the caller
288-
* that it needs to handle this selection as a line comment.
292+
* If all the lines inside the selection are line-comment and if the selection is not inside a block-comment, it will
293+
* line uncomment all the lines, otherwise it will block comment/uncomment. In the first case, we return null to
294+
* indicate to the caller that it needs to handle this selection as a line comment.
289295
*
290296
* @param {!Editor} editor
291297
* @param {!string} prefix, e.g. "<!--"
@@ -358,6 +364,7 @@ define(function (require, exports, module) {
358364

359365
// If we are in a line that only has a prefix or a suffix and the prefix and suffix are the same string,
360366
// lets find first if this is a prefix or suffix and move the token to the inside of the block comment.
367+
// This means that the token will be anywere inside the block comment, including the lines with the delimiters.
361368
// This is required so that later we can find the prefix by moving backwards and the suffix by moving forwards.
362369
if (ctx.token.string === prefix && prefix === suffix) {
363370
searchCtx = TokenUtils.getInitialContext(editor._codeMirror, {line: ctx.pos.line, ch: ctx.token.start});
@@ -372,7 +379,7 @@ define(function (require, exports, module) {
372379

373380
if (isBlockComment) {
374381
// Save the initial position to start searching for the suffix from here
375-
initialPos = $.extend({}, ctx.pos);
382+
initialPos = _.cloneDeep(ctx.pos);
376383

377384
// Find the position of the start of the prefix
378385
result = true;
@@ -381,8 +388,11 @@ define(function (require, exports, module) {
381388
}
382389
prefixPos = result && {line: ctx.pos.line, ch: ctx.token.start};
383390

384-
// Restore the context at the initial position and find the position of the start of the suffix
385-
ctx = TokenUtils.getInitialContext(editor._codeMirror, {line: initialPos.line, ch: initialPos.ch});
391+
// Restore the context at the initial position to find the position of the start of the suffix,
392+
// but only when we found the prefix alone in one line
393+
if (ctx.token.string === prefix && prefix === suffix) {
394+
ctx = TokenUtils.getInitialContext(editor._codeMirror, _.cloneDeep(initialPos));
395+
}
386396

387397
while (result && !ctx.token.string.match(suffixExp)) {
388398
result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, ctx);
@@ -397,7 +407,7 @@ define(function (require, exports, module) {
397407
invalidComment = result && !!ctx.token.string.match(prefixExp);
398408

399409
// We moved the token at the start when it was in a whitespace, but maybe we shouldn't have done it
400-
if (prefixPos && editor.indexFromPos(sel.end) < editor.indexFromPos(prefixPos)) {
410+
if ((suffixPos && CodeMirror.cmpPos(sel.start, suffixPos) > 0) || (prefixPos && CodeMirror.cmpPos(sel.end, prefixPos) < 0)) {
401411
canComment = true;
402412
}
403413

test/spec/EditorCommandHandlers-test.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,21 +2037,78 @@ define(function (require, exports, module) {
20372037
expectSelection({start: {line: 6, ch: 0}, end: {line: 7, ch: 0}});
20382038
});
20392039

2040+
it("should block comment on an empty line around comments", function () {
2041+
var lines = coffeeContent.split("\n");
2042+
lines[2] = "###baz = \"hello\"###";
2043+
lines[3] = "";
2044+
lines[4] = "#number = -42";
2045+
var text = lines.join("\n");
2046+
2047+
lines[3] = "######";
2048+
var expectedText = lines.join("\n");
2049+
2050+
myDocument.setText(text);
2051+
myEditor.setCursorPos(3, 0);
2052+
2053+
CommandManager.execute(Commands.EDIT_BLOCK_COMMENT, myEditor);
2054+
2055+
expect(myDocument.getText()).toEqual(expectedText);
2056+
expectCursorAt({line: 3, ch: 3});
2057+
});
2058+
2059+
it("should block uncomment on an empty line inside a block comment", function () {
2060+
var lines = coffeeContent.split("\n");
2061+
lines[1] = "###bar = true";
2062+
lines[2] = "";
2063+
lines[3] = "number = -42###";
2064+
var text = lines.join("\n");
2065+
2066+
lines = coffeeContent.split("\n");
2067+
lines[2] = "";
2068+
var expectedText = lines.join("\n");
2069+
2070+
myDocument.setText(text);
2071+
myEditor.setCursorPos(2, 0);
2072+
2073+
CommandManager.execute(Commands.EDIT_BLOCK_COMMENT, myEditor);
2074+
2075+
expect(myDocument.getText()).toEqual(expectedText);
2076+
expectCursorAt({line: 2, ch: 0});
2077+
});
2078+
20402079
it("should line uncomment on line comments around a block comment", function () {
20412080
var lines = getContentCommented(1, 3).split("\n");
20422081
lines[5] = "#number = -42";
20432082
var text = lines.join("\n");
20442083

2084+
lines = text.split("\n");
2085+
lines[5] = "number = -42";
2086+
var expectedText = lines.join("\n");
2087+
20452088
myDocument.setText(text);
20462089
myEditor.setSelection({line: 5, ch: 0}, {line: 6, ch: 0});
20472090

20482091
CommandManager.execute(Commands.EDIT_BLOCK_COMMENT, myEditor);
20492092

2050-
lines[5] = "number = -42";
2093+
expect(myDocument.getText()).toEqual(expectedText);
2094+
expectSelection({start: {line: 5, ch: 0}, end: {line: 6, ch: 0}});
2095+
});
2096+
2097+
it("should line comment block commented lines", function () {
2098+
var lines = coffeeContent.split("\n");
2099+
lines[2] = "###baz = \"hello\"###";
2100+
var text = lines.join("\n");
2101+
2102+
lines = text.split("\n");
2103+
lines[2] = "####baz = \"hello\"###";
20512104
var expectedText = lines.join("\n");
20522105

2106+
myDocument.setText(text);
2107+
myEditor.setSelection({line: 2, ch: 0}, {line: 2, ch: 5});
2108+
CommandManager.execute(Commands.EDIT_LINE_COMMENT, myEditor);
2109+
20532110
expect(myDocument.getText()).toEqual(expectedText);
2054-
expectSelection({start: {line: 5, ch: 0}, end: {line: 6, ch: 0}});
2111+
expectSelection({start: {line: 2, ch: 0}, end: {line: 2, ch: 6}});
20552112
});
20562113

20572114
it("should line comment in block comment prefix or sufix starting lines", function () {
@@ -2069,11 +2126,9 @@ define(function (require, exports, module) {
20692126

20702127
myDocument.setText(text);
20712128
myEditor.setSelection({line: 0, ch: 0}, {line: 2, ch: 0});
2072-
20732129
CommandManager.execute(Commands.EDIT_LINE_COMMENT, myEditor);
20742130

20752131
myEditor.setSelection({line: 4, ch: 0}, {line: 6, ch: 0});
2076-
20772132
CommandManager.execute(Commands.EDIT_LINE_COMMENT, myEditor);
20782133

20792134
expect(myDocument.getText()).toEqual(expectedText);

0 commit comments

Comments
 (0)