Skip to content

Commit 3ef7ee2

Browse files
Use fallback indenter for textDocument/formatting request
To format entire GPR files. For eng/ide/ada_language_server#1529
1 parent f44bcd9 commit 3ef7ee2

File tree

11 files changed

+255
-47
lines changed

11 files changed

+255
-47
lines changed

source/ada/lsp-ada_handlers-formatting.adb

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,36 +202,56 @@ package body LSP.Ada_Handlers.Formatting is
202202
(Tracer : not null LSP.Tracers.Tracer_Access;
203203
Filename : GNATCOLL.VFS.Virtual_File;
204204
Document : LSP.Text_Documents.Text_Document'Class;
205-
Span : LSP.Structures.A_Range;
206205
Options : Gnatformat.Configuration.Format_Options_Type;
206+
Span : LSP.Structures.A_Range := LSP.Text_Documents.Empty_Range;
207207
Success : out Boolean;
208208
Response : out LSP.Structures.TextEdit_Vector;
209209
Messages : out VSS.String_Vectors.Virtual_String_Vector;
210210
Error : out LSP.Errors.ResponseError)
211211
is
212212
pragma Unreferenced (Messages);
213+
use LSP.Structures;
214+
use LSP.Text_Documents;
213215
use VSS.Strings;
214216

217+
Actual_Span : constant A_Range :=
218+
(if Span = Empty_Range
219+
then ((0, 0), (Integer'Max (Document.Line_Count - 1, 0), 0))
220+
else Span);
221+
-- If no span is provided, indent the whole document.
222+
223+
Buffer : constant VSS.Strings.Virtual_String :=
224+
(if Span = Empty_Range
225+
then Document.Text
226+
else Document.Slice (((0, 0), Actual_Span.an_end)));
227+
-- Get the relevant buffer to indent.
228+
-- If no span is provided, get the whole document buffer.
229+
-- Otherwise get the buffer from the start of the document
230+
-- to the end of the given span.
231+
215232
Indent_Lines :
216233
constant LSP.Formatters.Fallback_Indenter.Indentation_Array :=
217234
Get_Indentation
218235
(Filename => Filename,
219-
Buffer => Document.Slice (((0, 0), Span.an_end)),
220-
Span => Span,
236+
Buffer => Buffer,
237+
Span => Actual_Span,
221238
Options => Options);
222-
Pos : LSP.Structures.Position;
223-
Line_Span : LSP.Structures.A_Range;
239+
-- Get the indentation levels for each line in the span.
240+
241+
Pos : LSP.Structures.Position;
224242
begin
225-
Tracer.Trace_Text
226-
(Incorrect_Code_Msg & ", using the fallback indenter");
243+
Tracer.Trace_Text (Incorrect_Code_Msg & ", using the fallback indenter");
227244
for Line in Indent_Lines'Range loop
228245
if Indent_Lines (Line) /= -1 then
246+
-- LSP is 0-based, while the array returned by the fallback
247+
-- indenter is 1-based.
229248
Pos := (Line - 1, 0);
230-
Line_Span := (Pos, (Pos.line + 1, 0));
249+
250+
-- Generate a text edit to reindent the line.
231251
Response.Append
232252
(Reindent_Line
233253
(Filename => Filename,
234-
Line => Document.Slice (Line_Span),
254+
Line => Document.Get_Line (Pos.line),
235255
Options => Options,
236256
Pos => Pos,
237257
New_Indent => Indent_Lines (Line)));

source/ada/lsp-ada_handlers-formatting.ads

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ package LSP.Ada_Handlers.Formatting is
5959
return LSP.Formatters.Fallback_Indenter.Indentation_Array;
6060
-- Use the fallback indenter to get an array of indentation for each
6161
-- line in Span.
62+
-- Each line in the array is 1-based indexed (i.e., the first line is at
63+
-- index 1).
6264
-- Buffer is the content of the document referenced by Filename. Should
6365
-- contain the whole content of the document or a substring including
6466
-- at least the lines in Span.
@@ -67,14 +69,15 @@ package LSP.Ada_Handlers.Formatting is
6769
(Tracer : not null LSP.Tracers.Tracer_Access;
6870
Filename : GNATCOLL.VFS.Virtual_File;
6971
Document : LSP.Text_Documents.Text_Document'Class;
70-
Span : LSP.Structures.A_Range;
7172
Options : Gnatformat.Configuration.Format_Options_Type;
73+
Span : LSP.Structures.A_Range := LSP.Text_Documents.Empty_Range;
7274
Success : out Boolean;
7375
Response : out LSP.Structures.TextEdit_Vector;
7476
Messages : out VSS.String_Vectors.Virtual_String_Vector;
7577
Error : out LSP.Errors.ResponseError);
7678
-- Generate a TextEdit_Vector to reindent the lines in Span using the
7779
-- fallback indenter.
80+
-- If no Span is provided, the whole document is indented.
7881
-- Document is the document to indent.
7982
-- Tracer is used to log messages.
8083
-- Filename is the name of the file referenced by Document. Used to

source/gpr/lsp-gpr_handlers.adb

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ package body LSP.GPR_Handlers is
444444
others => <>));
445445
Capabilities.documentRangeFormattingProvider :=
446446
(Is_Set => True, Value => (Is_Boolean => True, Boolean => True));
447+
Capabilities.documentFormattingProvider :=
448+
(Is_Set => True, Value => (Is_Boolean => True, Boolean => True));
447449

