Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/gdscript/language_server/godot_lsp.h
10278 views
1
/**************************************************************************/
2
/* godot_lsp.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/doc_data.h"
34
#include "core/object/class_db.h"
35
#include "core/templates/list.h"
36
37
namespace LSP {
38
39
typedef String DocumentUri;
40
41
/** Format BBCode documentation from DocData to markdown */
42
static String marked_documentation(const String &p_bbcode);
43
44
/**
45
* Text documents are identified using a URI. On the protocol level, URIs are passed as strings.
46
*/
47
struct TextDocumentIdentifier {
48
/**
49
* The text document's URI.
50
*/
51
DocumentUri uri;
52
53
_FORCE_INLINE_ void load(const Dictionary &p_params) {
54
uri = p_params["uri"];
55
}
56
57
_FORCE_INLINE_ Dictionary to_json() const {
58
Dictionary dict;
59
dict["uri"] = uri;
60
return dict;
61
}
62
};
63
64
/**
65
* Position in a text document expressed as zero-based line and zero-based character offset.
66
* A position is between two characters like an ‘insert’ cursor in a editor.
67
* Special values like for example -1 to denote the end of a line are not supported.
68
*/
69
struct Position {
70
/**
71
* Line position in a document (zero-based).
72
*/
73
int line = 0;
74
75
/**
76
* Character offset on a line in a document (zero-based). Assuming that the line is
77
* represented as a string, the `character` value represents the gap between the
78
* `character` and `character + 1`.
79
*
80
* If the character value is greater than the line length it defaults back to the
81
* line length.
82
*/
83
int character = 0;
84
85
_FORCE_INLINE_ bool operator==(const Position &p_other) const {
86
return line == p_other.line && character == p_other.character;
87
}
88
89
String to_string() const {
90
return vformat("(%d,%d)", line, character);
91
}
92
93
_FORCE_INLINE_ void load(const Dictionary &p_params) {
94
line = p_params["line"];
95
character = p_params["character"];
96
}
97
98
_FORCE_INLINE_ Dictionary to_json() const {
99
Dictionary dict;
100
dict["line"] = line;
101
dict["character"] = character;
102
return dict;
103
}
104
};
105
106
/**
107
* A range in a text document expressed as (zero-based) start and end positions.
108
* A range is comparable to a selection in an editor. Therefore the end position is exclusive.
109
* If you want to specify a range that contains a line including the line ending character(s) then use an end position denoting the start of the next line.
110
*/
111
struct Range {
112
/**
113
* The range's start position.
114
*/
115
Position start;
116
117
/**
118
* The range's end position.
119
*/
120
Position end;
121
122
_FORCE_INLINE_ bool operator==(const Range &p_other) const {
123
return start == p_other.start && end == p_other.end;
124
}
125
126
bool contains(const Position &p_pos) const {
127
// Inside line range.
128
if (start.line <= p_pos.line && p_pos.line <= end.line) {
129
// If on start line: must come after start char.
130
bool start_ok = p_pos.line == start.line ? start.character <= p_pos.character : true;
131
// If on end line: must come before end char.
132
bool end_ok = p_pos.line == end.line ? p_pos.character <= end.character : true;
133
return start_ok && end_ok;
134
} else {
135
return false;
136
}
137
}
138
139
String to_string() const {
140
return vformat("[%s:%s]", start.to_string(), end.to_string());
141
}
142
143
_FORCE_INLINE_ void load(const Dictionary &p_params) {
144
start.load(p_params["start"]);
145
end.load(p_params["end"]);
146
}
147
148
_FORCE_INLINE_ Dictionary to_json() const {
149
Dictionary dict;
150
dict["start"] = start.to_json();
151
dict["end"] = end.to_json();
152
return dict;
153
}
154
};
155
156
/**
157
* Represents a location inside a resource, such as a line inside a text file.
158
*/
159
struct Location {
160
DocumentUri uri;
161
Range range;
162
163
_FORCE_INLINE_ void load(const Dictionary &p_params) {
164
uri = p_params["uri"];
165
range.load(p_params["range"]);
166
}
167
168
_FORCE_INLINE_ Dictionary to_json() const {
169
Dictionary dict;
170
dict["uri"] = uri;
171
dict["range"] = range.to_json();
172
return dict;
173
}
174
};
175
176
/**
177
* Represents a link between a source and a target location.
178
*/
179
struct LocationLink {
180
/**
181
* Span of the origin of this link.
182
*
183
* Used as the underlined span for mouse interaction. Defaults to the word range at
184
* the mouse position.
185
*/
186
Range *originSelectionRange = nullptr;
187
188
/**
189
* The target resource identifier of this link.
190
*/
191
String targetUri;
192
193
/**
194
* The full target range of this link. If the target for example is a symbol then target range is the
195
* range enclosing this symbol not including leading/trailing whitespace but everything else
196
* like comments. This information is typically used to highlight the range in the editor.
197
*/
198
Range targetRange;
199
200
/**
201
* The range that should be selected and revealed when this link is being followed, e.g the name of a function.
202
* Must be contained by the `targetRange`. See also `DocumentSymbol#range`
203
*/
204
Range targetSelectionRange;
205
};
206
207
/**
208
* A parameter literal used in requests to pass a text document and a position inside that document.
209
*/
210
struct TextDocumentPositionParams {
211
/**
212
* The text document.
213
*/
214
TextDocumentIdentifier textDocument;
215
216
/**
217
* The position inside the text document.
218
*/
219
Position position;
220
221
_FORCE_INLINE_ void load(const Dictionary &p_params) {
222
textDocument.load(p_params["textDocument"]);
223
position.load(p_params["position"]);
224
}
225
226
_FORCE_INLINE_ Dictionary to_json() const {
227
Dictionary dict;
228
dict["textDocument"] = textDocument.to_json();
229
dict["position"] = position.to_json();
230
return dict;
231
}
232
};
233
234
struct ReferenceContext {
235
/**
236
* Include the declaration of the current symbol.
237
*/
238
bool includeDeclaration = false;
239
};
240
241
struct ShowMessageParams {
242
/**
243
* The message type. See {@link MessageType}.
244
*/
245
int type;
246
247
/**
248
* The actual message.
249
*/
250
String message;
251
252
_FORCE_INLINE_ Dictionary to_json() const {
253
Dictionary dict;
254
dict["type"] = type;
255
dict["message"] = message;
256
return dict;
257
}
258
};
259
260
struct ReferenceParams : TextDocumentPositionParams {
261
ReferenceContext context;
262
};
263
264
struct DocumentLinkParams {
265
/**
266
* The document to provide document links for.
267
*/
268
TextDocumentIdentifier textDocument;
269
270
_FORCE_INLINE_ void load(const Dictionary &p_params) {
271
textDocument.load(p_params["textDocument"]);
272
}
273
};
274
275
/**
276
* A document link is a range in a text document that links to an internal or external resource, like another
277
* text document or a web site.
278
*/
279
struct DocumentLink {
280
/**
281
* The range this link applies to.
282
*/
283
Range range;
284
285
/**
286
* The uri this link points to. If missing a resolve request is sent later.
287
*/
288
DocumentUri target;
289
290
Dictionary to_json() const {
291
Dictionary dict;
292
dict["range"] = range.to_json();
293
dict["target"] = target;
294
return dict;
295
}
296
};
297
298
/**
299
* A textual edit applicable to a text document.
300
*/
301
struct TextEdit {
302
/**
303
* The range of the text document to be manipulated. To insert
304
* text into a document create a range where start === end.
305
*/
306
Range range;
307
308
/**
309
* The string to be inserted. For delete operations use an
310
* empty string.
311
*/
312
String newText;
313
};
314
315
/**
316
* The edits to be applied.
317
*/
318
struct WorkspaceEdit {
319
/**
320
* Holds changes to existing resources.
321
*/
322
HashMap<String, Vector<TextEdit>> changes;
323
324
_FORCE_INLINE_ void add_edit(const String &uri, const TextEdit &edit) {
325
if (changes.has(uri)) {
326
changes[uri].push_back(edit);
327
} else {
328
Vector<TextEdit> edits;
329
edits.push_back(edit);
330
changes[uri] = edits;
331
}
332
}
333
334
_FORCE_INLINE_ Dictionary to_json() const {
335
Dictionary dict;
336
337
Dictionary out_changes;
338
for (const KeyValue<String, Vector<TextEdit>> &E : changes) {
339
Array edits;
340
for (int i = 0; i < E.value.size(); ++i) {
341
Dictionary text_edit;
342
text_edit["range"] = E.value[i].range.to_json();
343
text_edit["newText"] = E.value[i].newText;
344
edits.push_back(text_edit);
345
}
346
out_changes[E.key] = edits;
347
}
348
dict["changes"] = out_changes;
349
350
return dict;
351
}
352
353
_FORCE_INLINE_ void add_change(const String &uri, const int &line, const int &start_character, const int &end_character, const String &new_text) {
354
TextEdit new_edit;
355
new_edit.newText = new_text;
356
new_edit.range.start.line = line;
357
new_edit.range.start.character = start_character;
358
new_edit.range.end.line = line;
359
new_edit.range.end.character = end_character;
360
361
if (HashMap<String, Vector<TextEdit>>::Iterator E = changes.find(uri)) {
362
E->value.push_back(new_edit);
363
} else {
364
Vector<TextEdit> edit_list;
365
edit_list.push_back(new_edit);
366
changes.insert(uri, edit_list);
367
}
368
}
369
};
370
371
/**
372
* Represents a reference to a command.
373
* Provides a title which will be used to represent a command in the UI.
374
* Commands are identified by a string identifier.
375
* The recommended way to handle commands is to implement their execution on the server side if the client and server provides the corresponding capabilities.
376
* Alternatively the tool extension code could handle the command. The protocol currently doesn’t specify a set of well-known commands.
377
*/
378
struct Command {
379
/**
380
* Title of the command, like `save`.
381
*/
382
String title;
383
/**
384
* The identifier of the actual command handler.
385
*/
386
String command;
387
/**
388
* Arguments that the command handler should be
389
* invoked with.
390
*/
391
Array arguments;
392
393
Dictionary to_json() const {
394
Dictionary dict;
395
dict["title"] = title;
396
dict["command"] = command;
397
if (arguments.size()) {
398
dict["arguments"] = arguments;
399
}
400
return dict;
401
}
402
};
403
404
// Use namespace instead of enumeration to follow the LSP specifications.
405
// `LSP::EnumName::EnumValue` is OK but `LSP::EnumValue` is not.
406
407
namespace TextDocumentSyncKind {
408
/**
409
* Documents should not be synced at all.
410
*/
411
static const int None = 0;
412
413
/**
414
* Documents are synced by always sending the full content
415
* of the document.
416
*/
417
static const int Full = 1;
418
419
/**
420
* Documents are synced by sending the full content on open.
421
* After that only incremental updates to the document are
422
* send.
423
*/
424
static const int Incremental = 2;
425
}; // namespace TextDocumentSyncKind
426
427
namespace MessageType {
428
/**
429
* An error message.
430
*/
431
static const int Error = 1;
432
/**
433
* A warning message.
434
*/
435
static const int Warning = 2;
436
/**
437
* An information message.
438
*/
439
static const int Info = 3;
440
/**
441
* A log message.
442
*/
443
static const int Log = 4;
444
}; // namespace MessageType
445
446
/**
447
* Completion options.
448
*/
449
struct CompletionOptions {
450
/**
451
* The server provides support to resolve additional
452
* information for a completion item.
453
*/
454
bool resolveProvider = true;
455
456
/**
457
* The characters that trigger completion automatically.
458
*/
459
Vector<String> triggerCharacters;
460
461
CompletionOptions() {
462
triggerCharacters.push_back(".");
463
triggerCharacters.push_back("$");
464
triggerCharacters.push_back("'");
465
triggerCharacters.push_back("\"");
466
}
467
468
Dictionary to_json() const {
469
Dictionary dict;
470
dict["resolveProvider"] = resolveProvider;
471
dict["triggerCharacters"] = triggerCharacters;
472
return dict;
473
}
474
};
475
476
/**
477
* Signature help options.
478
*/
479
struct SignatureHelpOptions {
480
/**
481
* The characters that trigger signature help
482
* automatically.
483
*/
484
Vector<String> triggerCharacters;
485
486
Dictionary to_json() {
487
Dictionary dict;
488
dict["triggerCharacters"] = triggerCharacters;
489
return dict;
490
}
491
};
492
493
/**
494
* Code Lens options.
495
*/
496
struct CodeLensOptions {
497
/**
498
* Code lens has a resolve provider as well.
499
*/
500
bool resolveProvider = false;
501
502
Dictionary to_json() {
503
Dictionary dict;
504
dict["resolveProvider"] = resolveProvider;
505
return dict;
506
}
507
};
508
509
/**
510
* Rename options
511
*/
512
struct RenameOptions {
513
/**
514
* Renames should be checked and tested before being executed.
515
*/
516
bool prepareProvider = true;
517
518
Dictionary to_json() {
519
Dictionary dict;
520
dict["prepareProvider"] = prepareProvider;
521
return dict;
522
}
523
};
524
525
/**
526
* Document link options.
527
*/
528
struct DocumentLinkOptions {
529
/**
530
* Document links have a resolve provider as well.
531
*/
532
bool resolveProvider = false;
533
534
Dictionary to_json() {
535
Dictionary dict;
536
dict["resolveProvider"] = resolveProvider;
537
return dict;
538
}
539
};
540
541
/**
542
* Execute command options.
543
*/
544
struct ExecuteCommandOptions {
545
/**
546
* The commands to be executed on the server
547
*/
548
Vector<String> commands;
549
550
Dictionary to_json() {
551
Dictionary dict;
552
dict["commands"] = commands;
553
return dict;
554
}
555
};
556
557
/**
558
* Save options.
559
*/
560
struct SaveOptions {
561
/**
562
* The client is supposed to include the content on save.
563
*/
564
bool includeText = true;
565
566
Dictionary to_json() {
567
Dictionary dict;
568
dict["includeText"] = includeText;
569
return dict;
570
}
571
};
572
573
/**
574
* Color provider options.
575
*/
576
struct ColorProviderOptions {
577
Dictionary to_json() {
578
Dictionary dict;
579
return dict;
580
}
581
};
582
583
/**
584
* Folding range provider options.
585
*/
586
struct FoldingRangeProviderOptions {
587
Dictionary to_json() {
588
Dictionary dict;
589
return dict;
590
}
591
};
592
593
struct TextDocumentSyncOptions {
594
/**
595
* Open and close notifications are sent to the server. If omitted open close notification should not
596
* be sent.
597
*/
598
bool openClose = true;
599
600
/**
601
* Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
602
* and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
603
*/
604
int change = TextDocumentSyncKind::Full;
605
606
/**
607
* If present will save notifications are sent to the server. If omitted the notification should not be
608
* sent.
609
*/
610
bool willSave = false;
611
612
/**
613
* If present will save wait until requests are sent to the server. If omitted the request should not be
614
* sent.
615
*/
616
bool willSaveWaitUntil = true;
617
618
/**
619
* If present save notifications are sent to the server. If omitted the notification should not be
620
* sent.
621
*/
622
SaveOptions save;
623
624
Dictionary to_json() {
625
Dictionary dict;
626
dict["willSaveWaitUntil"] = willSaveWaitUntil;
627
dict["willSave"] = willSave;
628
dict["openClose"] = openClose;
629
dict["change"] = change;
630
dict["save"] = save.to_json();
631
return dict;
632
}
633
};
634
635
/**
636
* Static registration options to be returned in the initialize request.
637
*/
638
struct StaticRegistrationOptions {
639
/**
640
* The id used to register the request. The id can be used to deregister
641
* the request again. See also Registration#id.
642
*/
643
String id;
644
};
645
646
/**
647
* Format document on type options.
648
*/
649
struct DocumentOnTypeFormattingOptions {
650
/**
651
* A character on which formatting should be triggered, like `}`.
652
*/
653
String firstTriggerCharacter;
654
655
/**
656
* More trigger characters.
657
*/
658
Vector<String> moreTriggerCharacter;
659
660
Dictionary to_json() {
661
Dictionary dict;
662
dict["firstTriggerCharacter"] = firstTriggerCharacter;
663
dict["moreTriggerCharacter"] = moreTriggerCharacter;
664
return dict;
665
}
666
};
667
668
struct TextDocumentItem {
669
/**
670
* The text document's URI.
671
*/
672
DocumentUri uri;
673
674
/**
675
* The text document's language identifier.
676
*/
677
String languageId;
678
679
/**
680
* The version number of this document (it will increase after each
681
* change, including undo/redo).
682
*/
683
int version = 0;
684
685
/**
686
* The content of the opened text document.
687
*/
688
String text;
689
690
void load(const Dictionary &p_dict) {
691
uri = p_dict["uri"];
692
languageId = p_dict["languageId"];
693
version = p_dict["version"];
694
text = p_dict["text"];
695
}
696
697
Dictionary to_json() const {
698
Dictionary dict;
699
dict["uri"] = uri;
700
dict["languageId"] = languageId;
701
dict["version"] = version;
702
dict["text"] = text;
703
return dict;
704
}
705
};
706
707
/**
708
* An event describing a change to a text document. If range and rangeLength are omitted
709
* the new text is considered to be the full content of the document.
710
*/
711
struct TextDocumentContentChangeEvent {
712
/**
713
* The range of the document that changed.
714
*/
715
Range range;
716
717
/**
718
* The length of the range that got replaced.
719
*/
720
int rangeLength = 0;
721
722
/**
723
* The new text of the range/document.
724
*/
725
String text;
726
727
void load(const Dictionary &p_params) {
728
text = p_params["text"];
729
rangeLength = p_params["rangeLength"];
730
range.load(p_params["range"]);
731
}
732
};
733
734
// Use namespace instead of enumeration to follow the LSP specifications
735
namespace DiagnosticSeverity {
736
/**
737
* Reports an error.
738
*/
739
static const int Error = 1;
740
/**
741
* Reports a warning.
742
*/
743
static const int Warning = 2;
744
/**
745
* Reports an information.
746
*/
747
static const int Information = 3;
748
/**
749
* Reports a hint.
750
*/
751
static const int Hint = 4;
752
}; // namespace DiagnosticSeverity
753
754
/**
755
* Represents a related message and source code location for a diagnostic. This should be
756
* used to point to code locations that cause or related to a diagnostics, e.g when duplicating
757
* a symbol in a scope.
758
*/
759
struct DiagnosticRelatedInformation {
760
/**
761
* The location of this related diagnostic information.
762
*/
763
Location location;
764
765
/**
766
* The message of this related diagnostic information.
767
*/
768
String message;
769
770
Dictionary to_json() const {
771
Dictionary dict;
772
dict["location"] = location.to_json();
773
dict["message"] = message;
774
return dict;
775
}
776
};
777
778
/**
779
* Represents a diagnostic, such as a compiler error or warning.
780
* Diagnostic objects are only valid in the scope of a resource.
781
*/
782
struct Diagnostic {
783
/**
784
* The range at which the message applies.
785
*/
786
Range range;
787
788
/**
789
* The diagnostic's severity. Can be omitted. If omitted it is up to the
790
* client to interpret diagnostics as error, warning, info or hint.
791
*/
792
int severity = 0;
793
794
/**
795
* The diagnostic's code, which might appear in the user interface.
796
*/
797
int code = 0;
798
799
/**
800
* A human-readable string describing the source of this
801
* diagnostic, e.g. 'typescript' or 'super lint'.
802
*/
803
String source;
804
805
/**
806
* The diagnostic's message.
807
*/
808
String message;
809
810
/**
811
* An array of related diagnostic information, e.g. when symbol-names within
812
* a scope collide all definitions can be marked via this property.
813
*/
814
Vector<DiagnosticRelatedInformation> relatedInformation;
815
816
Dictionary to_json() const {
817
Dictionary dict;
818
dict["range"] = range.to_json();
819
dict["code"] = code;
820
dict["severity"] = severity;
821
dict["message"] = message;
822
dict["source"] = source;
823
if (!relatedInformation.is_empty()) {
824
Array arr;
825
arr.resize(relatedInformation.size());
826
for (int i = 0; i < relatedInformation.size(); i++) {
827
arr[i] = relatedInformation[i].to_json();
828
}
829
dict["relatedInformation"] = arr;
830
}
831
return dict;
832
}
833
};
834
835
// Use namespace instead of enumeration to follow the LSP specifications
836
/**
837
* Describes the content type that a client supports in various
838
* result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
839
*
840
* Please note that `MarkupKinds` must not start with a `$`. This kinds
841
* are reserved for internal usage.
842
*/
843
namespace MarkupKind {
844
static const String PlainText = "plaintext";
845
static const String Markdown = "markdown";
846
}; // namespace MarkupKind
847
848
/**
849
* A `MarkupContent` literal represents a string value which content is interpreted base on its
850
* kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
851
*
852
* If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
853
* See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
854
*
855
* Here is an example how such a string can be constructed using JavaScript / TypeScript:
856
* ```typescript
857
* let markdown: MarkdownContent = {
858
* kind: MarkupKind.Markdown,
859
* value: [
860
* '# Header',
861
* 'Some text',
862
* '```typescript',
863
* 'someCode();',
864
* '```'
865
* ].join('\n')
866
* };
867
* ```
868
*
869
* *Please Note* that clients might sanitize the return markdown. A client could decide to
870
* remove HTML from the markdown to avoid script execution.
871
*/
872
struct MarkupContent {
873
/**
874
* The type of the Markup.
875
*/
876
String kind;
877
878
/**
879
* The content itself.
880
*/
881
String value;
882
883
MarkupContent() {
884
kind = MarkupKind::Markdown;
885
}
886
887
MarkupContent(const String &p_value) {
888
value = p_value;
889
kind = MarkupKind::Markdown;
890
}
891
892
Dictionary to_json() const {
893
Dictionary dict;
894
dict["kind"] = kind;
895
dict["value"] = value;
896
return dict;
897
}
898
};
899
900
// Use namespace instead of enumeration to follow the LSP specifications
901
// `LSP::EnumName::EnumValue` is OK but `LSP::EnumValue` is not.
902
// And here C++ compilers are unhappy with our enumeration name like `Color`, `File`, `RefCounted` etc.
903
/**
904
* The kind of a completion entry.
905
*/
906
namespace CompletionItemKind {
907
static const int Text = 1;
908
static const int Method = 2;
909
static const int Function = 3;
910
static const int Constructor = 4;
911
static const int Field = 5;
912
static const int Variable = 6;
913
static const int Class = 7;
914
static const int Interface = 8;
915
static const int Module = 9;
916
static const int Property = 10;
917
static const int Unit = 11;
918
static const int Value = 12;
919
static const int Enum = 13;
920
static const int Keyword = 14;
921
static const int Snippet = 15;
922
static const int Color = 16;
923
static const int File = 17;
924
static const int RefCounted = 18;
925
static const int Folder = 19;
926
static const int EnumMember = 20;
927
static const int Constant = 21;
928
static const int Struct = 22;
929
static const int Event = 23;
930
static const int Operator = 24;
931
static const int TypeParameter = 25;
932
}; // namespace CompletionItemKind
933
934
// Use namespace instead of enumeration to follow the LSP specifications.
935
/**
936
* Defines whether the insert text in a completion item should be interpreted as
937
* plain text or a snippet.
938
*/
939
namespace InsertTextFormat {
940
/**
941
* The primary text to be inserted is treated as a plain string.
942
*/
943
static const int PlainText = 1;
944
945
/**
946
* The primary text to be inserted is treated as a snippet.
947
*
948
* A snippet can define tab stops and placeholders with `$1`, `$2`
949
* and `${3:foo}`. `$0` defines the final tab stop, it defaults to
950
* the end of the snippet. Placeholders with equal identifiers are linked,
951
* that is typing in one will update others too.
952
*/
953
static const int Snippet = 2;
954
}; // namespace InsertTextFormat
955
956
struct CompletionItem {
957
/**
958
* The label of this completion item. By default
959
* also the text that is inserted when selecting
960
* this completion.
961
*/
962
String label;
963
964
/**
965
* The kind of this completion item. Based of the kind
966
* an icon is chosen by the editor. The standardized set
967
* of available values is defined in `CompletionItemKind`.
968
*/
969
int kind = 0;
970
971
/**
972
* A human-readable string with additional information
973
* about this item, like type or symbol information.
974
*/
975
String detail;
976
977
/**
978
* A human-readable string that represents a doc-comment.
979
*/
980
MarkupContent documentation;
981
982
/**
983
* Indicates if this item is deprecated.
984
*/
985
bool deprecated = false;
986
987
/**
988
* Select this item when showing.
989
*
990
* *Note* that only one completion item can be selected and that the
991
* tool / client decides which item that is. The rule is that the *first*
992
* item of those that match best is selected.
993
*/
994
bool preselect = false;
995
996
/**
997
* A string that should be used when comparing this item
998
* with other items. When omitted the label is used
999
* as the filter text for this item.
1000
*/
1001
String sortText;
1002
1003
/**
1004
* A string that should be used when filtering a set of
1005
* completion items. When omitted the label is used as the
1006
* filter text for this item.
1007
*/
1008
String filterText;
1009
1010
/**
1011
* A string that should be inserted into a document when selecting
1012
* this completion. When omitted the label is used as the insert text
1013
* for this item.
1014
*
1015
* The `insertText` is subject to interpretation by the client side.
1016
* Some tools might not take the string literally. For example
1017
* VS Code when code complete is requested in this example
1018
* `con<cursor position>` and a completion item with an `insertText` of
1019
* `console` is provided it will only insert `sole`. Therefore it is
1020
* recommended to use `textEdit` instead since it avoids additional client
1021
* side interpretation.
1022
*/
1023
String insertText;
1024
1025
/**
1026
* The format of the insert text. The format applies to both the `insertText` property
1027
* and the `newText` property of a provided `textEdit`.
1028
*/
1029
int insertTextFormat = 0;
1030
1031
/**
1032
* An edit which is applied to a document when selecting this completion. When an edit is provided the value of
1033
* `insertText` is ignored.
1034
*
1035
* *Note:* The range of the edit must be a single line range and it must contain the position at which completion
1036
* has been requested.
1037
*/
1038
TextEdit textEdit;
1039
1040
/**
1041
* An optional array of additional text edits that are applied when
1042
* selecting this completion. Edits must not overlap (including the same insert position)
1043
* with the main edit nor with themselves.
1044
*
1045
* Additional text edits should be used to change text unrelated to the current cursor position
1046
* (for example adding an import statement at the top of the file if the completion item will
1047
* insert an unqualified type).
1048
*/
1049
Vector<TextEdit> additionalTextEdits;
1050
1051
/**
1052
* An optional set of characters that when pressed while this completion is active will accept it first and
1053
* then type that character. *Note* that all commit characters should have `length=1` and that superfluous
1054
* characters will be ignored.
1055
*/
1056
Vector<String> commitCharacters;
1057
1058
/**
1059
* An optional command that is executed *after* inserting this completion. *Note* that
1060
* additional modifications to the current document should be described with the
1061
* additionalTextEdits-property.
1062
*/
1063
Command command;
1064
1065
/**
1066
* A data entry field that is preserved on a completion item between
1067
* a completion and a completion resolve request.
1068
*/
1069
Variant data;
1070
1071
_FORCE_INLINE_ Dictionary to_json(bool resolved = false) const {
1072
Dictionary dict;
1073
dict["label"] = label;
1074
dict["kind"] = kind;
1075
dict["data"] = data;
1076
if (!insertText.is_empty()) {
1077
dict["insertText"] = insertText;
1078
}
1079
if (resolved) {
1080
dict["detail"] = detail;
1081
dict["documentation"] = documentation.to_json();
1082
dict["deprecated"] = deprecated;
1083
dict["preselect"] = preselect;
1084
if (!sortText.is_empty()) {
1085
dict["sortText"] = sortText;
1086
}
1087
if (!filterText.is_empty()) {
1088
dict["filterText"] = filterText;
1089
}
1090
if (commitCharacters.size()) {
1091
dict["commitCharacters"] = commitCharacters;
1092
}
1093
if (!command.command.is_empty()) {
1094
dict["command"] = command.to_json();
1095
}
1096
}
1097
return dict;
1098
}
1099
1100
void load(const Dictionary &p_dict) {
1101
if (p_dict.has("label")) {
1102
label = p_dict["label"];
1103
}
1104
if (p_dict.has("kind")) {
1105
kind = p_dict["kind"];
1106
}
1107
if (p_dict.has("detail")) {
1108
detail = p_dict["detail"];
1109
}
1110
if (p_dict.has("documentation")) {
1111
Variant doc = p_dict["documentation"];
1112
if (doc.is_string()) {
1113
documentation.value = doc;
1114
} else if (doc.get_type() == Variant::DICTIONARY) {
1115
Dictionary v = doc;
1116
documentation.value = v["value"];
1117
}
1118
}
1119
if (p_dict.has("deprecated")) {
1120
deprecated = p_dict["deprecated"];
1121
}
1122
if (p_dict.has("preselect")) {
1123
preselect = p_dict["preselect"];
1124
}
1125
if (p_dict.has("sortText")) {
1126
sortText = p_dict["sortText"];
1127
}
1128
if (p_dict.has("filterText")) {
1129
filterText = p_dict["filterText"];
1130
}
1131
if (p_dict.has("insertText")) {
1132
insertText = p_dict["insertText"];
1133
}
1134
if (p_dict.has("data")) {
1135
data = p_dict["data"];
1136
}
1137
}
1138
};
1139
1140
/**
1141
* Represents a collection of [completion items](#CompletionItem) to be presented
1142
* in the editor.
1143
*/
1144
struct CompletionList {
1145
/**
1146
* This list it not complete. Further typing should result in recomputing
1147
* this list.
1148
*/
1149
bool isIncomplete = false;
1150
1151
/**
1152
* The completion items.
1153
*/
1154
Vector<CompletionItem> items;
1155
};
1156
1157
// Use namespace instead of enumeration to follow the LSP specifications
1158
// `LSP::EnumName::EnumValue` is OK but `LSP::EnumValue` is not
1159
// And here C++ compilers are unhappy with our enumeration name like `String`, `Array`, `Object` etc
1160
/**
1161
* A symbol kind.
1162
*/
1163
namespace SymbolKind {
1164
static const int File = 1;
1165
static const int Module = 2;
1166
static const int Namespace = 3;
1167
static const int Package = 4;
1168
static const int Class = 5;
1169
static const int Method = 6;
1170
static const int Property = 7;
1171
static const int Field = 8;
1172
static const int Constructor = 9;
1173
static const int Enum = 10;
1174
static const int Interface = 11;
1175
static const int Function = 12;
1176
static const int Variable = 13;
1177
static const int Constant = 14;
1178
static const int String = 15;
1179
static const int Number = 16;
1180
static const int Boolean = 17;
1181
static const int Array = 18;
1182
static const int Object = 19;
1183
static const int Key = 20;
1184
static const int Null = 21;
1185
static const int EnumMember = 22;
1186
static const int Struct = 23;
1187
static const int Event = 24;
1188
static const int Operator = 25;
1189
static const int TypeParameter = 26;
1190
}; // namespace SymbolKind
1191
1192
/**
1193
* Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
1194
* hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
1195
* e.g. the range of an identifier.
1196
*/
1197
struct DocumentSymbol {
1198
/**
1199
* The name of this symbol. Will be displayed in the user interface and therefore must not be
1200
* an empty string or a string only consisting of white spaces.
1201
*/
1202
String name;
1203
1204
/**
1205
* More detail for this symbol, e.g the signature of a function.
1206
*/
1207
String detail;
1208
1209
/**
1210
* Documentation for this symbol.
1211
*/
1212
String documentation;
1213
1214
/**
1215
* Class name for the native symbols.
1216
*/
1217
String native_class;
1218
1219
/**
1220
* The kind of this symbol.
1221
*/
1222
int kind = SymbolKind::File;
1223
1224
/**
1225
* Indicates if this symbol is deprecated.
1226
*/
1227
bool deprecated = false;
1228
1229
/**
1230
* If `true`: Symbol is local to script and cannot be accessed somewhere else.
1231
*
1232
* For example: local variable inside a `func`.
1233
*/
1234
bool local = false;
1235
1236
/**
1237
* The range enclosing this symbol not including leading/trailing whitespace but everything else
1238
* like comments. This information is typically used to determine if the clients cursor is
1239
* inside the symbol to reveal in the symbol in the UI.
1240
*/
1241
Range range;
1242
1243
/**
1244
* The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
1245
* Must be contained by the `range`.
1246
*/
1247
Range selectionRange;
1248
1249
DocumentUri uri;
1250
String script_path;
1251
1252
/**
1253
* Children of this symbol, e.g. properties of a class.
1254
*/
1255
Vector<DocumentSymbol> children;
1256
1257
Dictionary to_json(bool with_doc = false) const {
1258
Dictionary dict;
1259
dict["name"] = name;
1260
dict["detail"] = detail;
1261
dict["kind"] = kind;
1262
dict["deprecated"] = deprecated;
1263
dict["range"] = range.to_json();
1264
dict["selectionRange"] = selectionRange.to_json();
1265
if (with_doc) {
1266
dict["documentation"] = documentation;
1267
dict["native_class"] = native_class;
1268
}
1269
if (!children.is_empty()) {
1270
Array arr;
1271
for (int i = 0; i < children.size(); i++) {
1272
if (children[i].local) {
1273
continue;
1274
}
1275
arr.push_back(children[i].to_json(with_doc));
1276
}
1277
if (!children.is_empty()) {
1278
dict["children"] = arr;
1279
}
1280
}
1281
return dict;
1282
}
1283
1284
_FORCE_INLINE_ MarkupContent render() const {
1285
MarkupContent markdown;
1286
if (detail.length()) {
1287
markdown.value = "\t" + detail + "\n\n";
1288
}
1289
if (documentation.length()) {
1290
markdown.value += marked_documentation(documentation) + "\n\n";
1291
}
1292
if (script_path.length()) {
1293
markdown.value += "Defined in [" + script_path + "](" + uri + ")";
1294
}
1295
return markdown;
1296
}
1297
1298
_FORCE_INLINE_ CompletionItem make_completion_item(bool resolved = false) const {
1299
LSP::CompletionItem item;
1300
item.label = name;
1301
1302
if (resolved) {
1303
item.documentation = render();
1304
}
1305
1306
switch (kind) {
1307
case LSP::SymbolKind::Enum:
1308
item.kind = LSP::CompletionItemKind::Enum;
1309
break;
1310
case LSP::SymbolKind::Class:
1311
item.kind = LSP::CompletionItemKind::Class;
1312
break;
1313
case LSP::SymbolKind::Property:
1314
item.kind = LSP::CompletionItemKind::Property;
1315
break;
1316
case LSP::SymbolKind::Method:
1317
case LSP::SymbolKind::Function:
1318
item.kind = LSP::CompletionItemKind::Method;
1319
break;
1320
case LSP::SymbolKind::Event:
1321
item.kind = LSP::CompletionItemKind::Event;
1322
break;
1323
case LSP::SymbolKind::Constant:
1324
item.kind = LSP::CompletionItemKind::Constant;
1325
break;
1326
case LSP::SymbolKind::Variable:
1327
item.kind = LSP::CompletionItemKind::Variable;
1328
break;
1329
case LSP::SymbolKind::File:
1330
item.kind = LSP::CompletionItemKind::File;
1331
break;
1332
default:
1333
item.kind = LSP::CompletionItemKind::Text;
1334
break;
1335
}
1336
1337
return item;
1338
}
1339
};
1340
1341
struct ApplyWorkspaceEditParams {
1342
WorkspaceEdit edit;
1343
1344
Dictionary to_json() {
1345
Dictionary dict;
1346
1347
dict["edit"] = edit.to_json();
1348
1349
return dict;
1350
}
1351
};
1352
1353
struct NativeSymbolInspectParams {
1354
String native_class;
1355
String symbol_name;
1356
1357
void load(const Dictionary &p_params) {
1358
native_class = p_params["native_class"];
1359
symbol_name = p_params["symbol_name"];
1360
}
1361
};
1362
1363
/**
1364
* Enum of known range kinds
1365
*/
1366
namespace FoldingRangeKind {
1367
/**
1368
* Folding range for a comment
1369
*/
1370
static const String Comment = "comment";
1371
/**
1372
* Folding range for a imports or includes
1373
*/
1374
static const String Imports = "imports";
1375
/**
1376
* Folding range for a region (e.g. `#region`)
1377
*/
1378
static const String Region = "region";
1379
} // namespace FoldingRangeKind
1380
1381
/**
1382
* Represents a folding range.
1383
*/
1384
struct FoldingRange {
1385
/**
1386
* The zero-based line number from where the folded range starts.
1387
*/
1388
int startLine = 0;
1389
1390
/**
1391
* The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.
1392
*/
1393
int startCharacter = 0;
1394
1395
/**
1396
* The zero-based line number where the folded range ends.
1397
*/
1398
int endLine = 0;
1399
1400
/**
1401
* The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.
1402
*/
1403
int endCharacter = 0;
1404
1405
/**
1406
* Describes the kind of the folding range such as `comment' or 'region'. The kind
1407
* is used to categorize folding ranges and used by commands like 'Fold all comments'. See
1408
* [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
1409
*/
1410
String kind = FoldingRangeKind::Region;
1411
1412
_FORCE_INLINE_ Dictionary to_json() const {
1413
Dictionary dict;
1414
dict["startLine"] = startLine;
1415
dict["startCharacter"] = startCharacter;
1416
dict["endLine"] = endLine;
1417
dict["endCharacter"] = endCharacter;
1418
return dict;
1419
}
1420
};
1421
1422
// Use namespace instead of enumeration to follow the LSP specifications
1423
/**
1424
* How a completion was triggered
1425
*/
1426
namespace CompletionTriggerKind {
1427
/**
1428
* Completion was triggered by typing an identifier (24x7 code
1429
* complete), manual invocation (e.g Ctrl+Space) or via API.
1430
*/
1431
static const int Invoked = 1;
1432
1433
/**
1434
* Completion was triggered by a trigger character specified by
1435
* the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
1436
*/
1437
static const int TriggerCharacter = 2;
1438
1439
/**
1440
* Completion was re-triggered as the current completion list is incomplete.
1441
*/
1442
static const int TriggerForIncompleteCompletions = 3;
1443
} // namespace CompletionTriggerKind
1444
1445
/**
1446
* Contains additional information about the context in which a completion request is triggered.
1447
*/
1448
struct CompletionContext {
1449
/**
1450
* How the completion was triggered.
1451
*/
1452
int triggerKind = CompletionTriggerKind::TriggerCharacter;
1453
1454
/**
1455
* The trigger character (a single character) that has trigger code complete.
1456
* Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
1457
*/
1458
String triggerCharacter;
1459
1460
void load(const Dictionary &p_params) {
1461
triggerKind = int(p_params["triggerKind"]);
1462
triggerCharacter = p_params["triggerCharacter"];
1463
}
1464
};
1465
1466
struct CompletionParams : public TextDocumentPositionParams {
1467
/**
1468
* The completion context. This is only available if the client specifies
1469
* to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
1470
*/
1471
CompletionContext context;
1472
1473
void load(const Dictionary &p_params) {
1474
TextDocumentPositionParams::load(p_params);
1475
context.load(p_params["context"]);
1476
}
1477
1478
Dictionary to_json() {
1479
Dictionary ctx;
1480
ctx["triggerCharacter"] = context.triggerCharacter;
1481
ctx["triggerKind"] = context.triggerKind;
1482
1483
Dictionary dict;
1484
dict = TextDocumentPositionParams::to_json();
1485
dict["context"] = ctx;
1486
return dict;
1487
}
1488
};
1489
1490
/**
1491
* The result of a hover request.
1492
*/
1493
struct Hover {
1494
/**
1495
* The hover's content
1496
*/
1497
MarkupContent contents;
1498
1499
/**
1500
* An optional range is a range inside a text document
1501
* that is used to visualize a hover, e.g. by changing the background color.
1502
*/
1503
Range range;
1504
1505
_FORCE_INLINE_ Dictionary to_json() const {
1506
Dictionary dict;
1507
dict["range"] = range.to_json();
1508
dict["contents"] = contents.to_json();
1509
return dict;
1510
}
1511
};
1512
1513
/**
1514
* Represents a parameter of a callable-signature. A parameter can
1515
* have a label and a doc-comment.
1516
*/
1517
struct ParameterInformation {
1518
/**
1519
* The label of this parameter information.
1520
*
1521
* Either a string or an inclusive start and exclusive end offsets within its containing
1522
* signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
1523
* string representation as `Position` and `Range` does.
1524
*
1525
* *Note*: a label of type string should be a substring of its containing signature label.
1526
* Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`.
1527
*/
1528
String label;
1529
1530
/**
1531
* The human-readable doc-comment of this parameter. Will be shown
1532
* in the UI but can be omitted.
1533
*/
1534
MarkupContent documentation;
1535
1536
Dictionary to_json() const {
1537
Dictionary dict;
1538
dict["label"] = label;
1539
dict["documentation"] = documentation.to_json();
1540
return dict;
1541
}
1542
};
1543
1544
/**
1545
* Represents the signature of something callable. A signature
1546
* can have a label, like a function-name, a doc-comment, and
1547
* a set of parameters.
1548
*/
1549
struct SignatureInformation {
1550
/**
1551
* The label of this signature. Will be shown in
1552
* the UI.
1553
*/
1554
String label;
1555
1556
/**
1557
* The human-readable doc-comment of this signature. Will be shown
1558
* in the UI but can be omitted.
1559
*/
1560
MarkupContent documentation;
1561
1562
/**
1563
* The parameters of this signature.
1564
*/
1565
Vector<ParameterInformation> parameters;
1566
1567
Dictionary to_json() const {
1568
Dictionary dict;
1569
dict["label"] = label;
1570
dict["documentation"] = documentation.to_json();
1571
Array args;
1572
for (int i = 0; i < parameters.size(); i++) {
1573
args.push_back(parameters[i].to_json());
1574
}
1575
dict["parameters"] = args;
1576
return dict;
1577
}
1578
};
1579
1580
/**
1581
* Signature help represents the signature of something
1582
* callable. There can be multiple signature but only one
1583
* active and only one active parameter.
1584
*/
1585
struct SignatureHelp {
1586
/**
1587
* One or more signatures.
1588
*/
1589
Vector<SignatureInformation> signatures;
1590
1591
/**
1592
* The active signature. If omitted or the value lies outside the
1593
* range of `signatures` the value defaults to zero or is ignored if
1594
* `signatures.length === 0`. Whenever possible implementers should
1595
* make an active decision about the active signature and shouldn't
1596
* rely on a default value.
1597
* In future version of the protocol this property might become
1598
* mandatory to better express this.
1599
*/
1600
int activeSignature = 0;
1601
1602
/**
1603
* The active parameter of the active signature. If omitted or the value
1604
* lies outside the range of `signatures[activeSignature].parameters`
1605
* defaults to 0 if the active signature has parameters. If
1606
* the active signature has no parameters it is ignored.
1607
* In future version of the protocol this property might become
1608
* mandatory to better express the active parameter if the
1609
* active signature does have any.
1610
*/
1611
int activeParameter = 0;
1612
1613
Dictionary to_json() const {
1614
Dictionary dict;
1615
Array sigs;
1616
for (int i = 0; i < signatures.size(); i++) {
1617
sigs.push_back(signatures[i].to_json());
1618
}
1619
dict["signatures"] = sigs;
1620
dict["activeSignature"] = activeSignature;
1621
dict["activeParameter"] = activeParameter;
1622
return dict;
1623
}
1624
};
1625
1626
/**
1627
* A pattern to describe in which file operation requests or notifications
1628
* the server is interested in.
1629
*/
1630
struct FileOperationPattern {
1631
/**
1632
* The glob pattern to match.
1633
*/
1634
String glob = "**/*.gd";
1635
1636
/**
1637
* Whether to match `file`s or `folder`s with this pattern.
1638
*
1639
* Matches both if undefined.
1640
*/
1641
String matches = "file";
1642
1643
Dictionary to_json() const {
1644
Dictionary dict;
1645
1646
dict["glob"] = glob;
1647
dict["matches"] = matches;
1648
1649
return dict;
1650
}
1651
};
1652
1653
/**
1654
* A filter to describe in which file operation requests or notifications
1655
* the server is interested in.
1656
*/
1657
struct FileOperationFilter {
1658
/**
1659
* The actual file operation pattern.
1660
*/
1661
FileOperationPattern pattern;
1662
1663
Dictionary to_json() const {
1664
Dictionary dict;
1665
1666
dict["pattern"] = pattern.to_json();
1667
1668
return dict;
1669
}
1670
};
1671
1672
/**
1673
* The options to register for file operations.
1674
*/
1675
struct FileOperationRegistrationOptions {
1676
/**
1677
* The actual filters.
1678
*/
1679
Vector<FileOperationFilter> filters;
1680
1681
FileOperationRegistrationOptions() {
1682
filters.push_back(FileOperationFilter());
1683
}
1684
1685
Dictionary to_json() const {
1686
Dictionary dict;
1687
1688
Array filts;
1689
for (int i = 0; i < filters.size(); i++) {
1690
filts.push_back(filters[i].to_json());
1691
}
1692
dict["filters"] = filts;
1693
1694
return dict;
1695
}
1696
};
1697
1698
/**
1699
* The server is interested in file notifications/requests.
1700
*/
1701
struct FileOperations {
1702
/**
1703
* The server is interested in receiving didDeleteFiles file notifications.
1704
*/
1705
FileOperationRegistrationOptions didDelete;
1706
1707
Dictionary to_json() const {
1708
Dictionary dict;
1709
1710
dict["didDelete"] = didDelete.to_json();
1711
1712
return dict;
1713
}
1714
};
1715
1716
/**
1717
* Workspace specific server capabilities
1718
*/
1719
struct Workspace {
1720
/**
1721
* The server is interested in file notifications/requests.
1722
*/
1723
FileOperations fileOperations;
1724
1725
Dictionary to_json() const {
1726
Dictionary dict;
1727
1728
dict["fileOperations"] = fileOperations.to_json();
1729
1730
return dict;
1731
}
1732
};
1733
1734
struct ServerCapabilities {
1735
/**
1736
* Defines how text documents are synced. Is either a detailed structure defining each notification or
1737
* for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
1738
*/
1739
TextDocumentSyncOptions textDocumentSync;
1740
1741
/**
1742
* The server provides hover support.
1743
*/
1744
bool hoverProvider = true;
1745
1746
/**
1747
* The server provides completion support.
1748
*/
1749
CompletionOptions completionProvider;
1750
1751
/**
1752
* The server provides signature help support.
1753
*/
1754
SignatureHelpOptions signatureHelpProvider;
1755
1756
/**
1757
* The server provides goto definition support.
1758
*/
1759
bool definitionProvider = true;
1760
1761
/**
1762
* The server provides Goto Type Definition support.
1763
*
1764
* Since 3.6.0
1765
*/
1766
bool typeDefinitionProvider = false;
1767
1768
/**
1769
* The server provides Goto Implementation support.
1770
*
1771
* Since 3.6.0
1772
*/
1773
bool implementationProvider = false;
1774
1775
/**
1776
* The server provides find references support.
1777
*/
1778
bool referencesProvider = true;
1779
1780
/**
1781
* The server provides document highlight support.
1782
*/
1783
bool documentHighlightProvider = false;
1784
1785
/**
1786
* The server provides document symbol support.
1787
*/
1788
bool documentSymbolProvider = true;
1789
1790
/**
1791
* The server provides workspace symbol support.
1792
*/
1793
bool workspaceSymbolProvider = false;
1794
1795
/**
1796
* The server supports workspace folder.
1797
*/
1798
Workspace workspace;
1799
1800
/**
1801
* The server provides code actions. The `CodeActionOptions` return type is only
1802
* valid if the client signals code action literal support via the property
1803
* `textDocument.codeAction.codeActionLiteralSupport`.
1804
*/
1805
bool codeActionProvider = false;
1806
1807
/**
1808
* The server provides code lens.
1809
*/
1810
CodeLensOptions codeLensProvider;
1811
1812
/**
1813
* The server provides document formatting.
1814
*/
1815
bool documentFormattingProvider = false;
1816
1817
/**
1818
* The server provides document range formatting.
1819
*/
1820
bool documentRangeFormattingProvider = false;
1821
1822
/**
1823
* The server provides document formatting on typing.
1824
*/
1825
DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
1826
1827
/**
1828
* The server provides rename support. RenameOptions may only be
1829
* specified if the client states that it supports
1830
* `prepareSupport` in its initial `initialize` request.
1831
*/
1832
RenameOptions renameProvider;
1833
1834
/**
1835
* The server provides document link support.
1836
*/
1837
DocumentLinkOptions documentLinkProvider;
1838
1839
/**
1840
* The server provides color provider support.
1841
*
1842
* Since 3.6.0
1843
*/
1844
ColorProviderOptions colorProvider;
1845
1846
/**
1847
* The server provides folding provider support.
1848
*
1849
* Since 3.10.0
1850
*/
1851
FoldingRangeProviderOptions foldingRangeProvider;
1852
1853
/**
1854
* The server provides go to declaration support.
1855
*
1856
* Since 3.14.0
1857
*/
1858
bool declarationProvider = true;
1859
1860
/**
1861
* The server provides execute command support.
1862
*/
1863
ExecuteCommandOptions executeCommandProvider;
1864
1865
_FORCE_INLINE_ Dictionary to_json() {
1866
Dictionary dict;
1867
dict["textDocumentSync"] = textDocumentSync.to_json();
1868
dict["completionProvider"] = completionProvider.to_json();
1869
signatureHelpProvider.triggerCharacters.push_back(",");
1870
signatureHelpProvider.triggerCharacters.push_back("(");
1871
dict["signatureHelpProvider"] = signatureHelpProvider.to_json();
1872
//dict["codeLensProvider"] = codeLensProvider.to_json();
1873
dict["documentOnTypeFormattingProvider"] = documentOnTypeFormattingProvider.to_json();
1874
dict["renameProvider"] = renameProvider.to_json();
1875
dict["documentLinkProvider"] = documentLinkProvider.to_json();
1876
dict["colorProvider"] = false; // colorProvider.to_json();
1877
dict["foldingRangeProvider"] = false; //foldingRangeProvider.to_json();
1878
dict["executeCommandProvider"] = executeCommandProvider.to_json();
1879
dict["hoverProvider"] = hoverProvider;
1880
dict["definitionProvider"] = definitionProvider;
1881
dict["typeDefinitionProvider"] = typeDefinitionProvider;
1882
dict["implementationProvider"] = implementationProvider;
1883
dict["referencesProvider"] = referencesProvider;
1884
dict["documentHighlightProvider"] = documentHighlightProvider;
1885
dict["documentSymbolProvider"] = documentSymbolProvider;
1886
dict["workspaceSymbolProvider"] = workspaceSymbolProvider;
1887
dict["workspace"] = workspace.to_json();
1888
dict["codeActionProvider"] = codeActionProvider;
1889
dict["documentFormattingProvider"] = documentFormattingProvider;
1890
dict["documentRangeFormattingProvider"] = documentRangeFormattingProvider;
1891
dict["declarationProvider"] = declarationProvider;
1892
return dict;
1893
}
1894
};
1895
1896
struct InitializeResult {
1897
/**
1898
* The capabilities the language server provides.
1899
*/
1900
ServerCapabilities capabilities;
1901
1902
_FORCE_INLINE_ Dictionary to_json() {
1903
Dictionary dict;
1904
dict["capabilities"] = capabilities.to_json();
1905
return dict;
1906
}
1907
};
1908
1909
struct GodotNativeClassInfo {
1910
String name;
1911
const DocData::ClassDoc *class_doc = nullptr;
1912
const ClassDB::ClassInfo *class_info = nullptr;
1913
1914
Dictionary to_json() const {
1915
Dictionary dict;
1916
dict["name"] = name;
1917
dict["inherits"] = class_doc->inherits;
1918
return dict;
1919
}
1920
};
1921
1922
/** Features not included in the standard lsp specifications */
1923
struct GodotCapabilities {
1924
/**
1925
* Native class list
1926
*/
1927
List<GodotNativeClassInfo> native_classes;
1928
1929
Dictionary to_json() const {
1930
Dictionary dict;
1931
Array classes;
1932
for (const GodotNativeClassInfo &native_class : native_classes) {
1933
classes.push_back(native_class.to_json());
1934
}
1935
dict["native_classes"] = classes;
1936
return dict;
1937
}
1938
};
1939
1940
/** Format BBCode documentation from DocData to markdown */
1941
static String marked_documentation(const String &p_bbcode) {
1942
String markdown = p_bbcode.strip_edges();
1943
1944
Vector<String> lines = markdown.split("\n");
1945
bool in_code_block = false;
1946
int code_block_indent = -1;
1947
1948
markdown = "";
1949
for (int i = 0; i < lines.size(); i++) {
1950
String line = lines[i];
1951
int block_start = line.find("[codeblock]");
1952
if (block_start != -1) {
1953
code_block_indent = block_start;
1954
in_code_block = true;
1955
line = "\n";
1956
} else if (in_code_block) {
1957
line = "\t" + line.substr(code_block_indent);
1958
}
1959
1960
if (in_code_block && line.contains("[/codeblock]")) {
1961
line = "\n";
1962
in_code_block = false;
1963
}
1964
1965
if (!in_code_block) {
1966
line = line.strip_edges();
1967
line = line.replace("[code]", "`");
1968
line = line.replace("[/code]", "`");
1969
line = line.replace("[i]", "*");
1970
line = line.replace("[/i]", "*");
1971
line = line.replace("[b]", "**");
1972
line = line.replace("[/b]", "**");
1973
line = line.replace("[u]", "__");
1974
line = line.replace("[/u]", "__");
1975
line = line.replace("[method ", "`");
1976
line = line.replace("[member ", "`");
1977
line = line.replace("[signal ", "`");
1978
line = line.replace("[enum ", "`");
1979
line = line.replace("[constant ", "`");
1980
line = line.replace_chars("[]", '`');
1981
}
1982
1983
if (!in_code_block && i < lines.size() - 1) {
1984
line += "\n\n";
1985
} else if (i < lines.size() - 1) {
1986
line += "\n";
1987
}
1988
markdown += line;
1989
}
1990
return markdown;
1991
}
1992
} // namespace LSP
1993
1994