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