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

Fix: No gray JSLint star when Brackets launched with JSLint disabled #2099

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/command/Commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ define(function (require, exports, module) {
exports.EDIT_DUPLICATE = "edit.duplicate";
exports.EDIT_DELETE_LINES = "edit.deletelines";
exports.EDIT_LINE_COMMENT = "edit.lineComment";
exports.EDIT_BLOCK_COMMENT = "edit.blockComment";
exports.EDIT_LINE_UP = "edit.lineUp";
exports.EDIT_LINE_DOWN = "edit.lineDown";

Expand Down
2 changes: 2 additions & 0 deletions src/command/Menus.js
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,8 @@ define(function (require, exports, module) {
platform: "mac"}]);
menu.addMenuDivider();
menu.addMenuItem(Commands.EDIT_LINE_COMMENT, "Ctrl-/");
menu.addMenuItem(Commands.EDIT_BLOCK_COMMENT, [{key: "Ctrl-Shift-/", platform: "win"},
{key: "Ctrl-Alt-/", platform: "mac"}]);

/*
* View menu
Expand Down
250 changes: 240 additions & 10 deletions src/editor/EditorCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ define(function (require, exports, module) {
var Commands = require("command/Commands"),
Strings = require("strings"),
CommandManager = require("command/CommandManager"),
EditorManager = require("editor/EditorManager");
EditorManager = require("editor/EditorManager"),
StringUtils = require("utils/StringUtils"),
TokenUtils = require("utils/TokenUtils");


/**
Expand All @@ -44,6 +46,30 @@ define(function (require, exports, module) {
var DIRECTION_UP = -1;
var DIRECTION_DOWN = +1;


/**
* @private
* Searchs for an uncomented line in between sartLine and endLine
* @param {!Editor} editor
* @param {!number} startLine - valid line inside the document
* @param {!number} endLine - valid line inside the document
* @return {boolean} true if there is at least one uncomented line
*/
function _containsUncommented(editor, startLine, endLine) {
var containsUncommented = false;
var i;
var line;
for (i = startLine; i <= endLine; i++) {
line = editor.document.getLine(i);
// A line is commented out if it starts with 0-N whitespace chars, then "//"
if (!line.match(/^\s*\/\//) && line.match(/\S/)) {
containsUncommented = true;
break;
}
}
return containsUncommented;
}

/**
* Add or remove line-comment tokens to all the lines in the selected range, preserving selection
* and cursor position. Applies to currently focused Editor.
Expand All @@ -70,17 +96,9 @@ define(function (require, exports, module) {
// Decide if we're commenting vs. un-commenting
// Are there any non-blank lines that aren't commented out? (We ignore blank lines because
// some editors like Sublime don't comment them out)
var containsUncommented = false;
var containsUncommented = _containsUncommented(editor, startLine, endLine);
var i;
var line;
for (i = startLine; i <= endLine; i++) {
line = doc.getLine(i);
// A line is commented out if it starts with 0-N whitespace chars, then "//"
if (!line.match(/^\s*\/\//) && line.match(/\S/)) {
containsUncommented = true;
break;
}
}

// Make the edit
doc.batchOperation(function () {
Expand Down Expand Up @@ -130,6 +148,217 @@ define(function (require, exports, module) {
}


/**
* @private
* Moves the token context to the token that starts the block-comment. Ctx starts in a block-comment
* Returns the position of the prefix.
* @param {!{editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}}} ctx - token context
* @param {!RegExp} prefixExp - a valid regular expression
* @return {{line: number, ch: number}}
*/
function _findCommentStart(ctx, prefixExp) {
while (!ctx.token.string.match(prefixExp)) {
TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken, ctx);
}
return {line: ctx.pos.line, ch: ctx.token.start};
}

/**
* @private
* Moves the token context to the token that ends the block-comment. Ctx starts in a block-comment.
* Returns the position of the sufix or null if gets to the end of the document and didn't found it.
* @param {!{editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}}} ctx - token context
* @param {!RegExp} suffixExp - a valid regular expression
* @param {!number} suffixLen - length of the suffix
* @return {?{line: number, ch: number}}
*/
function _findCommentEnd(ctx, suffixExp, suffixLen) {
var result = true;

while (result && !ctx.token.string.match(suffixExp)) {
result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, ctx);
}
return !result ? null : {line: ctx.pos.line, ch: ctx.token.end - suffixLen};
}

