Skip to content

Commit e497c0c

Browse files
n6g7DonJayamanne
authored andcommitted
Add isort CodeAction (sort imports on save) (#1926)
Fixes #156
1 parent 348ac72 commit e497c0c

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

news/1 Enhancements/156.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for the `editor.codeActionsOnSave.source.organizeImports` setting (thanks [Nathan Gaberel](https://github.com/n6g7)).

src/client/extension.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { IServiceContainer, IServiceManager } from './ioc/types';
4040
import { LinterCommands } from './linters/linterCommands';
4141
import { registerTypes as lintersRegisterTypes } from './linters/serviceRegistry';
4242
import { ILintingEngine } from './linters/types';
43+
import { PythonCodeActionProvider } from './providers/codeActionsProvider';
4344
import { PythonFormattingEditProvider } from './providers/formatProvider';
4445
import { LinterProvider } from './providers/linterProvider';
4546
import { PythonRenameProvider } from './providers/renameProvider';
@@ -145,6 +146,8 @@ export async function activate(context: ExtensionContext) {
145146
context.subscriptions.push(new TerminalProvider(serviceContainer));
146147
context.subscriptions.push(new WorkspaceSymbols(serviceContainer));
147148

149+
context.subscriptions.push(languages.registerCodeActionsProvider(PYTHON, new PythonCodeActionProvider()));
150+
148151
type ConfigurationProvider = BaseConfigurationProvider<LaunchRequestArguments, AttachRequestArguments>;
149152
serviceContainer.getAll<ConfigurationProvider>(IDebugConfigurationProvider).forEach(debugConfig => {
150153
context.subscriptions.push(debug.registerDebugConfigurationProvider(debugConfig.debugType, debugConfig));
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import * as vscode from 'vscode';
7+
8+
export class PythonCodeActionProvider implements vscode.CodeActionProvider {
9+
public provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CodeAction[]> {
10+
const sortImports = new vscode.CodeAction(
11+
'Sort imports on save',
12+
vscode.CodeActionKind.SourceOrganizeImports
13+
);
14+
sortImports.command = {
15+
title: 'Sort imports',
16+
command: 'python.sortImports'
17+
};
18+
19+
return [sortImports];
20+
}
21+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import { expect } from 'chai';
7+
import * as TypeMoq from 'typemoq';
8+
import { CancellationToken, CodeActionContext, CodeActionKind, Range, TextDocument } from 'vscode';
9+
import { PythonCodeActionProvider } from '../../client/providers/codeActionsProvider';
10+
11+
suite('CodeAction Provider', () => {
12+
let codeActionsProvider: PythonCodeActionProvider;
13+
let document: TypeMoq.IMock<TextDocument>;
14+
let range: TypeMoq.IMock<Range>;
15+
let context: TypeMoq.IMock<CodeActionContext>;
16+
let token: TypeMoq.IMock<CancellationToken>;
17+
18+
setup(() => {
19+
codeActionsProvider = new PythonCodeActionProvider();
20+
document = TypeMoq.Mock.ofType<TextDocument>();
21+
range = TypeMoq.Mock.ofType<Range>();
22+
context = TypeMoq.Mock.ofType<CodeActionContext>();
23+
token = TypeMoq.Mock.ofType<CancellationToken>();
24+
});
25+
26+
test('Ensure it always returns a source.organizeImports CodeAction', async () => {
27+
const codeActions = await codeActionsProvider.provideCodeActions(
28+
document.object,
29+
range.object,
30+
context.object,
31+
token.object
32+
);
33+
34+
if (!codeActions) {
35+
throw Error(`codeActionsProvider.provideCodeActions did not return an array (it returned ${codeActions})`);
36+
}
37+
38+
const organizeImportsCodeAction = codeActions.filter(
39+
codeAction => codeAction.kind === CodeActionKind.SourceOrganizeImports
40+
);
41+
expect(organizeImportsCodeAction).to.have.length(1);
42+
expect(organizeImportsCodeAction[0].kind).to.eq(CodeActionKind.SourceOrganizeImports);
43+
});
44+
});

0 commit comments

Comments
 (0)