From cb71399aa96a9812a3553eb4ccf97dc265e982f9 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Thu, 23 Jun 2022 19:24:07 +0200 Subject: [PATCH] feat: format via alejandra when feature is set Signed-off-by: Roman Volosatovs --- Cargo.lock | 35 +++++++++++++++++++++++++++++++++++ Cargo.toml | 5 +++-- src/main.rs | 42 +++++++++++++++++++++++++++++++++--------- 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e48ea78..3da61b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "alejandra_engine" +version = "1.5.0" +source = "git+https://github.com/kamadorueda/alejandra#18fe24f335f4b841b7f6354e7a86eae0103943af" +dependencies = [ + "mimalloc", + "rnix", + "rowan", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -61,6 +71,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + [[package]] name = "cfg-if" version = "0.1.10" @@ -295,6 +311,15 @@ version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +[[package]] +name = "libmimalloc-sys" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ca136052550448f55df7898c6dbe651c6b574fe38a0d9ea687a9f8088a2e2c" +dependencies = [ + "cc", +] + [[package]] name = "log" version = "0.4.14" @@ -350,6 +375,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mimalloc" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f64ad83c969af2e732e907564deb0d0ed393cec4af80776f77dd77a1a427698" +dependencies = [ + "libmimalloc-sys", +] + [[package]] name = "nixpkgs-fmt-rnix" version = "1.2.0" @@ -455,6 +489,7 @@ dependencies = [ name = "rnix-lsp" version = "0.3.0-dev" dependencies = [ + "alejandra_engine", "dirs", "env_logger", "gc", diff --git a/Cargo.toml b/Cargo.toml index 553d831..068ba79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,8 @@ rnix = "0.10.2" rowan = "0.12.6" serde = "1.0.104" serde_json = "1.0.44" -nixpkgs-fmt-rnix = "1.2.0" +nixpkgs-fmt-rnix = { version = "1.2.0", optional = true } +alejandra_engine = { version = "1.5.0", git = "https://github.com/kamadorueda/alejandra", optional = true } [dev-dependencies] stoppable_thread = "0.2" @@ -32,7 +33,7 @@ stoppable_thread = "0.2" [features] # Set this to ["verbose"] when debugging -default = [] +default = [ "nixpkgs-fmt-rnix" ] # Enable showing internal errors via editor UI, such as via hover popups. # This can be helpful for debugging, but we don't want the evaluator to diff --git a/src/main.rs b/src/main.rs index a7bf037..522ddb3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -205,16 +205,40 @@ impl App { let document_links = self.document_links(¶ms).unwrap_or_default(); self.reply(Response::new_ok(id, document_links)); } else if let Some((id, params)) = cast::(&mut req) { - let changes = if let Some((ast, code, _)) = self.files.get(¶ms.text_document.uri) { - let fmt = nixpkgs_fmt::reformat_node(&ast.node()); - vec![TextEdit { - range: utils::range(&code, TextRange::up_to(ast.node().text().len())), - new_text: fmt.text().to_string(), - }] + if let Some((ast, code, _)) = self.files.get(¶ms.text_document.uri) { + let node = ast.node(); + let range = utils::range(&code, TextRange::up_to(node.text().len())); + if cfg!(feature = "nixpkgs-fmt-rnix") { + #[cfg(feature = "nixpkgs-fmt-rnix")] + self.reply(Response::new_ok( + id, + vec![TextEdit { + range, + new_text: nixpkgs_fmt::reformat_node(&node).text().to_string(), + }], + )); + } else if cfg!(feature = "alejandra_engine") { + #[cfg(feature = "alejandra_engine")] + match alejandra_engine::format::in_memory( + params.text_document.uri.to_string(), + code.to_string(), + ) { + (alejandra_engine::format::Status::Changed(true), new_text) => { + self.reply(Response::new_ok(id, vec![TextEdit { range, new_text }])) + } + (alejandra_engine::format::Status::Changed(false), _) => { + self.reply(Response::new_ok(id, ())) + } + (alejandra_engine::format::Status::Error(e), _) => { + self.reply(Response::new_err(id, ErrorCode::InternalError as i32, e)) + } + } + } else { + self.reply(Response::new_ok(id, ())) + } } else { - Vec::new() - }; - self.reply(Response::new_ok(id, changes)); + self.reply(Response::new_ok(id, ())) + } } else if let Some((id, params)) = cast::(&mut req) { if let Some((range, markdown)) = self.hover(params) { self.reply(Response::new_ok(