@@ -995,20 +995,213 @@ 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 LSP.Utils.Previous_Non_Trivia (Token));
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 := LSP.Utils.Previous_Non_Trivia (Previous);
1121
+ end if ;
1122
+
1123
+ declare
1124
+ Node : constant Ada_Node :=
1125
+ Unit.Root.Lookup (Start_Sloc (Sloc_Range (Data (Previous))));
1126
+
1127
+ begin
1128
+ if (Node.Kind in Ada_Begin_Block_Range
1129
+ and Kind (Data (Previous)) in Ada_Begin)
1130
+ or (Node.Kind in Ada_Decl_Block_Range
1131
+ and Kind (Data (Previous)) in Ada_Declare)
1132
+ or Kind (Data (Previous)) in Ada_Brack_Open
1133
+ or Node.Kind in Ada_Params_Range
1134
+ then
1135
+ return Node.Parents;
1136
+
1137
+ elsif Node.Kind in Ada_Subp_Body_Range then
1138
+ if Kind (Data (Previous)) in Ada_Is then
1139
+ return Node.As_Subp_Body.F_Decls.Parents;
1140
+
1141
+ elsif Kind (Data (Previous)) in Ada_Begin then
1142
+ return Node.As_Subp_Body.F_Stmts.Parents;
1143
+ end if ;
1144
+
1145
+ elsif Node.Kind in Ada_Package_Body_Range then
1146
+ if Kind (Data (Previous)) in Ada_Is then
1147
+ return Node.As_Package_Body.F_Decls.Parents;
1148
+
1149
+ elsif Kind (Data (Previous)) in Ada_Begin then
1150
+ return Node.As_Package_Body.F_Stmts.Parents;
1151
+ end if ;
1152
+
1153
+ elsif Node.Kind in Ada_Package_Decl_Range then
1154
+ if Kind (Data (Previous)) in Ada_Is then
1155
+ return Node.As_Package_Decl.F_Public_Part.Parents;
1156
+
1157
+ elsif Kind (Data (Previous)) in Ada_Private then
1158
+ return Node.As_Package_Decl.F_Private_Part.Parents;
1159
+ end if ;
1160
+
1161
+ elsif Node.Kind in Ada_Generic_Package_Internal_Range then
1162
+ if Kind (Data (Previous)) in Ada_Is then
1163
+ return
1164
+ Node.As_Generic_Package_Internal.F_Public_Part.Parents;
1165
+
1166
+ elsif Kind (Data (Previous)) in Ada_Private then
1167
+ return
1168
+ Node.As_Generic_Package_Internal.F_Private_Part.Parents;
1169
+ end if ;
1170
+
1171
+ elsif Node.Kind in Ada_Generic_Formal_Part_Range then
1172
+ if Kind (Data (Previous)) in Ada_Generic then
1173
+ return Node.As_Generic_Formal_Part.F_Decls.Parents;
1174
+ end if ;
1175
+ end if ;
1176
+
1177
+ return Node.Parents (With_Self => False);
1178
+ end ;
1179
+ end Get_Relevant_Parents ;
1180
+
1181
+ Unit : constant Analysis_Unit := Self.Unit (Context);
1182
+ Line_Number : constant Langkit_Support.Slocs.Line_Number :=
1183
+ Self.To_Source_Location ((Line, 1 )).Line;
1184
+ Token : constant Token_Reference :=
1185
+ Unit.Lookup_Token (Source_Location'(Line_Number, 1 ));
1186
+
1187
+ Format_Options : constant Gnatformat.Configuration.Format_Options_Type :=
1188
+ Context.Get_Format_Options;
1189
+
1190
+ Indentation : constant Positive :=
1191
+ Gnatformat.Configuration.Get_Indentation
1192
+ (Format_Options, Unit.Get_Filename);
1193
+ Indentation_Continuation : constant Positive :=
1194
+ Gnatformat.Configuration.Get_Indentation_Continuation
1195
+ (Format_Options, Unit.Get_Filename);
1196
+
1197
+ begin
1198
+ return
1199
+ VSS.Strings.Character_Count
1200
+ (Parent_Based_Indentation
1201
+ (Parents => Get_Relevant_Parents (Unit, Token),
1202
+ Indentation => Indentation,
1203
+ Indentation_Continuation => Indentation_Continuation));
1204
+ end Estimate_Indentation ;
1012
1205
1013
1206
-- ---------------
1014
1207
-- Get_Node_At --
0 commit comments