Skip to content

Fix issues causing Remove Unused Imports to not show up in VS Code#2720

Open
ahoppen wants to merge 1 commit into
swiftlang:mainfrom
ahoppen:fix-remove-unused-imports
Open

Fix issues causing Remove Unused Imports to not show up in VS Code#2720
ahoppen wants to merge 1 commit into
swiftlang:mainfrom
ahoppen:fix-remove-unused-imports

Conversation

@ahoppen

@ahoppen ahoppen commented Jul 14, 2026

Copy link
Copy Markdown
Member

We had two issues here:

  1. VS Code does not show code actions with kind sourceOrganizeImports in the lightbulb menu. Change it to empty so that it does show up.
  2. We didn’t declare the command in SwiftLanguageService, so VS Code didn’t know to invoke SourceKit-LSP to perform the remove.unused.imports.command

We had two issues here:
1. VS Code does not show code actions with kind `sourceOrganizeImports` in the lightbulb menu. Change it to `empty` so that it does show up.
2. We didn’t declare the command in `SwiftLanguageService`, so VS Code didn’t know to invoke SourceKit-LSP to perform the `remove.unused.imports.command`
@ahoppen

ahoppen commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

@swift-ci Please test

@rintaro

rintaro commented Jul 21, 2026

Copy link
Copy Markdown
Member

How about providing RemoveUnusedImportsCommand regardless of the scope and leaving the kind as sourceOrganizeImports. Because that's what this kind is for, right?

@ahoppen

ahoppen commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

I haven’t been able to figure out when VS Code shows sourceOrganizeImports code actions. Do you know?

@rintaro

rintaro commented Jul 23, 2026

Copy link
Copy Markdown
Member

I looked into this and tested locally:

  • Command Palette >Organize Imports - for this to show up, the server needs to advertise source.organizeImports explicitly in the server capability codeActionProvider.codeActionKinds. When executing it, VS Code requests the code actions with: "only": ["source.organizeImports"]". Interestingly, this didn't surface "Remove Unused Imports", it was just executed. I haven't tried what happens if we return multiple source.organizeImports actions.
  • Context Menu > Source Actions... - for this, the server needs to advertise source explicitly in the capability, Also the code action is requested with "only": ["source"]". This shows the sub menu that lists "Remove Unused Imports"

So to support this, we need to advertise source.organizeImports (this covers source as well) and handle only for source.organizeImports AND source.

@ahoppen

ahoppen commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

Oh, interesting. Thanks for investigating this, Rintaro.

I just thought about this a bit more and I think that refactor is actually the correct code action kind we want here:

  • Organize imports: I would imagine that this is mostly about sorting imports (organizing doesn’t imply removal to me) and since Remove Unused Imports doesn’t sort the imports, I don’t think this matches
  • General source actions: The LSP spec describes them as Source code actions apply to the entire file. Since this code action only applies to imports (which in >99.9% of all cases for one coherent block at the source of the start of the file), I think doesn’t make sense to classify this code action as the source kind.

So, I would continue with the implementation as it is in this PR. What do you think?

@rintaro

rintaro commented Jul 24, 2026

Copy link
Copy Markdown
Member

Organize imports: I would imagine that this is mostly about sorting imports (organizing doesn’t imply removal to me) and since Remove Unused Imports doesn’t sort the imports, I don’t think this matches

THE standard implementation does remove unused imports, fwiw. But it's true it's mainly for sorting them.

General source actions: The LSP spec describes them as Source code actions apply to the entire file. Since this code action only applies to imports (which in >99.9% of all cases for one coherent block at the source of the start of the file), I think doesn’t make sense to classify this code action as the source kind.

But source.organizeImport IS a source action.


That said, I'm totally fine with going with refactor.

So, I would continue with the implementation as it is in this PR. What do you think?

Why .empty not .refactor?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants