11#include " CodeFormatServer/LanguageClient.h"
22#include < iterator>
3+ #include < fstream>
34#include " CodeService/LuaEditorConfig.h"
45#include " CodeService/LuaFormatter.h"
56#include " LuaParser/LuaParser.h"
@@ -22,7 +23,8 @@ LanguageClient& LanguageClient::GetInstance()
2223LanguageClient::LanguageClient ()
2324 : _defaultOptions(std::make_shared<LuaCodeStyleOptions>()),
2425 _idCounter(0 ),
25- _ioc(1 )
26+ _ioc(1 ),
27+ _configVersion(0 )
2628{
2729}
2830
@@ -60,7 +62,14 @@ void LanguageClient::SendNotification(std::string_view method, std::shared_ptr<v
6062 auto json = nlohmann::json::object ();
6163 json[" jsonrpc" ] = " 2.0" ;
6264 json[" method" ] = method;
63- json[" params" ] = param->Serialize ();
65+ if (param != nullptr )
66+ {
67+ json[" params" ] = param->Serialize ();
68+ }
69+ else
70+ {
71+ json[" params" ] = nullptr ;
72+ }
6473
6574 if (_session)
6675 {
@@ -130,75 +139,135 @@ void LanguageClient::ClearFile(std::string_view uri)
130139 }
131140}
132141
133- void LanguageClient::DiagnosticFile (std::string_view uri)
142+ void LanguageClient::DiagnosticFile (std::string_view uri, std::string_view prevId,
143+ std::shared_ptr<vscode::DocumentDiagnosticReport> report)
134144{
145+ report->kind = vscode::DocumentDiagnosticReportKind::Unchanged;
135146 auto filename = url::UrlToFilePath (uri);
136147 auto it = _fileMap.find (filename);
137148 if (it == _fileMap.end ())
138149 {
139150 return ;
140151 }
152+ auto & virtualFile = it->second ;
141153
142- auto vscodeDiagnosis = std::make_shared<vscode::PublishDiagnosticsParams>();
143- vscodeDiagnosis->uri = uri;
154+ auto resultId = std::to_string (_configVersion) + " |" + std::to_string (virtualFile->GetVersion ());
155+ report->resultId = resultId;
156+ if (resultId == prevId)
157+ {
158+ return ;
159+ }
144160
145161 auto options = GetOptions (uri);
146162 if (!options->enable_check_codestyle )
147163 {
148- SendNotification ( " textDocument/publishDiagnostics " , vscodeDiagnosis) ;
164+ report-> kind = vscode::DocumentDiagnosticReportKind::Full ;
149165 return ;
150166 }
151167
152168 std::shared_ptr<LuaParser> parser = it->second ->GetLuaParser ();
153169
154170 if (parser->HasError ())
155171 {
172+ report->kind = vscode::DocumentDiagnosticReportKind::Unchanged;
156173 return ;
157174 }
158175
176+ report->kind = vscode::DocumentDiagnosticReportKind::Full;
177+
159178 // TODO move spell check to SpellService
160179 auto formatDiagnostic = GetService<CodeFormatService>()->Diagnose (filename, parser, options);
161- std::copy (formatDiagnostic.begin (), formatDiagnostic.end (), std::back_inserter (vscodeDiagnosis-> diagnostics ));
180+ std::copy (formatDiagnostic.begin (), formatDiagnostic.end (), std::back_inserter (report-> items ));
162181
163182 if (_vscodeSettings.lintModule )
164183 {
165184 auto moduleDiagnosis = GetService<ModuleService>()->Diagnose (filename, parser);
166- std::copy (moduleDiagnosis.begin (), moduleDiagnosis.end (), std::back_inserter (vscodeDiagnosis-> diagnostics ));
185+ std::copy (moduleDiagnosis.begin (), moduleDiagnosis.end (), std::back_inserter (report-> items ));
167186 }
168-
169- SendNotification (" textDocument/publishDiagnostics" , vscodeDiagnosis);
170187}
171188
172- void LanguageClient::DelayDiagnosticFile (std::string_view uri)
189+ std::optional< uint64_t > LanguageClient::GetFileVersion (std::string_view uri)
173190{
174- auto stringUri = std::string (uri);
175- auto task = std::make_shared<asio::steady_timer>(GetIOContext (), std::chrono::milliseconds (300 ));
176- auto it = _fileDiagnosticTask.find (uri);
177- if (it != _fileDiagnosticTask.end ())
178- {
179- it->second ->cancel ();
180- it->second = task;
181- }
182- else
191+ auto filename = url::UrlToFilePath (uri);
192+ auto it = _fileMap.find (filename);
193+ if (it == _fileMap.end ())
183194 {
184- _fileDiagnosticTask. insert ({stringUri, task}) ;
195+ return {} ;
185196 }
186-
187- task->async_wait ([this , stringUri](const asio::error_code& code)
188- {
189- if (code == asio::error::operation_aborted)
190- {
191- return ;
192- }
193- DiagnosticFile (stringUri);
194- auto it = _fileDiagnosticTask.find (stringUri);
195- if (it != _fileDiagnosticTask.end ())
196- {
197- _fileDiagnosticTask.erase (it);
198- }
199- });
197+ auto & virtualFile = it->second ;
198+ return virtualFile->GetVersion ();
200199}
201200
201+ //
202+ // void LanguageClient::DiagnosticFile(std::string_view uri)
203+ // {
204+ // auto filename = url::UrlToFilePath(uri);
205+ // auto it = _fileMap.find(filename);
206+ // if (it == _fileMap.end())
207+ // {
208+ // return;
209+ // }
210+ //
211+ // auto vscodeDiagnosis = std::make_shared<vscode::PublishDiagnosticsParams>();
212+ // vscodeDiagnosis->uri = uri;
213+ //
214+ // auto options = GetOptions(uri);
215+ // if (!options->enable_check_codestyle)
216+ // {
217+ // SendNotification("textDocument/publishDiagnostics", vscodeDiagnosis);
218+ // return;
219+ // }
220+ //
221+ // std::shared_ptr<LuaParser> parser = it->second->GetLuaParser();
222+ //
223+ // if (parser->HasError())
224+ // {
225+ // return;
226+ // }
227+ //
228+ // // TODO move spell check to SpellService
229+ // auto formatDiagnostic = GetService<CodeFormatService>()->Diagnose(filename, parser, options);
230+ // std::copy(formatDiagnostic.begin(), formatDiagnostic.end(), std::back_inserter(vscodeDiagnosis->diagnostics));
231+ //
232+ // if (_vscodeSettings.lintModule)
233+ // {
234+ // auto moduleDiagnosis = GetService<ModuleService>()->Diagnose(filename, parser);
235+ // std::copy(moduleDiagnosis.begin(), moduleDiagnosis.end(), std::back_inserter(vscodeDiagnosis->diagnostics));
236+ // }
237+ //
238+ // SendNotification("textDocument/publishDiagnostics", vscodeDiagnosis);
239+ // }
240+
241+ // void LanguageClient::DelayDiagnosticFile(std::string_view uri)
242+ // {
243+ // auto stringUri = std::string(uri);
244+ // auto task = std::make_shared<asio::steady_timer>(GetIOContext(), std::chrono::milliseconds(300));
245+ // auto it = _fileDiagnosticTask.find(uri);
246+ // if (it != _fileDiagnosticTask.end())
247+ // {
248+ // it->second->cancel();
249+ // it->second = task;
250+ // }
251+ // else
252+ // {
253+ // _fileDiagnosticTask.insert({stringUri, task});
254+ // }
255+ //
256+ // task->async_wait([this, stringUri](const asio::error_code& code)
257+ // {
258+ // if (code == asio::error::operation_aborted)
259+ // {
260+ // return;
261+ // }
262+ // DiagnosticFile(stringUri);
263+ // auto it = _fileDiagnosticTask.find(stringUri);
264+ // if (it != _fileDiagnosticTask.end())
265+ // {
266+ // _fileDiagnosticTask.erase(it);
267+ // }
268+ // });
269+ // }
270+
202271std::shared_ptr<LuaParser> LanguageClient::GetFileParser (std::string_view uri)
203272{
204273 auto filename = url::UrlToFilePath (uri);
@@ -250,6 +319,7 @@ std::shared_ptr<LuaCodeStyleOptions> LanguageClient::GetOptions(std::string_view
250319
251320void LanguageClient::UpdateCodeStyleOptions (std::string_view workspaceUri, std::string_view configPath)
252321{
322+ _configVersion++;
253323 auto workspace = url::UrlToFilePath (workspaceUri);
254324 for (auto & pair : _editorConfigVector)
255325 {
@@ -272,6 +342,7 @@ void LanguageClient::UpdateCodeStyleOptions(std::string_view workspaceUri, std::
272342
273343void LanguageClient::RemoveCodeStyleOptions (std::string_view workspaceUri)
274344{
345+ ++_configVersion;
275346 auto workspace = url::UrlToFilePath (workspaceUri);
276347 for (auto it = _editorConfigVector.begin (); it != _editorConfigVector.end (); it++)
277348 {
@@ -282,18 +353,24 @@ void LanguageClient::RemoveCodeStyleOptions(std::string_view workspaceUri)
282353 }
283354 }
284355}
285-
286- void LanguageClient::UpdateAllDiagnosis ()
356+ //
357+ // void LanguageClient::UpdateAllDiagnosis()
358+ // {
359+ // for (auto it : _fileMap)
360+ // {
361+ // auto uri = url::FilePathToUrl(it.first);
362+ // DiagnosticFile(uri);
363+ // }
364+ // }
365+
366+ void LanguageClient::RefreshDiagnostic ()
287367{
288- for (auto it : _fileMap)
289- {
290- auto uri = url::FilePathToUrl (it.first );
291- DiagnosticFile (uri);
292- }
368+ SendNotification (" workspace/diagnostic/refresh" , nullptr );
293369}
294370
295371void LanguageClient::UpdateModuleInfo ()
296372{
373+ _configVersion++;
297374 FileFinder finder (_root);
298375
299376 finder.AddIgnoreDirectory (" .git" );
@@ -306,7 +383,8 @@ void LanguageClient::UpdateModuleInfo()
306383 finder.AddFindExtension (" .lua" );
307384 finder.AddFindExtension (" .lua.txt" );
308385
309- GetService<ModuleService>()->GetIndex ().RebuildIndex (finder.FindFiles ());
386+ _workspaceReadyFiles = finder.FindFiles ();
387+ GetService<ModuleService>()->GetIndex ().RebuildIndex (_workspaceReadyFiles);
310388}
311389
312390void LanguageClient::SetRoot (std::string_view root)
@@ -326,11 +404,35 @@ vscode::VscodeSettings& LanguageClient::GetSettings()
326404
327405void LanguageClient::SetVscodeSettings (vscode::VscodeSettings& settings)
328406{
407+ _configVersion++;
329408 _vscodeSettings = settings;
330409
331410 GetService<CodeFormatService>()->SetCustomDictionary (_vscodeSettings.spellDict );
332411}
333412
413+ void LanguageClient::LoadWorkspace ()
414+ {
415+ if (_workspaceReadyFiles.empty ())
416+ {
417+ return ;
418+ }
419+
420+ for (auto & filename: _workspaceReadyFiles)
421+ {
422+ if (_fileMap.count (filename) == 0 )
423+ {
424+ std::fstream fin (filename, std::ios::in);
425+ if (fin.is_open ())
426+ {
427+ std::stringstream s;
428+ s << fin.rdbuf ();
429+ UpdateFile (url::FilePathToUrl (filename), vscode::Range (), std::move (s.str ()));
430+ }
431+ }
432+ }
433+ _workspaceReadyFiles.clear ();
434+ }
435+
334436uint64_t LanguageClient::GetRequestId ()
335437{
336438 return ++_idCounter;
0 commit comments