Skip to content

Commit

Permalink
Add limited support for :sort
Browse files Browse the repository at this point in the history
 - Works on a range
 - ! option is supported to reverse the sort
 - Other options not supported at this time

Fixes: #1341
  • Loading branch information
jordan-heemskerk committed Feb 28, 2017
1 parent 862ef4a commit 99e4a40
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
64 changes: 64 additions & 0 deletions src/cmd_line/commands/sort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"use strict";

import * as vscode from "vscode";
import * as node from "../node";
import * as token from "../token";
import { ModeHandler } from "../../mode/modeHandler";
import { TextEditor } from "../../textEditor";

export interface ISortCommandArguments extends node.ICommandArgs {
reverse: boolean;
}


export class SortCommand extends node.CommandBase {

protected _arguments : ISortCommandArguments;

constructor(args: ISortCommandArguments) {
super();
this._arguments = args;
}

get arguments() : ISortCommandArguments {
return this._arguments;
}

async execute(modeHandler : ModeHandler): Promise<void> {
await this.sortLines(new vscode.Position(0, 0), new vscode.Position(TextEditor.getLineCount() - 1, 0));
}

async sortLines(startLine: vscode.Position, endLine: vscode.Position) {
let originalLines: String[] = [];

for (let currentLine = startLine.line; currentLine <= endLine.line && currentLine < TextEditor.getLineCount(); currentLine++) {
originalLines.push(TextEditor.readLineAt(currentLine));
}

let lastLineLength = originalLines[originalLines.length - 1].length;
let sortedLines = originalLines.sort();

if (this._arguments.reverse) {
sortedLines.reverse();
}

let sortedContent = sortedLines.join("\n");

await TextEditor.replace(new vscode.Range(startLine.line, 0, endLine.line, lastLineLength), sortedContent);
}

async executeWithRange(modeHandler : ModeHandler, range: node.LineRange) {
let startLine: vscode.Position;
let endLine: vscode.Position;

if (range.left[0].type === token.TokenType.Percent) {
startLine = new vscode.Position(0, 0);
endLine = new vscode.Position(TextEditor.getLineCount() - 1, 0);
} else {
startLine = range.lineRefToPosition(vscode.window.activeTextEditor, range.left, modeHandler);
endLine = range.lineRefToPosition(vscode.window.activeTextEditor, range.right, modeHandler);
}

await this.sortLines(startLine, endLine);
}
}
3 changes: 3 additions & 0 deletions src/cmd_line/subparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { parseSubstituteCommandArgs } from './subparsers/substitute';
import { parseReadCommandArgs } from './subparsers/read';
import { parseRegisterCommandArgs } from './subparsers/register';
import { parseDeleteRangeLinesCommandArgs } from './subparsers/deleteRange';
import { parseSortCommandArgs } from './subparsers/sort';

// maps command names to parsers for said commands.
export const commandParsers = {
Expand Down Expand Up @@ -83,4 +84,6 @@ export const commandParsers = {

d: parseDeleteRangeLinesCommandArgs,

sort: parseSortCommandArgs,

};
16 changes: 16 additions & 0 deletions src/cmd_line/subparsers/sort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use strict";

import * as node from "../commands/sort";

export function parseSortCommandArgs(args : string) : node.SortCommand {

let reverse_ = false;
if (args != null && args.indexOf("!") >= 0) {
reverse_ = true;
}

return new node.SortCommand({
reverse: reverse_,
});

}
62 changes: 62 additions & 0 deletions test/cmd_line/sort.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use strict";

import { ModeHandler } from '../../src/mode/modeHandler';
import { setupWorkspace, cleanUpWorkspace, assertEqualLines } from './../testUtils';
import { runCmdLine } from '../../src/cmd_line/main';

suite("Basic sort", () => {
let modeHandler: ModeHandler;

setup(async () => {
await setupWorkspace();
modeHandler = new ModeHandler();
});

teardown(cleanUpWorkspace);

test("Sort whole file, asc", async () => {
await modeHandler.handleMultipleKeyEvents(['i', 'b', '<Esc>', 'o', 'a', '<Esc>', 'o', 'c', '<Esc>']);
await runCmdLine("sort", modeHandler);

assertEqualLines([
"a",
"b",
"c"
]);
});

test("Sort whole file, dsc", async () => {
await modeHandler.handleMultipleKeyEvents(['i', 'b', '<Esc>', 'o', 'a', '<Esc>', 'o', 'c', '<Esc>']);
await runCmdLine("sort!", modeHandler);

assertEqualLines([
"c",
"b",
"a"
]);
});

test("Sort range, asc", async () => {
await modeHandler.handleMultipleKeyEvents(['i', 'b', '<Esc>', 'o', 'd', '<Esc>', 'o', 'a', '<Esc>', 'o', 'c', '<Esc>']);
await runCmdLine("1,3sort", modeHandler);

assertEqualLines([
"a",
"b",
"d",
"c"
]);
});

test("Sort range, dsc", async () => {
await modeHandler.handleMultipleKeyEvents(['i', 'b', '<Esc>', 'o', 'd', '<Esc>', 'o', 'a', '<Esc>', 'o', 'c', '<Esc>']);
await runCmdLine("2,4sort!", modeHandler);

assertEqualLines([
"b",
"d",
"c",
"a"
]);
});
});

0 comments on commit 99e4a40

Please sign in to comment.