1 module served.protocol;
2 
3 import std.conv;
4 import std.json;
5 import std.traits;
6 
7 import painlessjson;
8 
9 struct Optional(T)
10 {
11 	bool isNull = true;
12 	T value;
13 
14 	this(T val)
15 	{
16 		value = val;
17 		isNull = false;
18 	}
19 
20 	this(U)(U val)
21 	{
22 		value = val;
23 		isNull = false;
24 	}
25 
26 	this(typeof(null))
27 	{
28 		isNull = true;
29 	}
30 
31 	void opAssign(typeof(null))
32 	{
33 		nullify();
34 	}
35 
36 	void opAssign(T val)
37 	{
38 		isNull = false;
39 		value = val;
40 	}
41 
42 	void opAssign(U)(U val)
43 	{
44 		isNull = false;
45 		value = val;
46 	}
47 
48 	void nullify()
49 	{
50 		isNull = true;
51 	}
52 
53 	string toString() const
54 	{
55 		if (isNull)
56 			return "null(" ~ T.stringof ~ ")";
57 		else
58 			return value.to!string;
59 	}
60 
61 	const JSONValue _toJSON()
62 	{
63 		if (isNull)
64 			return JSONValue(null);
65 		else
66 			return value.toJSON;
67 	}
68 
69 	static Optional!T _fromJSON(JSONValue val)
70 	{
71 		Optional!T ret;
72 		ret.isNull = false;
73 		ret.value = val.fromJSON!T;
74 		return ret;
75 	}
76 
77 	ref T get()
78 	{
79 		return value;
80 	}
81 
82 	alias value this;
83 }
84 
85 Optional!T opt(T)(T val)
86 {
87 	return Optional!T(val);
88 }
89 
90 struct ArrayOrSingle(T)
91 {
92 	T[] value;
93 
94 	this(T val)
95 	{
96 		value = [val];
97 	}
98 
99 	this(T[] val)
100 	{
101 		value = val;
102 	}
103 
104 	void opAssign(T val)
105 	{
106 		value = [val];
107 	}
108 
109 	void opAssign(T[] val)
110 	{
111 		value = val;
112 	}
113 
114 	const JSONValue _toJSON()
115 	{
116 		if (value.length == 1)
117 			return value[0].toJSON;
118 		else
119 			return value.toJSON;
120 	}
121 
122 	static ArrayOrSingle!T fromJSON(JSONValue val)
123 	{
124 		ArrayOrSingle!T ret;
125 		if (val.type == JSON_TYPE.ARRAY)
126 			ret.value = val.fromJSON!(T[]);
127 		else
128 			ret.value = [val.fromJSON!T];
129 		return ret;
130 	}
131 
132 	alias value this;
133 }
134 
135 struct RequestToken
136 {
137 	this(const(JSONValue)* val)
138 	{
139 		if (!val)
140 		{
141 			hasData = false;
142 			return;
143 		}
144 		hasData = true;
145 		if (val.type == JSON_TYPE.STRING)
146 		{
147 			isString = true;
148 			str = val.str;
149 		}
150 		else if (val.type == JSON_TYPE.INTEGER)
151 		{
152 			isString = false;
153 			num = val.integer;
154 		}
155 		else
156 			throw new Exception("Invalid ID");
157 	}
158 
159 	union
160 	{
161 		string str;
162 		long num;
163 	}
164 
165 	bool hasData, isString;
166 
167 	JSONValue toJSON()
168 	{
169 		JSONValue ret = null;
170 		if (!hasData)
171 			return ret;
172 		ret = isString ? JSONValue(str) : JSONValue(num);
173 		return ret;
174 	}
175 
176 	JSONValue _toJSON()()
177 	{
178 		pragma(msg, "Attempted painlesstraits.toJSON on RequestToken");
179 	}
180 
181 	void _fromJSON()(JSONValue val)
182 	{
183 		pragma(msg, "Attempted painlesstraits.fromJSON on RequestToken");
184 	}
185 
186 	string toString()
187 	{
188 		return hasData ? (isString ? str : num.to!string) : "none";
189 	}
190 
191 	static RequestToken random()
192 	{
193 		import std.uuid;
194 
195 		JSONValue id = JSONValue(randomUUID.toString);
196 		return RequestToken(&id);
197 	}
198 
199 	bool opEquals(RequestToken b) const
200 	{
201 		return isString == b.isString && (isString ? str == b.str : num == b.num);
202 	}
203 }
204 
205 struct RequestMessage
206 {
207 	this(JSONValue val)
208 	{
209 		id = RequestToken("id" in val);
210 		method = val["method"].str;
211 		auto ptr = "params" in val;
212 		if (ptr)
213 			params = *ptr;
214 	}
215 
216 	RequestToken id;
217 	string method;
218 	JSONValue params;
219 
220 	bool isCancelRequest()
221 	{
222 		return method == "$/cancelRequest";
223 	}
224 
225 	JSONValue toJSON()
226 	{
227 		auto ret = JSONValue(["jsonrpc" : JSONValue("2.0"), "method" : JSONValue(method)]);
228 		if (!params.isNull)
229 			ret["params"] = params;
230 		if (id.hasData)
231 			ret["id"] = id.toJSON;
232 		return ret;
233 	}
234 }
235 
236 enum ErrorCode
237 {
238 	parseError = -32700,
239 	invalidRequest = -32600,
240 	methodNotFound = -32601,
241 	invalidParams = -32602,
242 	internalError = -32603,
243 	serverErrorStart = -32099,
244 	serverErrorEnd = -32000,
245 	serverNotInitialized = -32002,
246 	unknownErrorCode = -32001
247 }
248 
249 enum MessageType
250 {
251 	error = 1,
252 	warning,
253 	info,
254 	log
255 }
256 
257 struct ResponseError
258 {
259 	ErrorCode code;
260 	string message;
261 	JSONValue data;
262 
263 	this(Throwable t)
264 	{
265 		code = ErrorCode.unknownErrorCode;
266 		message = t.msg;
267 		data = JSONValue(t.to!string);
268 	}
269 
270 	this(ErrorCode c)
271 	{
272 		code = c;
273 		message = c.to!string;
274 	}
275 
276 	this(ErrorCode c, string msg)
277 	{
278 		code = c;
279 		message = msg;
280 	}
281 }
282 
283 class MethodException : Exception
284 {
285 	this(ResponseError error, string file = __FILE__, size_t line = __LINE__) pure nothrow @nogc @safe
286 	{
287 		super(error.message, file, line);
288 		this.error = error;
289 	}
290 
291 	ResponseError error;
292 }
293 
294 struct ResponseMessage
295 {
296 	this(RequestToken id, JSONValue result)
297 	{
298 		this.id = id;
299 		this.result = result;
300 	}
301 
302 	this(RequestToken id, ResponseError error)
303 	{
304 		this.id = id;
305 		this.error = error;
306 	}
307 
308 	RequestToken id;
309 	JSONValue result;
310 	Optional!ResponseError error;
311 }
312 
313 alias DocumentUri = string;
314 
315 enum EolType
316 {
317 	cr,
318 	lf,
319 	crlf
320 }
321 
322 string toString(EolType eol)
323 {
324 	final switch (eol)
325 	{
326 	case EolType.cr:
327 		return "\r";
328 	case EolType.lf:
329 		return "\n";
330 	case EolType.crlf:
331 		return "\r\n";
332 	}
333 }
334 
335 struct Position
336 {
337 	uint line, character;
338 }
339 
340 struct TextRange
341 {
342 	union
343 	{
344 		struct
345 		{
346 			Position start;
347 			Position end;
348 		}
349 
350 		Position[2] range;
351 	}
352 
353 	alias range this;
354 
355 	this(Num)(Num startLine, Num startCol, Num endLine, Num endCol) if (isNumeric!Num)
356 	{
357 		this(Position(cast(uint) startLine, cast(uint) startCol),
358 				Position(cast(uint) endLine, cast(uint) endCol));
359 	}
360 
361 	this(Position start, Position end)
362 	{
363 		this.start = start;
364 		this.end = end;
365 	}
366 
367 	this(Position[2] range)
368 	{
369 		this.range = range;
370 	}
371 
372 	this(Position pos)
373 	{
374 		this.start = pos;
375 		this.end = pos;
376 	}
377 }
378 
379 struct Location
380 {
381 	DocumentUri uri;
382 	TextRange range;
383 }
384 
385 struct Diagnostic
386 {
387 	TextRange range;
388 	DiagnosticSeverity severity;
389 	JSONValue code;
390 	string source;
391 	string message;
392 }
393 
394 enum DiagnosticSeverity
395 {
396 	error = 1,
397 	warning,
398 	information,
399 	hint
400 }
401 
402 struct Command
403 {
404 	string title;
405 	string command;
406 	JSONValue[] arguments;
407 }
408 
409 struct TextEdit
410 {
411 	TextRange range;
412 	string newText;
413 }
414 
415 alias TextEditCollection = TextEdit[];
416 
417 struct WorkspaceEdit
418 {
419 	TextEditCollection[DocumentUri] changes;
420 }
421 
422 struct TextDocumentIdentifier
423 {
424 	DocumentUri uri;
425 }
426 
427 struct VersionedTextDocumentIdentifier
428 {
429 	DocumentUri uri;
430 	@SerializedName("version") long version_;
431 }
432 
433 struct TextDocumentItem
434 {
435 	DocumentUri uri;
436 	string languageId;
437 	@SerializedName("version") long version_;
438 	string text;
439 }
440 
441 struct TextDocumentPositionParams
442 {
443 	TextDocumentIdentifier textDocument;
444 	Position position;
445 }
446 
447 struct DocumentFilter
448 {
449 	Optional!string language;
450 	Optional!string scheme;
451 	Optional!string pattern;
452 }
453 
454 alias DocumentSelector = DocumentFilter[];
455 
456 struct InitializeParams
457 {
458 	int processId;
459 	string rootPath;
460 	DocumentUri rootUri;
461 	JSONValue initializationOptions;
462 	ClientCapabilities capabilities;
463 	string trace = "off";
464 	WorkspaceFolder[] workspaceFolders;
465 }
466 
467 struct DynamicRegistration
468 {
469 	Optional!bool dynamicRegistration;
470 }
471 
472 struct WorkspaceClientCapabilities
473 {
474 	bool applyEdit;
475 	Optional!DynamicRegistration didChangeConfiguration;
476 	Optional!DynamicRegistration didChangeWatchedFiles;
477 	Optional!DynamicRegistration symbol;
478 	Optional!DynamicRegistration executeCommand;
479 	Optional!bool workspaceFolders;
480 	Optional!bool configuration;
481 }
482 
483 struct TextDocumentClientCapabilities
484 {
485 	struct SyncInfo
486 	{
487 		Optional!bool dynamicRegistration;
488 		bool willSave;
489 		bool willSaveWaitUntil;
490 		bool didSave;
491 	}
492 
493 	struct CompletionInfo
494 	{
495 		struct CompletionItem
496 		{
497 			bool snippetSupport;
498 		}
499 
500 		CompletionItem completionItem;
501 	}
502 
503 	struct PublishDiagnosticsCap
504 	{
505 		Optional!bool relatedInformation;
506 	}
507 
508 	Optional!SyncInfo synchronization;
509 	Optional!CompletionInfo completion;
510 	Optional!DynamicRegistration hover;
511 	Optional!DynamicRegistration signatureHelp;
512 	Optional!DynamicRegistration references;
513 	Optional!DynamicRegistration documentHighlight;
514 	Optional!DynamicRegistration documentSymbol;
515 	Optional!DynamicRegistration formatting;
516 	Optional!DynamicRegistration rangeFormatting;
517 	Optional!DynamicRegistration onTypeFormatting;
518 	Optional!DynamicRegistration definition;
519 	Optional!DynamicRegistration typeDefinition;
520 	Optional!DynamicRegistration implementation;
521 	Optional!DynamicRegistration codeAction;
522 	Optional!DynamicRegistration codeLens;
523 	Optional!DynamicRegistration documentLink;
524 	Optional!DynamicRegistration colorProvider;
525 	Optional!DynamicRegistration rename;
526 	Optional!PublishDiagnosticsCap publishDiagnostics;
527 }
528 
529 struct ClientCapabilities
530 {
531 	Optional!WorkspaceClientCapabilities workspace;
532 	Optional!TextDocumentClientCapabilities textDocument;
533 	JSONValue experimental;
534 }
535 
536 unittest
537 {
538 	string json = q{{
539 		"workspace": {
540 			"configuration": true
541 		}
542 	}};
543 	auto caps = json.parseJSON.fromJSON!ClientCapabilities;
544 	assert(caps.workspace.configuration);
545 }
546 
547 struct InitializeResult
548 {
549 	ServerCapabilities capabilities;
550 }
551 
552 struct InitializeError
553 {
554 	bool retry;
555 }
556 
557 enum TextDocumentSyncKind
558 {
559 	none,
560 	full,
561 	incremental
562 }
563 
564 struct CompletionOptions
565 {
566 	bool resolveProvider;
567 	string[] triggerCharacters;
568 }
569 
570 struct SignatureHelpOptions
571 {
572 	string[] triggerCharacters;
573 }
574 
575 struct CodeLensOptions
576 {
577 	bool resolveProvider;
578 }
579 
580 struct DocumentOnTypeFormattingOptions
581 {
582 	string firstTriggerCharacter;
583 	Optional!(string[]) moreTriggerCharacter;
584 }
585 
586 struct DocumentLinkOptions
587 {
588 	bool resolveProvider;
589 }
590 
591 struct ColorProviderOptions
592 {
593 }
594 
595 struct ExecuteCommandOptions
596 {
597 	string[] commands;
598 }
599 
600 struct SaveOptions
601 {
602 	bool includeText;
603 }
604 
605 struct TextDocumentSyncOptions
606 {
607 	bool openClose;
608 	int change;
609 	bool willSave;
610 	bool willSaveWaitUntil;
611 	SaveOptions save;
612 }
613 
614 struct ServerCapabilities
615 {
616 	JSONValue textDocumentSync;
617 	bool hoverProvider;
618 	Optional!CompletionOptions completionProvider;
619 	Optional!SignatureHelpOptions signatureHelpProvider;
620 	bool definitionProvider;
621 	Optional!bool typeDefinitionProvider;
622 	Optional!bool implementationProvider;
623 	bool referencesProvider;
624 	bool documentHighlightProvider;
625 	bool documentSymbolProvider;
626 	bool workspaceSymbolProvider;
627 	bool codeActionProvider;
628 	Optional!CodeLensOptions codeLensProvider;
629 	bool documentFormattingProvider;
630 	bool documentRangeFormattingProvider;
631 	Optional!DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
632 	bool renameProvider;
633 	Optional!DocumentLinkOptions documentLinkProvider;
634 	Optional!ColorProviderOptions colorProvider;
635 	Optional!ExecuteCommandOptions executeCommandProvider;
636 	Optional!ServerWorkspaceCapabilities workspace;
637 	JSONValue experimental;
638 }
639 
640 struct ServerWorkspaceCapabilities
641 {
642 	struct WorkspaceFolders
643 	{
644 		Optional!bool supported;
645 		Optional!bool changeNotifications;
646 	}
647 
648 	Optional!WorkspaceFolders workspaceFolders;
649 }
650 
651 struct ShowMessageParams
652 {
653 	MessageType type;
654 	string message;
655 }
656 
657 struct ShowMessageRequestParams
658 {
659 	MessageType type;
660 	string message;
661 	Optional!(MessageActionItem[]) actions;
662 }
663 
664 struct MessageActionItem
665 {
666 	string title;
667 }
668 
669 struct LogMessageParams
670 {
671 	MessageType type;
672 	string message;
673 }
674 
675 struct Registration
676 {
677 	string id;
678 	string method;
679 	JSONValue registerOptions;
680 }
681 
682 struct RegistrationParams
683 {
684 	Registration[] registrations;
685 }
686 
687 struct TextDocumentRegistrationOptions
688 {
689 	Optional!DocumentSelector documentSelector;
690 }
691 
692 struct Unregistration
693 {
694 	string id;
695 	string method;
696 }
697 
698 struct UnregistrationParams
699 {
700 	Unregistration[] unregistrations;
701 }
702 
703 struct DidChangeConfigurationParams
704 {
705 	JSONValue settings;
706 }
707 
708 struct ConfigurationParams
709 {
710 	ConfigurationItem[] items;
711 }
712 
713 struct ConfigurationItem
714 {
715 	Optional!string scopeUri;
716 	Optional!string section;
717 }
718 
719 struct DidOpenTextDocumentParams
720 {
721 	TextDocumentItem textDocument;
722 }
723 
724 struct DidChangeTextDocumentParams
725 {
726 	VersionedTextDocumentIdentifier textDocument;
727 	TextDocumentContentChangeEvent[] contentChanges;
728 }
729 
730 struct TextDocumentContentChangeEvent
731 {
732 	Optional!TextRange range;
733 	Optional!int rangeLength;
734 	string text;
735 }
736 
737 struct TextDocumentChangeRegistrationOptions
738 {
739 	Optional!DocumentSelector documentSelector;
740 	TextDocumentSyncKind syncKind;
741 }
742 
743 struct WillSaveTextDocumentParams
744 {
745 	TextDocumentIdentifier textDocument;
746 	TextDocumentSaveReason reason;
747 }
748 
749 enum TextDocumentSaveReason
750 {
751 	manual = 1,
752 	afterDelay,
753 	focusOut
754 }
755 
756 struct DidSaveTextDocumentParams
757 {
758 	TextDocumentIdentifier textDocument;
759 	Optional!string text;
760 }
761 
762 struct TextDocumentSaveRegistrationOptions
763 {
764 	Optional!DocumentSelector documentSelector;
765 	bool includeText;
766 }
767 
768 struct DidCloseTextDocumentParams
769 {
770 	TextDocumentIdentifier textDocument;
771 }
772 
773 struct DidChangeWatchedFilesParams
774 {
775 	FileEvent[] changes;
776 }
777 
778 struct FileEvent
779 {
780 	DocumentUri uri;
781 	FileChangeType type;
782 }
783 
784 enum FileChangeType
785 {
786 	created = 1,
787 	changed,
788 	deleted
789 }
790 
791 struct PublishDiagnosticsParams
792 {
793 	DocumentUri uri;
794 	Diagnostic[] diagnostics;
795 }
796 
797 struct CompletionList
798 {
799 	bool isIncomplete;
800 	CompletionItem[] items;
801 }
802 
803 enum InsertTextFormat
804 {
805 	plainText = 1,
806 	snippet
807 }
808 
809 struct CompletionItem
810 {
811 	string label;
812 	Optional!CompletionItemKind kind;
813 	Optional!string detail;
814 	Optional!MarkupContent documentation;
815 	Optional!string sortText;
816 	Optional!string filterText;
817 	Optional!string insertText;
818 	Optional!InsertTextFormat insertTextFormat;
819 	Optional!TextEdit textEdit;
820 	Optional!(TextEdit[]) additionalTextEdits;
821 	Optional!Command command;
822 	JSONValue data;
823 }
824 
825 enum CompletionItemKind
826 {
827 	text = 1,
828 	method,
829 	function_,
830 	constructor,
831 	field,
832 	variable,
833 	class_,
834 	interface_,
835 	module_,
836 	property,
837 	unit,
838 	value,
839 	enum_,
840 	keyword,
841 	snippet,
842 	color,
843 	file,
844 	reference
845 }
846 
847 struct CompletionRegistrationOptions
848 {
849 	Optional!DocumentSelector documentSelector;
850 	Optional!(string[]) triggerCharacters;
851 	bool resolveProvider;
852 }
853 
854 struct Hover
855 {
856 	ArrayOrSingle!MarkedString contents;
857 	Optional!TextRange range;
858 }
859 
860 struct MarkedString
861 {
862 	string value;
863 	string language;
864 
865 	const JSONValue _toJSON()
866 	{
867 		if (!language.length)
868 			return JSONValue(value);
869 		else
870 			return JSONValue(["value" : JSONValue(value), "language" : JSONValue(language)]);
871 	}
872 
873 	static MarkedString fromJSON(JSONValue val)
874 	{
875 		MarkedString ret;
876 		if (val.type == JSON_TYPE.STRING)
877 			ret.value = val.str;
878 		else
879 		{
880 			ret.value = val["value"].str;
881 			ret.language = val["language"].str;
882 		}
883 		return ret;
884 	}
885 }
886 
887 enum MarkupKind : string
888 {
889 	plaintext = "plaintext",
890 	markdown = "markdown"
891 }
892 
893 struct MarkupContent
894 {
895 	MarkupKind kind;
896 	string value;
897 
898 	this(string text)
899 	{
900 		kind = MarkupKind.plaintext;
901 		value = text;
902 	}
903 
904 	this(MarkedString[] markup)
905 	{
906 		kind = MarkupKind.markdown;
907 		foreach (block; markup)
908 		{
909 			if (block.language.length)
910 			{
911 				value ~= "```" ~ block.language ~ "\n";
912 				value ~= block.value;
913 				value ~= "```";
914 			}
915 			else
916 				value ~= block.value;
917 			value ~= "\n\n";
918 		}
919 	}
920 }
921 
922 struct SignatureHelp
923 {
924 	SignatureInformation[] signatures;
925 	Optional!int activeSignature;
926 	Optional!int activeParameter;
927 
928 	this(SignatureInformation[] signatures)
929 	{
930 		this.signatures = signatures;
931 	}
932 
933 	this(SignatureInformation[] signatures, int activeSignature, int activeParameter)
934 	{
935 		this.signatures = signatures;
936 		this.activeSignature = activeSignature;
937 		this.activeParameter = activeParameter;
938 	}
939 }
940 
941 struct SignatureInformation
942 {
943 	string label;
944 	Optional!MarkupContent documentation;
945 	Optional!(ParameterInformation[]) parameters;
946 }
947 
948 struct ParameterInformation
949 {
950 	string label;
951 	Optional!MarkupContent documentation;
952 }
953 
954 struct SignatureHelpRegistrationOptions
955 {
956 	Optional!DocumentSelector documentSelector;
957 	Optional!(string[]) triggerCharacters;
958 }
959 
960 struct ReferenceParams
961 {
962 	TextDocumentIdentifier textDocument;
963 	Position position;
964 	ReferenceContext context;
965 }
966 
967 struct ReferenceContext
968 {
969 	bool includeDeclaration;
970 }
971 
972 struct DocumentHighlight
973 {
974 	TextRange range;
975 	Optional!DocumentHighlightKind kind;
976 }
977 
978 enum DocumentHighlightKind
979 {
980 	text = 1,
981 	read,
982 	write
983 }
984 
985 struct DocumentSymbolParams
986 {
987 	TextDocumentIdentifier textDocument;
988 }
989 
990 struct SymbolInformation
991 {
992 	string name;
993 	SymbolKind kind;
994 	Location location;
995 	Optional!string containerName;
996 }
997 
998 enum SymbolKind
999 {
1000 	file = 1,
1001 	module_,
1002 	namespace,
1003 	package_,
1004 	class_,
1005 	method,
1006 	property,
1007 	field,
1008 	constructor,
1009 	enum_,
1010 	interface_,
1011 	function_,
1012 	variable,
1013 	constant,
1014 	string,
1015 	number,
1016 	boolean,
1017 	array
1018 }
1019 
1020 struct WorkspaceSymbolParams
1021 {
1022 	string query;
1023 }
1024 
1025 struct CodeActionParams
1026 {
1027 	TextDocumentIdentifier textDocument;
1028 	TextRange range;
1029 	CodeActionContext context;
1030 }
1031 
1032 struct CodeActionContext
1033 {
1034 	Diagnostic[] diagnostics;
1035 }
1036 
1037 struct CodeLensParams
1038 {
1039 	TextDocumentIdentifier textDocument;
1040 }
1041 
1042 struct CodeLens
1043 {
1044 	TextRange range;
1045 	Optional!Command command;
1046 	JSONValue data;
1047 }
1048 
1049 struct CodeLensRegistrationOptions
1050 {
1051 	Optional!DocumentSelector documentSelector;
1052 	bool resolveProvider;
1053 }
1054 
1055 struct DocumentLinkParams
1056 {
1057 	TextDocumentIdentifier textDocument;
1058 }
1059 
1060 struct DocumentLink
1061 {
1062 	TextRange range;
1063 	DocumentUri target;
1064 }
1065 
1066 struct DocumentLinkRegistrationOptions
1067 {
1068 	Optional!DocumentSelector documentSelector;
1069 	bool resolveProvider;
1070 }
1071 
1072 struct DocumentFormattingParams
1073 {
1074 	TextDocumentIdentifier textDocument;
1075 	FormattingOptions options;
1076 }
1077 
1078 struct FormattingOptions
1079 {
1080 	int tabSize;
1081 	bool insertSpaces;
1082 	JSONValue data;
1083 }
1084 
1085 struct DocumentRangeFormattingParams
1086 {
1087 	TextDocumentIdentifier textDocument;
1088 	TextRange range;
1089 	FormattingOptions options;
1090 }
1091 
1092 struct DocumentOnTypeFormattingParams
1093 {
1094 	TextDocumentIdentifier textDocument;
1095 	Position position;
1096 	string ch;
1097 	FormattingOptions options;
1098 }
1099 
1100 struct DocumentOnTypeFormattingRegistrationOptions
1101 {
1102 	Optional!DocumentSelector documentSelector;
1103 	string firstTriggerCharacter;
1104 	Optional!(string[]) moreTriggerCharacter;
1105 }
1106 
1107 struct RenameParams
1108 {
1109 	TextDocumentIdentifier textDocument;
1110 	Position position;
1111 	string newName;
1112 }
1113 
1114 struct ExecuteCommandParams
1115 {
1116 	string command;
1117 	Optional!(JSONValue[]) arguments;
1118 }
1119 
1120 struct ExecuteCommandRegistrationOptions
1121 {
1122 	string[] commands;
1123 }
1124 
1125 struct ApplyWorkspaceEditParams
1126 {
1127 	WorkspaceEdit edit;
1128 }
1129 
1130 struct ApplyWorkspaceEditResponse
1131 {
1132 	bool applied;
1133 }
1134 
1135 struct WorkspaceFolder
1136 {
1137 	string uri;
1138 	string name;
1139 }
1140 
1141 struct DidChangeWorkspaceFoldersParams
1142 {
1143 	WorkspaceFoldersChangeEvent event;
1144 }
1145 
1146 struct WorkspaceFoldersChangeEvent
1147 {
1148 	WorkspaceFolder[] added;
1149 	WorkspaceFolder[] removed;
1150 }