Support remote sessions

This commit is contained in:
Kirill Bulatov 2023-05-23 17:11:23 +03:00
parent f6d7b3d2e8
commit 3327e8a6dd
4 changed files with 99 additions and 25 deletions

View file

@ -111,7 +111,7 @@ pub(crate) struct GetCodeActions {
pub(crate) struct OnTypeFormatting { pub(crate) struct OnTypeFormatting {
pub position: PointUtf16, pub position: PointUtf16,
pub new_char: char, pub trigger: String,
// TODO kb formatting options? // TODO kb formatting options?
} }
@ -1607,18 +1607,18 @@ impl LspCommand for GetCodeActions {
impl LspCommand for OnTypeFormatting { impl LspCommand for OnTypeFormatting {
type Response = Vec<(Range<Anchor>, String)>; type Response = Vec<(Range<Anchor>, String)>;
type LspRequest = lsp::request::OnTypeFormatting; type LspRequest = lsp::request::OnTypeFormatting;
type ProtoRequest = proto::PerformRename; type ProtoRequest = proto::OnTypeFormatting;
fn check_capabilities(&self, server_capabilities: &lsp::ServerCapabilities) -> bool { fn check_capabilities(&self, server_capabilities: &lsp::ServerCapabilities) -> bool {
let Some(on_type_formatting_options) = &server_capabilities.document_on_type_formatting_provider else { return false }; let Some(on_type_formatting_options) = &server_capabilities.document_on_type_formatting_provider else { return false };
on_type_formatting_options on_type_formatting_options
.first_trigger_character .first_trigger_character
.contains(self.new_char) .contains(&self.trigger)
|| on_type_formatting_options || on_type_formatting_options
.more_trigger_character .more_trigger_character
.iter() .iter()
.flatten() .flatten()
.any(|chars| chars.contains(self.new_char)) .any(|chars| chars.contains(&self.trigger))
} }
fn to_lsp( fn to_lsp(
@ -1633,7 +1633,7 @@ impl LspCommand for OnTypeFormatting {
lsp::TextDocumentIdentifier::new(lsp::Url::from_file_path(path).unwrap()), lsp::TextDocumentIdentifier::new(lsp::Url::from_file_path(path).unwrap()),
point_to_lsp(self.position), point_to_lsp(self.position),
), ),
ch: self.new_char.to_string(), ch: self.trigger.clone(),
// TODO kb pass current editor ones // TODO kb pass current editor ones
options: lsp::FormattingOptions::default(), options: lsp::FormattingOptions::default(),
} }
@ -1656,44 +1656,92 @@ impl LspCommand for OnTypeFormatting {
.context("LSP edits conversion") .context("LSP edits conversion")
} }
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::PerformRename { fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::OnTypeFormatting {
todo!("TODO kb") proto::OnTypeFormatting {
project_id,
buffer_id: buffer.remote_id(),
position: Some(language::proto::serialize_anchor(
&buffer.anchor_before(self.position),
)),
trigger: self.trigger.clone(),
version: serialize_version(&buffer.version()),
}
} }
async fn from_proto( async fn from_proto(
message: proto::PerformRename, message: proto::OnTypeFormatting,
_: ModelHandle<Project>, _: ModelHandle<Project>,
buffer: ModelHandle<Buffer>, buffer: ModelHandle<Buffer>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<Self> { ) -> Result<Self> {
todo!("TODO kb") let position = message
.position
.and_then(deserialize_anchor)
.ok_or_else(|| anyhow!("invalid position"))?;
buffer
.update(&mut cx, |buffer, _| {
buffer.wait_for_version(deserialize_version(&message.version))
})
.await?;
Ok(Self {
position: buffer.read_with(&cx, |buffer, _| position.to_point_utf16(buffer)),
trigger: message.trigger.clone(),
})
} }
fn response_to_proto( fn response_to_proto(
response: Vec<(Range<Anchor>, String)>, response: Vec<(Range<Anchor>, String)>,
project: &mut Project, _: &mut Project,
peer_id: PeerId, _: PeerId,
_: &clock::Global, buffer_version: &clock::Global,
cx: &mut AppContext, _: &mut AppContext,
) -> proto::PerformRenameResponse { ) -> proto::OnTypeFormattingResponse {
// let transaction = project.serialize_project_transaction_for_peer(response, peer_id, cx); proto::OnTypeFormattingResponse {
// proto::PerformRenameResponse { entries: response
// transaction: Some(transaction), .into_iter()
// } .map(
todo!("TODO kb") |(response_range, new_text)| proto::OnTypeFormattingResponseEntry {
start: Some(language::proto::serialize_anchor(&response_range.start)),
end: Some(language::proto::serialize_anchor(&response_range.end)),
new_text,
},
)
.collect(),
version: serialize_version(&buffer_version),
}
} }
async fn response_from_proto( async fn response_from_proto(
self, self,
message: proto::PerformRenameResponse, message: proto::OnTypeFormattingResponse,
project: ModelHandle<Project>, _: ModelHandle<Project>,
_: ModelHandle<Buffer>, buffer: ModelHandle<Buffer>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<Vec<(Range<Anchor>, String)>> { ) -> Result<Vec<(Range<Anchor>, String)>> {
todo!("TODO kb") buffer
.update(&mut cx, |buffer, _| {
buffer.wait_for_version(deserialize_version(&message.version))
})
.await?;
message
.entries
.into_iter()
.map(|entry| {
let start = entry
.start
.and_then(language::proto::deserialize_anchor)
.ok_or_else(|| anyhow!("invalid start"))?;
let end = entry
.end
.and_then(language::proto::deserialize_anchor)
.ok_or_else(|| anyhow!("invalid end"))?;
Ok((start..end, entry.new_text))
})
.collect()
} }
fn buffer_id_from_proto(message: &proto::PerformRename) -> u64 { fn buffer_id_from_proto(message: &proto::OnTypeFormatting) -> u64 {
message.buffer_id message.buffer_id
} }
} }

