Skip to content

Commit 8c849b9

Browse files
Add --config option to specify a server configuration
This allows to setup the server with the wanted configuration at startup, without having to speicify them via the 'initialize' or the 'didChangeConfiguration' requests Closes #1108
1 parent b94307b commit 8c849b9

File tree

4 files changed

+108
-50
lines changed

4 files changed

+108
-50
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ The `ada_language_server` doesn't require any command line options,
9191
but it understands these options:
9292

9393
* `--tracefile=<FILE>` - Full path to a file containing traces configuration
94+
* `--config=<FILE>` - Full path to a JSON file containing the server's configuration
9495
* `--help` - Display supported command like options and exit.
9596

9697
You can turn some debugging and experimental features trought
@@ -99,7 +100,9 @@ You can turn some debugging and experimental features trought
99100
The server also gets configuration via `workspace/didChangeConfiguration`
100101
notification and `initializationOptions` of `initialize` request.
101102
See more [details here](doc/settings.md). Each LSP
102-
client provides its-own way to set such settings.
103+
client provides its-own way to set such settings. You can use the `--config`
104+
option if you want to provide the configuration directly via a JSON file
105+
instead of specifying it via the requests listed just above.
103106

104107
## Supported LSP Server Requests
105108

source/ada/lsp-ada_driver.adb

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
with Ada.Characters.Latin_1;
2121
with Ada.Text_IO;
2222
with Ada.Exceptions; use Ada.Exceptions;
23+
with Ada.Strings.Unbounded;
2324
with GNAT.Command_Line; use GNAT.Command_Line;
2425
with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic;
2526
with GNAT.OS_Lib;
@@ -33,9 +34,11 @@ with VSS.Application;
3334
with VSS.Standard_Paths;
3435
with VSS.Strings.Conversions;
3536

37+
with GNATCOLL.JSON;
3638
with GNATCOLL.Memory; use GNATCOLL.Memory;
3739
with GNATCOLL.Traces; use GNATCOLL.Traces;
3840
with GNATCOLL.VFS; use GNATCOLL.VFS;
41+
with GNATCOLL.Utils;
3942

4043
with LSP.Ada_Handlers;
4144
with LSP.Ada_Handlers.Named_Parameters_Commands;
@@ -195,7 +198,9 @@ procedure LSP.Ada_Driver is
195198
GNATdebug : constant Virtual_File := Create_From_Base
196199
(".gnatdebug");
197200

198-
Tracefile_Name : aliased String_Access;
201+
Traces_File_Path : aliased String_Access;
202+
Config_File_Path : aliased String_Access;
203+
Traces_File : Virtual_File;
199204
Config_File : Virtual_File;
200205
Help_Arg : aliased Boolean := False;
201206
Version_Arg : aliased Boolean := False;
@@ -210,10 +215,18 @@ begin
210215

211216
Define_Switch
212217
(Cmdline,
213-
Output => Tracefile_Name'Access,
218+
Output => Traces_File_Path'Access,
214219
Long_Switch => "--tracefile=",
215220
Help => "Full path to a file containing traces configuration");
216221

222+
Define_Switch
223+
(Cmdline,
224+
Output => Config_File_Path'Access,
225+
Long_Switch => "--config=",
226+
Help => "Full path to a JSON file containing initialization "
227+
& "options for the server (i.e: all the settings that can be specified "
228+
& "through LSP 'initialize' request's initializattionOptions)");
229+
217230
Define_Switch
218231
(Cmdline,
219232
Output => Language_GPR_Arg'Access,
@@ -251,15 +264,15 @@ begin
251264
-- - passed on the command line via --tracefile,
252265
-- - in a .gnatdebug file locally
253266
-- - in "traces.cfg" in the ALS home directory
254-
if Tracefile_Name /= null
255-
and then Tracefile_Name.all /= ""
267+
if Traces_File_Path /= null
268+
and then Traces_File_Path.all /= ""
256269
then
257-
Config_File := Create (+Tracefile_Name.all);
258-
if not Config_File.Is_Regular_File then
270+
Traces_File := Create (+Traces_File_Path.all);
271+
if not Traces_File.Is_Regular_File then
259272
Ada.Text_IO.Put_Line ("Could not find the specified traces file");
260273
GNAT.OS_Lib.OS_Exit (1);
261274
end if;
262-
Parse_Config_File (Config_File);
275+
Parse_Config_File (Traces_File);
263276

264277
elsif GNATdebug.Is_Regular_File then
265278
Parse_Config_File (GNATdebug);
@@ -276,8 +289,46 @@ begin
276289
".$T.$$.log:buffer_size=0");
277290
end if;
278291

