Skip to content

Commit 3471a28

Browse files
committed
Limit CodeActions within passed range
Return only actions within range specified by client.
1 parent 9f8a172 commit 3471a28

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

hls-plugin-api/src/Ide/PluginUtils.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module Ide.PluginUtils
1919
mkLspCommand,
2020
mkLspCmdId,
2121
getPid,
22-
allLspCmdIds,allLspCmdIds',installSigUsr1Handler, subRange)
22+
allLspCmdIds,allLspCmdIds',installSigUsr1Handler, subRange, overlappingRange)
2323
where
2424

2525

@@ -185,6 +185,11 @@ subRange smallRange range =
185185
positionInRange (_start smallRange) range
186186
&& positionInRange (_end smallRange) range
187187

188+
overlappingRange :: Range -> Range -> Bool
189+
overlappingRange (Range s e) range =
190+
positionInRange s range
191+
|| positionInRange e range
192+
188193
positionInRange :: Position -> Range -> Bool
189194
positionInRange (Position pl po) (Range (Position sl so) (Position el eo)) =
190195
pl > sl && pl < el

plugins/hls-hlint-plugin/src/Ide/Plugin/Hlint.hs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,20 +268,26 @@ getHlintSettingsRule usage =
268268
-- ---------------------------------------------------------------------
269269

270270
codeActionProvider :: PluginMethodHandler IdeState TextDocumentCodeAction
271-
codeActionProvider ideState plId (CodeActionParams _ _ docId _ context) = Right . LSP.List . map InR <$> liftIO getCodeActions
271+
codeActionProvider ideState plId (CodeActionParams _ _ docId caRange context) = Right . LSP.List . map InR <$> liftIO getCodeActions
272272
where
273273

274274
getCodeActions = do
275275
diags <- getDiagnostics ideState
276276
let docNfp = toNormalizedFilePath' <$> uriToFilePath' (docId ^. LSP.uri)
277-
numHintsInDoc = length
277+
hints =
278278
[d | (nfp, _, d) <- diags
279279
, validCommand d
280280
, Just nfp == docNfp
281281
]
282+
numHintsInDoc = length hints
283+
numHintsInRange = length
284+
[d | d@LSP.Diagnostic{_range=range} <- hints
285+
, overlappingRange caRange range
286+
]
282287
-- We only want to show the applyAll code action if there is more than 1
283-
-- hint in the current document
284-
if numHintsInDoc > 1 then do
288+
-- hint in the current document and if code action range contains at
289+
-- least one hint
290+
if numHintsInDoc > 1 && numHintsInRange > 0 then do
285291
pure $ applyAllAction:applyOneActions
286292
else
287293
pure applyOneActions

test/functional/FunctionalCodeAction.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,22 @@ hlintTests = testGroup "hlint suggestions" [
170170

171171
, testCase "apply-refact preserve regular comments" $ runHlintSession "" $ do
172172
testRefactor "ApplyRefact6.hs" "Redundant bracket" expectedComments
173+
174+
, testCase "applyAll is shown only when there is at least one diagnostic in range" $ runHlintSession "" $ do
175+
doc <- openDoc "ApplyRefact7.hs" "haskell"
176+
_ <- waitForDiagnosticsFromSource doc "hlint"
177+
178+
firstLine <- map fromAction <$> getCodeActions doc (mkRange 0 0 0 0)
179+
secondLine <- map fromAction <$> getCodeActions doc (mkRange 1 0 1 0)
180+
thirdLine <- map fromAction <$> getCodeActions doc (mkRange 2 0 2 0)
181+
multiLine <- map fromAction <$> getCodeActions doc (mkRange 0 0 2 0)
182+
183+
let hasApplyAll = isJust . find (\ca -> "Apply all hints" `T.isSuffixOf` (ca ^. L.title))
184+
185+
liftIO $ hasApplyAll firstLine @? "Missing apply all code action"
186+
liftIO $ hasApplyAll secondLine @? "Missing apply all code action"
187+
liftIO $ not (hasApplyAll thirdLine) @? "Unexpected apply all code action"
188+
liftIO $ hasApplyAll multiLine @? "Missing apply all code action"
173189
]
174190
where
175191
runHlintSession :: FilePath -> Session a -> IO a

test/testdata/hlint/ApplyRefact7.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
f = (1)
2+
g = (1)
3+

0 commit comments

Comments
 (0)