feat: set_option completion
This commit is contained in:
parent
0a94aaabc9
commit
20f569c033
3 changed files with 21 additions and 12 deletions
|
|
@ -159,6 +159,10 @@ class Value (α : Type) where
|
|||
@[inline] def set {α : Type} [s : Value α] (m : KVMap) (k : Name) (v : α) : KVMap :=
|
||||
m.insert k (Value.toDataValue v)
|
||||
|
||||
instance : Value DataValue where
|
||||
toDataValue := id
|
||||
ofDataValue? := some
|
||||
|
||||
instance : Value Bool where
|
||||
toDataValue := DataValue.ofBool
|
||||
ofDataValue?
|
||||
|
|
|
|||
|
|
@ -21,15 +21,12 @@ def elabSetOption (id : Syntax) (val : Syntax) : m Options := do
|
|||
match val with
|
||||
| Syntax.atom _ "true" => setOption optionName (DataValue.ofBool true)
|
||||
| Syntax.atom _ "false" => setOption optionName (DataValue.ofBool false)
|
||||
| _ => throwError "unexpected set_option value {val}"
|
||||
| _ =>
|
||||
addCompletionInfo <| CompletionInfo.option (← getRef)
|
||||
throwError "unexpected set_option value {val}"
|
||||
where
|
||||
setOption (optionName : Name) (val : DataValue) : m Options := do
|
||||
let decl ←
|
||||
try
|
||||
IO.toEIO (fun (ex : IO.Error) => Exception.error (← getRef) ex.toString) (getOptionDecl optionName)
|
||||
catch ex =>
|
||||
addCompletionInfo <| CompletionInfo.option id
|
||||
throw ex
|
||||
let decl ← IO.toEIO (fun (ex : IO.Error) => Exception.error (← getRef) ex.toString) (getOptionDecl optionName)
|
||||
unless decl.defValue.sameCtor val do throwError "type mismatch at set_option"
|
||||
return (← getOptions).insert optionName val
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ private def isTypeApplicable (type : Expr) (expectedType? : Option Expr) : MetaM
|
|||
numArgs := numArgs - targetTypeNumArgs
|
||||
let (newMVars, _, type) ← forallMetaTelescopeReducing type (some numArgs)
|
||||
-- TODO take coercions into account
|
||||
dbg_trace "{type} =?= {expectedType}"
|
||||
isDefEq type expectedType
|
||||
-- We use `withReducible` to make sure we don't spend too much time unfolding definitions
|
||||
-- Alternative: use default and small number of heartbeats
|
||||
withReducible <| isDefEq type expectedType
|
||||
|
||||
private def filterBlackListed (cs : Array ConstantInfo) : MetaM (Array ConstantInfo) :=
|
||||
cs.filterM fun c => return !(← isBlackListedForCompletion c.name)
|
||||
|
|
@ -62,7 +63,7 @@ private def toCompletionItem (c : ConstantInfo) : MetaM CompletionItem := do
|
|||
|
||||
private def dotCompletion (ctx : ContextInfo) (info : TermInfo) (expectedType? : Option Expr) : IO (Option CompletionList) :=
|
||||
info.runMetaM ctx do
|
||||
dbg_trace ">> {info.stx}, {info.expr}"
|
||||
-- dbg_trace ">> {info.stx}, {info.expr}"
|
||||
let type ← instantiateMVars (← inferType info.expr)
|
||||
match type.getAppFn with
|
||||
| Expr.const name .. =>
|
||||
|
|
@ -71,7 +72,6 @@ private def dotCompletion (ctx : ContextInfo) (info : TermInfo) (expectedType? :
|
|||
let cs ← filterBlackListed cs
|
||||
let mut itemsMain := #[] -- we put entries that satisfy `isTypeApplicable` first
|
||||
let mut itemsOther := #[]
|
||||
dbg_trace ">>>> {expectedType?}"
|
||||
for c in cs do
|
||||
if (← isTypeApplicable c.type expectedType?) then
|
||||
itemsMain := itemsMain.push (← toCompletionItem c)
|
||||
|
|
@ -84,14 +84,22 @@ private def idCompletion (ctx : ContextInfo) (lctx : LocalContext) (stx : Syntax
|
|||
ctx.runMetaM lctx do
|
||||
let id := stx.getId
|
||||
if id.hasMacroScopes then return none
|
||||
|
||||
return none
|
||||
|
||||
private def optionCompletion (ctx : ContextInfo) (stx : Syntax) : IO (Option CompletionList) := do
|
||||
ctx.runMetaM {} do
|
||||
let decls ← getOptionDecls
|
||||
let opts ← getOptions
|
||||
let items : Array CompletionItem := decls.fold (init := #[]) fun items name decl =>
|
||||
items.push { label := name.toString, detail? := s!"({opts.get name decl.defValue}), {decl.descr}", documentation? := none }
|
||||
return some { items := sortCompletionItems items, isIncomplete := true }
|
||||
|
||||
partial def find? (fileMap : FileMap) (hoverPos : String.Pos) (infoTree : InfoTree) : IO (Option CompletionList) := do
|
||||
let ⟨hoverLine, _⟩ := fileMap.toPosition hoverPos
|
||||
match infoTree.foldInfo (init := none) (choose fileMap hoverLine) with
|
||||
| some (ctx, Info.ofCompletionInfo (CompletionInfo.dot info (expectedType? := expectedType?) ..)) => dotCompletion ctx info expectedType?
|
||||
| some (ctx, Info.ofCompletionInfo (CompletionInfo.id stx lctx openDecls expectedType?)) => idCompletion ctx lctx stx openDecls expectedType?
|
||||
| some (ctx, Info.ofCompletionInfo (CompletionInfo.option stx)) => optionCompletion ctx stx
|
||||
| _ => return none
|
||||
where
|
||||
choose (fileMap : FileMap) (hoverLine : Nat) (ctx : ContextInfo) (info : Info) (best? : Option (ContextInfo × Info)) : Option (ContextInfo × Info) :=
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue