prettier / prettier-vscode

Visual Studio Code extension for Prettier
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
MIT License
5.04k stars 446 forks source link

Plugin has a conflict with the built-in organize imports #716

Closed paustint closed 4 years ago

paustint commented 5 years ago

As soon as VScode was updated to 1.31.0, it appears that this prettier extensions conflicts with the the built-in organize imports setting, when organize imports on save is enabled.

prettier: "prettier": "^1.16.4", (was initially on 1.13.7, tried to update) vscode: Version 1.31.0 (1.31.0) extension: 1.8.0

I first opened a ticket with vscode core, but was referred to the extension as the source of the problem: https://github.com/Microsoft/vscode/issues/68193

Steps to reproduce

  1. Add setting for editor.codeActionsOnSave.source.organizeImports = true (see below for example json)
  2. Ensure prettier is configured to format on save
  3. create a ts file (may also work with js) that has an import that exceeds the configured line length, which should be turned into a multi-line import
  4. Save file

Expected behavior:

  1. imports should be organized
  2. imports should be formatted to multi-line import
  3. file should be saved

Actual behavior:

  1. imports are organized
  2. imports remain on a single line
  3. file remains "dirty" - with the little white dot in the tab-bar

Note: I can format the document manually using the command menu and the import is correctly formatted, but then on save it is unformatted and the file shows as modified by the file system.

"editor.codeActionsOnSave": {
    "source.organizeImports": true
},

Initial file

image

Format file manually, just to show that it works

image

image

After Save (cmd+s)

image

beeme1mr commented 5 years ago

I'm running into the same issue. I've disabled organize imports for now.

nikitavoloboev commented 5 years ago

Can this be solved in some way? I would like to help if I can to implement this.

hevans90 commented 5 years ago

This only seems to have happened with VSCode's refactor/extension of how code-formatters are chosen & configured. It is a shame because prior to this VSCode version you could have a nice formatOnSave + source.organizeImports combo which would work seamlessly.

I've tried to mess with the timeouts of these actions, but no workaround seems to be consistent here. Turning this off for now :(

hevans90 commented 5 years ago

After playing with some of the VSCode settings a bit more, you can make the editor behave in a REALLY strange way:

weird_formatting_conflicts

And look at what happens if you repeatedly save the file:

image

Yep, either Prettier or VSCode's organizeImports breaks code - looks like a race condition. I'd stay away from organizeImports for now.

marty-wang commented 4 years ago

Any member can chime in?

felixfbecker commented 4 years ago

I get severely corrupted files from this all the time. Looks like some kind of serious race condition

AlberErre commented 4 years ago

same issue here, any workaround?

Undistraction commented 4 years ago

@ntotten I think this is a bug, not an enhancement. It means Prettier VSCode is totally incompatible with one of VSCode's more useful features.

jaywhy13 commented 4 years ago

I'm having this same issue too. I think I might have to disable this too.

satelllte commented 4 years ago

I'm having a similar issue w/ end of file & braces: Is it this bug too?

prettier-issue

janosh commented 4 years ago

It seems weird that this is getting so little attention, considering it's the 3rd most upvoted issue of prettier-vscode. @nikitavoloboev even offered to help. Couldn't a member pick him up on that?

ntotten commented 4 years ago

I need somebody to provide a github repo I can use to reproduce this. I do see the flicker where first the organize is applied, then prettier is applied, but I can't get it to actually cause any problems like "corrupted" files.

bitttttten commented 4 years ago

It doesn't seem to be causing any bugs for me in the code. For example the module imports do not get distorted. The problem for me is that if I format on save and have this issue, then linting with prettier will fail.

jscul commented 4 years ago

This is an issue for me as well. When I have the following settings w/ prettier:

"editor.codeActionsOnSave": {
    "source.organizeImports": true
},
"editor.formatOnSave": true,

It'd be nice if source.organizeImports ran then format ran prior to rendering to prevent the really shaky UI. I'm going to disable organizeImports for the time being.

hevans90 commented 4 years ago

I found a workaround: a 6 core i7. No joke - my new macbook can run these two settings in tandem with no issues 🤔🙄

nfarina commented 4 years ago

This happens to me frequently when my imports are long enough that Prettier needs to wrap them. I believe it's also related to the fact that I'm running a large project so my CPU is usually pretty throttled on save. What typically happens is, I press save, the imports are organized, then Prettier runs and reformats them, but then the file is still marked "dirty" - I have to save it again (or maybe 2 or 3 more times) before the little asterisk in the tab is gone. It feels like there's a race condition here that is exacerbated by the CPU demands of other TypeScript activities.

pdemarino commented 4 years ago

I see exactly the same issue every day.

janosh commented 4 years ago

I do see the flicker where first the organize is applied, then prettier is applied, but I can't get it to actually cause any problems like "corrupted" files.

@ntotten Not sure anyone reported corrupted files. Rather sometimes when saving a file it remains unsaved because changes to the imports are applied post-save.

But in any case, isn't flickering when saving enough of an annoyance to treat that as the issue?

ntotten commented 4 years ago

@janosh https://github.com/prettier/prettier-vscode/issues/716#issuecomment-515533849

