@@ -65,7 +65,6 @@ import Language.LSP.Types.Capabilities
6565import qualified Language.LSP.VFS as VFS
6666import Text.Fuzzy.Parallel (Scored (score ),
6767 original )
68- import Safe (fromJustNote )
6968
7069-- Chunk size used for parallelizing fuzzy matching
7170chunkSize :: 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