Skip to content
This repository has been archived by the owner on Jun 4, 2019. It is now read-only.

Commit

Permalink
MVP code
Browse files Browse the repository at this point in the history
  • Loading branch information
MLoughry committed Mar 25, 2017
1 parent 1c5acd9 commit 0de32cf
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export interface NamedImport {
alias?: string;
}

export type DestructedImport = NamedImport | string;
export type DestructedImport = NamedImport;

export interface TypescriptImport {
path: string;
Expand Down
6 changes: 4 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import sortSelectedImports from "./sortSelectedImports";

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
Expand All @@ -17,8 +18,9 @@ export function activate(context: vscode.ExtensionContext) {
let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
// The code you place here will be executed every time your command is executed

// Display a message box to the user
vscode.window.showInformationMessage('Hello World!');
if (vscode.window.activeTextEditor.document.languageId === 'typescript') {
sortSelectedImports();
}
});

context.subscriptions.push(disposable);
Expand Down
32 changes: 15 additions & 17 deletions src/import-parser/parseImportNodes.ts → src/parseImportNodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,24 @@ export default function parseImportNodes(source: string) {
importRegex.lastIndex = 0;
let imports: TypescriptImport[] = [];

let strippedSource = source.replace(
importRegex,
() => {
imports.push({
path: arguments[30],
default: arguments[4] || arguments[17],
namedImports: parseDestructiveImports(arguments[5] || arguments[18]),
namespace: arguments[2],
});
return "";
}
);

return {
imports,
strippedSource
};
let match;
while (match = importRegex.exec(source)) {
imports.push({
path: match[30],
default: match[4] || match[17],
namedImports: parseDestructiveImports(match[5] || match[18]),
namespace: match[2],
});
}

return imports;
}

function parseDestructiveImports(destructiveImports: string): DestructedImport[] {
if (!destructiveImports) {
return null;
}

return destructiveImports
.split(",")
.map(destructiveImport => {
Expand Down
31 changes: 31 additions & 0 deletions src/processImports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { TypescriptImport } from "./TypescriptImport";

export default function processImports(importClauses: TypescriptImport[]): TypescriptImport[] {
return importClauses
.sort(compareImportClauses)
.map(importClause => {
if (importClause.namedImports) {
importClause.namedImports.sort((a, b) => a.importName.localeCompare(b.importName, "en", "base"));
}
return importClause;
});
}

function compareImportClauses(a: TypescriptImport, b: TypescriptImport) {
return comparePath(a, b)
|| a.path.localeCompare(b.path, "en", "base");
}

function comparePath(a: TypescriptImport, b: TypescriptImport) {
return getPathPriority(a.path) - getPathPriority(b.path);
}

function getPathPriority(path: string) {
if (/^\./.test(path)) {
return 0;
} else if (/^\.\./.test(path)) {
return 1;
} else {
return 2;
}
}
26 changes: 26 additions & 0 deletions src/sortSelectedImports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as vscode from "vscode";
import parseImports from "./parseImportNodes";
import processImports from "./processImports";
import writeImports from "./writeImports";

export default function sortSelectedImports() {
let editor = vscode.window.activeTextEditor;

let startLine = editor.selection.start.with(undefined, 0);
let endLine = editor.selection.end.with(undefined, 0);
if (editor.selection.end.character) {
endLine = endLine.translate(1);
}

let selectedLinesRange = editor.selection.with(startLine, endLine);

let imports = parseImports(editor.document.getText(selectedLinesRange));
imports = processImports(imports);
let sortedImportText = writeImports(imports);

editor.edit(
editBuilder => {
editBuilder.replace(selectedLinesRange, sortedImportText);
}
)
}
29 changes: 29 additions & 0 deletions src/writeImports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { TypescriptImport, NamedImport } from "./TypescriptImport";

export default function getSortedImportStatements(importClauses: TypescriptImport[]): string {
return importClauses
.map(getImportClauseString)
.join("\n") + "\n";
}

function getImportClauseString(importClause: TypescriptImport): string {
if (importClause.namespace) {
return `import * as ${importClause.namespace} from '${importClause.path}';`;
} else if (importClause.default) {
if (importClause.namedImports) {
return `import ${importClause.default}, { ${importClause.namedImports.map(generateNamedImport).join(", ")} } from '${importClause.path}';`;
} else {
return `import ${importClause.default} from '${importClause.path}';`;
}
} else {
return `import { ${importClause.namedImports.map(generateNamedImport).join(", ")} } from '${importClause.path}';`;
}
}

function generateNamedImport(namedImport: NamedImport): string {
if (namedImport.alias) {
return `${namedImport.importName} as ${namedImport.alias}`;
} else {
return namedImport.importName;
}
}

0 comments on commit 0de32cf

Please sign in to comment.