Detailed changes
@@ -5520,6 +5520,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "prettier"
version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "fs",
+ "gpui",
+ "language",
+]
[[package]]
name = "pretty_assertions"
@@ -5635,6 +5641,7 @@ dependencies = [
"lsp",
"parking_lot 0.11.2",
"postage",
+ "prettier",
"pretty_assertions",
"rand 0.8.5",
"regex",
@@ -149,10 +149,15 @@ pub enum ShowWhitespaceSetting {
All,
}
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
+#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum Formatter {
+ #[default]
+ Auto,
LanguageServer,
+ Prettier {
+ config: (), // Support some of the most important settings in the prettier-vscode extension.
+ },
External {
command: Arc<str>,
arguments: Arc<[String]>,
@@ -3,7 +3,18 @@ name = "prettier"
version = "0.1.0"
edition = "2021"
-[dependencies]
-
[lib]
path = "src/prettier.rs"
+
+[dependencies]
+language = { path = "../language" }
+gpui = { path = "../gpui" }
+fs = { path = "../fs" }
+
+anyhow.workspace = true
+
+
+[dev-dependencies]
+language = { path = "../language", features = ["test-support"] }
+gpui = { path = "../gpui", features = ["test-support"] }
+fs = { path = "../fs", features = ["test-support"] }
@@ -1,14 +1,46 @@
-pub fn add(left: usize, right: usize) -> usize {
- left + right
+pub use std::path::{Path, PathBuf};
+pub use std::sync::Arc;
+
+use fs::Fs;
+use gpui::ModelHandle;
+use language::{Buffer, Diff};
+
+pub struct Prettier {
+ _private: (),
}
-#[cfg(test)]
-mod tests {
- use super::*;
+type NodeRuntime = ();
+
+impl Prettier {
+ // This was taken from the prettier-vscode extension.
+ pub const CONFIG_FILE_NAMES: &'static [&'static str] = &[
+ ".prettierrc",
+ ".prettierrc.json",
+ ".prettierrc.json5",
+ ".prettierrc.yaml",
+ ".prettierrc.yml",
+ ".prettierrc.toml",
+ ".prettierrc.js",
+ ".prettierrc.cjs",
+ "package.json",
+ "prettier.config.js",
+ "prettier.config.cjs",
+ ".editorconfig",
+ ];
+
+ pub async fn locate(starting_path: Option<&Path>, fs: Arc<dyn Fs>) -> PathBuf {
+ todo!()
+ }
+
+ pub async fn start(prettier_path: &Path, node: Arc<NodeRuntime>) -> anyhow::Result<Self> {
+ todo!()
+ }
+
+ pub async fn format(&self, buffer: &ModelHandle<Buffer>) -> anyhow::Result<Diff> {
+ todo!()
+ }
- #[test]
- fn it_works() {
- let result = add(2, 2);
- assert_eq!(result, 4);
+ pub async fn clear_cache(&self) -> anyhow::Result<()> {
+ todo!()
}
}
@@ -31,6 +31,7 @@ git = { path = "../git" }
gpui = { path = "../gpui" }
language = { path = "../language" }
lsp = { path = "../lsp" }
+prettier = { path = "../prettier" }
rpc = { path = "../rpc" }
settings = { path = "../settings" }
sum_tree = { path = "../sum_tree" }
@@ -50,6 +50,7 @@ use lsp::{
};
use lsp_command::*;
use postage::watch;
+use prettier::Prettier;
use project_settings::{LspSettings, ProjectSettings};
use rand::prelude::*;
use search::SearchQuery;
@@ -152,6 +153,7 @@ pub struct Project {
copilot_lsp_subscription: Option<gpui::Subscription>,
copilot_log_subscription: Option<lsp::Subscription>,
current_lsp_settings: HashMap<Arc<str>, LspSettings>,
+ prettier_instances: HashMap<(WorktreeId, PathBuf), Shared<Task<Result<Arc<Prettier>>>>>,
}
struct DelayedDebounced {
@@ -660,6 +662,7 @@ impl Project {
copilot_lsp_subscription,
copilot_log_subscription: None,
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
+ prettier_instances: HashMap::default(),
}
})
}
@@ -757,6 +760,7 @@ impl Project {
copilot_lsp_subscription,
copilot_log_subscription: None,
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
+ prettier_instances: HashMap::default(),
};
for worktree in worktrees {
let _ = this.add_worktree(&worktree, cx);
@@ -4027,6 +4031,7 @@ impl Project {
enum FormatOperation {
Lsp(Vec<(Range<Anchor>, String)>),
External(Diff),
+ Prettier(Diff),
}
// Apply language-specific formatting using either a language server
@@ -4062,8 +4067,8 @@ impl Project {
| (_, FormatOnSave::External { command, arguments }) => {
if let Some(buffer_abs_path) = buffer_abs_path {
format_operation = Self::format_via_external_command(
- &buffer,
- &buffer_abs_path,
+ buffer,
+ buffer_abs_path,
&command,
&arguments,
&mut cx,
@@ -4076,6 +4081,45 @@ impl Project {
.map(FormatOperation::External);
}
}
+ (Formatter::Auto, FormatOnSave::On | FormatOnSave::Off) => {
+ if let Some(prettier) = this.update(&mut cx, |project, _| {
+ project.prettier_instance_for_buffer(buffer)
+ }) {
+ format_operation = Some(FormatOperation::Prettier(
+ prettier
+ .format(buffer)
+ .await
+ .context("autoformatting via prettier")?,
+ ));
+ } else if let Some((language_server, buffer_abs_path)) =
+ language_server.as_ref().zip(buffer_abs_path.as_ref())
+ {
+ format_operation = Some(FormatOperation::Lsp(
+ Self::format_via_lsp(
+ &this,
+ &buffer,
+ buffer_abs_path,
+ &language_server,
+ tab_size,
+ &mut cx,
+ )
+ .await
+ .context("failed to format via language server")?,
+ ));
+ }
+ }
+ (Formatter::Prettier { .. }, FormatOnSave::On | FormatOnSave::Off) => {
+ if let Some(prettier) = this.update(&mut cx, |project, _| {
+ project.prettier_instance_for_buffer(buffer)
+ }) {
+ format_operation = Some(FormatOperation::Prettier(
+ prettier
+ .format(buffer)
+ .await
+ .context("formatting via prettier")?,
+ ));
+ }
+ }
};
buffer.update(&mut cx, |b, cx| {
@@ -4100,6 +4144,9 @@ impl Project {
FormatOperation::External(diff) => {
b.apply_diff(diff, cx);
}
+ FormatOperation::Prettier(diff) => {
+ b.apply_diff(diff, cx);
+ }
}
if let Some(transaction_id) = whitespace_transaction_id {
@@ -8109,6 +8156,11 @@ impl Project {
Vec::new()
}
}
+
+ fn prettier_instance_for_buffer(&self, buffer: &ModelHandle<Buffer>) -> Option<Prettier> {
+ // TODO kb
+ None
+ }
}
fn subscribe_for_copilot_events(