Skip to content

Commit

Permalink
feat(inlayHint): implement inlayHint basic types
Browse files Browse the repository at this point in the history
  • Loading branch information
sno2 committed Mar 21, 2022
1 parent 3113162 commit 29a50e7
Show file tree
Hide file tree
Showing 2 changed files with 265 additions and 0 deletions.
253 changes: 253 additions & 0 deletions src/inlay_hint.rs
@@ -0,0 +1,253 @@
#![cfg(feature = "proposed")]

use crate::{
Command, Location, MarkupContent, Position, Range, StaticRegistrationOptions,
TextDocumentIdentifier, TextDocumentRegistrationOptions, TextEdit, WorkDoneProgressOptions,
WorkDoneProgressParams,
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintClientCapabilitiesResolveSupport {
/// The properties that a client can resolve lazily.
pub properties: Vec<String>,
}

/// Inlay hint client capabilities.
///
/// @since 3.17.0 - proposed state
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintClientCapabilities {
/// Whether inlay hints support dynamic registration.
#[serde(skip_serializing_if = "Option::is_none")]
pub dynamic_registration: Option<bool>,

/// Indicates which properties a client can resolve lazily on a inlay
/// hint.
#[serde(skip_serializing_if = "Option::is_none")]
pub resolve_support: Option<InlayHintClientCapabilitiesResolveSupport>,
}

/// Inlay hint options used during static registration.
///
/// @since 3.17.0 - proposed state
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintOptions {
#[serde(flatten)]
pub work_done_progress_options: WorkDoneProgressOptions,

/// The server provides support to resolve additional
/// information for an inlay hint item.
#[serde(skip_serializing_if = "Option::is_none")]
pub resolve_provider: Option<bool>,
}

/// Inlay hint options used during static or dynamic registration.
///
/// @since 3.17.0 - proposed state
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintRegistrationOptions {
#[serde(flatten)]
pub inlay_hints_options: InlayHintOptions,

#[serde(flatten)]
pub text_document_registration_options: TextDocumentRegistrationOptions,

#[serde(flatten)]
pub static_registration_options: StaticRegistrationOptions,
}

/// A parameter literal used in inlay hint requests.
///
/// @since 3.17.0 - proposed state
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintParams {
#[serde(flatten)]
pub work_done_progress_params: WorkDoneProgressParams,

/// The text document.
pub text_document: TextDocumentIdentifier,

/// The visible document range for which inlay hints should be computed.
pub range: Range,
}

/// Inlay hint information.
///
/// @since 3.17.0 - proposed state
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHint {
/// The position of this hint.
pub position: Position,

/// The label of this hint. A human readable string or an array of
/// InlayHintLabelPart label parts.
///
/// *Note* that neither the string nor the label part can be empty.
pub label: InlayHintLabel,

/// The kind of this hint. Can be omitted in which case the client
/// should fall back to a reasonable default.
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<InlayHintKind>,

/// Optional text edits that are performed when accepting this inlay hint.
///
/// *Note* that edits are expected to change the document so that the inlay
/// hint (or its nearest variant) is now part of the document and the inlay
/// hint itself is now obsolete.
///
/// Depending on the client capability `inlayHint.resolveSupport` clients
/// might resolve this property late using the resolve request.
#[serde(skip_serializing_if = "Option::is_none")]
pub text_edits: Option<Vec<TextEdit>>,

/// The tooltip text when you hover over this item.
///
/// Depending on the client capability `inlayHint.resolveSupport` clients
/// might resolve this property late using the resolve request.
#[serde(skip_serializing_if = "Option::is_none")]
pub tooltip: Option<InlayHintTooltip>,

/// Render padding before the hint.
///
/// Note: Padding should use the editor's background color, not the
/// background color of the hint itself. That means padding can be used
/// to visually align/separate an inlay hint.
#[serde(skip_serializing_if = "Option::is_none")]
pub padding_left: Option<bool>,

/// Render padding after the hint.
///
/// Note: Padding should use the editor's background color, not the
/// background color of the hint itself. That means padding can be used
/// to visually align/separate an inlay hint.
#[serde(skip_serializing_if = "Option::is_none")]
pub padding_right: Option<bool>,
// FIXME(sno2): add [`data`] field after [`LSPAny`] is implemented
// /// A data entry field that is preserved on a inlay hint between
// /// a `textDocument/inlayHint` and a `inlayHint/resolve` request.
// #[serde(skip_serializing_if = "Option::is_none")]
// pub data: Option<crate::LSPAny>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum InlayHintLabel {
String(String),
LabelParts(Vec<InlayHintLabelPart>),
}

impl From<String> for InlayHintLabel {
#[inline]
fn from(from: String) -> Self {
Self::String(from)
}
}

impl From<Vec<InlayHintLabelPart>> for InlayHintLabel {
#[inline]
fn from(from: Vec<InlayHintLabelPart>) -> Self {
Self::LabelParts(from)
}
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum InlayHintTooltip {
String(String),
MarkupContent(MarkupContent),
}

impl From<String> for InlayHintTooltip {
#[inline]
fn from(from: String) -> Self {
Self::String(from)
}
}

impl From<MarkupContent> for InlayHintTooltip {
#[inline]
fn from(from: MarkupContent) -> Self {
Self::MarkupContent(from)
}
}

/// An inlay hint label part allows for interactive and composite labels
/// of inlay hints.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintLabelPart {
/// The value of this label part.
pub value: String,

/// The tooltip text when you hover over this label part. Depending on
/// the client capability `inlayHint.resolveSupport` clients might resolve
/// this property late using the resolve request.
#[serde(skip_serializing_if = "Option::is_none")]
pub tooltip: Option<InlayHintLabelPartTooltip>,

/// An optional source code location that represents this
/// label part.
///
/// The editor will use this location for the hover and for code navigation
/// features: This part will become a clickable link that resolves to the
/// definition of the symbol at the given location (not necessarily the
/// location itself), it shows the hover that shows at the given location,
/// and it shows a context menu with further code navigation commands.
///
/// Depending on the client capability `inlayHint.resolveSupport` clients
/// might resolve this property late using the resolve request.
#[serde(skip_serializing_if = "Option::is_none")]
pub location: Option<Location>,

/// An optional command for this label part.
///
/// Depending on the client capability `inlayHint.resolveSupport` clients
/// might resolve this property late using the resolve request.
#[serde(skip_serializing_if = "Option::is_none")]
pub command: Option<Command>,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum InlayHintLabelPartTooltip {
String(String),
MarkupContent(MarkupContent),
}

impl From<String> for InlayHintLabelPartTooltip {
#[inline]
fn from(from: String) -> Self {
Self::String(from)
}
}

impl From<MarkupContent> for InlayHintLabelPartTooltip {
#[inline]
fn from(from: MarkupContent) -> Self {
Self::MarkupContent(from)
}
}

/// Inlay hint kinds.
///
/// @since 3.17.0 - proposed state
#[derive(Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct InlayHintKind(i32);
lsp_enum! {
impl InlayHintKind {
/// An inlay hint that for a type annotation.
pub const TYPE: InlayHintKind = InlayHintKind(1);

/// An inlay hint that is for a parameter.
pub const PARAMETER: InlayHintKind = InlayHintKind(2);
}
}
12 changes: 12 additions & 0 deletions src/lib.rs
Expand Up @@ -144,6 +144,11 @@ pub use formatting::*;
mod hover;
pub use hover::*;

#[cfg(feature = "proposed")]
mod inlay_hint;
#[cfg(feature = "proposed")]
pub use inlay_hint::*;

mod moniker;
pub use moniker::*;

Expand Down Expand Up @@ -1451,6 +1456,13 @@ pub struct TextDocumentClientCapabilities {
/// @since 3.16.0
#[serde(skip_serializing_if = "Option::is_none")]
pub moniker: Option<MonikerClientCapabilities>,

/// Capabilities specific to the `textDocument/inlayHint` request.
///
/// @since 3.17.0 - proposed state
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg(feature = "proposed")]
pub inlay_hint: Option<InlayHintClientCapabilities>,
}

/// Where ClientCapabilities are currently empty:
Expand Down

0 comments on commit 29a50e7

Please sign in to comment.