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 {
|
if had_active_copilot_suggestion {
|
||||||
this.refresh_copilot_suggestions(true, cx);
|
this.refresh_copilot_suggestions(true, cx);
|
||||||
if !this.has_active_copilot_suggestion(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(
|
fn trigger_on_type_formatting(
|
||||||
&self,
|
&self,
|
||||||
input: String,
|
input: String,
|
||||||
|
|
|
@ -388,6 +388,9 @@ impl LanguageServer {
|
||||||
resolve_support: None,
|
resolve_support: None,
|
||||||
..WorkspaceSymbolClientCapabilities::default()
|
..WorkspaceSymbolClientCapabilities::default()
|
||||||
}),
|
}),
|
||||||
|
inlay_hint: Some(InlayHintWorkspaceClientCapabilities {
|
||||||
|
refresh_support: Default::default(),
|
||||||
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
text_document: Some(TextDocumentClientCapabilities {
|
text_document: Some(TextDocumentClientCapabilities {
|
||||||
|
@ -429,6 +432,11 @@ impl LanguageServer {
|
||||||
content_format: Some(vec![MarkupKind::Markdown]),
|
content_format: Some(vec![MarkupKind::Markdown]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
// TODO kb add the resolution at least
|
||||||
|
inlay_hint: Some(InlayHintClientCapabilities {
|
||||||
|
resolve_support: None,
|
||||||
|
dynamic_registration: Some(false),
|
||||||
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
experimental: Some(json!({
|
experimental: Some(json!({
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
DocumentHighlight, Hover, HoverBlock, HoverBlockKind, Location, LocationLink, Project,
|
DocumentHighlight, Hover, HoverBlock, HoverBlockKind, InlayHint, InlayHintLabel,
|
||||||
ProjectTransaction,
|
InlayHintLabelPart, InlayHintLabelPartTooltip, InlayHintTooltip, Location, LocationLink,
|
||||||
|
MarkupContent, Project, ProjectTransaction,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
@ -126,6 +127,10 @@ pub(crate) struct OnTypeFormatting {
|
||||||
pub push_to_history: bool,
|
pub push_to_history: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct InlayHints {
|
||||||
|
pub range: Range<Anchor>,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct FormattingOptions {
|
pub(crate) struct FormattingOptions {
|
||||||
tab_size: u32,
|
tab_size: u32,
|
||||||
}
|
}
|
||||||
|
@ -1780,3 +1785,147 @@ impl LspCommand for OnTypeFormatting {
|
||||||
message.buffer_id
|
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>,
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LocationLink {
|
pub struct LocationLink {
|
||||||
pub origin: Option<Location>,
|
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)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn search(
|
pub fn search(
|
||||||
&self,
|
&self,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue