use jsonrpc_core::Value;
use lsp_msg_derive::{lsp_object, lsp_kind};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
#[lsp_kind]
#[serde(untagged)]
pub enum Elective<T> {
Absent,
Present(T)
}
impl<T> Elective<T> {
fn is_absent(&self) -> bool {
match self {
Elective::Absent => true,
Elective::Present(_) => false,
}
}
}
impl<T> Default for Elective<T> {
fn default() -> Self {
Elective::Absent
}
}
#[lsp_object]
pub struct InitializeParams {
pub process_id: Option<u64>,
pub root_path: Elective<Option<String>>,
pub root_uri: Option<String>,
pub initialization_options: Elective<Value>,
pub capabilities: ClientCapabilities,
#[serde(default)]
pub trace: TraceKind,
pub workspace_folders: Elective<Option<Vec<WorkspaceFolder>>>
}
#[lsp_object(allow_missing)]
pub struct ClientCapabilities {
workspace: WorkspaceClientCapabilities,
text_document: TextDocumentClientCapabilities,
experimental: Elective<Value>,
}
#[lsp_object(allow_missing)]
struct WorkspaceClientCapabilities {
apply_edit: bool,
workspace_edit: WorkspaceEditCapabilities,
did_change_configuration: DidChangeConfigurationCapabilities,
did_change_watched_files: DidChangeWatchedFilesCapabilities,
symbol: SymbolCapabilities,
execute_command: ExecuteCommandCapabilities,
workspace_folders: bool,
configuration: bool,
}
#[lsp_object(allow_missing)]
struct TextDocumentClientCapabilities {
synchronization: SynchronizationCapabilities,
completion: CompletionCapabilities,
hover: HoverCapabilities,
signature_help: SignatureHelpCapabilities,
references: ReferencesCapabilities,
document_highlight: DocumentHighlightCapabilities,
document_symbol: DocumentSymbolCapabilities,
formatting: FormattingCapabilities,
range_formatting: RangeFormattingCapabilities,
on_type_formatting: OnTypeFormattingCapabilities,
declaration: DeclarationCapabilities,
definition: DefinitionCapabilities,
type_definition: TypeDefinitionCapabilities,
implementation: ImplementationCapabilities,
code_action: CodeActionCapabilities,
code_lens: CodeLensCapabilities,
document_link: DocumentLinkCapabilities,
color_provider: ColorProviderCapabilities,
rename: RenameCapabilities,
publish_diagnostics: PublishDiagnosticsCapabilities,
folding_range: FoldingRangeCapabilities,
}
#[lsp_object(allow_missing)]
struct WorkspaceEditCapabilities {
document_changes: bool,
resource_operations: Elective<Vec<ResourceOperationKind>>,
failure_handling: Elective<FailureHandlingKind>,
}
#[lsp_object(allow_missing, dynamic_registration = "`workspace/didChangeConfiguration` notification")]
struct DidChangeConfigurationCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`workspace/didChangeWatchedFiles` notification")]
struct DidChangeWatchedFilesCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`workspace/symbol` request")]
struct SymbolCapabilities {
symbol_kind: SymbolKindCapabilities,
}
#[lsp_object(allow_missing, dynamic_registration = "`workspace/executeCommand` request")]
struct ExecuteCommandCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "text document synchronization")]
struct SynchronizationCapabilities {
will_save: bool,
will_save_until: bool,
did_save: bool,
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/completion` request")]
struct CompletionCapabilities {
completion_item: CompletionItemCapabilities,
completion_item_kind: CompletionItemKindCapabilities,
context_support: bool,
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/hover` request", markup_kind_list = "content")]
struct HoverCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/signatureHelp` request")]
struct SignatureHelpCapabilities {
signature_information: SignatureInformationCapabilities,
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/references` request")]
struct ReferencesCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/documentHighlight` request")]
struct DocumentHighlightCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/documentSymbol` request")]
struct DocumentSymbolCapabilities {
symbol_kind: SymbolKindCapabilities,
hierarchical_document_symbol_support: bool,
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/formatting` request")]
struct FormattingCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/rangeFormatting` request")]
struct RangeFormattingCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/onTypeFormatting` request")]
struct OnTypeFormattingCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/declaration` request", link_support = "declaration")]
struct DeclarationCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/definition` request", link_support = "definition")]
struct DefinitionCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/typeDefinition` request", link_support = "definition")]
struct TypeDefinitionCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/implementation` request", link_support = "implementation")]
struct ImplementationCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/codeAction` request")]
struct CodeActionCapabilities {
code_action_literal_support: Elective<CodeActionLiteralCapabilities>,
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/codeLens` request")]
struct CodeLensCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/documentLink` request")]
struct DocumentLinkCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "color provider")]
struct ColorProviderCapabilities {
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/rename` request")]
struct RenameCapabilities {
prepare_support: bool,
}
#[lsp_object(allow_missing)]
struct PublishDiagnosticsCapabilities {
related_information: bool,
}
#[lsp_object(allow_missing, dynamic_registration = "`textDocument/foldingRange` request")]
struct FoldingRangeCapabilities {
range_limit: u64,
line_folding_only: bool,
}
#[lsp_kind]
enum ResourceOperationKind {
Create,
Rename,
Delete,
}
#[lsp_kind]
enum FailureHandlingKind {
Abort,
Transactional,
TextOnlyTransactional,
Undo,
}
#[lsp_object(allow_missing)]
struct SymbolKindCapabilities {
value_set: Elective<Vec<u64>>,
}
#[lsp_object(allow_missing, markup_kind_list = "documentation")]
struct CompletionItemCapabilities {
snippet_support: bool,
commit_characters_support: bool,
deprecated_support: bool,
preselect_support: bool,
}
#[lsp_object(allow_missing)]
struct CompletionItemKindCapabilities {
value_set: Elective<Vec<u64>>,
}
#[lsp_kind]
enum MarkupKind {
Plaintext,
Markdown,
}
#[lsp_object(allow_missing, markup_kind_list = "documentation")]
struct SignatureInformationCapabilities {
parameter_information: ParameterInformationCapabilities,
}
#[lsp_object(allow_missing)]
struct CodeActionLiteralCapabilities {
code_action_kind: CodeActionKindCapabilities,
}
#[lsp_kind]
enum SymbolKind {
File = 1,
Module,
Namespace,
Package,
Class,
Method,
Property,
Field,
Constructor,
Enum,
Interface,
Function,
Variable,
Constant,
String,
Number,
Boolean,
Array,
Object,
Key,
Null,
EnumMember,
Struct,
Event,
Operator,
TypeParameter,
}
#[lsp_kind]
enum CompletionItemKind {
Text = 1,
Method,
Function,
Constructor,
Field,
Variable,
Class,
Interface,
Module,
Property,
Unit,
Value,
Enum,
Keyword,
Snippet,
Color,
File,
Reference,
Folder,
EnumMember,
Constant,
Struct,
Event,
Operator,
TypeParameter,
}
#[lsp_object(allow_missing)]
struct ParameterInformationCapabilities {
label_offset_support: bool,
}
#[lsp_object(allow_missing)]
struct CodeActionKindCapabilities {
value_set: Elective<Vec<String>>,
}
#[lsp_kind]
pub enum TraceKind {
Off,
Messages,
Verbose,
}
impl Default for TraceKind {
fn default() -> Self {
TraceKind::Off
}
}
#[lsp_object]
pub struct WorkspaceFolder {
uri: String,
name: String,
}
#[lsp_object]
pub struct InitializeResult {
pub capabilities: ServerCapabilities,
}
#[lsp_object(allow_missing)]
pub struct ServerCapabilities {
text_document_sync: TextDocumentSyncProvider,
hover_provider: bool,
completion_provider: CompletionOptions,
signature_help_provider: SignatureHelpOptions,
definition_provider: bool,
type_definition_provider: BooleanOrOptions<GotoOptions>,
implementation_provider: BooleanOrOptions<GotoOptions>,
references_provider: bool,
document_highlight_provider: bool,
document_symbol_provider: bool,
workspace_symbol_provider: bool,
code_action_provider: BooleanOrOptions<CodeActionOptions>,
code_lens_provider: CodeLensOptions,
document_formatting_provider: bool,
document_range_formatting_provider: bool,
document_on_type_formatting_provider: DocumentOnTypeFormattingOptions,
rename_provider: BooleanOrOptions<RenameOptions>,
document_link_provider: DocumentLinkOptions,
color_provider: BooleanOrOptionsOrStaticDocumentSelectorOptions<ColorProviderOptions>,
folding_range_provider: BooleanOrOptionsOrStaticDocumentSelectorOptions<FoldingRangeProviderOptions>,
declaration_provider: BooleanOrOptions<GotoOptions>,
execute_command_provider: ExecuteCommandOptions,
workspace: WorkspaceOptions,
experimental: Elective<Value>,
}
#[lsp_kind]
#[serde(untagged)]
pub enum TextDocumentSyncProvider {
Options(TextDocumentSyncOptions),
Kind(TextDocumentSyncKind),
}
impl Default for TextDocumentSyncProvider {
fn default() -> Self {
TextDocumentSyncProvider::Kind(TextDocumentSyncKind::default())
}
}
#[lsp_kind(number)]
pub enum TextDocumentSyncKind {
None = 0,
Full,
Incremental,
}
impl Default for TextDocumentSyncKind {
fn default() -> Self {
TextDocumentSyncKind::None
}
}
#[lsp_object(allow_missing, triggers = "completion", resolve_provider = "completion")]
struct CompletionOptions {
}
#[lsp_object(allow_missing, triggers = "signature help")]
struct SignatureHelpOptions {
}
#[lsp_object(document_selector, static_registration)]
struct GotoOptions {
}
#[lsp_kind]
#[serde(untagged)]
enum BooleanOrOptions<T> {
Boolean(bool),
Options(T),
}
impl<T> Default for BooleanOrOptions<T> {
fn default() -> Self {
BooleanOrOptions::Boolean(false)
}
}
#[lsp_object(allow_missing)]
struct CodeActionOptions {
code_action_kinds: Vec<String>,
}
#[lsp_object(allow_missing, resolve_provider = "code lens")]
struct CodeLensOptions {
}
#[lsp_object]
struct DocumentOnTypeFormattingOptions {
first_trigger_character: String,
#[serde(default)]
more_trigger_character: Vec<String>,
}
#[lsp_object(allow_missing)]
struct RenameOptions {
prepare_provider: bool,
}
#[lsp_object(allow_missing, resolve_provider = "document links")]
struct DocumentLinkOptions {
}
#[lsp_object(document_selector, static_registration)]
struct StaticDocumentSelectorOptions<T> {
options: T,
}
#[lsp_object]
struct ColorProviderOptions {
}
#[lsp_object]
struct FoldingRangeProviderOptions {
}
#[lsp_kind]
#[serde(untagged)]
enum BooleanOrOptionsOrStaticDocumentSelectorOptions<T> {
Boolean(bool),
Options(T),
StaticDocumentSelectorOptions(StaticDocumentSelectorOptions<T>),
}
impl<T> Default for BooleanOrOptionsOrStaticDocumentSelectorOptions<T> {
fn default() -> Self {
BooleanOrOptionsOrStaticDocumentSelectorOptions::Boolean(false)
}
}
#[lsp_object]
struct ExecuteCommandOptions {
commands: Vec<String>,
}
#[lsp_object(allow_missing)]
struct WorkspaceOptions {
workspace_folders: WorkspaceFoldersOptions,
}
#[lsp_object(allow_missing)]
pub struct TextDocumentSyncOptions {
open_close: bool,
change: TextDocumentSyncKind,
will_save: bool,
will_save_wait_until: bool,
save: SaveOptions,
}
#[lsp_object(allow_missing)]
struct WorkspaceFoldersOptions {
supported: bool,
change_notifications: ChangeNotificationsOptions,
}
#[lsp_object(allow_missing)]
struct SaveOptions {
include_text: bool,
}
#[lsp_kind]
#[serde(untagged)]
enum ChangeNotificationsOptions {
Boolean(bool),
Id(String),
}
impl Default for ChangeNotificationsOptions {
fn default() -> Self {
ChangeNotificationsOptions::Boolean(false)
}
}
#[lsp_object]
pub struct InitializedParams {
}
#[lsp_object]
pub struct RegistrationParams {
pub registrations: Vec<Registration>,
}
#[lsp_object]
pub struct Registration {
id: String,
method: String,
register_options: Elective<Value>,
}
#[lsp_object]
struct RegistrationResult {
}
#[lsp_object]
pub struct DidOpenTextDocumentParams {
text_document: TextDocumentItem,
}
impl From<TextDocumentItem> for DidOpenTextDocumentParams {
fn from(text_document: TextDocumentItem) -> Self {
DidOpenTextDocumentParams { text_document }
}
}
#[lsp_object]
#[derive(Clone)]
pub struct TextDocumentItem {
pub uri: String,
pub language_id: String,
pub version: i64,
pub text: String,
}
impl TextDocumentItem {
pub fn increment_version(&mut self) {
self.version += 1;
}
}
#[lsp_object]
pub struct DidChangeTextDocumentParams {
text_document: VersionedTextDocumentIdentifier,
content_changes: Vec<TextDocumentContentChangeEvent>,
}
impl DidChangeTextDocumentParams {
pub fn new(text_document: VersionedTextDocumentIdentifier, content_changes: Vec<TextDocumentContentChangeEvent>) -> Self {
DidChangeTextDocumentParams {
text_document,
content_changes,
}
}
}
#[lsp_object]
pub struct VersionedTextDocumentIdentifier {
uri: String,
version: Option<i64>,
}
impl From<TextDocumentItem> for VersionedTextDocumentIdentifier {
fn from(value: TextDocumentItem) -> Self {
Self {
uri: value.uri.clone(),
version: Some(value.version),
}
}
}
#[lsp_object]
pub struct TextDocumentContentChangeEvent {
range: Elective<Range>,
range_length: Elective<u64>,
text: String,
}
impl TextDocumentContentChangeEvent {
pub fn new(range: Range, text: String) -> Self {
TextDocumentContentChangeEvent {
range: Elective::Present(range),
range_length: Elective::Absent,
text,
}
}
}
#[lsp_object]
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Range {
pub start: Position,
pub end: Position,
}
impl Range {
pub fn with_line(line: u64) -> Self {
Range::with_partial_line(line, 0, u64::max_value())
}
pub fn with_partial_line(line: u64, start: u64, end: u64) -> Self {
Range {
start: Position { line, character: start },
end: Position { line, character: end },
}
}
}
impl From<Position> for Range {
fn from(value: Position) -> Self {
Range {
start: value,
end: value,
}
}
}
#[lsp_object]
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct Position {
pub line: u64,
pub character: u64,
}
impl Position {
pub fn move_up(&mut self) {
self.line -= 1;
}
pub fn move_to_end_of_line(&mut self) {
self.character = u64::max_value();
}
pub fn move_left(&mut self) {
self.character -= 1;
}
pub fn move_right(&mut self) {
self.character += 1;
}
pub fn is_first_character(&self) -> bool {
self.character == 0
}
pub fn is_first_line(&self) -> bool {
self.line == 0
}
}
#[lsp_object]
pub struct PublishDiagnosticsParams {
uri: String,
diagnostics: Vec<Diagnostic>,
}
#[lsp_object]
struct Diagnostic {
range: Range,
severity: Elective<DiagnosticSeverity>,
code: Elective<DiagnosticCode>,
source: Elective<String>,
message: String,
related_information: Elective<Vec<DiagnosticRelatedInformation>>,
}
#[lsp_kind]
enum DiagnosticSeverity {
Error = 1,
Warning,
Information,
Hint,
}
#[lsp_kind]
#[serde(untagged)]
enum DiagnosticCode {
Number(i64),
String(String),
}
#[lsp_object]
struct DiagnosticRelatedInformation {
location: Location,
message: String,
}
#[lsp_object]
struct Location {
uri: String,
range: Range,
}