@@ -80,7 +80,8 @@ import GHC.Exts (fromList)
80
80
import qualified GHC.LanguageExtensions as Lang
81
81
import Ide.Logger hiding
82
82
(group )
83
- import Ide.PluginUtils (extractTextInRange ,
83
+ import Ide.PluginUtils (extendToFullLines ,
84
+ extractTextInRange ,
84
85
subRange )
85
86
import Ide.Types
86
87
import Language.LSP.Protocol.Message (Method (.. ),
@@ -112,16 +113,16 @@ import Text.Regex.TDFA ((=~), (=~~))
112
113
113
114
-- | Generate code actions.
114
115
codeAction :: PluginMethodHandler IdeState 'Method_TextDocumentCodeAction
115
- codeAction state _ (CodeActionParams _ _ (TextDocumentIdentifier uri) _range CodeActionContext {_diagnostics = xs} ) = do
116
+ codeAction state _ (CodeActionParams _ _ (TextDocumentIdentifier uri) range _ ) = do
116
117
contents <- lift $ LSP. getVirtualFile $ toNormalizedUri uri
117
118
liftIO $ do
118
119
let text = virtualFileText <$> contents
119
120
mbFile = toNormalizedFilePath' <$> uriToFilePath uri
120
- diag <- atomically $ fmap (\ (_, _, d) -> d) . filter (\ (p, _, _) -> mbFile == Just p) <$> getDiagnostics state
121
+ allDiags <- atomically $ fmap (\ (_, _, d) -> d) . filter (\ (p, _, _) -> mbFile == Just p) <$> getDiagnostics state
121
122
(join -> parsedModule) <- runAction " GhcideCodeActions.getParsedModule" state $ getParsedModule `traverse` mbFile
122
123
let
123
- actions = caRemoveRedundantImports parsedModule text diag xs uri
124
- <> caRemoveInvalidExports parsedModule text diag xs uri
124
+ actions = caRemoveRedundantImports parsedModule text allDiags range uri
125
+ <> caRemoveInvalidExports parsedModule text allDiags range uri
125
126
pure $ InL $ actions
126
127
127
128
-------------------------------------------------------------------------------------------------
@@ -441,19 +442,25 @@ suggestRemoveRedundantImport ParsedModule{pm_parsed_source = L _ HsModule{hsmod
441
442
= [(" Remove import" , [TextEdit (extendToWholeLineIfPossible contents _range) " " ])]
442
443
| otherwise = []
443
444
445
+ diagInRange :: Diagnostic -> Range -> Bool
446
+ diagInRange Diagnostic {_range = dr} r = dr `subRange` extendedRange
447
+ where
448
+ -- Ensures the range captures full lines. Makes it easier to trigger the correct
449
+ -- "remove redundant" code actions from anywhere on the offending line.
450
+ extendedRange = extendToFullLines r
444
451
445
452
-- Note [Removing imports is preferred]
446
453
-- It's good to prefer the remove imports code action because an unused import
447
454
-- is likely to be removed and less likely the warning will be disabled.
448
455
-- Therefore actions to remove a single or all redundant imports should be
449
456
-- preferred, so that the client can prioritize them higher.
450
- caRemoveRedundantImports :: Maybe ParsedModule -> Maybe T. Text -> [Diagnostic ] -> [ Diagnostic ] -> Uri -> [Command |? CodeAction ]
451
- caRemoveRedundantImports m contents digs ctxDigs uri
457
+ caRemoveRedundantImports :: Maybe ParsedModule -> Maybe T. Text -> [Diagnostic ] -> Range -> Uri -> [Command |? CodeAction ]
458
+ caRemoveRedundantImports m contents allDiags contextRange uri
452
459
| Just pm <- m,
453
- r <- join $ map (\ d -> repeat d `zip` suggestRemoveRedundantImport pm contents d) digs ,
460
+ r <- join $ map (\ d -> repeat d `zip` suggestRemoveRedundantImport pm contents d) allDiags ,
454
461
allEdits <- [ e | (_, (_, edits)) <- r, e <- edits],
455
462
caRemoveAll <- removeAll allEdits,
456
- ctxEdits <- [ x | x@ (d, _) <- r, d `elem` ctxDigs ],
463
+ ctxEdits <- [ x | x@ (d, _) <- r, d `diagInRange` contextRange ],
457
464
not $ null ctxEdits,
458
465
caRemoveCtx <- map (\ (d, (title, tedit)) -> removeSingle title tedit d) ctxEdits
459
466
= caRemoveCtx ++ [caRemoveAll]
@@ -477,8 +484,8 @@ caRemoveRedundantImports m contents digs ctxDigs uri
477
484
_data_ = Nothing
478
485
_changeAnnotations = Nothing
479
486
480
- caRemoveInvalidExports :: Maybe ParsedModule -> Maybe T. Text -> [Diagnostic ] -> [ Diagnostic ] -> Uri -> [Command |? CodeAction ]
481
- caRemoveInvalidExports m contents digs ctxDigs uri
487
+ caRemoveInvalidExports :: Maybe ParsedModule -> Maybe T. Text -> [Diagnostic ] -> Range -> Uri -> [Command |? CodeAction ]
488
+ caRemoveInvalidExports m contents digs contextRange uri
482
489
| Just pm <- m,
483
490
Just txt <- contents,
484
491
txt' <- indexedByPosition $ T. unpack txt,
@@ -488,7 +495,7 @@ caRemoveInvalidExports m contents digs ctxDigs uri
488
495
allRanges <- nubOrd $ [ range | (_,_,ranges) <- r, range <- ranges],
489
496
allRanges' <- extend txt' allRanges,
490
497
Just caRemoveAll <- removeAll allRanges',
491
- ctxEdits <- [ x | x@ (_, d, _) <- r, d `elem` ctxDigs ],
498
+ ctxEdits <- [ x | x@ (_, d, _) <- r, d `diagInRange` contextRange ],
492
499
not $ null ctxEdits
493
500
= caRemoveCtx ++ [caRemoveAll]
494
501
| otherwise = []
0 commit comments