mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-24 17:28:40 +00:00
Draft remote prettier formatting
This commit is contained in:
parent
2ec2036c2f
commit
b5705e079f
5 changed files with 121 additions and 32 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue