/- Copyright (c) 2021 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura, Marc Huisinga -/ module prelude public import Lean.Server.Completion.CompletionCollectors public import Lean.Server.RequestCancellation public import Std.Data.HashMap public section namespace Lean.Server.Completion open Lsp open Elab private def filterDuplicateCompletionItems (items : Array CompletionItem) : Array CompletionItem := let duplicationGroups := items.groupByKey fun i => ( i.label, i.textEdit?, i.detail?, i.kind?, i.tags?, i.documentation?, ) duplicationGroups.map (fun _ duplicateItems => duplicateItems[0]!) |>.valuesArray partial def find? (params : CompletionParams) (fileMap : FileMap) (hoverPos : String.Pos) (cmdStx : Syntax) (infoTree : InfoTree) (caps : ClientCapabilities) : CancellableM CompletionList := do let (prioritizedPartitions, isComplete) := findPrioritizedCompletionPartitionsAt fileMap hoverPos cmdStx infoTree let mut allCompletions := #[] for partition in prioritizedPartitions do for (i, completionInfoPos) in partition do CancellableM.checkCancelled let completions : Array ScoredCompletionItem ← match i.info with | .id stx id danglingDot lctx .. => idCompletion params completionInfoPos i.ctx lctx stx id i.hoverInfo danglingDot | .dot info .. => dotCompletion params completionInfoPos i.ctx info | .dotId _ id lctx expectedType? => dotIdCompletion params completionInfoPos i.ctx lctx id expectedType? | .fieldId _ id lctx structName => fieldIdCompletion params completionInfoPos i.ctx lctx id structName | .option stx => optionCompletion params completionInfoPos i.ctx stx caps | .errorName _ partialId => errorNameCompletion params completionInfoPos i.ctx partialId caps | .tactic .. => tacticCompletion params completionInfoPos i.ctx | _ => pure #[] allCompletions := allCompletions ++ completions if ! allCompletions.isEmpty then -- Stop accumulating completions with lower priority if we found completions for a higher -- priority. break let finalCompletions := allCompletions |> filterDuplicateCompletionItems return { items := finalCompletions, isIncomplete := ! isComplete } end Lean.Server.Completion