Skip to content

Commit b5e77b4

Browse files
tophfmarijnh
authored andcommitted
[continuecomment] skip some edge cases, respect indentWithTabs
* line comment: - if both cursor and line comment are at pos 0 - if cursor is at EOL or in trailing space at EOL, but always continue if the next line is a line comment * block comment: - if it's inside a line comment e.g. // /*
1 parent 86a87a2 commit b5e77b4

File tree

1 file changed

+54
-19
lines changed

1 file changed

+54
-19
lines changed

addon/comment/continuecomment.js

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
else // Plain browser env
1010
mod(CodeMirror);
1111
})(function(CodeMirror) {
12+
var nonspace = /\S/g;
13+
var repeat = String.prototype.repeat || function (n) { return Array(n + 1).join(this); };
1214
function continueComment(cm) {
1315
if (cm.getOption("disableInput")) return CodeMirror.Pass;
1416
var ranges = cm.listSelections(), mode, inserts = [];
@@ -19,29 +21,56 @@
1921
if (!mode) mode = modeHere;
2022
else if (mode != modeHere) return CodeMirror.Pass;
2123

22-
var insert = null;
23-
if (mode.blockCommentStart && mode.blockCommentContinue) {
24-
var line = cm.getLine(pos.line).slice(0, pos.ch)
25-
var end = line.lastIndexOf(mode.blockCommentEnd), found
26-
if (end != -1 && end == pos.ch - mode.blockCommentEnd.length) {
27-
// Comment ended, don't continue it
28-
} else if ((found = line.lastIndexOf(mode.blockCommentStart)) > -1 && found > end) {
29-
insert = line.slice(0, found)
30-
if (/\S/.test(insert)) {
31-
insert = ""
32-
for (var j = 0; j < found; ++j) insert += " "
24+
var insert = null, line, found;
25+
var blockStart = mode.blockCommentStart, lineCmt = mode.lineComment;
26+
if (blockStart && mode.blockCommentContinue) {
27+
line = cm.getLine(pos.line);
28+
var end = line.lastIndexOf(mode.blockCommentEnd, pos.ch - mode.blockCommentEnd.length);
29+
// 1. if this block comment ended
30+
// 2. if this is actually inside a line comment
31+
if (end != -1 && end == pos.ch - mode.blockCommentEnd.length ||
32+
lineCmt && (found = line.lastIndexOf(lineCmt, pos.ch - 1)) > -1 &&
33+
/\bcomment\b/.test(cm.getTokenTypeAt({line: pos.line, ch: found + 1}))) {
34+
// ...then don't continue it
35+
} else if ((found = line.lastIndexOf(blockStart, pos.ch - blockStart.length)) > -1 &&
36+
found > end) {
37+
// reuse the existing leading spaces/tabs/mixed
38+
// or build the correct indent using CM's tab/indent options
39+
if (nonspaceAfter(0, line) >= found) {
40+
insert = line.slice(0, found);
41+
} else {
42+
var tabSize = cm.options.tabSize, numTabs;
43+
found = CodeMirror.countColumn(line, found, tabSize);
44+
insert = !cm.options.indentWithTabs ? repeat.call(" ", found) :
45+
repeat.call("\t", (numTabs = Math.floor(found / tabSize))) +
46+
repeat.call(" ", found - tabSize * numTabs);
3347
}
34-
} else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 && !/\S/.test(line.slice(0, found))) {
35-
insert = line.slice(0, found)
48+
} else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 &&
49+
found <= pos.ch &&
50+
found <= nonspaceAfter(0, line)) {
51+
insert = line.slice(0, found);
3652
}
3753
if (insert != null) insert += mode.blockCommentContinue
3854
}
39-
if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) {
40-
var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment);
41-
if (found > -1) {
42-
insert = line.slice(0, found);
43-
if (/\S/.test(insert)) insert = null;
44-
else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0];
55+
if (insert == null && lineCmt && continueLineCommentEnabled(cm)) {
56+
if (line == null) line = cm.getLine(pos.line);
57+
found = line.indexOf(lineCmt);
58+
// cursor at pos 0, line comment also at pos 0 => shift it down, don't continue
59+
if (!pos.ch && !found) insert = "";
60+
// continue only if the line starts with an optional space + line comment
61+
else if (found > -1 && nonspaceAfter(0, line) >= found) {
62+
// don't continue if there's only space(s) after cursor or the end of the line
63+
insert = nonspaceAfter(pos.ch, line) > -1;
64+
// but always continue if the next line starts with a line comment too
65+
if (!insert) {
66+
var next = cm.getLine(pos.line + 1) || '',
67+
nextFound = next.indexOf(lineCmt);
68+
insert = nextFound > -1 && nonspaceAfter(0, next) >= nextFound || null;
69+
}
70+
if (insert) {
71+
insert = line.slice(0, found) + lineCmt +
72+
line.slice(found + lineCmt.length).match(/^\s*/)[0];
73+
}
4574
}
4675
}
4776
if (insert == null) return CodeMirror.Pass;
@@ -54,6 +83,12 @@
5483
});
5584
}
5685

86+
function nonspaceAfter(ch, str) {
87+
nonspace.lastIndex = ch;
88+
var m = nonspace.exec(str);
89+
return m ? m.index : -1;
90+
}
91+
5792
function continueLineCommentEnabled(cm) {
5893
var opt = cm.getOption("continueComments");
5994
if (opt && typeof opt == "object")

0 commit comments

Comments
 (0)