279-
if Tracefile_Name /= null then
280-
Free (Tracefile_Name);
292+
if Traces_File_Path /= null then
293+
Free (Traces_File_Path);
294+
end if;
295+
296+
-- Look for a config file, that contains the configuration for the server
297+
-- (i.e: the configuration that can be specified through the 'initialize'
298+
-- request initializationOptions).
299+
300+
if Config_File_Path /= null
301+
and then Config_File_Path.all /= ""
302+
then
303+
Config_File := Create (+Config_File_Path.all);
304+
305+
if not Config_File.Is_Regular_File then
306+
Ada.Text_IO.Put_Line ("Could not find the specified config file");
307+
GNAT.OS_Lib.OS_Exit (1);
308+
end if;
309+
310+
declare
311+
JSON_Contents : GNAT.Strings.String_Access := Config_File.Read_File;
312+
Parse_Result : GNATCOLL.JSON.Read_Result;
313+
begin
314+
Parse_Result := GNATCOLL.JSON.Read (JSON_Contents.all);
315+
GNAT.Strings.Free (JSON_Contents);
316+
317+
if not Parse_Result.Success then
318+
Ada.Text_IO.Put_Line
319+
("Error when parsing config file at "
320+
& GNATCOLL.Utils.Image (Parse_Result.Error.Line, 1)
321+
& ":"
322+
& GNATCOLL.Utils.Image (Parse_Result.Error.Column, 1));
323+
Ada.Text_IO.Put_Line
324+
(Ada.Strings.Unbounded.To_String (Parse_Result.Error.Message));
325+
GNAT.OS_Lib.OS_Exit (1);
326+
end if;
327+
328+
Ada_Handler.Change_Configuration (Parse_Result.Value);
329+
end;
330+
331+
Free (Config_File_Path);
281332
end if;
282333

283334
Server_Trace.Trace ("ALS version: " & $VERSION);

source/ada/lsp-ada_handlers.adb

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ with Ada.Unchecked_Deallocation;
2828

2929
with GNAT.OS_Lib; use GNAT.OS_Lib;
3030
with GNAT.Strings;
31-
with GNATCOLL.JSON;
3231
with GNATCOLL.Utils; use GNATCOLL.Utils;
3332

3433
with VSS.Characters.Latin;
@@ -319,11 +318,6 @@ package body LSP.Ada_Handlers is
319318
-- Attempt to load the given project file, with the scenario provided.
320319
-- This unloads all currently loaded project contexts.
321320

322-
procedure Change_Configuration
323-
(Self : access Message_Handler;
324-
Ada : LSP.Types.LSP_Any);
325-
-- Change server configuration with settings from Ada JSON object.
326-
327321
procedure Mark_Source_Files_For_Indexing (Self : access Message_Handler);
328322
-- Mark all sources in all projects for indexing. This factorizes code
329323
-- between Load_Project and Load_Implicit_Project.
@@ -4234,8 +4228,8 @@ package body LSP.Ada_Handlers is
42344228
--------------------------
42354229