View file

@ -4221,7 +4221,7 @@ impl Project {
buffer.clone(), buffer.clone(),
OnTypeFormatting { OnTypeFormatting {
position, position,
new_char: input, trigger: input.to_string(),
}, },
cx, cx,
); );

View file

@ -129,6 +129,9 @@ message Envelope {
GetPrivateUserInfo get_private_user_info = 105; GetPrivateUserInfo get_private_user_info = 105;
GetPrivateUserInfoResponse get_private_user_info_response = 106; GetPrivateUserInfoResponse get_private_user_info_response = 106;
UpdateDiffBase update_diff_base = 107; UpdateDiffBase update_diff_base = 107;
OnTypeFormatting on_type_formatting = 111;
OnTypeFormattingResponse on_type_formatting_response = 112;
} }
} }
@ -670,6 +673,25 @@ message PerformRename {
repeated VectorClockEntry version = 5; repeated VectorClockEntry version = 5;
} }
message OnTypeFormatting {
uint64 project_id = 1;
uint64 buffer_id = 2;
Anchor position = 3;
string trigger = 4;
repeated VectorClockEntry version = 5;
}
message OnTypeFormattingResponse {
repeated OnTypeFormattingResponseEntry entries = 1;
repeated VectorClockEntry version = 2;
}
message OnTypeFormattingResponseEntry {
Anchor start = 1;
Anchor end = 2;
string new_text = 3;
}
message PerformRenameResponse { message PerformRenameResponse {
ProjectTransaction transaction = 2; ProjectTransaction transaction = 2;
} }

View file

@ -195,6 +195,8 @@ messages!(
(OpenBufferResponse, Background), (OpenBufferResponse, Background),
(PerformRename, Background), (PerformRename, Background),
(PerformRenameResponse, Background), (PerformRenameResponse, Background),
(OnTypeFormatting, Background),
(OnTypeFormattingResponse, Background),
(Ping, Foreground), (Ping, Foreground),
(PrepareRename, Background), (PrepareRename, Background),
(PrepareRenameResponse, Background), (PrepareRenameResponse, Background),
@ -279,6 +281,7 @@ request_messages!(
(Ping, Ack), (Ping, Ack),
(PerformRename, PerformRenameResponse), (PerformRename, PerformRenameResponse),
(PrepareRename, PrepareRenameResponse), (PrepareRename, PrepareRenameResponse),
(OnTypeFormatting, OnTypeFormattingResponse),
(ReloadBuffers, ReloadBuffersResponse), (ReloadBuffers, ReloadBuffersResponse),
(RequestContact, Ack), (RequestContact, Ack),
(RemoveContact, Ack), (RemoveContact, Ack),
@ -323,6 +326,7 @@ entity_messages!(
OpenBufferByPath, OpenBufferByPath,
OpenBufferForSymbol, OpenBufferForSymbol,
PerformRename, PerformRename,
OnTypeFormatting,
PrepareRename, PrepareRename,
ReloadBuffers, ReloadBuffers,
RemoveProjectCollaborator, RemoveProjectCollaborator,