11module Language.PureScript.Ide.Completion
22 ( getCompletions
33 , getExactMatches
4+ , getExactCompletions
5+ , simpleExport
6+ , completionFromMatch
47 , CompletionOptions (.. )
58 , defaultCompletionOptions
69 , applyCompletionOptions
710 ) where
811
912import Protolude
1013
14+ import Control.Lens hiding ((&) , op )
1115import Data.Aeson
16+ import qualified Data.Map as Map
17+ import qualified Data.Text as T
18+ import qualified Language.PureScript as P
19+ import Language.PureScript.Ide.Error (prettyPrintTypeSingleLine )
1220import Language.PureScript.Ide.Filter
1321import Language.PureScript.Ide.Matcher
1422import Language.PureScript.Ide.Types
15- import qualified Language.PureScript as P
23+ import Language.PureScript.Ide.Util
1624
1725type Module = (P. ModuleName , [IdeDeclarationAnn ])
1826
@@ -23,37 +31,111 @@ getCompletions
2331 -> Matcher IdeDeclarationAnn
2432 -> CompletionOptions
2533 -> [Module ]
26- -> [Match IdeDeclarationAnn ]
34+ -> [Completion ]
2735getCompletions filters matcher options modules =
2836 modules
2937 & applyFilters filters
30- & completionsFromModules
38+ & matchesFromModules
3139 & runMatcher matcher
3240 & applyCompletionOptions options
41+ <&> completionFromMatch
3342
3443getExactMatches :: Text -> [Filter ] -> [Module ] -> [Match IdeDeclarationAnn ]
3544getExactMatches search filters modules =
36- completionsFromModules (applyFilters (equalityFilter search : filters) modules)
45+ modules
46+ & applyFilters (equalityFilter search : filters)
47+ & matchesFromModules
3748
38- completionsFromModules :: [Module ] -> [Match IdeDeclarationAnn ]
39- completionsFromModules = foldMap completionFromModule
49+ getExactCompletions :: Text -> [Filter ] -> [Module ] -> [Completion ]
50+ getExactCompletions search filters modules =
51+ modules
52+ & getExactMatches search filters
53+ <&> simpleExport
54+ <&> completionFromMatch
55+
56+ matchesFromModules :: [Module ] -> [Match IdeDeclarationAnn ]
57+ matchesFromModules = foldMap completionFromModule
4058 where
4159 completionFromModule (moduleName, decls) =
4260 map (\ x -> Match (moduleName, x)) decls
4361
4462data CompletionOptions = CompletionOptions
4563 { coMaxResults :: Maybe Int
64+ , coGroupReexports :: Bool
4665 }
4766
48- defaultCompletionOptions :: CompletionOptions
49- defaultCompletionOptions = CompletionOptions { coMaxResults = Nothing }
50-
51- applyCompletionOptions :: CompletionOptions -> [a ] -> [a ]
52- applyCompletionOptions co =
53- maybe identity take (coMaxResults co)
54-
5567instance FromJSON CompletionOptions where
5668 parseJSON = withObject " CompletionOptions" $ \ o -> do
5769 maxResults <- o .:? " maxResults"
58- pure (CompletionOptions { coMaxResults = maxResults })
70+ groupReexports <- o .:? " groupReexports" .!= False
71+ pure (CompletionOptions { coMaxResults = maxResults
72+ , coGroupReexports = groupReexports
73+ })
74+
75+ defaultCompletionOptions :: CompletionOptions
76+ defaultCompletionOptions = CompletionOptions { coMaxResults = Nothing , coGroupReexports = False }
77+
78+ applyCompletionOptions :: CompletionOptions -> [Match IdeDeclarationAnn ] -> [(Match IdeDeclarationAnn , [P. ModuleName ])]
79+ applyCompletionOptions co decls =
80+ maybe identity take (coMaxResults co) decls
81+ & if coGroupReexports co
82+ then groupCompletionReexports
83+ else map simpleExport
84+
85+ simpleExport :: Match a -> (Match a , [P. ModuleName ])
86+ simpleExport match@ (Match (moduleName, _)) = (match, [moduleName])
87+
88+ groupCompletionReexports :: [Match IdeDeclarationAnn ] -> [(Match IdeDeclarationAnn , [P. ModuleName ])]
89+ groupCompletionReexports initial =
90+ Map. elems (foldr go Map. empty initial)
91+ where
92+ go (Match (moduleName, d@ (IdeDeclarationAnn ann decl))) =
93+ let
94+ origin = fromMaybe moduleName (ann^. annExportedFrom)
95+ in
96+ Map. alter
97+ (insertDeclaration moduleName origin d)
98+ (Namespaced (namespaceForDeclaration decl)
99+ (P. runModuleName origin <> " ." <> identifierFromIdeDeclaration decl))
100+ insertDeclaration moduleName origin d old = case old of
101+ Nothing -> Just ( Match (origin, d & idaAnnotation. annExportedFrom .~ Nothing )
102+ , [moduleName]
103+ )
104+ Just x -> Just (second (moduleName : ) x)
105+
106+ data Namespaced a = Namespaced IdeNamespace a
107+ deriving (Show , Eq , Ord )
108+
109+ completionFromMatch :: (Match IdeDeclarationAnn , [P. ModuleName ]) -> Completion
110+ completionFromMatch (Match (m, IdeDeclarationAnn ann decl), mns) =
111+ Completion {.. }
112+ where
113+ (complIdentifier, complExpandedType) = case decl of
114+ IdeDeclValue v -> (v ^. ideValueIdent . identT, v ^. ideValueType & prettyPrintTypeSingleLine)
115+ IdeDeclType t -> (t ^. ideTypeName . properNameT, t ^. ideTypeKind & P. prettyPrintKind)
116+ IdeDeclTypeSynonym s -> (s ^. ideSynonymName . properNameT, s ^. ideSynonymType & prettyPrintTypeSingleLine)
117+ IdeDeclDataConstructor d -> (d ^. ideDtorName . properNameT, d ^. ideDtorType & prettyPrintTypeSingleLine)
118+ IdeDeclTypeClass d -> (d ^. ideTCName . properNameT, d ^. ideTCKind & P. prettyPrintKind)
119+ IdeDeclValueOperator (IdeValueOperator op ref precedence associativity typeP) ->
120+ (P. runOpName op, maybe (showFixity precedence associativity (valueOperatorAliasT ref) op) prettyPrintTypeSingleLine typeP)
121+ IdeDeclTypeOperator (IdeTypeOperator op ref precedence associativity kind) ->
122+ (P. runOpName op, maybe (showFixity precedence associativity (typeOperatorAliasT ref) op) P. prettyPrintKind kind)
123+ IdeDeclKind k -> (P. runProperName k, " kind" )
124+
125+ complExportedFrom = mns
126+
127+ complModule = P. runModuleName m
128+
129+ complType = maybe complExpandedType prettyPrintTypeSingleLine (_annTypeAnnotation ann)
130+
131+ complLocation = _annLocation ann
132+
133+ complDocumentation = Nothing
134+
135+ showFixity p a r o =
136+ let asso = case a of
137+ P. Infix -> " infix"
138+ P. Infixl -> " infixl"
139+ P. Infixr -> " infixr"
140+ in T. unwords [asso, show p, r, " as" , P. runOpName o]
59141
0 commit comments