42364230
procedure Change_Configuration
4237-
(Self : access Message_Handler;
4238-
Ada : LSP.Types.LSP_Any)
4231+
(Self : access Message_Handler;
4232+
Options : GNATCOLL.JSON.JSON_Value'Class)
42394233
is
42404234
use type GNATCOLL.JSON.JSON_Value_Type;
42414235

@@ -4275,9 +4269,9 @@ package body LSP.Ada_Handlers is
42754269
Variables : Scenario_Variable_List;
42764270

42774271
function Property (Name : String) return VSS.Strings.Virtual_String is
4278-
(if Ada.Has_Field (Name)
4272+
(if Options.Has_Field (Name)
42794273
then VSS.Strings.Conversions.To_Virtual_String
4280-
(String'(Get (Get (Ada, Name))))
4274+
(String'(Options.Get (Name)))
42814275
else VSS.Strings.Empty_Virtual_String);
42824276

42834277
------------------
@@ -4309,7 +4303,7 @@ package body LSP.Ada_Handlers is
43094303
Value.dynamicRegistration.Is_Set = True;
43104304

43114305
begin
4312-
if Ada.Kind = GNATCOLL.JSON.JSON_Object_Type then
4306+
if Options.Kind = GNATCOLL.JSON.JSON_Object_Type then
43134307
Relocate := Property (relocateBuildTree);
43144308
Root := Property (rootDir);
43154309
Charset := Property (defaultCharset);
@@ -4320,76 +4314,80 @@ package body LSP.Ada_Handlers is
43204314
File := Self.URI_To_File (File);
43214315
end if;
43224316

4323-
if Ada.Has_Field (scenarioVariables) and then
4324-
Ada.Get (scenarioVariables).Kind = GNATCOLL.JSON.JSON_Object_Type
4317+
if Options.Has_Field (scenarioVariables) and then
4318+
Options.Get
4319+
(scenarioVariables).Kind = GNATCOLL.JSON.JSON_Object_Type
43254320
then
4326-
Ada.Get (scenarioVariables).Map_JSON_Object (Add_Variable'Access);
4321+
Options.Get
4322+
(scenarioVariables).Map_JSON_Object (Add_Variable'Access);
43274323
end if;
43284324

43294325
-- It looks like the protocol does not allow clients to say whether
43304326
-- or not they want diagnostics as part of
43314327
-- InitializeParams.capabilities.textDocument. So we support
43324328
-- deactivating of diagnostics via a setting here.
4333-
if Ada.Has_Field (enableDiagnostics) then
4334-
Self.Diagnostics_Enabled := Ada.Get (enableDiagnostics);
4329+
if Options.Has_Field (enableDiagnostics) then
4330+
Self.Diagnostics_Enabled := Options.Get (enableDiagnostics);
43354331
end if;
43364332

43374333
-- Similarly to diagnostics, we support selectively activating
43384334
-- indexing in the parameters to this request.
4339-
if Ada.Has_Field (enableIndexing) then
4340-
Self.Indexing_Enabled := Ada.Get (enableIndexing);
4335+
if Options.Has_Field (enableIndexing) then
4336+
Self.Indexing_Enabled := Options.Get (enableIndexing);
43414337
end if;
43424338

43434339
-- Retrieve the different textDocument/rename options if specified
43444340

4345-
if Ada.Has_Field (renameInComments) then
4341+
if Options.Has_Field (renameInComments) then
43464342
Self.Options.Refactoring.Renaming.In_Comments :=
4347-
Ada.Get (renameInComments);
4343+
Options.Get (renameInComments);
43484344
end if;
43494345

4350-
if Ada.Has_Field (foldComments) then
4351-
Self.Options.Folding.Comments := Ada.Get (foldComments);
4346+
if Options.Has_Field (foldComments) then
4347+
Self.Options.Folding.Comments := Options.Get (foldComments);
43524348
end if;
43534349

43544350
-- Retrieve the number of parameters / components at which point
43554351
-- named notation is used for subprogram/aggregate completion
43564352
-- snippets.
43574353

4358-
if Ada.Has_Field (namedNotationThreshold) then
4359-
Self.Named_Notation_Threshold := Ada.Get (namedNotationThreshold);
4354+
if Options.Has_Field (namedNotationThreshold) then
4355+
Self.Named_Notation_Threshold :=
4356+
Options.Get (namedNotationThreshold);
43604357
end if;
43614358

4362-
if Ada.Has_Field (logThreshold) then
4363-
Self.Log_Threshold := Ada.Get (logThreshold);
4359+
if Options.Has_Field (logThreshold) then
4360+
Self.Log_Threshold := Options.Get (logThreshold);
43644361
end if;
43654362

43664363
-- Check the 'useCompletionSnippets' flag to see if we should use
43674364
-- snippets in completion (if the client supports it).
43684365
if not Self.Completion_Snippets_Enabled then
43694366
Self.Use_Completion_Snippets := False;
4370-
elsif Ada.Has_Field (useCompletionSnippets) then
4371-
Self.Use_Completion_Snippets := Ada.Get (useCompletionSnippets);
4367+
elsif Options.Has_Field (useCompletionSnippets) then
4368+
Self.Use_Completion_Snippets :=
4369+
Options.Get (useCompletionSnippets);
43724370
end if;
43734371

43744372
-- Retrieve the policy for displaying type hierarchy on navigation
43754373
-- requests.
4376-
if Ada.Has_Field (displayMethodAncestryOnNavigation) then
4374+
if Options.Has_Field (displayMethodAncestryOnNavigation) then
43774375
Self.Display_Method_Ancestry_Policy :=
43784376
LSP.Messages.AlsDisplayMethodAncestryOnNavigationPolicy'Value
4379-
(Ada.Get (displayMethodAncestryOnNavigation));
4377+
(Options.Get (displayMethodAncestryOnNavigation));
43804378
end if;
43814379

43824380
-- Retrieve the follow symlinks policy.
43834381

4384-
if Ada.Has_Field (followSymlinks) then
4385-
Self.Follow_Symlinks := Ada.Get (followSymlinks);
4382+
if Options.Has_Field (followSymlinks) then
4383+
Self.Follow_Symlinks := Options.Get (followSymlinks);
43864384
end if;
43874385

4388-
if Ada.Has_Field (documentationStyle) then
4386+
if Options.Has_Field (documentationStyle) then
43894387
begin
43904388
Self.Options.Documentation.Style :=
43914389
GNATdoc.Comments.Options.Documentation_Style'Value
4392-
(Ada.Get (documentationStyle));
4390+
(Options.Get (documentationStyle));
43934391

43944392
exception
43954393
when Constraint_Error =>
@@ -4401,12 +4399,12 @@ package body LSP.Ada_Handlers is
44014399

44024400
if not File.Is_Empty then
44034401
Self.Load_Project
4404-
(File,
4405-
Variables,
4406-
Charset,
4407-
Valid_Project_Configured,
4408-
Relocate,
4409-
Root);
4402+
(Project_File => File,
4403+
Scenario => Variables,
4404+
Charset => Charset,
4405+
Status => Valid_Project_Configured,
4406+
Relocate_Build_Tree => Relocate,
4407+
Root_Dir => Root);
44104408
end if;
44114409

44124410
Self.Ensure_Project_Loaded;

source/ada/lsp-ada_handlers.ads

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
with Ada.Containers.Hashed_Maps;
2222
with Ada.Containers.Hashed_Sets;
2323

24+
with GNATCOLL.JSON;
2425
with GNATCOLL.VFS; use GNATCOLL.VFS;
2526
with GNATCOLL.Projects;
2627
with GNATCOLL.Traces;
@@ -63,6 +64,11 @@ package LSP.Ada_Handlers is
6364
-- This procedure will be called when an unexpected error is raised in the
6465
-- request processing loop.
6566

67+
procedure Change_Configuration
68+
(Self : access Message_Handler;
69+
Options : GNATCOLL.JSON.JSON_Value'Class);
70+
-- Change server configuration with settings from Ada JSON object.
71+
6672
procedure Stop_File_Monitoring (Self : access Message_Handler);
6773

6874
procedure Cleanup (Self : access Message_Handler);

0 commit comments

Comments
 (0)