I get that its an annoyance, but I am not even sure fixing it is possible. VS Code runes save actions that extensions provide, this extension doesn't know anything about nor have any influence on the order imports.

pdemarino commented 4 years ago

Question: isn't the issue here the sequence of invocation? In other words, if one could make sure that the reshuffling of the imports always happened before the invocation of Prettier, we would be golden.

ntotten commented 4 years ago

I believe that formatting runs before code actions. I don't think there is any way to control that.

pluma commented 4 years ago

This issue (files being set to "dirty" after save due to reformatting) affects me ~4/5 times when I press save (including when I then press save again). The truncation is a bit rarer but happens fairly frequently when the system is under heavy load.

ntotten commented 4 years ago

Playing around with this, one semi-workaround is to set prettier's printWidth to 120. The VS Code sorter/formatter for imports appears to be hardcoded to 120 characters. There is an issue to make this setting customizable in VS Code (https://github.com/microsoft/TypeScript/issues/22991), if they did that I think setting the VS Code setting and prettier to the same length would remove the flicker.

ntotten commented 4 years ago

Since Microsoft has closed the issue (https://github.com/microsoft/vscode/issues/87096) that would have enabled us to solve this and has indicated they are not going to fix it, this isn't something that the extension can fix. As such I am closing this issue.

kmvan commented 4 years ago

Can I remove unused importer only? Needless resort.

ZYinMD commented 4 years ago

In the new VSCode v1.44.x, Explicit ordering for Code Actions on save was introduced. It looks like it might be the answer we've been searching for years. However, I tried playing with it but failed to get it to work.

What I tried was:

// settings.json
"editor.formatOnSave": false,
"editor.codeActionsOnSave": [
  "source.organizeImports",
  "editor.action.formatDocument" // does not work
],

The problem is, I don't know what actions are available. I got the source.organizeImports from the examples in the docs, and got the editor.action.formatDocument from the keybinding UI, but apparently it won't just work like that.

JonnyBurger commented 4 years ago

I disabled source.organizeImports and installed this prettier plugin:

https://github.com/simonhaenisch/prettier-plugin-organize-imports

The problem was fixed after a restart!

jonkoops commented 4 years ago

Can confirm that @ZYinMD's solution works like a charm.

laurensnl commented 4 years ago

Thanks @JonnyBurger! That's what we've boon looking for. Works perfect!

janosh commented 4 years ago

@JonnyBurger I must be doing something wrong. I also disabled source.organizeImports and ran

yarn add -D prettier-plugin-organize-imports prettier typescript

After restarting VS Code and disordering some imports, nothing happened on save.

Undistraction commented 4 years ago

@janosh are your files JS or Typescript? That plugin only works for Typescript files.

JonnyBurger commented 4 years ago

@janosh try setting "editor.codeActionsOnSave[source.fixAll]": true and editor.formatOnSave to true

janosh commented 4 years ago

@Undistraction That must be it. I'm working with JS files. How come this limitation though? The plugin readme states:

This is the same as using the "Organize Imports" action in VS Code.

"Organize Imports" in VS Code works for both TS and JS and uses (afaik) the same implementation.

rohit-gohri commented 4 years ago

"Organize Imports" in VS Code works for both TS and JS and uses (afaik) the same implementation.

@janosh Could try this approach, https://github.com/prettier/prettier-vscode/issues/1277#issuecomment-621175180, but with organize-imports instead of eslint. This is similar to @ZYinMD approach above, but I could not get that to work.

Install this VSCode extension. https://github.com/rohit-gohri/vscode-format-code-action/

This registers a custom codeAction: source.fixAll.format, which we can use instead of formatOnSave. It'll trigger "Format Document" with whatever default formatter you have setup.

These settings would run organizeImports first and then prettier on save:

  "editor.formatOnSave": false,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": [
    "source.organizeImports",
    "source.fixAll.format"
  ]
janosh commented 4 years ago

@rohit-gohri Thanks for the hint! It seems a little slower than "editor.formatOnSave": true,. Is that expected (maybe because code actions are now run in sequence, not in parallel)? Also, I'm still seeing multi-line imports flashing briefly to single-line formatting before reverting back. Do I have to specify Prettier's printWidth to agree with that of ESLint?

rohit-gohri commented 4 years ago

@rohit-gohri Thanks for the hint! It seems a little slower than "editor.formatOnSave": true,. Is that expected (maybe because code actions are now run in sequence, not in parallel)?

@janosh Yes, they do run in sequence hence the little flash and speed difference. You could run them in parallel by providing an object to codeActionsOnSave but then we'll be back to the original problem of the issue.

Also, I'm still seeing multi-line imports flashing briefly to single-line formatting before reverting back. Do I have to specify Prettier's printWidth to agree with that of ESLint?

That is due to VS Code's organize imports not supporting a max-line-length option: https://github.com/Microsoft/TypeScript/issues/22991 So can't do much there.

Undistraction commented 4 years ago

For anyone hoping to do:

"editor.codeActionsOnSave": [
    "source.organizeImports",
    "source.fixAll.format"
]

I'm still seeing the occasional lots of mangled files when imports wrap. Seems to be a little more reliable than it was though.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.