0 | module Idris.IDEMode.Holes
10 | import Idris.IDEMode.Commands
15 | record Premise where
16 | constructor MkHolePremise
19 | multiplicity : RigCount
22 | impBracket : Bool -> String -> String
23 | impBracket False str = str
24 | impBracket True str = "{" ++ str ++ "}"
27 | Show Holes.Premise where
29 | " " ++ showCount premise.multiplicity ++ " "
30 | ++ impBracket premise.isImplicit (show premise.name ++ " : " ++ show premise.type)
32 | prettyImpBracket : Bool -> Doc ann -> Doc ann
33 | prettyImpBracket False = id
34 | prettyImpBracket True = braces
37 | prettyRigHole : RigCount -> Doc IdrisSyntax
38 | prettyRigHole = elimSemi (keyword (pretty0 '0') <+> space)
39 | (keyword (pretty0 '1') <+> space)
40 | (const $
space <+> space)
43 | Pretty IdrisSyntax Holes.Premise where
45 | prettyRigHole premise.multiplicity
46 | <+> prettyImpBracket premise.isImplicit (pretty0 premise.name <++> colon <++> pretty premise.type)
50 | constructor MkHoleData
53 | context : List Holes.Premise
56 | prettyHoles : List Holes.Data -> Doc IdrisSyntax
57 | prettyHoles holes = case holes of
59 | [x] => "1 hole" <+> colon <++> prettyHole x
60 | xs => vcat $
(pretty0 (show $
length xs) <++> "holes" <+> colon)
61 | :: map (indent 2 . prettyHole) xs
65 | prettyHole : Holes.Data -> Doc IdrisSyntax
66 | prettyHole x = pretty0 x.name <++> colon <++> pretty x.type
72 | isHole : GlobalDef -> Maybe Nat
74 | = case definition def of
75 | Hole locs _ => Just locs
79 | SolvedHole n => Just n
85 | showName : Name -> Bool
86 | showName (UN Underscore) = False
87 | showName (MN {}) = False
91 | extractHoleData : {vars : _} ->
92 | {auto c : Ref Ctxt Defs} ->
93 | {auto s : Ref Syn SyntaxInfo} ->
94 | Defs -> Env Term vars -> Name -> Nat -> Term vars ->
96 | extractHoleData defs env fn (S args) (Bind fc x (Let _ c val ty) sc)
97 | = extractHoleData defs env fn args (subst val sc)
98 | extractHoleData defs env fn (S args) (Bind fc x b sc)
99 | = do rest <- extractHoleData defs (b :: env) fn args sc
100 | let True = showName x
101 | | False => do log "ide-mode.hole" 10 $
"Not showing name: " ++ show x
103 | log "ide-mode.hole" 10 $
"Showing name: " ++ show x
104 | ity <- resugar env !(normalise defs env (binderType b))
105 | let premise = MkHolePremise x ity (multiplicity b) (isImplicit b)
106 | pure $
{ context $= (premise ::) } rest
107 | extractHoleData defs env fn args ty
108 | = do nty <- normalise defs env ty
109 | ity <- resugar env nty
110 | log "ide-mode.hole" 20 $
111 | "Return type: " ++ show !(toFullNames ty)
112 | ++ "\n Evaluated to: " ++ show !(toFullNames nty)
113 | ++ "\n Resugared to: " ++ show ity
114 | pure $
MkHoleData fn ity []
118 | holeData : {vars : _} ->
119 | {auto c : Ref Ctxt Defs} ->
120 | {auto s : Ref Syn SyntaxInfo} ->
121 | Defs -> Env Term vars -> Name -> Nat -> Term vars ->
124 | holeData gam env fn args ty
125 | = do hdata <- extractHoleData gam env fn args ty
127 | pure $
if showImplicits pp
129 | else { context $= dropShadows } hdata
131 | dropShadows : List Holes.Premise -> List Holes.Premise
132 | dropShadows [] = []
133 | dropShadows (premise :: rest)
134 | = if premise.name `elem` map name rest
135 | then dropShadows rest
136 | else premise :: dropShadows rest
140 | {auto c : Ref Ctxt Defs} ->
141 | {auto s : Ref Syn SyntaxInfo} ->
142 | Core (List Holes.Data)
144 | = do defs <- get Ctxt
145 | let ctxt = gamma defs
147 | let globs = concat !(traverse (\n => lookupCtxtName n ctxt) ms)
148 | let holesWithArgs = mapMaybe (\(n, i, gdef) => do args <- isHole gdef
149 | pure (n, gdef, args))
151 | traverse (\n_gdef_args =>
153 | let (n, gdef, args) = the (Name, GlobalDef, Nat) n_gdef_args in
154 | holeData defs Env.empty n args (type gdef))
158 | showHole : {vars : _} ->
159 | {auto c : Ref Ctxt Defs} ->
160 | {auto s : Ref Syn SyntaxInfo} ->
161 | Defs -> Env Term vars -> Name -> Nat -> Term vars ->
164 | showHole defs env fn args ty
165 | = do hdata <- holeData defs env fn args ty
166 | case hdata.context of
167 | [] => pure $
show (hdata.name) ++ " : " ++ show hdata.type
169 | unlines (map show hdata.context)
170 | ++ "-------------------------------------\n"
171 | ++ nameRoot (hdata.name) ++ " : " ++ show hdata.type
174 | prettyHole : {vars : _} ->
175 | {auto c : Ref Ctxt Defs} ->
176 | {auto s : Ref Syn SyntaxInfo} ->
177 | Defs -> Env Term vars -> Name -> Nat -> Term vars ->
178 | Core (Doc IdrisSyntax)
179 | prettyHole defs env fn args ty
180 | = do hdata <- holeData defs env fn args ty
181 | case hdata.context of
182 | [] => pure $
pretty0 hdata.name <++> colon <++> pretty hdata.type
183 | _ => pure $
indent 1 (vsep $
map pretty hdata.context) <+> hardline
184 | <+> (pretty0 $
replicate 30 '-') <+> hardline
185 | <+> pretty0 (nameRoot $
hdata.name) <++> colon <++> pretty hdata.type
188 | premiseIDE : Holes.Premise -> HolePremise
189 | premiseIDE premise = IDE.MkHolePremise
190 | { name = " " ++ showCount premise.multiplicity ++ " "
191 | ++ (impBracket premise.isImplicit $
193 | , type = show premise.type
197 | holeIDE : Holes.Data -> IDE.HoleData
198 | holeIDE hole = IDE.MkHoleData
199 | { name = show hole.name
200 | , type = show hole.type
201 | , context = map premiseIDE hole.context