Add code actions for disabling a warning in the current file #897
Conversation
suggestDisableWarning Diagnostic{..} | ||
| Just (StringValue (showFlag -> Just w)) <- _code = | ||
pure | ||
( "Disable \"" <> w <> "\" warnings" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exact wording of message is bikeshed-able
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A test would be great
modifyVar_ warnings $ return . (wr_d:) | ||
res <- action $ \x -> x{ms_hspp_opts = (ms_hspp_opts x){log_action = newAction}} | ||
warns <- readVar warnings | ||
return (reverse $ concat warns, res) | ||
|
||
attachReason :: WarnReason -> Diagnostic -> Diagnostic | ||
attachReason wr d = d{_code = StringValue <$> showReason wr} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems pretty weird, especially since the specification says this field may be displayed to the user. Perhaps the reason can be recorded in the ide state, and the code action can be generated based off of that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems pretty weird, especially since the specification says this field may be displayed to the user.
Hmm, yeah, that is unfortunate. I was originally intending to use the more human-readable form here, analogously to how GHC shows e.g. -Wunused-imports
in the CLI output. But this way it was easier to be sure that a particular diagnostic comes from a GHC warning (using T.stripPrefix "Opt_Warn"
).
Perhaps the reason can be recorded in the ide state, and the code action can be generated based off of that?
That sounds promising. There's a diagnostics
field in ShakeExtras
but the DiagnosticStore
type doesn't seem to give us anywhere to store extra information, so I guess it would need replacing - I haven't yet looked at how much of a knock-on effect that might have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm struggling to see a nice way to put this information in ShakeExtras
.
Besides, based on other LSP servers, I think this actually is more or less the intended use case for the code
field. I'm thinking we put the full flag there e.g. -Wunused-imports
, and trigger the action for diagnostics whose code begins with "-W" Still a little bit ugly, but the very nature of LSP means we're bound to be resigned to the occasional but of string-ly typed code.
The way VScode at least shows this is actually quite nice: typecheck(-Wunused-imports)
. Regardless of the original purpose of this PR, it's nice to get this extra information about where a warning is coming from. In fact, it's the one thing in GHC's output that we're currently missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking we put the full flag there e.g. -Wunused-imports
This is what c2cd237 does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code
field is intended to refer to the "handbook code" for a diagnostic, as provided by some compilers. Version 3.16 of the spec has a data
field for this, prompted from microsoft/language-server-protocol#887. Perhaps use that instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think seeing as the flag is the closest thing to a "handbook code" GHC is likely to have any time soon, this is still the right place to put it. Especially given that the result is visually appealing in VScode (haven't tried other editors, but I'd hope they show something relatively similar).
Obviously I'll change this if you or any of the other core maintainers feel strongly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, but let's fix the location of the inserted pragmas to make sure the new flags are not overridden by later pragmas
What's left to merge this? |
Assuming @wz1000 is now happy with the Meanwhile, shall I open a PR on GHC's GitLab about exporting |
Yes. As a general approximation, if its useful, it should be exported from GHC. GHC isn't particularly careful about presenting a nice carefully crafted API. We've asked for things exported in the past - if it will be exported, adding it to the Compat layer for now and then introducing an ifdef to make it available later is a good way to go. |
Ok, thanks @ndmitchell, I'll do that. Just to note, I'm very busy at the moment - in the middle of changing jobs and moving between cities. I'll probably get to this next weekend. |
Done. |
Ok, now this really is finished. Thanks @mpickering for pointing out |
What 5a2ffa4 does is essentially inline the definition of It is a bit inefficient as it effectively uses a list as a map. But we don't have Then again, it's a list with bounded length (number of warnings - somewhere under 100), so it's not disastrous. |
Thank you @georgefst ! Please take a look at the merge conflicts so that we can merge this ASAP |
5a2ffa4
to
95aa3b3
Compare
@pepeiborra Rebased and resolved. |
Looks like there are still some test failures |
Ah, whoops. I'd only been running the ones I added. Turns out three of the old ones are broken by the presence of an additional code action. 64a0aa5 does the bare minimum to get the tests fixed but in some cases they should perhaps actually be made more robust instead... |
@@ -1042,7 +1044,7 @@ removeImportTests = testGroup "remove import actions" | |||
] | |||
doc <- createDoc "ModuleC.hs" "haskell" content | |||
_ <- waitForDiagnostics | |||
[_, _, _, _, CACodeAction action@CodeAction { _title = actionTitle }] | |||
[_, _, _, _, _, _, _, _, CACodeAction action@CodeAction { _title = actionTitle }] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is particularly nasty.
The ghcide Github project is becoming archived and merged into https://github.com/haskell/haskell-language-server This PR will need to be reopened in the HLS repo.
Thanks! EDIT: we rewrote the ghcide commit messages in the HLS repo to fix the links to GitHub Issues/PRs which has the side-effect of breaking the merge instructions above. Instead, you should use cherry-pick as below:
|
This is a little ugly - we need some way to keep track of the WarningFlag, so we store it as a string in the (previously unused by Ghcide)
_code
field of Diagnostic. I'm open to a better way.Closes haskell/haskell-language-server#571.