Skip to content

Commit 6796dc7

Browse files
committed
Improve action for fixing import typo
1 parent 3061ace commit 6796dc7

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

ghcide/src/Development/IDE/Plugin/CodeAction.hs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -700,17 +700,33 @@ suggestFillTypeWildcard Diagnostic{_range=_range,..}
700700
= [("Use type signature: ‘" <> typeSignature <> "", TextEdit _range typeSignature)]
701701
| otherwise = []
702702

703+
{- Handles two variants with different formatting
704+
705+
1. Could not find module ‘Data.Cha’
706+
Perhaps you meant Data.Char (from base-4.12.0.0)
707+
708+
2. Could not find module ‘Data.I’
709+
Perhaps you meant
710+
Data.Ix (from base-4.14.3.0)
711+
Data.Eq (from base-4.14.3.0)
712+
Data.Int (from base-4.14.3.0)
713+
-}
703714
suggestModuleTypo :: Diagnostic -> [(T.Text, TextEdit)]
704715
suggestModuleTypo Diagnostic{_range=_range,..}
705-
-- src/Development/IDE/Core/Compile.hs:58:1: error:
706-
-- Could not find module ‘Data.Cha’
707-
-- Perhaps you meant Data.Char (from base-4.12.0.0)
708716
| "Could not find module" `T.isInfixOf` _message
709-
, "Perhaps you meant" `T.isInfixOf` _message = let
710-
findSuggestedModules = map (head . T.words) . drop 2 . T.lines
711-
proposeModule mod = ("replace with " <> mod, TextEdit _range mod)
712-
in map proposeModule $ nubOrd $ findSuggestedModules _message
717+
, "Perhaps you meant" `T.isInfixOf` _message =
718+
case T.splitOn "Perhaps you meant" _message of
719+
[_, stuff] ->
720+
[ ("replace with " <> modul, TextEdit _range modul)
721+
| modul <- mapMaybe extractModule $ T.lines stuff
722+
]
723+
_ -> []
713724
| otherwise = []
725+
where
726+
extractModule line = case T.words line of
727+
[modul,"(from",_] -> Just modul
728+
_ -> Nothing
729+
714730

715731
suggestFillHole :: Diagnostic -> [(T.Text, TextEdit)]
716732
suggestFillHole Diagnostic{_range=_range,..}

ghcide/test/exe/Main.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ codeActionTests = testGroup "code actions"
778778
, suggestHideShadowTests
779779
, suggestImportDisambiguationTests
780780
, fixConstructorImportTests
781+
, fixModuleImportTypoTests
781782
, importRenameActionTests
782783
, fillTypedHoleTests
783784
, addSigActionTests
@@ -1804,6 +1805,31 @@ extendImportTests = testGroup "extend import actions"
18041805
contentAfterAction <- documentContents docB
18051806
liftIO $ expectedContentB @=? contentAfterAction
18061807

1808+
fixModuleImportTypoTests :: TestTree
1809+
fixModuleImportTypoTests = testGroup "fix module import typo"
1810+
[ testSession "works when single module suggested" $ do
1811+
doc <- createDoc "A.hs" "haskell" "import Data.Cha"
1812+
_ <- waitForDiagnostics
1813+
InR action@CodeAction { _title = actionTitle } : _ <- getCodeActions doc (R 0 0 0 10)
1814+
liftIO $ actionTitle @?= "replace with Data.Char"
1815+
executeCodeAction action
1816+
contentAfterAction <- documentContents doc
1817+
liftIO $ contentAfterAction @?= "import Data.Char"
1818+
, testSession "works when multiple modules suggested" $ do
1819+
doc <- createDoc "A.hs" "haskell" "import Data.I"
1820+
_ <- waitForDiagnostics
1821+
actions <- sortOn (\(InR CodeAction{_title=x}) -> x) <$> getCodeActions doc (R 0 0 0 10)
1822+
let actionTitles = [ title | InR CodeAction{_title=title} <- actions ]
1823+
liftIO $ actionTitles @?= [ "replace with Data.Eq"
1824+
, "replace with Data.Int"
1825+
, "replace with Data.Ix"
1826+
]
1827+
let InR replaceWithDataEq : _ = actions
1828+
executeCodeAction replaceWithDataEq
1829+
contentAfterAction <- documentContents doc
1830+
liftIO $ contentAfterAction @?= "import Data.Eq"
1831+
]
1832+
18071833
extendImportTestsRegEx :: TestTree
18081834
extendImportTestsRegEx = testGroup "regex parsing"
18091835
[

0 commit comments

Comments
 (0)