1 module dls.protocol.messages.general;
2 
3 import dls.protocol.interfaces.general;
4 import dls.server : Server;
5 import dls.util.logger : logger;
6 import std.json : JSONValue;
7 import std.typecons : nullable;
8 
9 @("")
10 InitializeResult initialize(InitializeParams params)
11 {
12     import dls.tools.tools : Tools;
13     import dls.util.uri : Uri;
14     import std.algorithm : map, sort, uniq;
15     import std.array : array;
16 
17     logger.info("Initializing server");
18     Server.initialized = true;
19     Server.initState = params;
20 
21     debug
22     {
23     }
24     else
25     {
26         import dls.updater : cleanup;
27 
28         cleanup();
29     }
30 
31     Tools.initialize();
32     Uri[] uris;
33 
34     if (!params.rootUri.isNull)
35     {
36         uris ~= new Uri(params.rootUri);
37     }
38     else if (!params.rootPath.isNull)
39     {
40         uris ~= Uri.fromPath(params.rootPath);
41     }
42 
43     if (!params.workspaceFolders.isNull)
44     {
45         uris ~= params.workspaceFolders.map!(wf => new Uri(wf.uri)).array;
46     }
47 
48     foreach (uri; uris.sort!q{a.path < b.path}
49             .uniq!q{a.path == b.path})
50     {
51         Tools.symbolTool.importPath(uri);
52         Tools.symbolTool.importSelections(uri);
53         Tools.analysisTool.addAnalysisConfigPath(uri);
54     }
55 
56     auto result = new InitializeResult();
57 
58     with (result.capabilities)
59     {
60         textDocumentSync = new TextDocumentSyncOptions(true.nullable,
61                 TextDocumentSyncKind.incremental.nullable);
62         textDocumentSync.save = new SaveOptions(false.nullable);
63         completionProvider = new CompletionOptions(true.nullable, ["."].nullable);
64         hoverProvider = true;
65         documentFormattingProvider = true;
66         definitionProvider = true;
67         documentHighlightProvider = true;
68         documentSymbolProvider = true;
69         workspaceSymbolProvider = true;
70         workspace = new ServerCapabilities.Workspace(new ServerCapabilities.Workspace.WorkspaceFolders(true.nullable,
71                 JSONValue(true).nullable).nullable);
72     }
73 
74     return result;
75 }
76 
77 @("")
78 void initialized(JSONValue nothing)
79 {
80     import dls.protocol.jsonrpc : send;
81     import dls.protocol.interfaces : DidChangeWatchedFilesRegistrationOptions,
82         FileSystemWatcher, Registration, RegistrationParams;
83 
84     debug
85     {
86     }
87     else
88     {
89         import dls.updater : update;
90         import std.concurrency : spawn;
91 
92         spawn(&update);
93     }
94 
95     const didChangeWatchedFiles = Server.initState.capabilities.workspace.didChangeWatchedFiles;
96 
97     if (!didChangeWatchedFiles.isNull && didChangeWatchedFiles.dynamicRegistration)
98     {
99         logger.info("Registering watchers");
100         auto watchers = [
101             new FileSystemWatcher("**/dub.selections.json"),
102             new FileSystemWatcher("**/dub.{json,sdl}"), new FileSystemWatcher("**/*.ini")
103         ];
104         auto registrationOptions = new DidChangeWatchedFilesRegistrationOptions(watchers);
105         auto registration = new Registration!DidChangeWatchedFilesRegistrationOptions(
106                 "dls-registration-watch-dub-files",
107                 "workspace/didChangeWatchedFiles", registrationOptions.nullable);
108         send("client/registerCapability",
109                 new RegistrationParams!DidChangeWatchedFilesRegistrationOptions([registration]));
110     }
111 }
112 
113 @("")
114 JSONValue shutdown(JSONValue nothing)
115 {
116     logger.info("Shutting down server");
117     Server.shutdown = true;
118     return JSONValue(null);
119 }
120 
121 @("")
122 void exit(JSONValue nothing)
123 {
124     logger.info("Exiting server");
125     Server.exit = true;
126 }
127 
128 @("$")
129 void cancelRequest(JSONValue id)
130 {
131 }