@@ -995,20 +995,214 @@ package body LSP.Ada_Documents is
995
995
Input_Range =>
996
996
Self.To_Source_Location_Range ((Position, Position))));
997
997
998
- -- -------------------
999
- -- Get_Indentation --
1000
- -- -------------------
998
+ -- ------------------------
999
+ -- Estimate_Indentation --
1000
+ -- ------------------------
1001
1001
1002
- function Get_Indentation
1003
- (Self : Document;
1004
- Context : LSP.Ada_Contexts.Context;
1005
- Line : Positive)
1002
+ function Estimate_Indentation
1003
+ (Self : Document; Context : LSP.Ada_Contexts.Context; Line : Positive)
1006
1004
return VSS.Strings.Character_Count
1007
1005
is
1008
- (VSS.Strings.Character_Count
1009
- (Laltools.Partial_GNATPP.Estimate_Indentation
1010
- (Self.Unit (Context),
1011
- Self.To_Source_Location ((Line, 1 )).Line)));
1006
+ use Langkit_Support.Slocs;
1007
+ use Libadalang.Analysis;
1008
+ use Libadalang.Common;
1009
+
1010
+ function Get_Relevant_Parents
1011
+ (Unit : Libadalang.Analysis.Analysis_Unit;
1012
+ Token : Token_Reference) return Ada_Node_Array;
1013
+ -- Analyze where in the tree this Token is and returns the appropriate
1014
+ -- parent nodes that influence indentation.
1015
+
1016
+ function Parent_Based_Indentation
1017
+ (Parents : Ada_Node_Array;
1018
+ Indentation : Positive := 3 ;
1019
+ Indentation_Continuation : Positive := 2 ) return Natural;
1020
+ -- Estimate the indentation starting at zero and incrementing based on
1021
+ -- that Parents kind. Returns earlier if it finds a parent that always
1022
+ -- sets indentation, for instance, a parameter list.
1023
+
1024
+ -- ----------------------------
1025
+ -- Parent_Based_Indentation --
1026
+ -- ----------------------------
1027
+
1028
+ function Parent_Based_Indentation
1029
+ (Parents : Ada_Node_Array;
1030
+ Indentation : Positive := 3 ;
1031
+ Indentation_Continuation : Positive := 2 ) return Natural
1032
+ is
1033
+ Current_Indentation : Natural := 0 ;
1034
+
1035
+ begin
1036
+ for Parent of Parents loop
1037
+ case Parent.Kind is
1038
+ when Ada_Loop_Stmt_Range
1039
+ | Ada_For_Loop_Stmt_Range
1040
+ | Ada_While_Loop_Stmt_Range
1041
+ | Ada_If_Stmt_Range
1042
+ | Ada_Case_Stmt_Range
1043
+ | Ada_Case_Stmt_Alternative_Range
1044
+ | Ada_Record_Type_Def_Range
1045
+ | Ada_Generic_Formal_Part_Range
1046
+ | Ada_Begin_Block_Range
1047
+ | Ada_Decl_Block_Range
1048
+ =>
1049
+ Current_Indentation := Current_Indentation + Indentation;
1050
+
1051
+ when Ada_Declarative_Part_Range =>
1052
+ -- When we type declare, a DeclBlock is created but not a
1053
+ -- DeclarativePart one. Only when you close the block with
1054
+ -- an end the node is created.
1055
+ -- DeclarativePart is a node that adds indentation.
1056
+ -- We cannot simply make DeclBlock also add indentation
1057
+ -- because it would double indent. So only add indentation
1058
+ -- to DeclarativeParts if their parent is not DeclBlock.
1059
+ if Parent.Parent.Kind not in Ada_Decl_Block_Range then
1060
+ Current_Indentation := Current_Indentation + Indentation;
1061
+ end if ;
1062
+
1063
+ when Ada_Handled_Stmts_Range =>
1064
+ -- HandledStmts can be children of DeclBlock and BeginBlock.
1065
+ -- These two add indentation, so HandledStmts should not
1066
+ -- double add if its their child.
1067
+ if Parent.Parent.Kind not in
1068
+ Ada_Begin_Block_Range
1069
+ | Ada_Decl_Block_Range
1070
+ then
1071
+ Current_Indentation := Current_Indentation + Indentation;
1072
+ end if ;
1073
+
1074
+ when Ada_Subp_Spec_Range | Ada_Assign_Stmt_Range =>
1075
+ Current_Indentation :=
1076
+ Current_Indentation + Indentation_Continuation;
1077
+
1078
+ when Ada_Dotted_Name_Range =>
1079
+ Current_Indentation :=
1080
+ Natural (Parent.Sloc_Range.Start_Column) - 1
1081
+ + Indentation_Continuation;
1082
+ exit ;
1083
+
1084
+ when Ada_Params_Range =>
1085
+ Current_Indentation :=
1086
+ Natural (Parent.Sloc_Range.Start_Column) - 1 + 1 ;
1087
+ exit ;
1088
+
1089
+ when Ada_Assoc_List_Range | Ada_Component_List_Range =>
1090
+ Current_Indentation :=
1091
+ Natural (Parent.Sloc_Range.Start_Column) - 1 ;
1092
+ exit ;
1093
+
1094
+ when others =>
1095
+ null ;
1096
+ end case ;
1097
+ end loop ;
1098
+
1099
+ return Current_Indentation;
1100
+ end Parent_Based_Indentation ;
1101
+
1102
+ -- ------------------------
1103
+ -- Get_Relevant_Parents --
1104
+ -- ------------------------
1105
+
1106
+ function Get_Relevant_Parents
1107
+ (Unit : Libadalang.Analysis.Analysis_Unit;
1108
+ Token : Token_Reference) return Ada_Node_Array
1109
+ is
1110
+ Previous : Token_Reference :=
1111
+ (if Token = No_Token then No_Token
1112
+ else Libadalang.Common.Previous (Token, Exclude_Trivia => True));
1113
+
1114
+ begin
1115
+ if Previous = No_Token then
1116
+ return [];
1117
+ end if ;
1118
+
1119
+ if Kind (Data (Previous)) in Ada_Comma | Ada_Dot then
1120
+ Previous :=
1121
+ Libadalang.Common.Previous (Previous, Exclude_Trivia => True);
1122
+ end if ;
1123
+
1124
+ declare
1125
+ Node : constant Ada_Node :=
1126
+ Unit.Root.Lookup (Start_Sloc (Sloc_Range (Data (Previous))));
1127
+
1128
+ begin
1129
+ if (Node.Kind in Ada_Begin_Block_Range
1130
+ and Kind (Data (Previous)) in Ada_Begin)
1131
+ or (Node.Kind in Ada_Decl_Block_Range
1132
+ and Kind (Data (Previous)) in Ada_Declare)
1133
+ or Kind (Data (Previous)) in Ada_Brack_Open
1134
+ or Node.Kind in Ada_Params_Range
1135
+ then
1136
+ return Node.Parents;
1137
+
1138
+ elsif Node.Kind in Ada_Subp_Body_Range then
1139
+ if Kind (Data (Previous)) in Ada_Is then
1140
+ return Node.As_Subp_Body.F_Decls.Parents;
1141
+
1142
+ elsif Kind (Data (Previous)) in Ada_Begin then
1143
+ return Node.As_Subp_Body.F_Stmts.Parents;
1144
+ end if ;
1145
+
1146
+ elsif Node.Kind in Ada_Package_Body_Range then
1147
+ if Kind (Data (Previous)) in Ada_Is then
1148
+ return Node.As_Package_Body.F_Decls.Parents;
1149
+
1150
+ elsif Kind (Data (Previous)) in Ada_Begin then
1151
+ return Node.As_Package_Body.F_Stmts.Parents;
1152
+ end if ;
1153
+
1154
+ elsif Node.Kind in Ada_Package_Decl_Range then
1155
+ if Kind (Data (Previous)) in Ada_Is then
1156
+ return Node.As_Package_Decl.F_Public_Part.Parents;
1157
+
1158
+ elsif Kind (Data (Previous)) in Ada_Private then
1159
+ return Node.As_Package_Decl.F_Private_Part.Parents;
1160
+ end if ;
1161
+
1162
+ elsif Node.Kind in Ada_Generic_Package_Internal_Range then
1163
+ if Kind (Data (Previous)) in Ada_Is then
1164
+ return
1165
+ Node.As_Generic_Package_Internal.F_Public_Part.Parents;
1166
+
1167
+ elsif Kind (Data (Previous)) in Ada_Private then
1168
+ return
1169
+ Node.As_Generic_Package_Internal.F_Private_Part.Parents;
1170
+ end if ;
1171
+
1172
+ elsif Node.Kind in Ada_Generic_Formal_Part_Range then
1173
+ if Kind (Data (Previous)) in Ada_Generic then
1174
+ return Node.As_Generic_Formal_Part.F_Decls.Parents;
1175
+ end if ;
1176
+ end if ;
1177
+
1178
+ return Node.Parents (With_Self => False);
1179
+ end ;
1180
+ end Get_Relevant_Parents ;
1181
+
1182
+ Unit : constant Analysis_Unit := Self.Unit (Context);
1183
+ Line_Number : constant Langkit_Support.Slocs.Line_Number :=
1184
+ Self.To_Source_Location ((Line, 1 )).Line;
1185
+ Token : constant Token_Reference :=
1186
+ Unit.Lookup_Token (Source_Location'(Line_Number, 1 ));
1187
+
1188
+ Format_Options : constant Gnatformat.Configuration.Format_Options_Type :=
1189
+ Context.Get_Format_Options;
1190
+
1191
+ Indentation : constant Positive :=
1192
+ Gnatformat.Configuration.Get_Indentation
1193
+ (Format_Options, Unit.Get_Filename);
1194
+ Indentation_Continuation : constant Positive :=
1195
+ Gnatformat.Configuration.Get_Indentation_Continuation
1196
+ (Format_Options, Unit.Get_Filename);
1197
+
1198
+ begin
1199
+ return
1200
+ VSS.Strings.Character_Count
1201
+ (Parent_Based_Indentation
1202
+ (Parents => Get_Relevant_Parents (Unit, Token),
1203
+ Indentation => Indentation,
1204
+ Indentation_Continuation => Indentation_Continuation));
1205
+ end Estimate_Indentation ;
1012
1206
1013
1207
-- ---------------
1014
1208
-- Get_Node_At --
0 commit comments