Skip to content

Commit 9ebc136

Browse files
committed
feat: add fix all problems button for eslint/other problems
1 parent d663d4e commit 9ebc136

4 files changed

Lines changed: 95 additions & 6 deletions

File tree

src/editor/Editor.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,18 @@ define(function (require, exports, module) {
14741474
this._codeMirror.replaceSelection(replacement, select);
14751475
};
14761476

1477+
/**
1478+
* Replaces the content of multiple selections with the strings in the array. The length of the given
1479+
* array should be the same as the number of active selections.
1480+
* @param {Array<string>} replacement the text array to replace the current selections with
1481+
* @param {string} [select] The optional select argument can be used to change selection. Passing "around"
1482+
* will cause the new text to be selected, passing "start" will collapse the selection to the start
1483+
* of the inserted text.
1484+
*/
1485+
Editor.prototype.replaceSelections = function (replacement, select) {
1486+
this._codeMirror.replaceSelections(replacement, select);
1487+
};
1488+
14771489
/**
14781490
* Replace the part of the document between from and to with the given string.
14791491
* @param {string} replacement the text to replace the current selection
@@ -1488,6 +1500,40 @@ define(function (require, exports, module) {
14881500
this._codeMirror.replaceRange(replacement, from, to, origin);
14891501
};
14901502

1503+
1504+
/**
1505+
* Replaces multiple ranges in the editor with the specified texts.
1506+
*
1507+
* @method
1508+
* @param {Array} ranges - An array of range objects, each containing `from`, `to`, and `text` properties.
1509+
* @param {Object} ranges[].from - The start position of the range to be replaced. It should have `line` and `ch` properties.
1510+
* @param {Object} ranges[].to - The end position of the range to be replaced. It should have `line` and `ch` properties.
1511+
* @param {string} ranges[].text - The text to replace the specified range.
1512+
* @param {string} [origin] - An optional origin identifier to be associated with the changes.
1513+
* @example
1514+
* editor.replaceMultipleRanges([
1515+
* { from: { line: 0, ch: 0 }, to: { line: 0, ch: 5 }, text: 'Hello' },
1516+
* { from: { line: 1, ch: 0 }, to: { line: 1, ch: 4 }, text: 'World' }
1517+
* ], 'exampleOrigin');
1518+
*/
1519+
Editor.prototype.replaceMultipleRanges = function (ranges, origin) {
1520+
// Sort ranges in descending order by start position so that they dont step over each other
1521+
let self = this;
1522+
self.operation(()=>{
1523+
ranges.sort((a, b) => {
1524+
if (a.from.line === b.from.line) {
1525+
return b.from.ch - a.from.ch;
1526+
}
1527+
return b.from.line - a.from.line;
1528+
});
1529+
1530+
// Replace each range with its corresponding replacement text
1531+
ranges.forEach(range => {
1532+
self.replaceRange(range.text, range.from, range.to, origin);
1533+
});
1534+
});
1535+
};
1536+
14911537
/**
14921538
* Clears any active selection if present.
14931539
*/

src/htmlContent/problems-panel.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<div id="problems-panel" class="bottom-panel vert-resizable top-resizer">
22
<div class="toolbar simple-toolbar-layout">
3+
<button class="btn btn-mini primary problems-fix-all-btn forced-hidden" style="margin-right: 10px;">Fix All</button>
34
<div class="title"><!-- filled in programmatically --></div>
45
<a href="#" class="close">&times;</a>
56
</div>

src/language/CodeInspection.js

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ define(function (require, exports, module) {
119119
*/
120120
var $problemsPanel;
121121

122+
let $fixAllBtn;
123+
122124
/**
123125
* @private the panelView
124126
* @type {Panel}
@@ -350,6 +352,7 @@ define(function (require, exports, module) {
350352
* @param fileName
351353
*/
352354
function updatePanelTitleAndStatusBar(numProblems, providersReportingProblems, aborted, fileName) {
355+
$fixAllBtn.addClass("forced-hidden");
353356
var message, tooltip;
354357

355358
if (providersReportingProblems.length === 1) {
@@ -358,14 +361,20 @@ define(function (require, exports, module) {
358361
$problemsPanelTable.find("tr").removeClass("forced-hidden");
359362

360363
if (numProblems === 1 && !aborted) {
361-
message = StringUtils.format(Strings.SINGLE_ERROR, providersReportingProblems[0].name, fileName);
364+
message = documentFixes.size ?
365+
StringUtils.format(Strings.SINGLE_ERROR_FIXABLE, providersReportingProblems[0].name,
366+
documentFixes.size, fileName):
367+
StringUtils.format(Strings.SINGLE_ERROR, providersReportingProblems[0].name, fileName);
362368
} else {
363369
if (aborted) {
364370
numProblems += "+";
365371
}
366372

367-
message = StringUtils.format(Strings.MULTIPLE_ERRORS, providersReportingProblems[0].name, numProblems,
368-
fileName);
373+
message = documentFixes.size ?
374+
StringUtils.format(Strings.MULTIPLE_ERRORS_FIXABLE, numProblems,
375+
providersReportingProblems[0].name, documentFixes.size, fileName):
376+
StringUtils.format(Strings.MULTIPLE_ERRORS, numProblems,
377+
providersReportingProblems[0].name, fileName);
369378
}
370379
} else if (providersReportingProblems.length > 1) {
371380
$problemsPanelTable.find(".inspector-section").show();
@@ -374,7 +383,10 @@ define(function (require, exports, module) {
374383
numProblems += "+";
375384
}
376385

377-
message = StringUtils.format(Strings.ERRORS_PANEL_TITLE_MULTIPLE, numProblems, fileName);
386+
message = documentFixes.size ?
387+
StringUtils.format(Strings.ERRORS_PANEL_TITLE_MULTIPLE_FIXABLE, numProblems,
388+
documentFixes.size, fileName):
389+
StringUtils.format(Strings.ERRORS_PANEL_TITLE_MULTIPLE, numProblems, fileName);
378390
} else {
379391
return;
380392
}
@@ -386,6 +398,7 @@ define(function (require, exports, module) {
386398
tooltip = StringUtils.format(Strings.STATUSBAR_CODE_INSPECTION_TOOLTIP_WITH_FIX,
387399
documentFixes.size, message);
388400
iconType = "inspection-repair";
401+
$fixAllBtn.removeClass("forced-hidden");
389402
}
390403

391404
StatusBar.updateIndicator(INDICATOR_ID, true, iconType, tooltip);
@@ -1006,14 +1019,40 @@ define(function (require, exports, module) {
10061019
MainViewManager.focusActivePane();
10071020
run();
10081021
}
1009-
1022+
1023+
function _fixAllProblems() {
1024+
const editor = EditorManager.getCurrentFullEditor();
1025+
if(!editor || editor.document.lastChangeTimestamp !== lastDocumentScanTimeStamp) {
1026+
Dialogs.showErrorDialog(Strings.CANNOT_FIX_TITLE, Strings.CANNOT_FIX_MESSAGE);
1027+
return;
1028+
}
1029+
if(!documentFixes.size){
1030+
return;
1031+
}
1032+
const replacements = [];
1033+
for(let fixDetails of documentFixes.values()){
1034+
replacements.push({
1035+
from: editor.posFromIndex(fixDetails.rangeOffset.start),
1036+
to: editor.posFromIndex(fixDetails.rangeOffset.end),
1037+
text: fixDetails.replaceText
1038+
});
1039+
}
1040+
editor.replaceMultipleRanges(replacements, EDIT_ORIGIN_LINT_FIX);
1041+
const finalCursor = replacements[replacements.length - 1].from;
1042+
editor.setCursorPos(finalCursor.line, finalCursor.ch);
1043+
MainViewManager.focusActivePane();
1044+
run();
1045+
}
1046+
10101047
// Initialize items dependent on HTML DOM
10111048
AppInit.htmlReady(function () {
10121049
Editor.registerGutter(CODE_INSPECTION_GUTTER, CODE_INSPECTION_GUTTER_PRIORITY);
10131050
// Create bottom panel to list error details
10141051
var panelHtml = Mustache.render(PanelTemplate, Strings);
10151052
problemsPanel = WorkspaceManager.createBottomPanel("errors", $(panelHtml), 100);
10161053
$problemsPanel = $("#problems-panel");
1054+
$fixAllBtn = $problemsPanel.find(".problems-fix-all-btn");
1055+
$fixAllBtn.click(_fixAllProblems);
10171056

10181057
function checkSelectionInsideElement(range, element) {
10191058
if(!range || range.endOffset === range.startOffset) {

src/nls/root/strings.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,11 @@ define({
412412
// CodeInspection: errors/warnings
413413
"ERRORS_NO_FILE": "No File Open",
414414
"ERRORS_PANEL_TITLE_MULTIPLE": "{0} Problems - {1}",
415+
"ERRORS_PANEL_TITLE_MULTIPLE_FIXABLE": "{0} Problems, {1} Fixable - {2}",
415416
"SINGLE_ERROR": "1 {0} Problem - {1}",
416-
"MULTIPLE_ERRORS": "{1} {0} Problems - {2}",
417+
"SINGLE_ERROR_FIXABLE": "1 {0} Problem, {1} Fixable - {2}",
418+
"MULTIPLE_ERRORS": "{0} {1} Problems - {2}",
419+
"MULTIPLE_ERRORS_FIXABLE": "{0} {1} Problems, {2} Fixable - {3}",
417420
"NO_ERRORS": "No {0} problems found - good job!",
418421
"NO_ERRORS_MULTIPLE_PROVIDER": "No problems found - good job!",
419422
"LINT_DISABLED": "Linting is disabled",

0 commit comments

Comments
 (0)