@@ -697,7 +697,7 @@ package body LSP.Ada_Handlers is
697697 Response.result.capabilities.signatureHelpProvider :=
698698 (True,
699699 (triggerCharacters => (True, Empty_Vector & (+" ," ) & (+" (" )),
700- retriggerCharacters => (True, Empty_Vector & (+" " )),
700+ retriggerCharacters => (True, Empty_Vector & (+( 1 => ASCII.BS) )),
701701 workDoneProgress => LSP.Types.None));
702702 Response.result.capabilities.completionProvider :=
703703 (True,
@@ -2494,11 +2494,33 @@ package body LSP.Ada_Handlers is
24942494 Sloc : constant Langkit_Support.Slocs.Source_Location :=
24952495 Document.Get_Source_Location (Value.position);
24962496
2497- Name_Node : Libadalang.Analysis.Name;
2498- Designator : Libadalang.Analysis.Ada_Node;
2499- Active_Position : LSP.Types.LSP_Number;
2497+ Name_Node : Libadalang.Analysis.Name;
2498+ Designator : Libadalang.Analysis.Ada_Node;
2499+ Active_Position : LSP.Types.LSP_Number;
2500+ Active_Signature : LSP.Types.LSP_Number := 0 ;
25002501
25012502 procedure Add_Signature (Decl_Node : Libadalang.Analysis.Basic_Decl);
2503+ -- Add the signature of Decl_Node if it matches the current context.
2504+
2505+ procedure Filter_Signature
2506+ (Signature_Info : SignatureInformation;
2507+ Designator : Libadalang.Analysis.Ada_Node;
2508+ Position : LSP.Types.LSP_Number;
2509+ Is_Active : Boolean);
2510+ -- Filter the signatures returned by the client using the current
2511+ -- current Position and designator.
2512+ -- Set Active_Signature to 0 when Is_Active and filtered out.
2513+
2514+ function Is_Signature_Active
2515+ (Parameters : ParameterInformation_Vector;
2516+ Sig_Label : LSP.Types.LSP_String;
2517+ Position : LSP.Types.LSP_Number;
2518+ Designator : Libadalang.Analysis.Ada_Node;
2519+ Active_Position : out LSP.Types.LSP_Number)
2520+ return Boolean;
2521+ -- Return True if Parameters is valid for the current Position and
2522+ -- Designator.
2523+ -- Active_Position will point to the active parameter inside Parameters.
25022524
25032525 -- -----------------
25042526 -- Add_Signature --
@@ -2537,6 +2559,88 @@ package body LSP.Ada_Handlers is
25372559 end ;
25382560 end Add_Signature ;
25392561
2562+ -- --------------------
2563+ -- Filter_Signature --
2564+ -- --------------------
2565+
2566+ procedure Filter_Signature
2567+ (Signature_Info : SignatureInformation;
2568+ Designator : Libadalang.Analysis.Ada_Node;
2569+ Position : LSP.Types.LSP_Number;
2570+ Is_Active : Boolean)
2571+ is
2572+ Active_Position : LSP.Types.LSP_Number;
2573+ begin
2574+ if Is_Signature_Active
2575+ (Parameters => Signature_Info.parameters,
2576+ Sig_Label => Signature_Info.label,
2577+ Position => Position,
2578+ Designator => Designator,
2579+ Active_Position => Active_Position)
2580+ then
2581+ declare
2582+ New_Signature : SignatureInformation := Signature_Info;
2583+ begin
2584+ -- Reuse Signature_Info after updating the active_position
2585+ New_Signature.activeParameter := (Is_Set => True,
2586+ Value => Active_Position);
2587+ Response.result.signatures.Append (New_Signature);
2588+ end ;
2589+ elsif Is_Active then
2590+ Active_Signature := 0 ;
2591+ end if ;
2592+ end Filter_Signature ;
2593+
2594+ -- -----------------------
2595+ -- Is_Signature_Active --
2596+ -- -----------------------
2597+
2598+ function Is_Signature_Active
2599+ (Parameters : ParameterInformation_Vector;
2600+ Sig_Label : LSP.Types.LSP_String;
2601+ Position : LSP.Types.LSP_Number;
2602+ Designator : Libadalang.Analysis.Ada_Node;
2603+ Active_Position : out LSP.Types.LSP_Number)
2604+ return Boolean
2605+ is
2606+ use VSS.Strings;
2607+ begin
2608+ Active_Position := 0 ;
2609+ if Designator = No_Ada_Node then
2610+ -- Check if Position is valid in Parameters (Note: Position starts
2611+ -- at 0)
2612+ Active_Position := Position;
2613+ return Position < LSP_Number (Parameters.Length);
2614+ else
2615+ declare
2616+ Name : constant Virtual_String :=
2617+ LSP.Lal_Utils.To_Virtual_String (Designator.Text);
2618+ Converted_Name : constant LSP_String :=
2619+ LSP.Types.To_LSP_String (Name);
2620+ begin
2621+ for Param of Parameters loop
2622+ -- Convert to lower case?
2623+ if Param.label.Is_String then
2624+ if Param.label.String = Name then
2625+ return True;
2626+ end if ;
2627+ else
2628+ if Slice (Sig_Label,
2629+ Integer (Param.label.From),
2630+ Integer (Param.label.Till))
2631+ = Converted_Name
2632+ then
2633+ return True;
2634+ end if ;
2635+ end if ;
2636+ Active_Position := Active_Position + 1 ;
2637+ end loop ;
2638+ end ;
2639+ end if ;
2640+
2641+ return False;
2642+ end Is_Signature_Active ;
2643+
25402644 begin
25412645 Response.result := (others => <>);
25422646
@@ -2552,18 +2656,57 @@ package body LSP.Ada_Handlers is
25522656 return Response;
25532657 end if ;
25542658
2555- for N of C.Find_All_Env_Elements (Name_Node) loop
2556- if N.Kind in Ada_Subp_Decl_Range
2557- | Ada_Null_Subp_Decl_Range
2558- | Ada_Expr_Function_Range
2559- then
2560- Add_Signature (N.As_Basic_Decl);
2561- end if ;
2562- end loop ;
2659+ if Value.context.Is_Set
2660+ and then Value.context.Value.isRetrigger
2661+ and then Value.context.Value.activeSignatureHelp.Is_Set
2662+ and then
2663+ (Value.context.Value.triggerKind /= TriggerCharacter
2664+ or else
2665+ -- Check if the trigger character is a backspace
2666+ ((not Value.context.Value.triggerCharacter.Is_Set)
2667+ or else Value.context.Value.triggerCharacter.Value /=
2668+ (+(1 => ASCII.BS))))
2669+ then
2670+ -- At this point, we are filtering the previous signatures:
2671+ -- * Don't recompute the list of signature
2672+ -- * Keep the previous activeSignature if not filtered out
2673+
2674+ declare
2675+ Prev_Res : SignatureHelp renames
2676+ Value.context.Value.activeSignatureHelp.Value;
2677+ -- Use index to find the activeSignature
2678+ Index : LSP.Types.LSP_Number := 0 ;
2679+ begin
2680+ if Prev_Res.activeSignature.Is_Set then
2681+ Active_Signature := Prev_Res.activeSignature.Value;
2682+ else
2683+ Active_Signature := 0 ;
2684+ end if ;
2685+
2686+ for Signature_Info of Prev_Res.signatures loop
2687+ Filter_Signature
2688+ (Signature_Info => Signature_Info,
2689+ Designator => Designator,
2690+ Position => Active_Position,
2691+ Is_Active => Index = Active_Signature);
2692+ Index := Index + 1 ;
2693+ end loop ;
2694+ end ;
2695+ else
2696+
2697+ for N of C.Find_All_Env_Elements (Name_Node) loop
2698+ if N.Kind in Ada_Subp_Decl_Range
2699+ | Ada_Null_Subp_Decl_Range
2700+ | Ada_Expr_Function_Range
2701+ then
2702+ Add_Signature (N.As_Basic_Decl);
2703+ end if ;
2704+ end loop ;
2705+ end if ;
25632706
25642707 -- Set the active values to default
25652708 Response.result.activeSignature := (Is_Set => True,
2566- Value => 0 );
2709+ Value => Active_Signature );
25672710 -- activeParameter will be ignored because it is properly set in
25682711 -- the signatures.
25692712 Response.result.activeParameter := (Is_Set => True,
0 commit comments