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

Commit

Permalink
Add new comments preference. Support indent block comments on line co…
Browse files Browse the repository at this point in the history
…mment command
  • Loading branch information
ficristo committed Apr 1, 2017
1 parent e1caef2 commit 99479bf
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 11 deletions.
41 changes: 39 additions & 2 deletions src/editor/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ define(function (require, exports, module) {
TokenUtils = require("utils/TokenUtils"),
ValidationUtils = require("utils/ValidationUtils"),
ViewUtils = require("utils/ViewUtils"),
DeprecationWarning = require("utils/DeprecationWarning"),
MainViewManager = require("view/MainViewManager"),
_ = require("thirdparty/lodash");

Expand All @@ -96,7 +97,8 @@ define(function (require, exports, module) {
UPPERCASE_COLORS = "uppercaseColors",
USE_TAB_CHAR = "useTabChar",
WORD_WRAP = "wordWrap",
INDENT_LINE_COMMENT = "indentLineComment";
INDENT_LINE_COMMENT = "indentLineComment",
COMMENTS = "comments";

/**
* A list of gutter name and priorities currently registered for editors.
Expand Down Expand Up @@ -228,6 +230,17 @@ define(function (require, exports, module) {
description: Strings.DESCRIPTION_INDENT_LINE_COMMENT
});

PreferencesManager.definePreference(COMMENTS, "object", { indent: false }, {
description: Strings.DESCRIPTION_COMMENTS,
keys: {
indent: {
type: "boolean",
description: Strings.DESCRIPTION_COMMENTS_INDENT,
initial: false
}
}
});

var editorOptions = Object.keys(cmOptions);

/** Editor preferences */
Expand Down Expand Up @@ -2684,24 +2697,48 @@ define(function (require, exports, module) {
/**
* Sets lineCommentIndent option.
*
* @deprecated
* @param {boolean} value
* @param {string=} fullPath Path to file to get preference for
* @return {boolean} true if value was valid
*/
Editor.setIndentLineComment = function (value, fullPath) {
DeprecationWarning.deprecationWarning("Editor.setIndentLineComment has been deprecated. Use Editor.setCommentsPreferences instead.");
var options = fullPath && {context: fullPath};
return PreferencesManager.set(INDENT_LINE_COMMENT, value, options);
};

/**
* Returns true if word wrap is enabled for the specified or current file
* Returns true if lineCommentIndent is enabled for the specified or current file
* @param {string=} fullPath Path to file to get preference for
* @return {boolean}
*/
Editor.getIndentLineComment = function (fullPath) {
DeprecationWarning.deprecationWarning("Editor.getIndentLineComment has been deprecated. Use Editor.getCommentsPreferences instead.");
return PreferencesManager.get(INDENT_LINE_COMMENT, _buildPreferencesContext(fullPath));
};

/**
* Sets comments option.
* Affects any editors that share the same preference location.
* @param {boolean} value
* @param {string=} fullPath Path to file to get preference for
* @return {boolean} true if value was valid
*/
Editor.setCommentsPreferences = function (value, fullPath) {
var options = fullPath && {context: fullPath};
return PreferencesManager.set(COMMENTS, value, options);
};

/**
* Returns the comments preferences for the specified or current file
* @param {string=} fullPath Path to file to get preference for
* @return {boolean}
*/
Editor.getCommentsPreferences = function (fullPath) {
return PreferencesManager.get(COMMENTS, _buildPreferencesContext(fullPath));
};

/**
* Runs callback for every Editor instance that currently exists
* @param {!function(!Editor)} callback
Expand Down
60 changes: 52 additions & 8 deletions src/editor/EditorCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,12 @@ define(function (require, exports, module) {
var originalCursorPosition = line.search(/\S|$/);

var firstCharPosition, cursorPosition = originalCursorPosition;


var commentsPref = Editor.getCommentsPreferences();

for (i = startLine; i <= endLine; i++) {
//check if preference for indent line comment is available otherwise go back to default indentation
if (Editor.getIndentLineComment()) {
if (commentsPref.indent || Editor.getIndentLineComment()) {
//ignore the first line and recalculate cursor position for first non white space char of every line
if (i !== startLine) {
line = doc.getLine(i);
Expand Down Expand Up @@ -297,6 +299,22 @@ define(function (require, exports, module) {
return false;
}

/**
* Return the column of the first non whitespace char in the given line.
*
* @private
* @param {!Document} doc
* @param {number} lineNum
* @returns {number} the column index or null
*/
function _firstNotWs(doc, lineNum) {
var text = doc.getLine(lineNum);
if (text === null || text === undefined) {
return null;
}

return text.search(/\S|$/);
}

/**
* Generates an edit that adds or removes block-comment tokens to the selection, preserving selection
Expand Down Expand Up @@ -345,6 +363,8 @@ define(function (require, exports, module) {

var searchCtx, atSuffix, suffixEnd, initialPos, endLine;

var commentsPref = Editor.getCommentsPreferences();

if (!selectionsToTrack) {
// Track the original selection.
selectionsToTrack = [_.cloneDeep(sel)];
Expand Down Expand Up @@ -467,12 +487,29 @@ define(function (require, exports, module) {
// Comment out - add the suffix to the start and the prefix to the end.
if (canComment) {
var completeLineSel = sel.start.ch === 0 && sel.end.ch === 0 && sel.start.line < sel.end.line;
var startCh = _firstNotWs(doc, sel.start.line);
if (completeLineSel) {
editGroup.push({text: suffix + "\n", start: sel.end});
editGroup.push({text: prefix + "\n", start: sel.start});
if (commentsPref.indent) {
var endCh = _firstNotWs(doc, sel.end.line - 1);
editGroup.push({
text: _.repeat(" ", endCh) + suffix + "\n",
start: {line: sel.end.line, ch: 0}
});
editGroup.push({
text: prefix + "\n" + _.repeat(" ", startCh),
start: {line: sel.start.line, ch: startCh}
});
} else {
editGroup.push({text: suffix + "\n", start: sel.end});
editGroup.push({text: prefix + "\n", start: sel.start});
}
} else {
editGroup.push({text: suffix, start: sel.end});
editGroup.push({text: prefix, start: sel.start});
if (commentsPref.indent) {
editGroup.push({text: prefix, start: { line: sel.start.line, ch: startCh }});
} else {
editGroup.push({text: prefix, start: sel.start});
}
}

// Correct the tracked selections. We can't just use the default selection fixup,
Expand Down Expand Up @@ -513,24 +550,31 @@ define(function (require, exports, module) {
// If both are found we assume that a complete line selection comment added new lines, so we remove them.
var line = doc.getLine(prefixPos.line).trim(),
prefixAtStart = prefixPos.ch === 0 && prefix.length === line.length,
suffixAtStart = false;
prefixIndented = commentsPref.indent && prefix.length === line.length,
suffixAtStart = false,
suffixIndented = false;

if (suffixPos) {
line = doc.getLine(suffixPos.line).trim();
suffixAtStart = suffixPos.ch === 0 && suffix.length === line.length;
suffixIndented = commentsPref.indent && suffix.length === line.length;
}

// Remove the suffix if there is one
if (suffixPos) {
if (prefixAtStart && suffixAtStart) {
if (prefixIndented) {
editGroup.push({text: "", start: {line: suffixPos.line, ch: 0}, end: {line: suffixPos.line + 1, ch: 0}});
} else if (prefixAtStart && suffixAtStart) {
editGroup.push({text: "", start: suffixPos, end: {line: suffixPos.line + 1, ch: 0}});
} else {
editGroup.push({text: "", start: suffixPos, end: {line: suffixPos.line, ch: suffixPos.ch + suffix.length}});
}
}

// Remove the prefix
if (prefixAtStart && suffixAtStart) {
if (suffixIndented) {
editGroup.push({text: "", start: {line: prefixPos.line, ch: 0}, end: {line: prefixPos.line + 1, ch: 0}});
} else if (prefixAtStart && suffixAtStart) {
editGroup.push({text: "", start: prefixPos, end: {line: prefixPos.line + 1, ch: 0}});
} else {
editGroup.push({text: "", start: prefixPos, end: {line: prefixPos.line, ch: prefixPos.ch + prefix.length}});
Expand Down
80 changes: 79 additions & 1 deletion test/spec/EditorCommandHandlers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ define(function (require, exports, module) {

require("editor/EditorCommandHandlers");

var shouldIndentLineComment = Editor.getIndentLineComment();
var shouldIndentLineComment = Editor.getIndentLineComment(),
commentsPrefDefault = Editor.getCommentsPreferences();

describe("EditorCommandHandlers", function () {

Expand Down Expand Up @@ -935,6 +936,83 @@ define(function (require, exports, module) {
});
});

describe("Line comment/uncomment in languages with only block comments and with comments.indent enabled", function () {
var htmlContent = "<html>\n" +
" <body>\n" +
" <p>Hello</p>\n" +
" </body>\n" +
"</html>";

beforeEach(function () {
setupFullEditor(htmlContent, "html");
PreferencesManager.set("comments", { indent: true });
});

afterEach(function () {
PreferencesManager.set("comments", commentsPrefDefault);
});

it("should comment/uncomment a single line, cursor at start", function () {
myEditor.setCursorPos(2, 0);

var lines = htmlContent.split("\n");
lines[2] = " <!--<p>Hello</p>-->";
var expectedText = lines.join("\n");

testToggleLine(expectedText, {line: 2, ch: 4});
});

it("should comment/uncomment a block", function () {
myEditor.setSelection({line: 1, ch: 7}, {line: 3, ch: 7});

CommandManager.execute(Commands.EDIT_LINE_COMMENT, myEditor);

var expectedText = "<html>\n" +
" <!--\n" +
" <body>\n" +
" <p>Hello</p>\n" +
" </body>\n" +
" -->\n" +
"</html>";

expect(myDocument.getText()).toEqual(expectedText);
expectSelection({start: {line: 2, ch: 7}, end: {line: 4, ch: 7}});
});

it("should comment/uncomment a block with not closing tag ", function () {
myEditor.setSelection({line: 1, ch: 7}, {line: 2, ch: 7});

CommandManager.execute(Commands.EDIT_LINE_COMMENT, myEditor);

var expectedText = "<html>\n" +
" <!--\n" +
" <body>\n" +
" <p>Hello</p>\n" +
" -->\n" +
" </body>\n" +
"</html>";

expect(myDocument.getText()).toEqual(expectedText);
expectSelection({start: {line: 2, ch: 7}, end: {line: 3, ch: 7}});
});

it("should comment/uncomment a block with not closing tag at end of file", function () {
myEditor.setSelection({line: 3, ch: 9}, {line: 4, ch: 5});

CommandManager.execute(Commands.EDIT_LINE_COMMENT, myEditor);

var expectedText = "<html>\n" +
" <body>\n" +
" <p>Hello</p>\n" +
" <!--\n" +
" </body>\n" +
"</html>-->\n";

expect(myDocument.getText()).toEqual(expectedText);
expectSelection({start: {line: 4, ch: 9}, end: {line: 5, ch: 5}});
});
});

describe("Line comment in languages with mutiple line comment prefixes", function () {
// Define a special version of JavaScript for testing purposes
LanguageManager.defineLanguage("javascript2", {
Expand Down

0 comments on commit 99479bf

Please sign in to comment.