Detailed changes
@@ -317,8 +317,8 @@ pub struct Chunk<'a> {
pub struct Diff {
pub(crate) base_version: clock::Global,
- line_ending: LineEnding,
- edits: Vec<(Range<usize>, Arc<str>)>,
+ pub(crate) line_ending: LineEnding,
+ pub(crate) edits: Vec<(Range<usize>, Arc<str>)>,
}
#[derive(Clone, Copy)]
@@ -1,6 +1,6 @@
use crate::{
diagnostic_set::DiagnosticEntry, CodeAction, CodeLabel, Completion, CursorShape, Diagnostic,
- Language,
+ Diff, Language,
};
use anyhow::{anyhow, Result};
use clock::ReplicaId;
@@ -587,3 +587,42 @@ pub fn serialize_version(version: &clock::Global) -> Vec<proto::VectorClockEntry
})
.collect()
}
+
+pub fn serialize_diff(diff: Diff) -> proto::Diff {
+ proto::Diff {
+ version: serialize_version(&diff.base_version),
+ line_ending: serialize_line_ending(diff.line_ending) as i32,
+ edits: diff
+ .edits
+ .into_iter()
+ .map(|(range, edit)| proto::DiffEdit {
+ range: Some(proto::Range {
+ start: range.start as u64,
+ end: range.end as u64,
+ }),
+ edit: edit.to_string(),
+ })
+ .collect(),
+ }
+}
+
+pub fn deserialize_diff(diff: proto::Diff) -> Diff {
+ Diff {
+ base_version: deserialize_version(&diff.version),
+ line_ending: deserialize_line_ending(
+ rpc::proto::LineEnding::from_i32(diff.line_ending)
+ .unwrap_or_else(|| panic!("invalid line ending {}", diff.line_ending)),
+ ),
+ edits: diff
+ .edits
+ .into_iter()
+ .map(|edit| {
+ let range = edit.range.expect("incorrect edit without a range");
+ (
+ range.start as usize..range.end as usize,
+ Arc::from(edit.edit.as_str()),
+ )
+ })
+ .collect(),
+ }
+}
@@ -3,11 +3,12 @@ use std::path::{Path, PathBuf};
use std::sync::Arc;
use anyhow::Context;
-use client::Client;
+use client::{proto, Client};
use collections::{HashMap, HashSet};
use fs::Fs;
use gpui::{AsyncAppContext, ModelHandle};
use language::language_settings::language_settings;
+use language::proto::deserialize_diff;
use language::{Buffer, BundledFormatter, Diff};
use lsp::request::Request;
use lsp::{LanguageServer, LanguageServerBinary, LanguageServerId};
@@ -28,6 +29,7 @@ pub struct Local {
}
pub struct Remote {
+ project_id: u64,
worktree_id: Option<usize>,
prettier_dir: PathBuf,
client: Arc<Client>,
@@ -61,8 +63,14 @@ impl Prettier {
".editorconfig",
];
- pub fn remote(worktree_id: Option<usize>, prettier_dir: PathBuf, client: Arc<Client>) -> Self {
+ pub fn remote(
+ project_id: u64,
+ worktree_id: Option<usize>,
+ prettier_dir: PathBuf,
+ client: Arc<Client>,
+ ) -> Self {
Self::Remote(Remote {
+ project_id,
worktree_id,
prettier_dir,
client,
@@ -80,7 +88,7 @@ impl Prettier {
.components()
.into_iter()
.take_while(|path_component| {
- path_component.as_os_str().to_str() != Some("node_modules")
+ path_component.as_os_str().to_string_lossy() != "node_modules"
})
.collect::<PathBuf>();
@@ -137,7 +145,7 @@ impl Prettier {
for path_component in file_to_format.components().into_iter() {
current_path = current_path.join(path_component);
paths_to_check.push_front(current_path.clone());
- if path_component.as_os_str().to_str() == Some("node_modules") {
+ if path_component.as_os_str().to_string_lossy() == "node_modules" {
break;
}
}
@@ -219,14 +227,18 @@ impl Prettier {
pub async fn invoke(
&self,
- buffer: &ModelHandle<Buffer>,
+ buffer: Option<&ModelHandle<Buffer>>,
buffer_path: Option<PathBuf>,
method: &str,
cx: &AsyncAppContext,
) -> anyhow::Result<Option<Diff>> {
match method {
Format::METHOD => self
- .format(buffer, buffer_path, cx)
+ .format(
+ buffer.expect("missing buffer for format invocation"),
+ buffer_path,
+ cx,
+ )
.await
.context("invoke method")
.map(Some),
@@ -374,7 +386,21 @@ impl Prettier {
let diff_task = buffer.read_with(cx, |buffer, cx| buffer.diff(response.text, cx));
Ok(diff_task.await)
}
- Self::Remote(remote) => todo!("TODO kb"),
+ Self::Remote(remote) => buffer
+ .read_with(cx, |buffer, _| {
+ remote.client.request(proto::InvokePrettierForBuffer {
+ buffer_id: Some(buffer.remote_id()),
+ worktree_id: self.worktree_id().map(|id| id as u64),
+ method: Format::METHOD.to_string(),
+ project_id: remote.project_id,
+ prettier_path: remote.prettier_dir.to_string_lossy().to_string(),
+ })
+ })
+ .await
+ .context("prettier diff invoke")?
+ .diff
+ .map(deserialize_diff)
+ .context("missing diff after prettier diff invocation"),
}
}
@@ -385,7 +411,23 @@ impl Prettier {
.request::<ClearCache>(())
.await
.context("prettier clear cache"),
- Self::Remote(remote) => todo!("TODO kb"),
+ Self::Remote(remote) => remote
+ .client
+ .request(proto::InvokePrettierForBuffer {
+ buffer_id: None,
+ worktree_id: self.worktree_id().map(|id| id as u64),
+ method: ClearCache::METHOD.to_string(),
+ project_id: remote.project_id,
+ prettier_path: remote.prettier_dir.to_string_lossy().to_string(),
+ })
+ .await
+ .map(|response| {
+ debug_assert!(
+ response.diff.is_none(),
+ "Cleare cache invocation returned diff data"
+ )
+ })
+ .context("prettier invoke clear cache"),
}
}
@@ -37,7 +37,7 @@ use language::{
point_to_lsp,
proto::{
deserialize_anchor, deserialize_fingerprint, deserialize_line_ending, deserialize_version,
- serialize_anchor, serialize_version, split_operations,
+ serialize_anchor, serialize_diff, serialize_version, split_operations,
},
range_from_lsp, range_to_lsp, Bias, Buffer, BufferSnapshot, BundledFormatter, CachedLspAdapter,
CodeAction, CodeLabel, Completion, Diagnostic, DiagnosticEntry, DiagnosticSet, Diff,
@@ -6382,7 +6382,7 @@ impl Project {
.filter(|(path, _, _)| {
!path
.components()
- .any(|component| component.as_os_str().to_str() == Some("node_modules"))
+ .any(|component| component.as_os_str().to_string_lossy() == "node_modules")
})
.find(|(path, _, _)| prettier_config_files.contains(path.as_ref()));
let current_worktree_id = worktree.read(cx).id();
@@ -8324,14 +8324,14 @@ impl Project {
this.prettier_instances
.get(&(
envelope.payload.worktree_id.map(WorktreeId::from_proto),
- PathBuf::from(&envelope.payload.buffer_path),
+ PathBuf::from(&envelope.payload.prettier_path),
))
.cloned()
})
.with_context(|| {
format!(
- "Missing prettier for worktree {:?} and path {}",
- envelope.payload.worktree_id, envelope.payload.buffer_path,
+ "Missing prettier for worktree {:?} and path {:?}",
+ envelope.payload.worktree_id, envelope.payload.prettier_path,
)
})?
.await;
@@ -8340,25 +8340,27 @@ impl Project {
Err(e) => anyhow::bail!("Prettier instance failed to start: {e:#}"),
};
- let buffer = this
- .update(&mut cx, |this, cx| {
- this.opened_buffers
- .get(&envelope.payload.buffer_id)
- .and_then(|buffer| buffer.upgrade(cx))
- })
- .with_context(|| format!("unknown buffer id {}", envelope.payload.buffer_id))?;
+ let buffer = this.update(&mut cx, |this, cx| {
+ envelope
+ .payload
+ .buffer_id
+ .and_then(|id| this.opened_buffers.get(&id))
+ .and_then(|buffer| buffer.upgrade(cx))
+ });
- let buffer_path = buffer.read_with(&cx, |buffer, cx| {
- File::from_dyn(buffer.file()).map(|f| f.full_path(cx))
+ let buffer_path = buffer.as_ref().and_then(|buffer| {
+ buffer.read_with(&cx, |buffer, cx| {
+ File::from_dyn(buffer.file()).map(|f| f.full_path(cx))
+ })
});
let diff = prettier
- .invoke(&buffer, buffer_path, &envelope.payload.method, &cx)
+ .invoke(buffer.as_ref(), buffer_path, &envelope.payload.method, &cx)
.await
.with_context(|| format!("prettier invoke method {}", &envelope.payload.method))?;
Ok(proto::InvokePrettierForBufferResponse {
- diff: todo!("TODO kb serialize diff"),
+ diff: diff.map(serialize_diff),
})
}
@@ -8523,6 +8525,7 @@ impl Project {
.map(|prettier_path| {
let prettier_task = Task::ready(
Ok(Arc::new(Prettier::remote(
+ project_id,
worktree_id.map(|id| id.to_usize()),
prettier_path.clone(),
client,
@@ -1574,8 +1574,8 @@ message PrettierInstanceForBufferResponse {
message InvokePrettierForBuffer {
uint64 project_id = 1;
- string buffer_path = 2;
- uint64 buffer_id = 3;
+ optional uint64 buffer_id = 3;
+ string prettier_path = 2;
optional uint64 worktree_id = 4;
string method = 5;
}
@@ -1585,7 +1585,12 @@ message InvokePrettierForBufferResponse {
}
message Diff {
- VectorClockEntry version = 1;
- string line_ending = 2;
- string edits = 3;
+ repeated VectorClockEntry version = 1;
+ LineEnding line_ending = 2;
+ repeated DiffEdit edits = 3;
+}
+
+message DiffEdit {
+ Range range = 1;
+ string edit = 2;
}