Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/gdscript/language_server/godot_lsp.h
11353 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
return Dictionary();
579
}
580
};
581
582
/**
583
* Folding range provider options.
584
*/
585
struct FoldingRangeProviderOptions {
586
Dictionary to_json() {
587
return Dictionary();
588
}
589
};
590
591
struct TextDocumentSyncOptions {
592
/**
593
* Open and close notifications are sent to the server. If omitted open close notification should not
594
* be sent.
595
*/
596
bool openClose = true;
597
598
/**
599
* Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
600
* and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
601
*/
602
int change = TextDocumentSyncKind::Full;
603
604
/**
605
* If present will save notifications are sent to the server. If omitted the notification should not be
606
* sent.
607
*/
608
bool willSave = false;
609
610
/**
611
* If present will save wait until requests are sent to the server. If omitted the request should not be
612
* sent.
613
*/
614
bool willSaveWaitUntil = true;
615
616
/**
617
* If present save notifications are sent to the server. If omitted the notification should not be
618
* sent.
619
*/
620
SaveOptions save;
621
622
Dictionary to_json() {
623
Dictionary dict;
624
dict["willSaveWaitUntil"] = willSaveWaitUntil;
625
dict["willSave"] = willSave;
626
dict["openClose"] = openClose;
627
dict["change"] = change;
628
dict["save"] = save.to_json();
629
return dict;
630
}
631
};
632
633
/**
634
* Static registration options to be returned in the initialize request.
635
*/
636
struct StaticRegistrationOptions {
637
/**
638
* The id used to register the request. The id can be used to deregister
639
* the request again. See also Registration#id.
640
*/
641
String id;
642
};
643
644
/**
645
* Format document on type options.
646
*/
647
struct DocumentOnTypeFormattingOptions {
648
/**
649
* A character on which formatting should be triggered, like `}`.
650
*/
651
String firstTriggerCharacter;
652
653
/**
654
* More trigger characters.
655
*/
656
Vector<String> moreTriggerCharacter;
657
658
Dictionary to_json() {
659
Dictionary dict;
660
dict["firstTriggerCharacter"] = firstTriggerCharacter;
661
dict["moreTriggerCharacter"] = moreTriggerCharacter;
662
return dict;
663
}
664
};
665
666
struct TextDocumentItem {
667
/**
668
* The text document's URI.
669
*/
670
DocumentUri uri;
671
672
/**
673
* The text document's language identifier.
674
*/
675
String languageId;
676
677
/**
678
* The version number of this document (it will increase after each
679
* change, including undo/redo).
680
*/
681
int version = 0;
682
683
/**
684
* The content of the opened text document.
685
*/
686
String text;
687
688
void load(const Dictionary &p_dict) {
689
uri = p_dict["uri"];
690
languageId = p_dict["languageId"];
691
version = p_dict["version"];
692
text = p_dict["text"];
693
}
694
695
Dictionary to_json() const {
696
Dictionary dict;
697
dict["uri"] = uri;
698
dict["languageId"] = languageId;
699
dict["version"] = version;
700
dict["text"] = text;
701
return dict;
702
}
703
};
704
705
/**
706
* An event describing a change to a text document. If range and rangeLength are omitted
707
* the new text is considered to be the full content of the document.
708
*/
709
struct TextDocumentContentChangeEvent {
710
/**
711
* The range of the document that changed.
712
*/
713
Range range;
714
715
/**
716
* The length of the range that got replaced.
717
*/
718
int rangeLength = 0;
719
720
/**
721
* The new text of the range/document.
722
*/
723
String text;
724
725
void load(const Dictionary &p_params) {
726
text = p_params["text"];
727
rangeLength = p_params["rangeLength"];
728
range.load(p_params["range"]);
729
}
730
};
731
732
// Use namespace instead of enumeration to follow the LSP specifications
733
namespace DiagnosticSeverity {
734
/**
735
* Reports an error.
736
*/
737
static const int Error = 1;
738
/**
739
* Reports a warning.
740
*/
741
static const int Warning = 2;
742
/**
743
* Reports an information.
744
*/
745
static const int Information = 3;
746
/**
747
* Reports a hint.
748
*/
749
static const int Hint = 4;
750
}; // namespace DiagnosticSeverity
751
752
/**
753
* Represents a related message and source code location for a diagnostic. This should be
754
* used to point to code locations that cause or related to a diagnostics, e.g when duplicating
755
* a symbol in a scope.
756
*/
757
struct DiagnosticRelatedInformation {
758
/**
759
* The location of this related diagnostic information.
760
*/
761
Location location;
762
763
/**
764
* The message of this related diagnostic information.
765
*/
766
String message;
767
768
Dictionary to_json() const {
769
Dictionary dict;
770
dict["location"] = location.to_json();
771
dict["message"] = message;
772
return dict;
773
}
774
};
775
776
/**
777
* Represents a diagnostic, such as a compiler error or warning.
778
* Diagnostic objects are only valid in the scope of a resource.
779
*/
780
struct Diagnostic {
781
/**
782
* The range at which the message applies.
783
*/
784
Range range;
785
786
/**
787
* The diagnostic's severity. Can be omitted. If omitted it is up to the
788
* client to interpret diagnostics as error, warning, info or hint.
789
*/
790
int severity = 0;
791
792
/**
793
* The diagnostic's code, which might appear in the user interface.
794
*/
795
int code = 0;
796
797
/**
798
* A human-readable string describing the source of this
799
* diagnostic, e.g. 'typescript' or 'super lint'.
800
*/
801
String source;
802
803
/**
804
* The diagnostic's message.
805
*/
806
String message;
807
808
/**
809
* An array of related diagnostic information, e.g. when symbol-names within
810
* a scope collide all definitions can be marked via this property.
811
*/
812
Vector<DiagnosticRelatedInformation> relatedInformation;
813
814
Dictionary to_json() const {
815
Dictionary dict;
816
dict["range"] = range.to_json();
817
dict["code"] = code;
818
dict["severity"] = severity;
819
dict["message"] = message;
820
dict["source"] = source;
821
if (!relatedInformation.is_empty()) {
822
Array arr;
823
arr.resize(relatedInformation.size());
824
for (int i = 0; i < relatedInformation.size(); i++) {
825
arr[i] = relatedInformation[i].to_json();
826
}
827
dict["relatedInformation"] = arr;
828
}
829
return dict;
830
}
831
};
832
833
// Use namespace instead of enumeration to follow the LSP specifications
834
/**
835
* Describes the content type that a client supports in various
836
* result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
837
*
838
* Please note that `MarkupKinds` must not start with a `$`. This kinds
839
* are reserved for internal usage.
840
*/
841
namespace MarkupKind {
842
static const String PlainText = "plaintext";
843
static const String Markdown = "markdown";
844
}; // namespace MarkupKind
845
846
/**
847
* A `MarkupContent` literal represents a string value which content is interpreted base on its
848
* kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
849
*
850
* If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
851
* See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
852
*
853
* Here is an example how such a string can be constructed using JavaScript / TypeScript:
854
* ```typescript
855
* let markdown: MarkdownContent = {
856
* kind: MarkupKind.Markdown,
857
* value: [
858
* '# Header',
859
* 'Some text',
860
* '```typescript',
861
* 'someCode();',
862
* '```'
863
* ].join('\n')
864
* };
865
* ```
866
*
867
* *Please Note* that clients might sanitize the return markdown. A client could decide to
868
* remove HTML from the markdown to avoid script execution.
869
*/
870
struct MarkupContent {
871
/**
872
* The type of the Markup.
873
*/
874
String kind;
875
876
/**
877
* The content itself.
878
*/
879
String value;
880
881
MarkupContent() {
882
kind = MarkupKind::Markdown;
883
}
884
885
MarkupContent(const String &p_value) {
886
value = p_value;
887
kind = MarkupKind::Markdown;
888
}
889
890
Dictionary to_json() const {
891
Dictionary dict;
892
dict["kind"] = kind;
893
dict["value"] = value;
894
return dict;
895
}
896
};
897
898
// Use namespace instead of enumeration to follow the LSP specifications
899
// `LSP::EnumName::EnumValue` is OK but `LSP::EnumValue` is not.
900
// And here C++ compilers are unhappy with our enumeration name like `Color`, `File`, `RefCounted` etc.
901
/**
902
* The kind of a completion entry.
903
*/
904
namespace CompletionItemKind {
905
static const int Text = 1;
906
static const int Method = 2;
907
static const int Function = 3;
908
static const int Constructor = 4;
909
static const int Field = 5;
910
static const int Variable = 6;
911
static const int Class = 7;
912
static const int Interface = 8;
913
static const int Module = 9;
914
static const int Property = 10;
915
static const int Unit = 11;
916
static const int Value = 12;
917
static const int Enum = 13;
918
static const int Keyword = 14;
919
static const int Snippet = 15;
920
static const int Color = 16;
921
static const int File = 17;
922
static const int RefCounted = 18;
923
static const int Folder = 19;
924
static const int EnumMember = 20;
925
static const int Constant = 21;
926
static const int Struct = 22;
927
static const int Event = 23;
928
static const int Operator = 24;
929
static const int TypeParameter = 25;
930
}; // namespace CompletionItemKind
931
932
// Use namespace instead of enumeration to follow the LSP specifications.
933
/**
934
* Defines whether the insert text in a completion item should be interpreted as
935
* plain text or a snippet.
936
*/
937
namespace InsertTextFormat {
938
/**
939
* The primary text to be inserted is treated as a plain string.
940
*/
941
static const int PlainText = 1;
942
943
/**
944
* The primary text to be inserted is treated as a snippet.
945
*
946
* A snippet can define tab stops and placeholders with `$1`, `$2`
947
* and `${3:foo}`. `$0` defines the final tab stop, it defaults to
948
* the end of the snippet. Placeholders with equal identifiers are linked,
949
* that is typing in one will update others too.
950
*/
951
static const int Snippet = 2;
952
}; // namespace InsertTextFormat
953
954
struct CompletionItem {
955
/**
956
* The label of this completion item. By default
957
* also the text that is inserted when selecting
958
* this completion.
959
*/
960
String label;
961
962
/**
963
* The kind of this completion item. Based of the kind
964
* an icon is chosen by the editor. The standardized set
965
* of available values is defined in `CompletionItemKind`.
966
*/
967
int kind = 0;
968
969
/**
970
* A human-readable string with additional information
971
* about this item, like type or symbol information.
972
*/
973
String detail;
974
975
/**
976
* A human-readable string that represents a doc-comment.
977
*/
978
MarkupContent documentation;
979
980
/**
981
* Indicates if this item is deprecated.
982
*/
983
bool deprecated = false;
984
985
/**
986
* Select this item when showing.
987
*
988
* *Note* that only one completion item can be selected and that the
989
* tool / client decides which item that is. The rule is that the *first*
990
* item of those that match best is selected.
991
*/
992
bool preselect = false;
993
994
/**
995
* A string that should be used when comparing this item
996
* with other items. When omitted the label is used
997
* as the filter text for this item.
998
*/
999
String sortText;
1000
1001
/**
1002
* A string that should be used when filtering a set of
1003
* completion items. When omitted the label is used as the
1004
* filter text for this item.
1005
*/
1006
String filterText;
1007
1008
/**
1009
* A string that should be inserted into a document when selecting
1010
* this completion. When omitted the label is used as the insert text
1011
* for this item.
1012
*
1013
* The `insertText` is subject to interpretation by the client side.
1014
* Some tools might not take the string literally. For example
1015
* VS Code when code complete is requested in this example
1016
* `con<cursor position>` and a completion item with an `insertText` of
1017
* `console` is provided it will only insert `sole`. Therefore it is
1018
* recommended to use `textEdit` instead since it avoids additional client
1019
* side interpretation.
1020
*/
1021
String insertText;
1022
1023
/**
1024
* The format of the insert text. The format applies to both the `insertText` property
1025
* and the `newText` property of a provided `textEdit`.
1026
*/
1027
int insertTextFormat = 0;
1028
1029
/**
1030
* An edit which is applied to a document when selecting this completion. When an edit is provided the value of
1031
* `insertText` is ignored.
1032
*
1033
* *Note:* The range of the edit must be a single line range and it must contain the position at which completion
1034
* has been requested.
1035
*/
1036
TextEdit textEdit;
1037
1038
/**
1039
* An optional array of additional text edits that are applied when
1040
* selecting this completion. Edits must not overlap (including the same insert position)
1041
* with the main edit nor with themselves.
1042
*
1043
* Additional text edits should be used to change text unrelated to the current cursor position
1044
* (for example adding an import statement at the top of the file if the completion item will
1045
* insert an unqualified type).
1046
*/
1047
Vector<TextEdit> additionalTextEdits;
1048
1049
/**
1050
* An optional set of characters that when pressed while this completion is active will accept it first and
1051
* then type that character. *Note* that all commit characters should have `length=1` and that superfluous
1052
* characters will be ignored.
1053
*/
1054
Vector<String> commitCharacters;
1055
1056
/**
1057
* An optional command that is executed *after* inserting this completion. *Note* that
1058
* additional modifications to the current document should be described with the
1059
* additionalTextEdits-property.
1060
*/
1061
Command command;
1062
1063
/**
1064
* A data entry field that is preserved on a completion item between
1065
* a completion and a completion resolve request.
1066
*/
1067
Variant data;
1068
1069
_FORCE_INLINE_ Dictionary to_json(bool resolved = false) const {
1070
Dictionary dict;
1071
dict["label"] = label;
1072
dict["kind"] = kind;
1073
dict["data"] = data;
1074
if (!insertText.is_empty()) {
1075
dict["insertText"] = insertText;
1076
}
1077
if (resolved) {
1078
dict["detail"] = detail;
1079
dict["documentation"] = documentation.to_json();
1080
dict["deprecated"] = deprecated;
1081
dict["preselect"] = preselect;
1082
if (!sortText.is_empty()) {
1083
dict["sortText"] = sortText;
1084
}
1085
if (!filterText.is_empty()) {
1086
dict["filterText"] = filterText;
1087
}
1088
if (commitCharacters.size()) {
1089
dict["commitCharacters"] = commitCharacters;
1090
}
1091
if (!command.command.is_empty()) {
1092
dict["command"] = command.to_json();
1093
}
1094
}
1095
return dict;
1096
}
1097
1098
void load(const Dictionary &p_dict) {
1099
if (p_dict.has("label")) {
1100
label = p_dict["label"];
1101
}
1102
if (p_dict.has("kind")) {
1103
kind = p_dict["kind"];
1104
}
1105
if (p_dict.has("detail")) {
1106
detail = p_dict["detail"];
1107
}
1108
if (p_dict.has("documentation")) {
1109
Variant doc = p_dict["documentation"];
1110
if (doc.is_string()) {
1111
documentation.value = doc;
1112
} else if (doc.get_type() == Variant::DICTIONARY) {
1113
Dictionary v = doc;
1114
documentation.value = v["value"];
1115
}
1116
}
1117
if (p_dict.has("deprecated")) {
1118
deprecated = p_dict["deprecated"];
1119
}
1120
if (p_dict.has("preselect")) {
1121
preselect = p_dict["preselect"];
1122
}
1123
if (p_dict.has("sortText")) {
1124
sortText = p_dict["sortText"];
1125
}
1126
if (p_dict.has("filterText")) {
1127
filterText = p_dict["filterText"];
1128
}
1129
if (p_dict.has("insertText")) {
1130
insertText = p_dict["insertText"];
1131
}
1132
if (p_dict.has("data")) {
1133
data = p_dict["data"];
1134
}
1135
}
1136
};
1137
1138
/**
1139
* Represents a collection of [completion items](#CompletionItem) to be presented
1140
* in the editor.
1141
*/
1142
struct CompletionList {
1143
/**
1144
* This list it not complete. Further typing should result in recomputing
1145
* this list.
1146
*/
1147
bool isIncomplete = false;
1148
1149
/**
1150
* The completion items.
1151
*/
1152
Vector<CompletionItem> items;
1153
};
1154
1155
// Use namespace instead of enumeration to follow the LSP specifications
1156
// `LSP::EnumName::EnumValue` is OK but `LSP::EnumValue` is not
1157
// And here C++ compilers are unhappy with our enumeration name like `String`, `Array`, `Object` etc
1158
/**
1159
* A symbol kind.
1160
*/
1161
namespace SymbolKind {
1162
static const int File = 1;
1163
static const int Module = 2;
1164
static const int Namespace = 3;
1165
static const int Package = 4;
1166
static const int Class = 5;
1167
static const int Method = 6;
1168
static const int Property = 7;
1169
static const int Field = 8;
1170
static const int Constructor = 9;
1171
static const int Enum = 10;
1172
static const int Interface = 11;
1173
static const int Function = 12;
1174
static const int Variable = 13;
1175
static const int Constant = 14;
1176
static const int String = 15;
1177
static const int Number = 16;
1178
static const int Boolean = 17;
1179
static const int Array = 18;
1180
static const int Object = 19;
1181
static const int Key = 20;
1182
static const int Null = 21;
1183
static const int EnumMember = 22;
1184
static const int Struct = 23;
1185
static const int Event = 24;
1186
static const int Operator = 25;
1187
static const int TypeParameter = 26;
1188
}; // namespace SymbolKind
1189
1190
/**
1191
* Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
1192
* hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
1193
* e.g. the range of an identifier.
1194
*/
1195
struct DocumentSymbol {
1196
/**
1197
* The name of this symbol. Will be displayed in the user interface and therefore must not be
1198
* an empty string or a string only consisting of white spaces.
1199
*/
1200
String name;
1201
1202
/**
1203
* More detail for this symbol, e.g the signature of a function.
1204
*/
1205
String detail;
1206
1207
/**
1208
* Documentation for this symbol.
1209
*/
1210
String documentation;
1211
1212
/**
1213
* Class name for the native symbols.
1214
*/
1215
String native_class;
1216
1217
/**
1218
* The kind of this symbol.
1219
*/
1220
int kind = SymbolKind::File;
1221
1222
/**
1223
* Indicates if this symbol is deprecated.
1224
*/
1225
bool deprecated = false;
1226
1227
/**
1228
* If `true`: Symbol is local to script and cannot be accessed somewhere else.
1229
*
1230
* For example: local variable inside a `func`.
1231
*/
1232
bool local = false;
1233
1234
/**
1235
* The range enclosing this symbol not including leading/trailing whitespace but everything else
1236
* like comments. This information is typically used to determine if the clients cursor is
1237
* inside the symbol to reveal in the symbol in the UI.
1238
*/
1239
Range range;
1240
1241
/**
1242
* The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
1243
* Must be contained by the `range`.
1244
*/
1245
Range selectionRange;
1246
1247
DocumentUri uri;
1248
String script_path;
1249
1250
/**
1251
* Children of this symbol, e.g. properties of a class.
1252
*/
1253
Vector<DocumentSymbol> children;
1254
1255
Dictionary to_json(bool with_doc = false) const {
1256
Dictionary dict;
1257
dict["name"] = name;
1258
dict["detail"] = detail;
1259
dict["kind"] = kind;
1260
dict["deprecated"] = deprecated;
1261
dict["range"] = range.to_json();
1262
dict["selectionRange"] = selectionRange.to_json();
1263
if (with_doc) {
1264
dict["documentation"] = documentation;
1265
dict["native_class"] = native_class;
1266
}
1267
if (!children.is_empty()) {
1268
Array arr;
1269
for (int i = 0; i < children.size(); i++) {
1270
if (children[i].local) {
1271
continue;
1272
}
1273
arr.push_back(children[i].to_json(with_doc));
1274
}
1275
if (!children.is_empty()) {
1276
dict["children"] = arr;
1277
}
1278
}
1279
return dict;
1280
}
1281
1282
_FORCE_INLINE_ MarkupContent render() const {
1283
MarkupContent markdown;
1284
if (detail.length()) {
1285
markdown.value = "\t" + detail + "\n\n";
1286
}
1287
if (documentation.length()) {
1288
markdown.value += marked_documentation(documentation) + "\n\n";
1289
}
1290
if (script_path.length()) {
1291
markdown.value += "Defined in [" + script_path + "](" + uri + ")";
1292
}
1293
return markdown;
1294
}
1295
1296
_FORCE_INLINE_ CompletionItem make_completion_item(bool resolved = false) const {
1297
LSP::CompletionItem item;
1298
item.label = name;
1299
1300
if (resolved) {
1301
item.documentation = render();
1302
}
1303
1304
switch (kind) {
1305
case LSP::SymbolKind::Enum:
1306
item.kind = LSP::CompletionItemKind::Enum;
1307
break;
1308
case LSP::SymbolKind::Class:
1309
item.kind = LSP::CompletionItemKind::Class;
1310
break;
1311
case LSP::SymbolKind::Property:
1312
item.kind = LSP::CompletionItemKind::Property;
1313
break;
1314
case LSP::SymbolKind::Method:
1315
case LSP::SymbolKind::Function:
1316
item.kind = LSP::CompletionItemKind::Method;
1317
break;
1318
case LSP::SymbolKind::Event:
1319
item.kind = LSP::CompletionItemKind::Event;
1320
break;
1321
case LSP::SymbolKind::Constant:
1322
item.kind = LSP::CompletionItemKind::Constant;
1323
break;
1324
case LSP::SymbolKind::Variable:
1325
item.kind = LSP::CompletionItemKind::Variable;
1326
break;
1327
case LSP::SymbolKind::File:
1328
item.kind = LSP::CompletionItemKind::File;
1329
break;
1330
default:
1331
item.kind = LSP::CompletionItemKind::Text;
1332
break;
1333
}
1334
1335
return item;
1336
}
1337
};
1338
1339
struct ApplyWorkspaceEditParams {
1340
WorkspaceEdit edit;
1341
1342
Dictionary to_json() {
1343
Dictionary dict;
1344
1345
dict["edit"] = edit.to_json();
1346
1347
return dict;
1348
}
1349
};
1350
1351
struct NativeSymbolInspectParams {
1352
String native_class;
1353
String symbol_name;
1354
1355
void load(const Dictionary &p_params) {
1356
native_class = p_params["native_class"];
1357
symbol_name = p_params["symbol_name"];
1358
}
1359
};
1360
1361
/**
1362
* Enum of known range kinds
1363
*/
1364
namespace FoldingRangeKind {
1365
/**
1366
* Folding range for a comment
1367
*/
1368
static const String Comment = "comment";
1369
/**
1370
* Folding range for a imports or includes
1371
*/
1372
static const String Imports = "imports";
1373
/**
1374
* Folding range for a region (e.g. `#region`)
1375
*/
1376
static const String Region = "region";
1377
} // namespace FoldingRangeKind
1378
1379
/**
1380
* Represents a folding range.
1381
*/
1382
struct FoldingRange {
1383
/**
1384
* The zero-based line number from where the folded range starts.
1385
*/
1386
int startLine = 0;
1387
1388
/**
1389
* The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.
1390
*/
1391
int startCharacter = 0;
1392
1393
/**
1394
* The zero-based line number where the folded range ends.
1395
*/
1396
int endLine = 0;
1397
1398
/**
1399
* The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.
1400
*/
1401
int endCharacter = 0;
1402
1403
/**
1404
* Describes the kind of the folding range such as `comment' or 'region'. The kind
1405
* is used to categorize folding ranges and used by commands like 'Fold all comments'. See
1406
* [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
1407
*/
1408
String kind = FoldingRangeKind::Region;
1409
1410
_FORCE_INLINE_ Dictionary to_json() const {
1411
Dictionary dict;
1412
dict["startLine"] = startLine;
1413
dict["startCharacter"] = startCharacter;
1414
dict["endLine"] = endLine;
1415
dict["endCharacter"] = endCharacter;
1416
return dict;
1417
}
1418
};
1419
1420
// Use namespace instead of enumeration to follow the LSP specifications
1421
/**
1422
* How a completion was triggered
1423
*/
1424
namespace CompletionTriggerKind {
1425
/**
1426
* Completion was triggered by typing an identifier (24x7 code
1427
* complete), manual invocation (e.g Ctrl+Space) or via API.
1428
*/
1429
static const int Invoked = 1;
1430
1431
/**
1432
* Completion was triggered by a trigger character specified by
1433
* the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
1434
*/
1435
static const int TriggerCharacter = 2;
1436
1437
/**
1438
* Completion was re-triggered as the current completion list is incomplete.
1439
*/
1440
static const int TriggerForIncompleteCompletions = 3;
1441
} // namespace CompletionTriggerKind
1442
1443
/**
1444
* Contains additional information about the context in which a completion request is triggered.
1445
*/
1446
struct CompletionContext {
1447
/**
1448
* How the completion was triggered.
1449
*/
1450
int triggerKind = CompletionTriggerKind::TriggerCharacter;
1451
1452
/**
1453
* The trigger character (a single character) that has trigger code complete.
1454
* Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
1455
*/
1456
String triggerCharacter;
1457
1458
void load(const Dictionary &p_params) {
1459
triggerKind = int(p_params["triggerKind"]);
1460
triggerCharacter = p_params["triggerCharacter"];
1461
}
1462
};
1463
1464
struct CompletionParams : public TextDocumentPositionParams {
1465
/**
1466
* The completion context. This is only available if the client specifies
1467
* to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
1468
*/
1469
CompletionContext context;
1470
1471
void load(const Dictionary &p_params) {
1472
TextDocumentPositionParams::load(p_params);
1473
context.load(p_params["context"]);
1474
}
1475
1476
Dictionary to_json() {
1477
Dictionary ctx;
1478
ctx["triggerCharacter"] = context.triggerCharacter;
1479
ctx["triggerKind"] = context.triggerKind;
1480
1481
Dictionary dict;
1482
dict = TextDocumentPositionParams::to_json();
1483
dict["context"] = ctx;
1484
return dict;
1485
}
1486
};
1487
1488
/**
1489
* The result of a hover request.
1490
*/
1491
struct Hover {
1492
/**
1493
* The hover's content
1494
*/
1495
MarkupContent contents;
1496
1497
/**
1498
* An optional range is a range inside a text document
1499
* that is used to visualize a hover, e.g. by changing the background color.
1500
*/
1501
Range range;
1502
1503
_FORCE_INLINE_ Dictionary to_json() const {
1504
Dictionary dict;
1505
dict["range"] = range.to_json();
1506
dict["contents"] = contents.to_json();
1507
return dict;
1508
}
1509
};
1510
1511
/**
1512
* Represents a parameter of a callable-signature. A parameter can
1513
* have a label and a doc-comment.
1514
*/
1515
struct ParameterInformation {
1516
/**
1517
* The label of this parameter information.
1518
*
1519
* Either a string or an inclusive start and exclusive end offsets within its containing
1520
* signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
1521
* string representation as `Position` and `Range` does.
1522
*
1523
* *Note*: a label of type string should be a substring of its containing signature label.
1524
* Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`.
1525
*/
1526
String label;
1527
1528
/**
1529
* The human-readable doc-comment of this parameter. Will be shown
1530
* in the UI but can be omitted.
1531
*/
1532
MarkupContent documentation;
1533
1534
Dictionary to_json() const {
1535
Dictionary dict;
1536
dict["label"] = label;
1537
dict["documentation"] = documentation.to_json();
1538
return dict;
1539
}
1540
};
1541
1542
/**
1543
* Represents the signature of something callable. A signature
1544
* can have a label, like a function-name, a doc-comment, and
1545
* a set of parameters.
1546
*/
1547
struct SignatureInformation {
1548
/**
1549
* The label of this signature. Will be shown in
1550
* the UI.
1551
*/
1552
String label;
1553
1554
/**
1555
* The human-readable doc-comment of this signature. Will be shown
1556
* in the UI but can be omitted.
1557
*/
1558
MarkupContent documentation;
1559
1560
/**
1561
* The parameters of this signature.
1562
*/
1563
Vector<ParameterInformation> parameters;
1564
1565
Dictionary to_json() const {
1566
Dictionary dict;
1567
dict["label"] = label;
1568
dict["documentation"] = documentation.to_json();
1569
Array args;
1570
for (int i = 0; i < parameters.size(); i++) {
1571
args.push_back(parameters[i].to_json());
1572
}
1573
dict["parameters"] = args;
1574
return dict;
1575
}
1576
};
1577
1578
/**
1579
* Signature help represents the signature of something
1580
* callable. There can be multiple signature but only one
1581
* active and only one active parameter.
1582
*/
1583
struct SignatureHelp {
1584
/**
1585
* One or more signatures.
1586
*/
1587
Vector<SignatureInformation> signatures;
1588
1589
/**
1590
* The active signature. If omitted or the value lies outside the
1591
* range of `signatures` the value defaults to zero or is ignored if
1592
* `signatures.length === 0`. Whenever possible implementers should
1593
* make an active decision about the active signature and shouldn't
1594
* rely on a default value.
1595
* In future version of the protocol this property might become
1596
* mandatory to better express this.
1597
*/
1598
int activeSignature = 0;
1599
1600
/**
1601
* The active parameter of the active signature. If omitted or the value
1602
* lies outside the range of `signatures[activeSignature].parameters`
1603
* defaults to 0 if the active signature has parameters. If
1604
* the active signature has no parameters it is ignored.
1605
* In future version of the protocol this property might become
1606
* mandatory to better express the active parameter if the
1607
* active signature does have any.
1608
*/
1609
int activeParameter = 0;
1610
1611
Dictionary to_json() const {
1612
Dictionary dict;
1613
Array sigs;
1614
for (int i = 0; i < signatures.size(); i++) {
1615
sigs.push_back(signatures[i].to_json());
1616
}
1617
dict["signatures"] = sigs;
1618
dict["activeSignature"] = activeSignature;
1619
dict["activeParameter"] = activeParameter;
1620
return dict;
1621
}
1622
};
1623
1624
/**
1625
* A pattern to describe in which file operation requests or notifications
1626
* the server is interested in.
1627
*/
1628
struct FileOperationPattern {
1629
/**
1630
* The glob pattern to match.
1631
*/
1632
String glob = "**/*.gd";
1633
1634
/**
1635
* Whether to match `file`s or `folder`s with this pattern.
1636
*
1637
* Matches both if undefined.
1638
*/
1639
String matches = "file";
1640
1641
Dictionary to_json() const {
1642
Dictionary dict;
1643
1644
dict["glob"] = glob;
1645
dict["matches"] = matches;
1646
1647
return dict;
1648
}
1649
};
1650
1651
/**
1652
* A filter to describe in which file operation requests or notifications
1653
* the server is interested in.
1654
*/
1655
struct FileOperationFilter {
1656
/**
1657
* The actual file operation pattern.
1658
*/
1659
FileOperationPattern pattern;
1660
1661
Dictionary to_json() const {
1662
Dictionary dict;
1663
1664
dict["pattern"] = pattern.to_json();
1665
1666
return dict;
1667
}
1668
};
1669
1670
/**
1671
* The options to register for file operations.
1672
*/
1673
struct FileOperationRegistrationOptions {
1674
/**
1675
* The actual filters.
1676
*/
1677
Vector<FileOperationFilter> filters;
1678
1679
FileOperationRegistrationOptions() {
1680
filters.push_back(FileOperationFilter());
1681
}
1682
1683
Dictionary to_json() const {
1684
Dictionary dict;
1685
1686
Array filts;
1687
for (int i = 0; i < filters.size(); i++) {
1688
filts.push_back(filters[i].to_json());
1689
}
1690
dict["filters"] = filts;
1691
1692
return dict;
1693
}
1694
};
1695
1696
/**
1697
* The server is interested in file notifications/requests.
1698
*/
1699
struct FileOperations {
1700
/**
1701
* The server is interested in receiving didDeleteFiles file notifications.
1702
*/
1703
FileOperationRegistrationOptions didDelete;
1704
1705
Dictionary to_json() const {
1706
Dictionary dict;
1707
1708
dict["didDelete"] = didDelete.to_json();
1709
1710
return dict;
1711
}
1712
};
1713
1714
/**
1715
* Workspace specific server capabilities
1716
*/
1717
struct Workspace {
1718
/**
1719
* The server is interested in file notifications/requests.
1720
*/
1721
FileOperations fileOperations;
1722
1723
Dictionary to_json() const {
1724
Dictionary dict;
1725
1726
dict["fileOperations"] = fileOperations.to_json();
1727
1728
return dict;
1729
}
1730
};
1731
1732
struct ServerCapabilities {
1733
/**
1734
* Defines how text documents are synced. Is either a detailed structure defining each notification or
1735
* for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
1736
*/
1737
TextDocumentSyncOptions textDocumentSync;
1738
1739
/**
1740
* The server provides hover support.
1741
*/
1742
bool hoverProvider = true;
1743
1744
/**
1745
* The server provides completion support.
1746
*/
1747
CompletionOptions completionProvider;
1748
1749
/**
1750
* The server provides signature help support.
1751
*/
1752
SignatureHelpOptions signatureHelpProvider;
1753
1754
/**
1755
* The server provides goto definition support.
1756
*/
1757
bool definitionProvider = true;
1758
1759
/**
1760
* The server provides Goto Type Definition support.
1761
*
1762
* Since 3.6.0
1763
*/
1764
bool typeDefinitionProvider = false;
1765
1766
/**
1767
* The server provides Goto Implementation support.
1768
*
1769
* Since 3.6.0
1770
*/
1771
bool implementationProvider = false;
1772
1773
/**
1774
* The server provides find references support.
1775
*/
1776
bool referencesProvider = true;
1777
1778
/**
1779
* The server provides document highlight support.
1780
*/
1781
bool documentHighlightProvider = false;
1782
1783
/**
1784
* The server provides document symbol support.
1785
*/
1786
bool documentSymbolProvider = true;
1787
1788
/**
1789
* The server provides workspace symbol support.
1790
*/
1791
bool workspaceSymbolProvider = false;
1792
1793
/**
1794
* The server supports workspace folder.
1795
*/
1796
Workspace workspace;
1797
1798
/**
1799
* The server provides code actions. The `CodeActionOptions` return type is only
1800
* valid if the client signals code action literal support via the property
1801
* `textDocument.codeAction.codeActionLiteralSupport`.
1802
*/
1803
bool codeActionProvider = false;
1804
1805
/**
1806
* The server provides code lens.
1807
*/
1808
CodeLensOptions codeLensProvider;
1809
1810
/**
1811
* The server provides document formatting.
1812
*/
1813
bool documentFormattingProvider = false;
1814
1815
/**
1816
* The server provides document range formatting.
1817
*/
1818
bool documentRangeFormattingProvider = false;
1819
1820
/**
1821
* The server provides document formatting on typing.
1822
*/
1823
DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
1824
1825
/**
1826
* The server provides rename support. RenameOptions may only be
1827
* specified if the client states that it supports
1828
* `prepareSupport` in its initial `initialize` request.
1829
*/
1830
RenameOptions renameProvider;
1831
1832
/**
1833
* The server provides document link support.
1834
*/
1835
DocumentLinkOptions documentLinkProvider;
1836
1837
/**
1838
* The server provides color provider support.
1839
*
1840
* Since 3.6.0
1841
*/
1842
ColorProviderOptions colorProvider;
1843
1844
/**
1845
* The server provides folding provider support.
1846
*
1847
* Since 3.10.0
1848
*/
1849
FoldingRangeProviderOptions foldingRangeProvider;
1850
1851
/**
1852
* The server provides go to declaration support.
1853
*
1854
* Since 3.14.0
1855
*/
1856
bool declarationProvider = true;
1857
1858
/**
1859
* The server provides execute command support.
1860
*/
1861
ExecuteCommandOptions executeCommandProvider;
1862
1863
_FORCE_INLINE_ Dictionary to_json() {
1864
Dictionary dict;
1865
dict["textDocumentSync"] = textDocumentSync.to_json();
1866
dict["completionProvider"] = completionProvider.to_json();
1867
signatureHelpProvider.triggerCharacters.push_back(",");
1868
signatureHelpProvider.triggerCharacters.push_back("(");
1869
dict["signatureHelpProvider"] = signatureHelpProvider.to_json();
1870
//dict["codeLensProvider"] = codeLensProvider.to_json();
1871
dict["documentOnTypeFormattingProvider"] = documentOnTypeFormattingProvider.to_json();
1872
dict["renameProvider"] = renameProvider.to_json();
1873
dict["documentLinkProvider"] = documentLinkProvider.to_json();
1874
dict["colorProvider"] = false; // colorProvider.to_json();
1875
dict["foldingRangeProvider"] = false; //foldingRangeProvider.to_json();
1876
dict["executeCommandProvider"] = executeCommandProvider.to_json();
1877
dict["hoverProvider"] = hoverProvider;
1878
dict["definitionProvider"] = definitionProvider;
1879
dict["typeDefinitionProvider"] = typeDefinitionProvider;
1880
dict["implementationProvider"] = implementationProvider;
1881
dict["referencesProvider"] = referencesProvider;
1882
dict["documentHighlightProvider"] = documentHighlightProvider;
1883
dict["documentSymbolProvider"] = documentSymbolProvider;
1884
dict["workspaceSymbolProvider"] = workspaceSymbolProvider;
1885
dict["workspace"] = workspace.to_json();
1886
dict["codeActionProvider"] = codeActionProvider;
1887
dict["documentFormattingProvider"] = documentFormattingProvider;
1888
dict["documentRangeFormattingProvider"] = documentRangeFormattingProvider;
1889
dict["declarationProvider"] = declarationProvider;
1890
return dict;
1891
}
1892
};
1893
1894
struct InitializeResult {
1895
/**
1896
* The capabilities the language server provides.
1897
*/
1898
ServerCapabilities capabilities;
1899
1900
_FORCE_INLINE_ Dictionary to_json() {
1901
Dictionary dict;
1902
dict["capabilities"] = capabilities.to_json();
1903
return dict;
1904
}
1905
};
1906
1907
struct GodotNativeClassInfo {
1908
String name;
1909
const DocData::ClassDoc *class_doc = nullptr;
1910
const ClassDB::ClassInfo *class_info = nullptr;
1911
1912
Dictionary to_json() const {
1913
Dictionary dict;
1914
dict["name"] = name;
1915
dict["inherits"] = class_doc->inherits;
1916
return dict;
1917
}
1918
};
1919
1920
/** Features not included in the standard lsp specifications */
1921
struct GodotCapabilities {
1922
/**
1923
* Native class list
1924
*/
1925
List<GodotNativeClassInfo> native_classes;
1926
1927
Dictionary to_json() const {
1928
Dictionary dict;
1929
Array classes;
1930
for (const GodotNativeClassInfo &native_class : native_classes) {
1931
classes.push_back(native_class.to_json());
1932
}
1933
dict["native_classes"] = classes;
1934
return dict;
1935
}
1936
};
1937
1938
/** Format BBCode documentation from DocData to markdown */
1939
static String marked_documentation(const String &p_bbcode) {
1940
String markdown = p_bbcode.strip_edges();
1941
1942
Vector<String> lines = markdown.split("\n");
1943
bool in_code_block = false;
1944
int code_block_indent = -1;
1945
1946
markdown = "";
1947
for (int i = 0; i < lines.size(); i++) {
1948
String line = lines[i];
1949
int block_start = line.find("[codeblock]");
1950
if (block_start != -1) {
1951
code_block_indent = block_start;
1952
in_code_block = true;
1953
line = "\n";
1954
} else if (in_code_block) {
1955
line = "\t" + line.substr(code_block_indent);
1956
}
1957
1958
if (in_code_block && line.contains("[/codeblock]")) {
1959
line = "\n";
1960
in_code_block = false;
1961
}
1962
1963
if (!in_code_block) {
1964
line = line.strip_edges();
1965
line = line.replace("[code]", "`");
1966
line = line.replace("[/code]", "`");
1967
line = line.replace("[i]", "*");
1968
line = line.replace("[/i]", "*");
1969
line = line.replace("[b]", "**");
1970
line = line.replace("[/b]", "**");
1971
line = line.replace("[u]", "__");
1972
line = line.replace("[/u]", "__");
1973
line = line.replace("[method ", "`");
1974
line = line.replace("[member ", "`");
1975
line = line.replace("[signal ", "`");
1976
line = line.replace("[enum ", "`");
1977
line = line.replace("[constant ", "`");
1978
line = line.replace_chars("[]", '`');
1979
}
1980
1981
if (!in_code_block && i < lines.size() - 1) {
1982
line += "\n\n";
1983
} else if (i < lines.size() - 1) {
1984
line += "\n";
1985
}
1986
markdown += line;
1987
}
1988
return markdown;
1989
}
1990
} // namespace LSP
1991
1992