448450
Capabilities.textDocumentSync :=
449451
(Is_Set => True,
@@ -508,6 +510,48 @@ package body LSP.GPR_Handlers is
508510
Self.Sender.On_Initialize_Response (Id, Response);
509511
end On_Initialize_Request;
510512

513+
---------------------------
514+
-- On_Formatting_Request --
515+
---------------------------
516+
517+
overriding
518+
procedure On_Formatting_Request
519+
(Self : in out Message_Handler;
520+
Id : LSP.Structures.Integer_Or_Virtual_String;
521+
Value : LSP.Structures.DocumentFormattingParams)
522+
is
523+
Document : constant LSP.GPR_Documents.Document_Access :=
524+
Self.Get_Open_Document (Value.textDocument.uri);
525+
Response : LSP.Structures.TextEdit_Vector_Or_Null;
526+
Error : LSP.Errors.ResponseError;
527+
Success : Boolean := True;
528+
Messages : VSS.String_Vectors.Virtual_String_Vector;
529+
Options : constant Gnatformat.Configuration.Format_Options_Type :=
530+
Gnatformat.Configuration.Default_Format_Options;
531+
begin
532+
LSP.Ada_Handlers.Formatting.Indent_Lines
533+
(Tracer => Self.Tracer,
534+
Filename => Self.To_File (Value.textDocument.uri),
535+
Document => Document.all,
536+
Options => Options,
537+
Success => Success,
538+
Response => Response,
539+
Messages => Messages,
540+
Error => Error);
541+
542+
if Success then
543+
Self.Sender.On_Formatting_Response (Id, Response);
544+
545+
for Message of Messages loop
546+
Self.Sender.On_ShowMessage_Notification
547+
((LSP.Enumerations.Info, Message));
548+
end loop;
549+
550+
else
551+
Self.Sender.On_Error_Response (Id, Error);
552+
end if;
553+
end On_Formatting_Request;
554+
511555
--------------------------------
512556
-- On_RangeFormatting_Request --
513557
--------------------------------
@@ -527,7 +571,6 @@ package body LSP.GPR_Handlers is
527571
Options : constant Gnatformat.Configuration.Format_Options_Type :=
528572
Gnatformat.Configuration.Default_Format_Options;
529573
begin
530-
-- TODO: check if we can get indentation options from GNATformat
531574
LSP.Ada_Handlers.Formatting.Indent_Lines
532575
(Tracer => Self.Tracer,
533576
Filename => Self.To_File (Value.textDocument.uri),

source/gpr/lsp-gpr_handlers.ads

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,18 @@ private
158158
(Self : in out Message_Handler;
159159
Value : LSP.Structures.DidSaveTextDocumentParams);
160160

161-
overriding procedure On_Hover_Request
161+
overriding
162+
procedure On_Hover_Request
162163
(Self : in out Message_Handler;
163164
Id : LSP.Structures.Integer_Or_Virtual_String;
164165
Value : LSP.Structures.HoverParams);
165166

167+
overriding
168+
procedure On_Formatting_Request
169+
(Self : in out Message_Handler;
170+
Id : LSP.Structures.Integer_Or_Virtual_String;
171+
Value : LSP.Structures.DocumentFormattingParams);
172+
166173
overriding
167174
procedure On_RangeFormatting_Request
168175
(Self : in out Message_Handler;

source/server/lsp-text_documents-langkit_documents.adb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ package body LSP.Text_Documents.Langkit_Documents is
5959
Line : constant Natural := To_LSP_Line (Index);
6060

6161
begin
62-
if Self.Line_Marker.Last_Index = Line then
62+
if Self.Line_Markers.Last_Index = Line then
6363
return
6464
Self.Text.Slice
65-
(Self.Line_Marker (Line), Self.Text.After_Last_Character);
65+
(Self.Line_Markers (Line), Self.Text.After_Last_Character);
6666

6767
else
6868
return
6969
Self.Text.Slice
70-
(Self.Line_Marker (Line), Self.Line_Marker (Line + 1));
70+
(Self.Line_Markers (Line), Self.Line_Markers (Line + 1));
7171
end if;
7272
end Line;
7373

@@ -187,7 +187,7 @@ package body LSP.Text_Documents.Langkit_Documents is
187187
return Langkit_Support.Slocs.Source_Location
188188
is
189189
Iterator : VSS.Strings.Character_Iterators.Character_Iterator :=
190-
Self.Text.At_Character (Self.Line_Marker (Position.line));
190+
Self.Text.At_Character (Self.Line_Markers (Position.line));
191191
begin
192192
return ((Line => To_Source_Line (Position.line),
193193
Column => To_Source_Column (Iterator, Position.character)));

0 commit comments

Comments
 (0)