fix(lsp): support TypeScript source action kinds - #4496
fix(lsp): support TypeScript source action kinds#4496Andrew Ghostuhin (TorinAsakura) wants to merge 8 commits into
Conversation
You should probably be looking at the vscode repo's typescript-language-features extension That being said, if the old extensions could not do this, then is this critical to do? |
I checked vscode’s typescript-language-features too; same result, I don’t see any .ts-specific source action kinds there. BTW, I re-read the issue, and I don’t think it’s rly about matching the current VS Code extension. It’s more about the multi-server case. With source.removeUnusedImports in codeActionsOnSave, the client is asking for a generic LSP source action, so any server attached to that doc can match it. source.removeUnusedImports.ts gives clients a TS-specific knob, while source.removeUnusedImports stays around for existing setups. That’s why I wired the actual only handling too, not just the initialize list. Otherwise we’d advertise a kind that doesn’t do anything. So yeah, it’s not something VS Code seems to need today. The PR is more about making that escape hatch available for clients that do need to split source actions between several servers. |
|
I did some digging; pyright/pylance do not do this for python, nor gopls for Go, nor rust-analyzer for Rust. The only one that adds these suffixes is |
Yeah, shit happens, especially in the JS ecosystem :) So where do we land with this PR in the end? I still think .ts matches what the issue asks for, but I’d rather settle on one direction now than keep guessing. |
| ) map[string][]*lsproto.TextEdit { | ||
| changeTracker := change.NewTracker(ctx, program.Options(), l.FormatOptions(), l.converters) | ||
| shouldSort := kind == lsproto.CodeActionKindSourceSortImports || kind == lsproto.CodeActionKindSourceOrganizeImports | ||
| baseKind := getBaseOrganizeImportsKind(kind) |
There was a problem hiding this comment.
arguably this could just be kind = getBaseOrganizeImportsKind(kind).
Or even, we have a method on the CodeActionKind type that strips the .ts suffix
There was a problem hiding this comment.
The first option makes sense, I’m changing that now. But I didn’t quite get the second part: I checked CodeActionKind on the current head and couldn’t find a method that strips the .ts suffix. Did you mean adding one, or am I missing an existing helper somewhere?
There was a problem hiding this comment.
I mean that you could add one, yes, which would simplfiy things I think. But, maybe not that much...
There was a problem hiding this comment.
| func isFixAllKind(kind lsproto.CodeActionKind) bool { | ||
| return codeActionKindContains(kind, lsproto.CodeActionKindSourceFixAll) | ||
| return codeActionKindContains(kind, lsproto.CodeActionKindSourceFixAll) || | ||
| kind == lsproto.CodeActionKindSourceFixAllTs |
There was a problem hiding this comment.
Is this even needed? Note the contains above. Does make me think that this could be simplified.
There was a problem hiding this comment.
Something like this?
There was a problem hiding this comment.
Hm, that feels weird. Maybe because the args are flipped?
There was a problem hiding this comment.
Ah, maybe. You added that helper in #3382, so I took the order as intentional: requestedKind contains actionKind.
That’s why I used it like that. The check itself behaves correctly, but I see why it reads oddly here, since the returned kind can still be the generic one.
Do you mean we should flip the helper to take (actionKind, requestedKind) and update all call sites? I don’t want to flip this one call and accidentally stop source and source.fixAll from matching.
|
So, overall, I think this PR's idea is fine, but I'm still unsure about the implementation; I feel like there must be a more simple form which just strips the Since we're about to move repos (like, within hours), I'm not sure there's time to redo it all. I think you can reopen it on the main TS repo or I can have a go. Perhaps I'm wrong! |
|
I think we need to settle the shape here before rewriting this again. We already normalize the TypeScript-specific kind before the organize-imports implementation runs. The part we cannot just drop is keeping the originally requested kind at the boundary: if the client asks for source.removeUnusedImports.ts and we return source.removeUnusedImports, that action is outside the requested only filter and the client can ignore it. The same applies to source.fixAll.ts. So stripping .ts off the incoming kind still has to do four things:
That is what this PR does. A generic TrimSuffix helper might save a few lines, but it does not remove the routing, and unless we constrain it back to these exact kinds it also starts treating arbitrary *.ts actions as TypeScript actions. If you have a concrete smaller flow in mind, spell it out and I’ll rework it. But there must be a simpler form is not enough to safely redo the PR again, especially with the repo move happening in a few hours. Otherwise, let’s make a call: take the current implementation, or move the issue to the main TypeScript repo and restart it there with the intended shape agreed upfront. |
|
Are you an agent, or are you pasting agent output into the comments? |
Look, this is starting to annoy me. I’m just trying to help the community, but you can’t seem to decide what you want yourself, and you keep trying to pin something on me. Let’s just get this over with. |
Let me try to clear this up. I’m Russian. If I want to express a complicated thought, I use a translator, because I can’t be bothered to sit around and think “in English.” Some things I write by hand, like this, and some I put through Apple Translate. Let’s solve the problems instead of giving me shit about how I write. Deal? |
Summary
Fixes #3793.
Before
The server advertised only generic source action kinds:
A client could not target the TypeScript server specifically with a code actions on save entry such as source.removeUnusedImports.ts.
After
The server advertises both generic and TypeScript-specific source action kinds:
Requests filtered to source.organizeImports.ts, source.removeUnusedImports.ts, source.sortImports.ts, or source.fixAll.ts now return matching TypeScript-specific code actions, while the existing generic kinds still work.
Validation
P.S. I did not find an existing microsoft/TypeScript precedent for these .ts source action kinds. This follows the LSP hierarchical kind model and keeps the generic kinds advertised and accepted for compatibility.