Skip to content

enable completions of local imports #2190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions ghcide/src/Development/IDE/Plugin/Completions/Logic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiWayIf #-}


-- Mostly taken from "haskell-ide-engine"
module Development.IDE.Plugin.Completions.Logic (
CachedCompletions
Expand Down Expand Up @@ -66,6 +65,7 @@ import qualified Language.LSP.VFS as VFS
import Outputable (Outputable)
import TyCoRep


-- From haskell-ide-engine/hie-plugin-api/Haskell/Ide/Engine/Context.hs

-- | A context of a declaration in the program
Expand Down Expand Up @@ -403,15 +403,12 @@ cacheDataProducer uri env curMod globalEnv inScopeEnv limports = do

(unquals,quals) <- getCompls rdrElts

-- The list of all importable Modules from all packages
moduleNames <- maybe [] (map showModName) <$> envVisibleModuleNames env

return $ CC
{ allModNamesAsNS = allModNamesAsNS
, unqualCompls = unquals
, qualCompls = quals
, anyQualCompls = []
, importableModules = moduleNames
}

-- | Produces completions from the top level declarations of a module.
Expand All @@ -421,7 +418,6 @@ localCompletionsForParsedModule uri pm@ParsedModule{pm_parsed_source = L _ HsMod
, unqualCompls = compls
, qualCompls = mempty
, anyQualCompls = []
, importableModules = mempty
}
where
typeSigIds = Set.fromList
Expand Down Expand Up @@ -535,7 +531,7 @@ getCompletions
-> CompletionsConfig
-> HM.HashMap T.Text (HashSet.HashSet IdentInfo)
-> IO [CompletionItem]
getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qualCompls, importableModules}
getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qualCompls}
maybe_parsed (localBindings, bmapping) prefixInfo caps config moduleExportsMap = do
let VFS.PosPrefixInfo { fullLine, prefixModule, prefixText } = prefixInfo
enteredQual = if T.null prefixModule then "" else prefixModule <> "."
Expand Down Expand Up @@ -604,12 +600,11 @@ getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qu
, enteredQual `T.isPrefixOf` label
]

filtImportCompls = filtListWith (mkImportCompl enteredQual) importableModules
filtImportCompls = filtListWith (mkImportCompl enteredQual) $ HM.keys moduleExportsMap
filterModuleExports moduleName = filtListWith $ mkModuleFunctionImport moduleName
filtKeywordCompls
| T.null prefixModule = filtListWith mkExtCompl (optKeywords ideOpts)
| otherwise = []

if
-- TODO: handle multiline imports
| "import " `T.isPrefixOf` fullLine
Expand Down
7 changes: 3 additions & 4 deletions ghcide/src/Development/IDE/Plugin/Completions/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ data CachedCompletions = CC
, qualCompls :: QualCompls -- ^ Completion items associated to
-- to a specific module name.
, anyQualCompls :: [Maybe T.Text -> CompItem] -- ^ Items associated to any qualifier
, importableModules :: [T.Text] -- ^ All modules that may be imported.
}

instance Show CachedCompletions where show _ = "<cached completions>"
Expand All @@ -104,8 +103,8 @@ instance NFData CachedCompletions where
rnf = rwhnf

instance Monoid CachedCompletions where
mempty = CC mempty mempty mempty mempty mempty
mempty = CC mempty mempty mempty mempty

instance Semigroup CachedCompletions where
CC a b c d e <> CC a' b' c' d' e' =
CC (a<>a') (b<>b') (c<>c') (d<>d') (e<>e')
CC a b c d <> CC a' b' c' d' =
CC (a<>a') (b<>b') (c<>c') (d<>d')
20 changes: 19 additions & 1 deletion ghcide/test/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import Development.IDE.Test (Cursor,
import Development.IDE.Test.Runfiles
import qualified Development.IDE.Types.Diagnostics as Diagnostics
import Development.IDE.Types.Location
import qualified Language.LSP.Types.Lens as Lens (label)
import Development.Shake (getDirectoryFilesIO)
import qualified Experiments as Bench
import Ide.Plugin.Config
Expand Down Expand Up @@ -4589,7 +4590,24 @@ projectCompletionTests =
<- compls
, _label == "anidentifier"
]
liftIO $ compls' @?= ["Defined in 'A"]
liftIO $ compls' @?= ["Defined in 'A"],
testSession' "auto complete project imports" $ \dir-> do
liftIO $ writeFile (dir </> "hie.yaml")
"cradle: {direct: {arguments: [\"-Wmissing-signatures\", \"ALocalModule\", \"B\"]}}"
_ <- createDoc "ALocalModule.hs" "haskell" $ T.unlines
[ "module ALocalModule (anidentifier) where",
"anidentifier = ()"
]
_ <- waitForDiagnostics
-- Note that B does not import A
doc <- createDoc "B.hs" "haskell" $ T.unlines
[ "module B where",
"import ALocal"
]
compls <- getCompletions doc (Position 1 13)
let item = head $ filter ((== "ALocalModule") . (^. Lens.label)) compls
liftIO $ do
item ^. Lens.label @?= "ALocalModule"
]

highlightTests :: TestTree
Expand Down