Skip to content

Commit 3de244e

Browse files
authored
Improve action for fixing import typo (#2522)
* Improve action for fixing import typo * Remove unnecessary isInfixOf
1 parent 3061ace commit 3de244e

File tree

2 files changed

+49
-8
lines changed

2 files changed

+49
-8
lines changed

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

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -700,17 +700,32 @@ 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)
708-
| "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
716+
| "Could not find module" `T.isInfixOf` _message =
717+
case T.splitOn "Perhaps you meant" _message of
718+
[_, stuff] ->
719+
[ ("replace with " <> modul, TextEdit _range modul)
720+
| modul <- mapMaybe extractModule (T.lines stuff)
721+
]
722+
_ -> []
713723
| otherwise = []
724+
where
725+
extractModule line = case T.words line of
726+
[modul, "(from", _] -> Just modul
727+
_ -> Nothing
728+
714729

715730
suggestFillHole :: Diagnostic -> [(T.Text, TextEdit)]
716731
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)