Skip to content

Run Isort when formatOnSave is on #156

Closed
whitedragon206/vscode-python
#3

Description

From eMerzh (@eMerzh) on August 5, 2017 10:39

Hi,
many many thanks for this extension, it's really great.
I use format on save and been pretty happy about it.
But I also wanted to do Isort on save, could it be possible to add both of the tools or smth ?

Thanks a lot

Copied from original issue: DonJayamanne/pythonVSCode#1140

Activity

  1. DonJayamanne commented on Nov 14, 2017

    @DonJayamanne
    Author

    Unfortunately, not at this stage. Will look into this later as a feature request.

  2. DonJayamanne commented on Nov 14, 2017

    @DonJayamanne
    Author

    From eMerzh (@eMerzh) on August 5, 2017 12:22

    Thanks a lot :)

    i'll follow the updates ;)

  3. DonJayamanne commented on Nov 14, 2017

    @DonJayamanne
    Author

    From Damian Pukaluk (@threaz) on August 23, 2017 19:24

    Is there any other way to run your sort imports command on save? I mean using some kind of hook etc.

  4. brettcannon commented on Jan 30, 2018

    @brettcannon
    Member

    We might consider adding this is someone submitted a PR that added a flag to also do import sorts as part of document formatting.

  5. 4 remaining items

  6. n6g7 commented on Jun 2, 2018

    @n6g7

    Brett Cannon (@brettcannon) I'd like to submit a PR to add this feature but I'm not yet familiar with the codebase. Do you have any pointers to get me started?

  7. ricardochaves commented on Jun 3, 2018

    @ricardochaves

    What would be the best way to implement this in your opinion?

    1 - One option would be to take one step further in the promise of provideDocumentFormattingEdits:

    const promise = pythonToolsExecutionService.exec(executionInfo, { cwd, throwOnStdErr: true, token }, document.uri)
                .then(data => {
                    const settings = PythonSettings.getInstance(document.uri);
                    if (settings.sortImports.sortOnSave) {
                        executionInfo.execPath = settings.sortImports.path;
                        executionInfo.moduleName = settings.sortImports.path;
                        executionInfo.args = ["--diff", document.fileName].concat(settings.sortImports.args);
                        const p = pythonToolsExecutionService.exec(executionInfo, { cwd, throwOnStdErr: true, token }, document.uri);
                        return p.then(data => { return data });
                    }
                    return data;
                })
                .then(output => output.stdout)
    

    I know there's a lot together there, but if you think it's a possible way so I can improve it and make a PR.

    This proposed code works, I ran a test locally and it made both of the formatting correctly.

    2 - Another option would be to transform the "python.formatting.provider" configuration into an array and it execute all the formats in sequence. ["autopep8", "isort"]. The problem here would be the mandatory change in who already uses the setting as a string.

  8. brettcannon commented on Jun 4, 2018

    @brettcannon
    Member

    Ricardo Baltazar Chaves (@ricardochaves) Import sorting is basically the only thing that people would potentially want to stack with other formatters, so I don't think making the support generic makes sense.

  9. ricardochaves commented on Jun 7, 2018

    @ricardochaves

    Perfect Brett Cannon (@brettcannon), and what do you think of this solution?

    New method in BaseFormatter:

        private execImportSort(formatedData, document, token, tempFile): Promise<string> {
            const pythonToolsExecutionService = this.serviceContainer.get<IPythonToolExecutionService>(IPythonToolExecutionService);
            const settings = PythonSettings.getInstance(document.uri);
            const isortArgs = ['--diff', document.fileName].concat(settings.sortImports.args);
            const executionIsortInfo = this.helper.getExecutionInfo(Product.isort, isortArgs, document.uri);
            return pythonToolsExecutionService.exec(executionIsortInfo, { throwOnStdErr: true, token }, document.uri)
                .then(data => {
                    if (this.checkCancellation(document.fileName, tempFile, token)) {
                        return formatedData;
                    }
                    return data;
                })
                .then(output => output.stdout);
        }
    

    In the format chain, after it applies the defined formatter, we call the new method:

                .then(data => {
                    const settings = PythonSettings.getInstance(document.uri);
                    if (settings.sortImports.sortOnSave) {
                        return this.execImportSort(data, document, token, tempFile);
                    }
                    return data;
                })
    
    • We created just one configuration settings.sortImports.sortOnSave.
    • We preserve and respect all formatters already created.
    • We run isort after formatting.
    • We use a single metric for both commands.
  10. DonJayamanne commented on Jun 8, 2018

    @DonJayamanne
    Author

    Ricardo Baltazar Chaves (@ricardochaves)
    Please make use of the PythonImportSortProvider class to invoke isort in /Users/donjayamanne/.vscode-insiders/extensions/pythonVSCode/src/client/providers/importSortProvider.ts

  11. DonJayamanne commented on Jun 8, 2018

    @DonJayamanne
    Author

    I think we need to take a closer look at this.
    Ideally sorting of imports during save should be done via the VS Code API.

    Please look at https://code.visualstudio.com/updates/v1_23#_run-code-actions-on-save

  12. ricardochaves commented on Jun 8, 2018

    @ricardochaves

    Hi Don Jayamanne (@DonJayamanne) ,

    What do you think of this solution?

    On sortImports.ts (/Users/ricardochaves/Desktop/projetos/vscode-python/src/client/sortImports.ts):

        vscode.workspace.onWillSaveTextDocument((activeEditor) => {
            const sort = new sortProvider.PythonImportSortProvider(serviceContainer).sortImports(rootDir, activeEditor.document);
            activeEditor.waitUntil(sort);
        });
    

    An extremely simple code. Using the onWillSaveTextDocument event and also the PythonImportSortProvider.

  13. DonJayamanne commented on Jun 9, 2018

    @DonJayamanne
    Author

    Ricardo Baltazar Chaves (@ricardochaves)
    Please could you look at utilizing the corresponding VS Code API (Code Actions) see here Please look at code.visualstudio.com/updates/v1_23#_run-code-actions-on-save

    I'd like to ensure sorting of imports within the python extension is implemented the way it is implemented in other languages (see above link).

  14. added a commit that references this issue on Jun 11, 2018
    e497c0c
  15. locked as resolved and limited conversation to collaborators on Jul 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions