Skip to content

Commit f15b6e3

Browse files
committed
Use parsed context for completions
1 parent d656731 commit f15b6e3

File tree

1 file changed

+32
-15
lines changed
  • ghcide/src/Development/IDE/Plugin/Completions

1 file changed

+32
-15
lines changed

ghcide/src/Development/IDE/Plugin/Completions/Logic.hs

+32-15
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ import Language.LSP.Types.Capabilities
6565
import qualified Language.LSP.VFS as VFS
6666
import Text.Fuzzy.Parallel (Scored (score),
6767
original)
68-
import Safe (fromJustNote)
6968

7069
-- Chunk size used for parallelizing fuzzy matching
7170
chunkSize :: Int
@@ -588,10 +587,7 @@ getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qu
588587
$ (if T.null enteredQual then id else mapMaybe (T.stripPrefix enteredQual))
589588
allModNamesAsNS
590589

591-
filtCompls = Fuzzy.filter chunkSize maxC prefixText ctxCompls (label . snd)
592-
where
593-
594-
mcc = case maybe_parsed of
590+
maybeContext = case maybe_parsed of
595591
Nothing -> Nothing
596592
Just (pm, pmapping) ->
597593
let PositionMapping pDelta = pmapping
@@ -600,8 +596,10 @@ getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qu
600596
hpos = upperRange position'
601597
in getCContext lpos pm <|> getCContext hpos pm
602598

599+
filtCompls = Fuzzy.filter chunkSize maxC prefixText ctxCompls (label . snd)
600+
where
603601
-- completions specific to the current context
604-
ctxCompls' = case mcc of
602+
ctxCompls' = case maybeContext of
605603
Nothing -> compls
606604
Just TypeContext -> filter ( isTypeCompl . snd) compls
607605
Just ValueContext -> filter (not . isTypeCompl . snd) compls
@@ -637,8 +635,15 @@ getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qu
637635
, enteredQual `T.isPrefixOf` original label
638636
]
639637

640-
getModuleName line = let ws = filter (/= "qualified") (T.words line)
641-
in if List.length ws >= 2 then Just (ws !! 1) else Nothing
638+
moduleImportListCompletions :: String -> [Scored CompletionItem]
639+
moduleImportListCompletions moduleNameS =
640+
let moduleName = T.pack moduleNameS
641+
funcs = HM.lookupDefault HashSet.empty moduleName moduleExportsMap
642+
funs = map (show . name) $ HashSet.toList funcs
643+
in filterModuleExports moduleName $ map T.pack funs
644+
645+
-- manually parse in case we don't have completion context ("import [qualified ]ModuleName")
646+
getModuleName line = filter (/= "qualified") (T.words line) !? 1
642647
filtImportCompls = filtListWith (mkImportCompl enteredQual) importableModules
643648
filterModuleExports moduleName = filtListWith $ mkModuleFunctionImport moduleName
644649
filtKeywordCompls
@@ -647,20 +652,32 @@ getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qu
647652

648653
if
649654
-- TODO: handle multiline imports
655+
| Just (ImportListContext moduleName) <- maybeContext
656+
-> pure $ moduleImportListCompletions moduleName
657+
658+
| Just (ImportHidingContext moduleName) <- maybeContext
659+
-> pure $ moduleImportListCompletions moduleName
660+
661+
-- TODO: Is manual parsing ever needed or is context always present for module?
662+
-- If possible only keep the above.
650663
| "import " `T.isPrefixOf` fullLine
651-
&& isJust (getModuleName fullLine)
652-
&& "(" `T.isInfixOf` fullLine
653-
-> do
654-
let moduleName = fromJustNote "NEVER FAILS: module name checked above" $ getModuleName fullLine
655-
funcs = HM.lookupDefault HashSet.empty moduleName moduleExportsMap
656-
funs = map (show . name) $ HashSet.toList funcs
657-
return $ filterModuleExports moduleName $ map T.pack funs
664+
, Just moduleName <- getModuleName fullLine
665+
, "(" `T.isInfixOf` fullLine
666+
-> pure $ moduleImportListCompletions $ T.unpack moduleName
667+
668+
| Just (ImportContext _moduleName) <- maybeContext
669+
-> return filtImportCompls
670+
671+
-- TODO: Can we avoid this manual parsing?
672+
-- If possible only keep the above.
658673
| "import " `T.isPrefixOf` fullLine
659674
-> return filtImportCompls
675+
660676
-- we leave this condition here to avoid duplications and return empty list
661677
-- since HLS implements these completions (#haskell-language-server/pull/662)
662678
| "{-# " `T.isPrefixOf` fullLine
663679
-> return []
680+
664681
| otherwise -> do
665682
-- assumes that nubOrdBy is stable
666683
let uniqueFiltCompls = nubOrdBy (uniqueCompl `on` snd . Fuzzy.original) filtCompls

0 commit comments

Comments
 (0)