/**
* @private
* Movesthe token context to the next block-comment if there is one before end.
* @param {!{editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}}} ctx - token context
* @param {!{line: number, ch: number}} end - where to stop searching
* @param {!RegExp} prefixExp - a valid regular expression
* @return {boolean} - true if it found a block-comment
*/
function _findNextBlockComment(ctx, end, prefixExp) {
var index = ctx.editor.indexFromPos(end),
search = ctx.editor.indexFromPos(ctx.pos) <= index;

while (search && !ctx.token.string.match(prefixExp)) {
TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, ctx);
search = ctx.editor.indexFromPos(ctx.pos) <= index;
}
return search && !!ctx.token.string.match(prefixExp);
}

/**
* Add or remove block-comment tokens to the selection, preserving selection
* and cursor position. Applies to the currently focused Editor.
*
* If the selection is inside a block-comment or one block-comment is inside or partially
* inside the selection we uncomment; otherwise we comment out.
* Commenting out adds the prefix before the selection and the suffix after.
* Uncommenting removes them.
*
* If slashComment is true and the start or end of the selection is inside a line-comment it
* will try to do a line uncomment if is not actually inside a bigger block comment and all
* the lines in the selection are line-commented.
*
* @param {!Editor} editor
* @param {!String} prefix
* @param {!String} suffix
* @param {?boolean} slashComment - true if the mode also supports "//" comments
*/
function blockCommentPrefixSuffix(editor, prefix, suffix, slashComment) {

var doc = editor.document,
sel = editor.getSelection(),
startCtx = TokenUtils.getInitialContext(editor._codeMirror, {line: sel.start.line, ch: sel.start.ch}),
endCtx = TokenUtils.getInitialContext(editor._codeMirror, {line: sel.end.line, ch: sel.end.ch}),
prefixExp = new RegExp("^" + StringUtils.regexEscape(prefix), "g"),
suffixExp = new RegExp(StringUtils.regexEscape(suffix) + "$", "g"),
prefixPos = null,
suffixPos = null,
canComment = false;

var result;

// If we are in an empty selection, find the next non-empty token
if (startCtx.token.className === null && endCtx.token.className === null) {
result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, startCtx);

// We found a comment, find the start and end and check if the selection is inside the block-comment
if (startCtx.token.className === "comment") {
prefixPos = _findCommentStart(startCtx, prefixExp);
suffixPos = _findCommentEnd(startCtx, suffixExp, suffix.length);

if (!editor.posWithinRange(sel.start, prefixPos, suffixPos)) {
canComment = true;
}
} else {
canComment = true;
}
} else {

// Move the context to the first non-empty token
if (startCtx.token.className === null) {
TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, startCtx);
}

// Check if we should just do a line uncomment (if all lines in the selection are commented)
if (slashComment && (startCtx.token.string.match(/^\/\//) || endCtx.token.string.match(/^\/\//))) {
// Find if we aren't actually inside a block-comment
while (startCtx.token.string.match(/^\/\//)) {
result = TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken, startCtx);
}

if (!result || startCtx.token.className !== "comment" || startCtx.token.string.match(suffixExp)) {
if (!_containsUncommented(editor, sel.start.line, sel.end.line)) {
lineCommentSlashSlash(editor);
return;
// If can't uncomment then let the user comment even if it will be an invalid block-comment
} else {
canComment = true;
}
} else {
prefixPos = _findCommentStart(startCtx, prefixExp);
suffixPos = _findCommentEnd(startCtx, suffixExp, suffix.length);
}

// If the start is inside a comment, find the prefix and suffix positions
} else if (startCtx.token.className === "comment") {
prefixPos = _findCommentStart(startCtx, prefixExp);
suffixPos = _findCommentEnd(startCtx, suffixExp, suffix.length);

// If not try to find the first comment inside the selection
} else {
result = _findNextBlockComment(startCtx, sel.end, prefixExp);

// If nothing was found is ok to comment
if (!result) {
canComment = true;
} else {
if (!startCtx.token.string.match(prefixExp)) {
prefixPos = _findCommentStart(startCtx, prefixExp);
} else {
prefixPos = {line: startCtx.pos.line, ch: startCtx.token.start};
}
suffixPos = _findCommentEnd(startCtx, suffixExp, suffix.length);
}
}
}

// Search if there is another comment in the selection. Let the user comment if there is.
if (!canComment && suffixPos) {
var start = {line: suffixPos.line, ch: suffixPos.ch + suffix.length + 1};
if (editor.posWithinRange(start, sel.start, sel.end)) {
// Start searching at the next token
result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, startCtx);
result = !result || _findNextBlockComment(startCtx, sel.end, prefixExp);

if (result) {
canComment = true;
}
}
}


