From 7a3bca59aafeb7566c83fcfc0b42b424029e8f71 Mon Sep 17 00:00:00 2001 From: Joe Martella Date: Sun, 7 Feb 2016 14:48:00 -0800 Subject: [PATCH 1/2] Adds sort lines (ascending and descending) commands. --- .../common/commands/sortLinesCommand.ts | 72 +++++++++++++++++++ .../linesOperations/common/linesOperations.ts | 45 +++++++++++- 2 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/vs/editor/common/commands/sortLinesCommand.ts diff --git a/src/vs/editor/common/commands/sortLinesCommand.ts b/src/vs/editor/common/commands/sortLinesCommand.ts new file mode 100644 index 00000000000..7cba742c3dd --- /dev/null +++ b/src/vs/editor/common/commands/sortLinesCommand.ts @@ -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 {Range} from 'vs/editor/common/core/range'; +import {EditOperation} from 'vs/editor/common/core/editOperation'; +import EditorCommon = require('vs/editor/common/editorCommon'); +import Strings = require('vs/base/common/strings'); +import {Position} from 'vs/editor/common/core/position'; + +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 { + var ops = sortLines(model, this.selection, this.descending); + for (var i = 0, len = ops.length; i < len; i++) { + var op = ops[i]; + + 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 trimming trailing whitespace on a model and ignore lines on which cursors are sitting. + */ +export function sortLines(model:EditorCommon.ITextModel, selection:EditorCommon.IEditorSelection, descending:boolean): EditorCommon.IIdentifiedSingleEditOperation[] { + var r:EditorCommon.IIdentifiedSingleEditOperation[] = []; + + // Nothing to sort if user didn't select anything. + if (selection.startLineNumber === selection.endLineNumber) { + return r; + } + + var linesToSort = []; + + // Get the contents of the selection to be sorted. + for (var lineNumber = selection.startLineNumber; lineNumber <= selection.endLineNumber; lineNumber++) { + linesToSort.push(model.getLineContent(lineNumber)); + } + + var sorted = linesToSort.sort(); + + // If descending, reverse the order. + if (descending === true) { + sorted = sorted.reverse(); + } + + // Make sure all text across start and end lines are replaced. + selection.startColumn = 1; + selection.endColumn = model.getLineMaxColumn(selection.endLineNumber); + + r.push(EditOperation.replace(selection, sorted.join('\n'))); + + return r; +} \ No newline at end of file diff --git a/src/vs/editor/contrib/linesOperations/common/linesOperations.ts b/src/vs/editor/contrib/linesOperations/common/linesOperations.ts index 6f3eab7639a..60901bbad65 100644 --- a/src/vs/editor/contrib/linesOperations/common/linesOperations.ts +++ b/src/vs/editor/contrib/linesOperations/common/linesOperations.ts @@ -12,6 +12,7 @@ import CopyLinesCommand = require('./copyLinesCommand'); import DeleteLinesCommand = require('./deleteLinesCommand'); import MoveLinesCommand = require('./moveLinesCommand'); import EditorCommon = require('vs/editor/common/editorCommon'); +import {SortLinesCommand} from 'vs/editor/common/commands/sortLinesCommand'; import {TrimTrailingWhitespaceCommand} from 'vs/editor/common/commands/trimTrailingWhitespaceCommand'; import {INullService} from 'vs/platform/instantiation/common/instantiation'; import {KeyMod, KeyCode} from 'vs/base/common/keyCodes'; @@ -101,6 +102,40 @@ class MoveLinesDownAction extends MoveLinesAction { } } +class SortLinesAction extends EditorAction { + private descending:boolean; + + constructor(descriptor:EditorCommon.IEditorActionDescriptorData, editor:EditorCommon.ICommonCodeEditor, descending:boolean) { + super(descriptor, editor); + this.descending = descending; + } + + public run():TPromise { + + 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:EditorCommon.IEditorActionDescriptorData, editor:EditorCommon.ICommonCodeEditor, @INullService ns) { + super(descriptor, editor, false); + } +} + +class SortLinesDescendingAction extends SortLinesAction { + static ID ='editor.action.sortLinesDescending'; + + constructor(descriptor:EditorCommon.IEditorActionDescriptorData, editor:EditorCommon.ICommonCodeEditor, @INullService ns) { + super(descriptor, editor, true); + } +} + class TrimTrailingWhitespaceAction extends EditorAction { static ID = 'editor.action.trimTrailingWhitespace'; @@ -235,6 +270,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_A +})); +CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(SortLinesDescendingAction, SortLinesDescendingAction.ID, nls.localize('lines.sortDescending', "Sort Lines Descending"), { + context: ContextKey.EditorTextFocus, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_2 +})); 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 @@ -275,5 +318,3 @@ CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(InsertLineA context: ContextKey.EditorTextFocus, primary: KeyMod.CtrlCmd | KeyCode.Enter })); - - From 60caccd1778521b0d0fbab0ca592feda8501d031 Mon Sep 17 00:00:00 2001 From: Joe Martella Date: Mon, 8 Feb 2016 10:48:25 -0800 Subject: [PATCH 2/2] Changes compare function to be case-insensitive. --- src/vs/editor/common/commands/sortLinesCommand.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/commands/sortLinesCommand.ts b/src/vs/editor/common/commands/sortLinesCommand.ts index 7cba742c3dd..3b08154e482 100644 --- a/src/vs/editor/common/commands/sortLinesCommand.ts +++ b/src/vs/editor/common/commands/sortLinesCommand.ts @@ -55,7 +55,9 @@ export function sortLines(model:EditorCommon.ITextModel, selection:EditorCommon. linesToSort.push(model.getLineContent(lineNumber)); } - var sorted = linesToSort.sort(); + var sorted = linesToSort.sort((a, b) => { + return a.toLowerCase().localeCompare(b.toLowerCase()); + }); // If descending, reverse the order. if (descending === true) { @@ -69,4 +71,4 @@ export function sortLines(model:EditorCommon.ITextModel, selection:EditorCommon. r.push(EditOperation.replace(selection, sorted.join('\n'))); return r; -} \ No newline at end of file +}