@@ -185,27 +185,28 @@ quitMessage = "See ya!"
185185
186186-- Haskeline completions
187187
188- data CompletionContext = Command String | FilePath | Module | Identifier | Fixed [String ] | Multiple [CompletionContext ]
188+ data CompletionContext = Command String | FilePath String | Module | Identifier
189+ | Type | Fixed [String ] | Multiple [CompletionContext ]
189190 deriving (Show )
190191
191192-- |
192193-- Decide what kind of completion we need based on input.
193- completionContext :: String -> Maybe CompletionContext
194- completionContext cmd@ " " = Just $ Multiple [Command cmd, Identifier ]
195- completionContext cmd@ (' :' : _ )
194+ completionContext :: String -> String -> Maybe CompletionContext
195+ completionContext cmd@ " " _ = Just $ Multiple [Command cmd, Identifier ]
196+ completionContext cmd@ (' :' : _ ) _
196197 | cmd `elem` C. commands || cmd == " :" = Just $ Command cmd
197- completionContext (' :' : c : _) = case c of
198+ completionContext (' :' : c : _) word = case c of
198199 ' i' -> Just Module
199200 ' b' -> Just Module
200- ' m' -> Just FilePath
201+ ' m' -> Just $ FilePath word
201202 ' q' -> Nothing
202203 ' r' -> Nothing
203204 ' ?' -> Nothing
204205 ' s' -> Just $ Fixed [" import" , " loaded" ]
205206 ' t' -> Just Identifier
206- ' k' -> Just Identifier
207+ ' k' -> Just Type
207208 _ -> Nothing
208- completionContext _ = Just Identifier
209+ completionContext _ _ = Just Identifier
209210
210211-- |
211212-- Loads module, function, and file completions.
@@ -215,53 +216,84 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
215216 where
216217 findCompletions :: String -> String -> StateT PSCiState IO [Completion ]
217218 findCompletions prev word = do
218- let ctx = completionContext $ ( dropWhile isSpace (reverse prev)) ++ word
219+ let ctx = completionContext (( dropWhile isSpace (reverse prev)) ++ word) word
219220 completions <- case ctx of
220221 Nothing -> return []
221222 (Just c) -> (mapMaybe $ either (\ cand -> if word `isPrefixOf` cand
222223 then Just $ simpleCompletion cand
223224 else Nothing ) Just )
224- <$> getCompletion c word
225+ <$> getCompletion c
225226 return $ sortBy sorter completions
226227
227- getCompletion :: CompletionContext -> String -> StateT PSCiState IO [Either String Completion ]
228- getCompletion (Command s) _ = return $ (map Left ) $ nub $ filter (isPrefixOf s) C. commands
229- getCompletion FilePath f = (map Right ) <$> listFiles f
230- getCompletion Module _ = (map Left ) <$> getModuleNames
231- getCompletion Identifier _ = (map Left ) <$> getIdentNames
232- getCompletion (Fixed list) _ = return $ (map Left ) list
233- getCompletion (Multiple contexts) f = concat <$> mapM (flip getCompletion $ f) contexts
228+ getCompletion :: CompletionContext -> StateT PSCiState IO [Either String Completion ]
229+ getCompletion (Command s) = return $ (map Left ) $ nub $ filter (isPrefixOf s) C. commands
230+ getCompletion (FilePath f) = (map Right ) <$> listFiles f
231+ getCompletion Module = (map Left ) <$> getModuleNames
232+ getCompletion Identifier = (map Left ) <$> ((++) <$> getIdentNames <*> getDctorNames)
233+ getCompletion Type = (map Left ) <$> getTypeNames
234+ getCompletion (Fixed list) = return $ (map Left ) list
235+ getCompletion (Multiple contexts) = concat <$> mapM getCompletion contexts
234236
235237 getLoadedModules :: StateT PSCiState IO [P. Module ]
236238 getLoadedModules = map snd . psciLoadedModules <$> get
237239
238240 getModuleNames :: StateT PSCiState IO [String ]
239241 getModuleNames = moduleNames <$> getLoadedModules
240242
243+ mapLoadedModulesAndQualify :: (Show a ) => (P. Module -> [a ]) -> StateT PSCiState IO [String ]
244+ mapLoadedModulesAndQualify f = do
245+ ms <- getLoadedModules
246+ q <- sequence [qualifyIfNeeded m (f m) | m <- ms]
247+ return $ concat q
248+
241249 getIdentNames :: StateT PSCiState IO [String ]
242- getIdentNames = identNames <$> getLoadedModules
243-
244- getDeclName :: Maybe [P. DeclarationRef ] -> P. Declaration -> Maybe P. Ident
245- getDeclName exts (P. ValueDeclaration ident _ _ _) | isExported ident exts = Just ident
246- getDeclName exts (P. ExternDeclaration _ ident _ _) | isExported ident exts = Just ident
247- getDeclName exts (P. PositionedDeclaration _ d) = getDeclName exts d
248- getDeclName _ _ = Nothing
249-
250- isExported :: N. Ident -> Maybe [P. DeclarationRef ] -> Bool
251- isExported ident = maybe True (any exports)
252- where
253- exports :: P. DeclarationRef -> Bool
254- exports (P. ValueRef ident') = ident == ident'
255- exports (P. PositionedDeclarationRef _ r) = exports r
256- exports _ = False
257-
258- identNames :: [P. Module ] -> [String ]
259- identNames ms = nub [ show qual
260- | P. Module moduleName ds exts <- ms
261- , ident <- mapMaybe (getDeclName exts) ds
262- , qual <- [ P. Qualified Nothing ident
263- , P. Qualified (Just moduleName) ident]
264- ]
250+ getIdentNames = mapLoadedModulesAndQualify identNames
251+
252+ getDctorNames :: StateT PSCiState IO [String ]
253+ getDctorNames = mapLoadedModulesAndQualify dctorNames
254+
255+ getTypeNames :: StateT PSCiState IO [String ]
256+ getTypeNames = mapLoadedModulesAndQualify typeDecls
257+
258+ qualifyIfNeeded :: (Show a ) => P. Module -> [a ] -> StateT PSCiState IO [String ]
259+ qualifyIfNeeded m decls = do
260+ let name = P. getModuleName m
261+ imported <- psciImportedModuleNames <$> get
262+ let qualified = map (P. Qualified $ Just name) decls
263+ if name `elem` imported then
264+ return $ map show $ qualified ++ (map (P. Qualified Nothing ) decls)
265+ else
266+ return $ map show qualified
267+
268+ typeDecls :: P. Module -> [N. ProperName ]
269+ typeDecls m = mapMaybe getTypeName $ filter P. isDataDecl (P. exportedDeclarations m)
270+ where getTypeName :: P. Declaration -> Maybe N. ProperName
271+ getTypeName (P. TypeSynonymDeclaration name _ _) = Just name
272+ getTypeName (P. DataDeclaration _ name _ _) = Just name
273+ getTypeName (P. PositionedDeclaration _ d) = getTypeName d
274+ getTypeName _ = Nothing
275+
276+ identNames :: P. Module -> [N. Ident ]
277+ identNames (P. Module _ ds exports) = nub [ ident | ident <- mapMaybe (getDeclName exports) ds ]
278+ where getDeclName :: Maybe [P. DeclarationRef ] -> P. Declaration -> Maybe P. Ident
279+ getDeclName exts decl@ (P. ValueDeclaration ident _ _ _) | P. isExported exts decl = Just ident
280+ getDeclName exts decl@ (P. ExternDeclaration _ ident _ _) | P. isExported exts decl = Just ident
281+ getDeclName exts (P. PositionedDeclaration _ d) = getDeclName exts d
282+ getDeclName _ _ = Nothing
283+
284+ dctorNames :: P. Module -> [N. ProperName ]
285+ dctorNames m = nub $ concat $ map (P. exportedDctors m) dnames
286+ where getDataDeclName :: P. Declaration -> Maybe N. ProperName
287+ getDataDeclName (P. DataDeclaration _ name _ _) = Just name
288+ getDataDeclName (P. PositionedDeclaration _ d) = getDataDeclName d
289+ getDataDeclName _ = Nothing
290+
291+ dnames :: [N. ProperName ]
292+ dnames = (mapMaybe getDataDeclName onlyDataDecls)
293+
294+ onlyDataDecls :: [P. Declaration ]
295+ onlyDataDecls = (filter P. isDataDecl (P. exportedDeclarations m))
296+
265297 moduleNames :: [P. Module ] -> [String ]
266298 moduleNames ms = nub [show moduleName | P. Module moduleName _ _ <- ms]
267299
@@ -601,7 +633,6 @@ main = execParser opts >>= loop
601633 infoModList = fullDesc <> headerInfo <> footerInfo
602634 headerInfo = header " psci - Interactive mode for PureScript"
603635 footerInfo = footer $ " psci " ++ showVersion Paths. version
604-
636+
605637 version :: Parser (a -> a )
606638 version = abortOption (InfoMsg (showVersion Paths. version)) $ long " version" <> Opts. help " Show the version number" <> hidden
607-
0 commit comments