// Make the edit
doc.batchOperation(function () {

if (canComment) {
// Comment out - add the suffix to the start and the prefix to the end
doc.replaceRange(prefix + editor.getSelectedText() + suffix, sel.start, sel.end);

// Correct the selection by prefix length
var newSelStart = {line: sel.start.line, ch: sel.start.ch + prefix.length};
if (sel.start.line === sel.end.line) {
editor.setSelection(newSelStart, {line: sel.end.line, ch: sel.end.ch + prefix.length});
} else {
editor.setSelection(newSelStart, {line: sel.end.line, ch: sel.end.ch});
}

} else {
// Uncomment - remove prefix and suffix
if (suffixPos) {
doc.replaceRange("", suffixPos, {line: suffixPos.line, ch: suffixPos.ch + suffix.length});
}
doc.replaceRange("", prefixPos, {line: prefixPos.line, ch: prefixPos.ch + prefix.length});
}
});
}

/**
* Invokes a language-specific block-comment/uncomment handler
* @param {?Editor} editor If unspecified, applies to the currently focused editor
*/
function blockComment(editor) {
editor = editor || EditorManager.getFocusedEditor();
if (!editor) {
return;
}

var mode = editor.getModeForSelection();

if (mode === "javascript" || mode === "less") {
blockCommentPrefixSuffix(editor, "/*", "*/", true);
} else if (mode === "css") {
blockCommentPrefixSuffix(editor, "/*", "*/");
} else if (mode === "html") {
blockCommentPrefixSuffix(editor, "<!--", "-->");
}
}


/**
* Duplicates the selected text, or current line if no selection. The cursor/selection is left
* on the second copy.
Expand Down Expand Up @@ -317,6 +546,7 @@ define(function (require, exports, module) {
CommandManager.register(Strings.CMD_INDENT, Commands.EDIT_INDENT, indentText);
CommandManager.register(Strings.CMD_UNINDENT, Commands.EDIT_UNINDENT, unidentText);
CommandManager.register(Strings.CMD_COMMENT, Commands.EDIT_LINE_COMMENT, lineComment);
CommandManager.register(Strings.CMD_BLOCK_COMMENT, Commands.EDIT_BLOCK_COMMENT, blockComment);
CommandManager.register(Strings.CMD_DUPLICATE, Commands.EDIT_DUPLICATE, duplicateText);
CommandManager.register(Strings.CMD_DELETE_LINES, Commands.EDIT_DELETE_LINES, deleteCurrentLines);
CommandManager.register(Strings.CMD_LINE_UP, Commands.EDIT_LINE_UP, moveLineUp);
Expand Down
2 changes: 1 addition & 1 deletion src/language/JSLintUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ define(function (require, exports, module) {
var $jslintResults = $("#jslint-results"),
$jslintContent = $("#jslint-results .table-container");

StatusBar.addIndicator(module.id, $("#gold-star"), false);
StatusBar.addIndicator(module.id, $("#gold-star"), true);
});

// Define public API
Expand Down
1 change: 1 addition & 0 deletions src/nls/root/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ define({
"CMD_DUPLICATE" : "Duplicate",
"CMD_DELETE_LINES" : "Delete Line",
"CMD_COMMENT" : "Toggle Line Comment",
"CMD_BLOCK_COMMENT" : "Toggle Block Comment",
"CMD_LINE_UP" : "Move Line Up",
"CMD_LINE_DOWN" : "Move Line Down",

Expand Down