Skip to content

Commit ce54b2c

Browse files
committed
using line edits for sorting of imports #151
1 parent cc30218 commit ce54b2c

2 files changed

Lines changed: 39 additions & 55 deletions

File tree

src/client/providers/importSortProvider.ts

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,38 @@ import * as vscode from "vscode";
44
import * as path from "path";
55
import * as fs from "fs";
66
import * as child_process from "child_process";
7+
import {getTextEditsFromPatch} from "../common/editor";
78

89
export class PythonImportSortProvider {
9-
public sortImports(extensionDir: string, document: vscode.TextDocument): Thenable<vscode.TextEdit[]> {
10+
public sortImports(extensionDir: string, document: vscode.TextDocument): Promise<vscode.TextEdit[]> {
11+
if (document.lineCount === 1) {
12+
return Promise.resolve([]);
13+
}
14+
let filePath = document.uri.fsPath;
15+
let importScript = path.join(extensionDir, "pythonFiles", "sortImports.py");
1016
return new Promise<vscode.TextEdit[]>((resolve, reject) => {
11-
let filePath = document.uri.fsPath;
12-
let importScript = path.join(extensionDir, "pythonFiles", "sortImports.py");
13-
if (!fs.existsSync(filePath)) {
14-
vscode.window.showErrorMessage(`File ${filePath} does not exist`);
15-
return resolve([]);
16-
}
17-
1817
let ext = path.extname(filePath);
1918
let tmp = require("tmp");
20-
tmp.file({ postfix: ext }, function _tempFileCreated(err, tmpFilePath, fd) {
19+
tmp.file({ postfix: ext }, function (err, tmpFilePath, fd) {
2120
if (err) {
22-
reject(err);
23-
return;
21+
return reject(err);
2422
}
25-
let documentText = document.getText();
26-
fs.writeFile(tmpFilePath, documentText, ex => {
23+
fs.writeFile(tmpFilePath, document.getText(), ex => {
2724
if (ex) {
28-
vscode.window.showErrorMessage(`Failed to create a temporary file, ${ex.message}`);
29-
return;
25+
return reject(`Failed to create a temporary file, ${ex.message}`);
3026
}
3127

32-
child_process.exec(`python "${importScript}" "${tmpFilePath}"`, (error, stdout, stderr) => {
33-
if (error || stderr) {
34-
vscode.window.showErrorMessage(`File ${filePath} does not exist`);
35-
return resolve([]);
28+
child_process.exec(`python "${importScript}" "${tmpFilePath}" --diff`, (error, stdout, stderr) => {
29+
if (error || (stderr && stderr.length > 0)) {
30+
return reject(error ? error : stderr);
3631
}
3732

38-
fs.readFile(tmpFilePath, (ex, data) => {
39-
if (ex) {
40-
vscode.window.showErrorMessage(`Failed to create a temporary file for sorting, ${ex.message}`);
41-
return;
42-
}
43-
44-
let formattedText = data.toString("utf-8");
45-
// Nothing to do
46-
if (document.getText() === formattedText) {
47-
return resolve([]);
48-
}
49-
50-
let range = new vscode.Range(document.lineAt(0).range.start, document.lineAt(document.lineCount - 1).range.end);
51-
let txtEdit = new vscode.TextEdit(range, formattedText);
52-
resolve([txtEdit]);
53-
});
33+
let formattedText = stdout;
34+
let edits = getTextEditsFromPatch(document.getText(), stdout);
35+
resolve(edits);
5436
});
5537
});
5638
});
57-
5839
});
5940
}
60-
}
41+
}

src/client/sortImports.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1-
'use strict';
1+
"use strict";
22

3-
import * as vscode from 'vscode';
4-
import * as sortProvider from './providers/importSortProvider';
3+
import * as vscode from "vscode";
4+
import * as sortProvider from "./providers/importSortProvider";
55

66
export function activate(context: vscode.ExtensionContext) {
7-
var rootDir = context.asAbsolutePath(".");
8-
var disposable = vscode.commands.registerCommand('python.sortImports', () => {
9-
10-
var activeEditor = vscode.window.activeTextEditor;
11-
if (activeEditor) {
12-
new sortProvider.PythonImportSortProvider().sortImports(rootDir, activeEditor.document).then(changes=> {
13-
if (!Array.isArray(changes) || changes.length === 0) {
14-
return;
15-
}
7+
let rootDir = context.asAbsolutePath(".");
8+
let disposable = vscode.commands.registerCommand("python.sortImports", () => {
9+
let activeEditor = vscode.window.activeTextEditor;
10+
if (!activeEditor || activeEditor.document.languageId !== "python") {
11+
vscode.window.showErrorMessage("Please open a Python source file to sort the imports.");
12+
return;
13+
}
14+
new sortProvider.PythonImportSortProvider().sortImports(rootDir, activeEditor.document).then(changes => {
15+
if (changes.length === 0) {
16+
return;
17+
}
1618

17-
activeEditor.edit(builder=> {
18-
builder.replace(changes[0].range, changes[0].newText)
19-
});
19+
activeEditor.edit(builder => {
20+
changes.forEach(change => builder.replace(change.range, change.newText));
2021
});
21-
}
22+
}).catch(error => {
23+
let message = typeof error === "string" ? error : (error.message ? error.message : error);
24+
vscode.window.showErrorMessage(message);
25+
});
2226
});
2327

24-
2528
context.subscriptions.push(disposable);
26-
}
29+
}

0 commit comments

Comments
 (0)