Skip to content

Commit 02d5c66

Browse files
OliverMadineOliver Madinejneira
authored
Fix: #1690 - Infix typed holes are now filled using infix notation (#1708)
* Fix: #1690 - Infix typed holes are now filled using infix notation * fix: postfix hole uses postfix notation of infix operator Co-authored-by: Oliver Madine <[email protected]> Co-authored-by: Javier Neira <[email protected]>
1 parent f1c0969 commit 02d5c66

File tree

2 files changed

+57
-7
lines changed

2 files changed

+57
-7
lines changed

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -677,16 +677,24 @@ suggestModuleTypo Diagnostic{_range=_range,..}
677677
suggestFillHole :: Diagnostic -> [(T.Text, TextEdit)]
678678
suggestFillHole Diagnostic{_range=_range,..}
679679
| Just holeName <- extractHoleName _message
680-
, (holeFits, refFits) <- processHoleSuggestions (T.lines _message)
681-
= map (proposeHoleFit holeName False) holeFits
682-
++ map (proposeHoleFit holeName True) refFits
680+
, (holeFits, refFits) <- processHoleSuggestions (T.lines _message) =
681+
let isInfixHole = _message =~ addBackticks holeName :: Bool in
682+
map (proposeHoleFit holeName False isInfixHole) holeFits
683+
++ map (proposeHoleFit holeName True isInfixHole) refFits
683684
| otherwise = []
684685
where
685686
extractHoleName = fmap head . flip matchRegexUnifySpaces "Found hole: ([^ ]*)"
686-
proposeHoleFit holeName parenthise name =
687+
addBackticks text = "`" <> text <> "`"
688+
addParens text = "(" <> text <> ")"
689+
proposeHoleFit holeName parenthise isInfixHole name =
690+
let isInfixOperator = T.head name == '('
691+
name' = getOperatorNotation isInfixHole isInfixOperator name in
687692
( "replace " <> holeName <> " with " <> name
688-
, TextEdit _range $ if parenthise then parens name else name)
689-
parens x = "(" <> x <> ")"
693+
, TextEdit _range (if parenthise then addParens name' else name')
694+
)
695+
getOperatorNotation True False name = addBackticks name
696+
getOperatorNotation True True name = T.drop 1 (T.dropEnd 1 name)
697+
getOperatorNotation _isInfixHole _isInfixOperator name = name
690698

691699
processHoleSuggestions :: [T.Text] -> ([T.Text], [T.Text])
692700
processHoleSuggestions mm = (holeSuggestions, refSuggestions)
@@ -858,7 +866,7 @@ suggestImportDisambiguation df (Just txt) ps@(L _ HsModule {hsmodImports}) diag@
858866
| otherwise = case mapM toModuleTarget mods of
859867
Just targets -> suggestionsImpl symbol (oneAndOthers targets)
860868
Nothing -> []
861-
suggestionsImpl symbol targetsWithRestImports =
869+
suggestionsImpl symbol targetsWithRestImports =
862870
sortOn fst
863871
[ ( renderUniquify mode modNameText symbol
864872
, disambiguateSymbol ps diag symbol mode

ghcide/test/exe/Main.hs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,6 +2386,48 @@ fillTypedHoleTests = let
23862386
executeCodeAction chosen
23872387
modifiedCode <- documentContents doc
23882388
liftIO $ mkDoc "E.toException" @=? modifiedCode
2389+
, testSession "filling infix type hole uses prefix notation" $ do
2390+
let mkDoc x = T.unlines
2391+
[ "module Testing where"
2392+
, "data A = A"
2393+
, "foo :: A -> A -> A"
2394+
, "foo A A = A"
2395+
, "test :: A -> A -> A"
2396+
, "test a1 a2 = a1 " <> x <> " a2"
2397+
]
2398+
doc <- createDoc "Test.hs" "haskell" $ mkDoc "`_`"
2399+
_ <- waitForDiagnostics
2400+
actions <- getCodeActions doc (Range (Position 5 16) (Position 5 19))
2401+
chosen <- liftIO $ pickActionWithTitle "replace _ with foo" actions
2402+
executeCodeAction chosen
2403+
modifiedCode <- documentContents doc
2404+
liftIO $ mkDoc "`foo`" @=? modifiedCode
2405+
, testSession "postfix hole uses postfix notation of infix operator" $ do
2406+
let mkDoc x = T.unlines
2407+
[ "module Testing where"
2408+
, "test :: Int -> Int -> Int"
2409+
, "test a1 a2 = " <> x <> " a1 a2"
2410+
]
2411+
doc <- createDoc "Test.hs" "haskell" $ mkDoc "_"
2412+
_ <- waitForDiagnostics
2413+
actions <- getCodeActions doc (Range (Position 2 13) (Position 2 14))
2414+
chosen <- liftIO $ pickActionWithTitle "replace _ with (+)" actions
2415+
executeCodeAction chosen
2416+
modifiedCode <- documentContents doc
2417+
liftIO $ mkDoc "(+)" @=? modifiedCode
2418+
, testSession "filling infix type hole uses infix operator" $ do
2419+
let mkDoc x = T.unlines
2420+
[ "module Testing where"
2421+
, "test :: Int -> Int -> Int"
2422+
, "test a1 a2 = a1 " <> x <> " a2"
2423+
]
2424+
doc <- createDoc "Test.hs" "haskell" $ mkDoc "`_`"
2425+
_ <- waitForDiagnostics
2426+
actions <- getCodeActions doc (Range (Position 2 16) (Position 2 19))
2427+
chosen <- liftIO $ pickActionWithTitle "replace _ with (+)" actions
2428+
executeCodeAction chosen
2429+
modifiedCode <- documentContents doc
2430+
liftIO $ mkDoc "+" @=? modifiedCode
23892431
]
23902432

23912433
addInstanceConstraintTests :: TestTree

0 commit comments

Comments
 (0)