mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 08:45:56 +01:00
Merge pull request #2796 from martellaj/joem/sort-lines
Adds sort lines (ascending and descending) command
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
|
||||
import {TPromise} from 'vs/base/common/winjs.base';
|
||||
import {SortLinesCommand} from 'vs/editor/contrib/linesOperations/common/sortLinesCommand';
|
||||
import {TrimTrailingWhitespaceCommand} from 'vs/editor/common/commands/trimTrailingWhitespaceCommand';
|
||||
import {EditorAction, HandlerEditorAction} from 'vs/editor/common/editorAction';
|
||||
import {Handler, ICommand, ICommonCodeEditor, IEditorActionDescriptorData} from 'vs/editor/common/editorCommon';
|
||||
@@ -100,6 +101,40 @@ class MoveLinesDownAction extends MoveLinesAction {
|
||||
}
|
||||
}
|
||||
|
||||
class SortLinesAction extends EditorAction {
|
||||
private descending:boolean;
|
||||
|
||||
constructor(descriptor:IEditorActionDescriptorData, editor:ICommonCodeEditor, descending:boolean) {
|
||||
super(descriptor, editor);
|
||||
this.descending = descending;
|
||||
}
|
||||
|
||||
public run():TPromise<boolean> {
|
||||
|
||||
var command = new SortLinesCommand(this.editor.getSelection(), this.descending);
|
||||
|
||||
this.editor.executeCommands(this.id, [command]);
|
||||
|
||||
return TPromise.as(true);
|
||||
}
|
||||
}
|
||||
|
||||
class SortLinesAscendingAction extends SortLinesAction {
|
||||
static ID ='editor.action.sortLinesAscending';
|
||||
|
||||
constructor(descriptor:IEditorActionDescriptorData, editor:ICommonCodeEditor) {
|
||||
super(descriptor, editor, false);
|
||||
}
|
||||
}
|
||||
|
||||
class SortLinesDescendingAction extends SortLinesAction {
|
||||
static ID ='editor.action.sortLinesDescending';
|
||||
|
||||
constructor(descriptor:IEditorActionDescriptorData, editor:ICommonCodeEditor) {
|
||||
super(descriptor, editor, true);
|
||||
}
|
||||
}
|
||||
|
||||
class TrimTrailingWhitespaceAction extends EditorAction {
|
||||
|
||||
static ID = 'editor.action.trimTrailingWhitespace';
|
||||
@@ -234,6 +269,14 @@ CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(DeleteLines
|
||||
context: ContextKey.EditorTextFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_K
|
||||
}));
|
||||
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(SortLinesAscendingAction, SortLinesAscendingAction.ID, nls.localize('lines.sortAscending', "Sort Lines Ascending"), {
|
||||
context: ContextKey.EditorTextFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_2
|
||||
}));
|
||||
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(SortLinesDescendingAction, SortLinesDescendingAction.ID, nls.localize('lines.sortDescending', "Sort Lines Descending"), {
|
||||
context: ContextKey.EditorTextFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_3
|
||||
}));
|
||||
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(TrimTrailingWhitespaceAction, TrimTrailingWhitespaceAction.ID, nls.localize('lines.trimTrailingWhitespace', "Trim Trailing Whitespace"), {
|
||||
context: ContextKey.EditorTextFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_X
|
||||
@@ -274,5 +317,3 @@ CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(InsertLineA
|
||||
context: ContextKey.EditorTextFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Enter
|
||||
}));
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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';
|
||||
|
||||
export class SortLinesCommand implements editorCommon.ICommand {
|
||||
|
||||
private selection:editorCommon.IEditorSelection;
|
||||
private selectionId:string;
|
||||
private descending:boolean;
|
||||
|
||||
constructor(selection:editorCommon.IEditorSelection, descending:boolean) {
|
||||
this.selection = selection;
|
||||
this.descending = descending;
|
||||
}
|
||||
|
||||
public getEditOperations(model:editorCommon.ITokenizedModel, 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:editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData):editorCommon.IEditorSelection {
|
||||
return helper.getTrackedSelection(this.selectionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate commands for sorting lines on a model.
|
||||
*/
|
||||
export function sortLines(model:editorCommon.ITextModel, selection:editorCommon.IEditorSelection, descending:boolean): editorCommon.IIdentifiedSingleEditOperation {
|
||||
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.sort((a, b) => {
|
||||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||
});
|
||||
|
||||
// If descending, reverse the order.
|
||||
if (descending === true) {
|
||||
sorted = sorted.reverse();
|
||||
}
|
||||
|
||||
return EditOperation.replace(
|
||||
new Range(startLineNumber, 1, endLineNumber, model.getLineMaxColumn(endLineNumber)),
|
||||
sorted.join('\n')
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {Selection} from 'vs/editor/common/core/selection';
|
||||
import {SortLinesCommand} from 'vs/editor/contrib/linesOperations/common/sortLinesCommand';
|
||||
import {testCommand} from 'vs/editor/test/common/commands/commandTestUtils';
|
||||
|
||||
function testSortLinesAscendingCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
|
||||
testCommand(lines, null, selection, (sel) => new SortLinesCommand(sel, false), expectedLines, expectedSelection);
|
||||
}
|
||||
|
||||
function testSortLinesDescendingCommand(lines: string[], selection: Selection, expectedLines: string[], expectedSelection: Selection): void {
|
||||
testCommand(lines, null, selection, (sel) => new SortLinesCommand(sel, true), expectedLines, expectedSelection);
|
||||
}
|
||||
|
||||
suite('Editor Contrib - Sort Lines Command', () => {
|
||||
|
||||
test('no op unless at least two lines selected 1', function () {
|
||||
testSortLinesAscendingCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 3, 1, 1),
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 3, 1, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('no op unless at least two lines selected 2', function () {
|
||||
testSortLinesAscendingCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 3, 2, 1),
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 3, 2, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('sorting two lines ascending', function () {
|
||||
testSortLinesAscendingCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(3, 3, 4, 2),
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'fourth line',
|
||||
'third line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(3, 3, 4, 2)
|
||||
);
|
||||
});
|
||||
|
||||
test('sorting first 4 lines ascending', function () {
|
||||
testSortLinesAscendingCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 1, 5, 1),
|
||||
[
|
||||
'first',
|
||||
'fourth line',
|
||||
'second line',
|
||||
'third line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 1, 5, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('sorting all lines ascending', function () {
|
||||
testSortLinesAscendingCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 1, 5, 6),
|
||||
[
|
||||
'fifth',
|
||||
'first',
|
||||
'fourth line',
|
||||
'second line',
|
||||
'third line',
|
||||
],
|
||||
new Selection(1, 1, 5, 6)
|
||||
);
|
||||
});
|
||||
|
||||
test('sorting first 4 lines desscending', function () {
|
||||
testSortLinesDescendingCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 1, 5, 1),
|
||||
[
|
||||
'third line',
|
||||
'second line',
|
||||
'fourth line',
|
||||
'first',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 1, 5, 1)
|
||||
);
|
||||
});
|
||||
|
||||
test('sorting all lines descending', function () {
|
||||
testSortLinesDescendingCommand(
|
||||
[
|
||||
'first',
|
||||
'second line',
|
||||
'third line',
|
||||
'fourth line',
|
||||
'fifth'
|
||||
],
|
||||
new Selection(1, 1, 5, 6),
|
||||
[
|
||||
'third line',
|
||||
'second line',
|
||||
'fourth line',
|
||||
'first',
|
||||
'fifth',
|
||||
],
|
||||
new Selection(1, 1, 5, 6)
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user