/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { EditOperation } from '../../../common/core/editOperation.js'; import { Range } from '../../../common/core/range.js'; export class SortLinesCommand { constructor(selection, descending) { this.selection = selection; this.descending = descending; this.selectionId = null; } static getCollator() { if (!SortLinesCommand._COLLATOR) { SortLinesCommand._COLLATOR = new Intl.Collator(); } return SortLinesCommand._COLLATOR; } getEditOperations(model, builder) { const op = sortLines(model, this.selection, this.descending); if (op) { builder.addEditOperation(op.range, op.text); } this.selectionId = builder.trackSelection(this.selection); } computeCursorState(model, helper) { return helper.getTrackedSelection(this.selectionId); } static canRun(model, selection, descending) { if (model === null) { return false; } const data = getSortData(model, selection, descending); if (!data) { return false; } for (let i = 0, len = data.before.length; i < len; i++) { if (data.before[i] !== data.after[i]) { return true; } } return false; } } SortLinesCommand._COLLATOR = null; function getSortData(model, selection, descending) { const startLineNumber = selection.startLineNumber; let endLineNumber = selection.endLineNumber; if (selection.endColumn === 1) { endLineNumber--; } // Nothing to sort if user didn't select anything. if (startLineNumber >= endLineNumber) { return null; } const linesToSort = []; // Get the contents of the selection to be sorted. for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { linesToSort.push(model.getLineContent(lineNumber)); } let sorted = linesToSort.slice(0); sorted.sort(SortLinesCommand.getCollator().compare); // If descending, reverse the order. if (descending === true) { sorted = sorted.reverse(); } return { startLineNumber: startLineNumber, endLineNumber: endLineNumber, before: linesToSort, after: sorted }; } /** * Generate commands for sorting lines on a model. */ function sortLines(model, selection, descending) { const data = getSortData(model, selection, descending); if (!data) { return null; } return EditOperation.replace(new Range(data.startLineNumber, 1, data.endLineNumber, model.getLineMaxColumn(data.endLineNumber)), data.after.join('\n')); }