Initial protocol check commit
This commit is contained in:
parent
1ae5261024
commit
8a3b515f56
4 changed files with 234 additions and 2 deletions
|
@ -2151,6 +2151,10 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(hints_task) = this.request_inlay_hints(cx) {
|
||||
hints_task.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
if had_active_copilot_suggestion {
|
||||
this.refresh_copilot_suggestions(true, cx);
|
||||
if !this.has_active_copilot_suggestion(cx) {
|
||||
|
@ -2577,6 +2581,27 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO kb proper inlay hints handling
|
||||
fn request_inlay_hints(&self, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
|
||||
let project = self.project.as_ref()?;
|
||||
let position = self.selections.newest_anchor().head();
|
||||
let (buffer, _) = self
|
||||
.buffer
|
||||
.read(cx)
|
||||
.text_anchor_for_position(position.clone(), cx)?;
|
||||
|
||||
let end = buffer.read(cx).len();
|
||||
let inlay_hints_task = project.update(cx, |project, cx| {
|
||||
project.inlay_hints(buffer.clone(), 0..end, cx)
|
||||
});
|
||||
|
||||
Some(cx.spawn(|_, _| async move {
|
||||
let inlay_hints = inlay_hints_task.await?;
|
||||
dbg!(inlay_hints);
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
|
||||
fn trigger_on_type_formatting(
|
||||
&self,
|
||||
input: String,
|
||||
|
|
|
@ -388,6 +388,9 @@ impl LanguageServer {
|
|||
resolve_support: None,
|
||||
..WorkspaceSymbolClientCapabilities::default()
|
||||
}),
|
||||
inlay_hint: Some(InlayHintWorkspaceClientCapabilities {
|
||||
refresh_support: Default::default(),
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
text_document: Some(TextDocumentClientCapabilities {
|
||||
|
@ -429,6 +432,11 @@ impl LanguageServer {
|
|||
content_format: Some(vec![MarkupKind::Markdown]),
|
||||
..Default::default()
|
||||
}),
|
||||
// TODO kb add the resolution at least
|
||||
inlay_hint: Some(InlayHintClientCapabilities {
|
||||
resolve_support: None,
|
||||
dynamic_registration: Some(false),
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
experimental: Some(json!({
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
DocumentHighlight, Hover, HoverBlock, HoverBlockKind, Location, LocationLink, Project,
|
||||
ProjectTransaction,
|
||||
DocumentHighlight, Hover, HoverBlock, HoverBlockKind, InlayHint, InlayHintLabel,
|
||||
InlayHintLabelPart, InlayHintLabelPartTooltip, InlayHintTooltip, Location, LocationLink,
|
||||
MarkupContent, Project, ProjectTransaction,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
|
@ -126,6 +127,10 @@ pub(crate) struct OnTypeFormatting {
|
|||
pub push_to_history: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct InlayHints {
|
||||
pub range: Range<Anchor>,
|
||||
}
|
||||
|
||||
pub(crate) struct FormattingOptions {
|
||||
tab_size: u32,
|
||||
}
|
||||
|
@ -1780,3 +1785,147 @@ impl LspCommand for OnTypeFormatting {
|
|||
message.buffer_id
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl LspCommand for InlayHints {
|
||||
type Response = Vec<InlayHint>;
|
||||
type LspRequest = lsp::InlayHintRequest;
|
||||
type ProtoRequest = proto::OnTypeFormatting;
|
||||
|
||||
fn check_capabilities(&self, server_capabilities: &lsp::ServerCapabilities) -> bool {
|
||||
let Some(inlay_hint_provider) = &server_capabilities.inlay_hint_provider else { return false };
|
||||
match inlay_hint_provider {
|
||||
lsp::OneOf::Left(enabled) => *enabled,
|
||||
lsp::OneOf::Right(inlay_hint_capabilities) => match inlay_hint_capabilities {
|
||||
lsp::InlayHintServerCapabilities::Options(_) => true,
|
||||
// TODO kb there could be dynamic registrations, resolve options
|
||||
lsp::InlayHintServerCapabilities::RegistrationOptions(_) => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn to_lsp(
|
||||
&self,
|
||||
path: &Path,
|
||||
buffer: &Buffer,
|
||||
_: &Arc<LanguageServer>,
|
||||
_: &AppContext,
|
||||
) -> lsp::InlayHintParams {
|
||||
lsp::InlayHintParams {
|
||||
text_document: lsp::TextDocumentIdentifier {
|
||||
uri: lsp::Url::from_file_path(path).unwrap(),
|
||||
},
|
||||
range: range_to_lsp(self.range.to_point_utf16(buffer)),
|
||||
work_done_progress_params: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn response_from_lsp(
|
||||
self,
|
||||
message: Option<Vec<lsp::InlayHint>>,
|
||||
_: ModelHandle<Project>,
|
||||
buffer: ModelHandle<Buffer>,
|
||||
_: LanguageServerId,
|
||||
cx: AsyncAppContext,
|
||||
) -> Result<Vec<InlayHint>> {
|
||||
cx.read(|cx| {
|
||||
let origin_buffer = buffer.read(cx);
|
||||
Ok(message
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|lsp_hint| InlayHint {
|
||||
position: origin_buffer.anchor_after(
|
||||
origin_buffer
|
||||
.clip_point_utf16(point_from_lsp(lsp_hint.position), Bias::Left),
|
||||
),
|
||||
label: match lsp_hint.label {
|
||||
lsp::InlayHintLabel::String(s) => InlayHintLabel::String(s),
|
||||
lsp::InlayHintLabel::LabelParts(lsp_parts) => InlayHintLabel::LabelParts(
|
||||
lsp_parts
|
||||
.into_iter()
|
||||
.map(|label_part| InlayHintLabelPart {
|
||||
value: label_part.value,
|
||||
tooltip: label_part.tooltip.map(|tooltip| match tooltip {
|
||||
lsp::InlayHintLabelPartTooltip::String(s) => {
|
||||
InlayHintLabelPartTooltip::String(s)
|
||||
}
|
||||
lsp::InlayHintLabelPartTooltip::MarkupContent(
|
||||
markup_content,
|
||||
) => InlayHintLabelPartTooltip::MarkupContent(
|
||||
MarkupContent {
|
||||
kind: format!("{:?}", markup_content.kind),
|
||||
value: markup_content.value,
|
||||
},
|
||||
),
|
||||
}),
|
||||
location: label_part.location.map(|lsp_location| {
|
||||
let target_start = origin_buffer.clip_point_utf16(
|
||||
point_from_lsp(lsp_location.range.start),
|
||||
Bias::Left,
|
||||
);
|
||||
let target_end = origin_buffer.clip_point_utf16(
|
||||
point_from_lsp(lsp_location.range.end),
|
||||
Bias::Left,
|
||||
);
|
||||
Location {
|
||||
buffer: buffer.clone(),
|
||||
range: origin_buffer.anchor_after(target_start)
|
||||
..origin_buffer.anchor_before(target_end),
|
||||
}
|
||||
}),
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
},
|
||||
kind: lsp_hint.kind.map(|kind| format!("{kind:?}")),
|
||||
tooltip: lsp_hint.tooltip.map(|tooltip| match tooltip {
|
||||
lsp::InlayHintTooltip::String(s) => InlayHintTooltip::String(s),
|
||||
lsp::InlayHintTooltip::MarkupContent(markup_content) => {
|
||||
InlayHintTooltip::MarkupContent(MarkupContent {
|
||||
kind: format!("{:?}", markup_content.kind),
|
||||
value: markup_content.value,
|
||||
})
|
||||
}
|
||||
}),
|
||||
})
|
||||
.collect())
|
||||
})
|
||||
}
|
||||
|
||||
fn to_proto(&self, _: u64, _: &Buffer) -> proto::OnTypeFormatting {
|
||||
todo!("TODO kb")
|
||||
}
|
||||
|
||||
async fn from_proto(
|
||||
_: proto::OnTypeFormatting,
|
||||
_: ModelHandle<Project>,
|
||||
_: ModelHandle<Buffer>,
|
||||
_: AsyncAppContext,
|
||||
) -> Result<Self> {
|
||||
todo!("TODO kb")
|
||||
}
|
||||
|
||||
fn response_to_proto(
|
||||
_: Vec<InlayHint>,
|
||||
_: &mut Project,
|
||||
_: PeerId,
|
||||
_: &clock::Global,
|
||||
_: &mut AppContext,
|
||||
) -> proto::OnTypeFormattingResponse {
|
||||
todo!("TODO kb")
|
||||
}
|
||||
|
||||
async fn response_from_proto(
|
||||
self,
|
||||
_: proto::OnTypeFormattingResponse,
|
||||
_: ModelHandle<Project>,
|
||||
_: ModelHandle<Buffer>,
|
||||
_: AsyncAppContext,
|
||||
) -> Result<Vec<InlayHint>> {
|
||||
todo!("TODO kb")
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::OnTypeFormatting) -> u64 {
|
||||
message.buffer_id
|
||||
}
|
||||
}
|
||||
|
|
|
@ -325,6 +325,45 @@ pub struct Location {
|
|||
pub range: Range<language::Anchor>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InlayHint {
|
||||
pub position: Anchor,
|
||||
pub label: InlayHintLabel,
|
||||
pub kind: Option<String>,
|
||||
pub tooltip: Option<InlayHintTooltip>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InlayHintLabel {
|
||||
String(String),
|
||||
LabelParts(Vec<InlayHintLabelPart>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InlayHintLabelPart {
|
||||
pub value: String,
|
||||
pub tooltip: Option<InlayHintLabelPartTooltip>,
|
||||
pub location: Option<Location>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InlayHintTooltip {
|
||||
String(String),
|
||||
MarkupContent(MarkupContent),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InlayHintLabelPartTooltip {
|
||||
String(String),
|
||||
MarkupContent(MarkupContent),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MarkupContent {
|
||||
pub kind: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LocationLink {
|
||||
pub origin: Option<Location>,
|
||||
|
@ -4837,6 +4876,17 @@ impl Project {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn inlay_hints<T: ToOffset>(
|
||||
&self,
|
||||
buffer_handle: ModelHandle<Buffer>,
|
||||
range: Range<T>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Vec<InlayHint>>> {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
let range = buffer.anchor_before(range.start)..buffer.anchor_before(range.end);
|
||||
self.request_lsp(buffer_handle, InlayHints { range }, cx)
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn search(
|
||||
&self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue