-
Notifications
You must be signed in to change notification settings - Fork 28.8k
/
sortLinesCommand.ts
106 lines (84 loc) · 3.05 KB
/
sortLinesCommand.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { ITextModel, IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
export class SortLinesCommand implements editorCommon.ICommand {
private selection: Selection;
private selectionId: string;
private descending: boolean;
constructor(selection: Selection, descending: boolean) {
this.selection = selection;
this.descending = descending;
}
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
let op = sortLines(model, this.selection, this.descending);
if (op) {
builder.addEditOperation(op.range, op.text);
}
this.selectionId = builder.trackSelection(this.selection);
}
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
return helper.getTrackedSelection(this.selectionId);
}
public static canRun(model: ITextModel, selection: Selection, descending: boolean): boolean {
let 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;
}
}
function getSortData(model: ITextModel, selection: Selection, descending: boolean) {
let 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;
}
let 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((a, b) => {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
// 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: ITextModel, selection: Selection, descending: boolean): IIdentifiedSingleEditOperation {
let 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')
);
}