From 1032533de56ceb8c91a46a3f734e8697666d7b93 Mon Sep 17 00:00:00 2001 From: Asaf Flescher Date: Fri, 27 Dec 2024 10:46:40 -0500 Subject: [PATCH 1/2] Formatter uses stdin instead of filepath In the current version, at least on Nvim and OSX, .clang-format in the root of the repo was being ignored because clang-format looks for a config file relative to the source file, not the working directory. This change allows .clang-format in the root of a workspace to be properly picked up with the addition of the assume-filename flag. --- src/formatter/clang.rs | 13 +++++++------ src/formatter/mod.rs | 4 ++-- src/lsp.rs | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/formatter/clang.rs b/src/formatter/clang.rs index d2e72d5..8e92a8e 100644 --- a/src/formatter/clang.rs +++ b/src/formatter/clang.rs @@ -85,12 +85,13 @@ impl ClangFormatter { Some(p) } - fn get_command(&self, u: &Path) -> Command { + fn get_command(&self, f: &str, u: &Path) -> Command { let mut c = Command::new(self.path.as_str()); if let Some(wd) = self.working_dir.as_ref() { c.current_dir(wd.as_str()); } - c.args([u.to_str().unwrap(), "--output-replacements-xml"]); + c.stdin(File::open(u).unwrap()); + c.args(["--output-replacements-xml", format!("--assume-filename={f}").as_str()]); c } @@ -107,9 +108,9 @@ impl ClangFormatter { } impl ProtoFormatter for ClangFormatter { - fn format_document(&self, content: &str) -> Option> { + fn format_document(&self, filename: &str, content: &str) -> Option> { let p = self.get_temp_file_path(content)?; - let output = self.get_command(p.as_ref()).output().ok()?; + let output = self.get_command(filename, p.as_ref()).output().ok()?; if !output.status.success() { tracing::error!( status = output.status.code(), @@ -120,12 +121,12 @@ impl ProtoFormatter for ClangFormatter { self.output_to_textedit(&String::from_utf8_lossy(&output.stdout), content) } - fn format_document_range(&self, r: &Range, content: &str) -> Option> { + fn format_document_range(&self, r: &Range, filename: &str, content: &str) -> Option> { let p = self.get_temp_file_path(content)?; let start = r.start.line + 1; let end = r.end.line + 1; let output = self - .get_command(p.as_ref()) + .get_command(filename, p.as_ref()) .args(["--lines", format!("{start}:{end}").as_str()]) .output() .ok()?; diff --git a/src/formatter/mod.rs b/src/formatter/mod.rs index 67f6913..d5e1993 100644 --- a/src/formatter/mod.rs +++ b/src/formatter/mod.rs @@ -3,6 +3,6 @@ use async_lsp::lsp_types::{Range, TextEdit}; pub mod clang; pub trait ProtoFormatter: Sized { - fn format_document(&self, content: &str) -> Option>; - fn format_document_range(&self, r: &Range, content: &str) -> Option>; + fn format_document(&self, filename: &str, content: &str) -> Option>; + fn format_document_range(&self, r: &Range, filename: &str, content: &str) -> Option>; } diff --git a/src/lsp.rs b/src/lsp.rs index 3674d43..0d9b59a 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -375,7 +375,7 @@ impl LanguageServer for ProtoLanguageServer { let response = self .state .get_formatter() - .and_then(|f| f.format_document(content.as_str())); + .and_then(|f| f.format_document(uri.path(), content.as_str())); Box::pin(async move { Ok(response) }) } @@ -390,7 +390,7 @@ impl LanguageServer for ProtoLanguageServer { let response = self .state .get_formatter() - .and_then(|f| f.format_document_range(¶ms.range, content.as_str())); + .and_then(|f| f.format_document_range(¶ms.range, uri.path(), content.as_str())); Box::pin(async move { Ok(response) }) } From 2b8a7f1185a272a204a84b343e8ab68316ab7fa9 Mon Sep 17 00:00:00 2001 From: Asaf Flescher Date: Mon, 30 Dec 2024 11:23:11 -0500 Subject: [PATCH 2/2] Gracefully handled file issues --- src/formatter/clang.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/formatter/clang.rs b/src/formatter/clang.rs index 8e92a8e..08e54c1 100644 --- a/src/formatter/clang.rs +++ b/src/formatter/clang.rs @@ -85,14 +85,14 @@ impl ClangFormatter { Some(p) } - fn get_command(&self, f: &str, u: &Path) -> Command { + fn get_command(&self, f: &str, u: &Path) -> Option { let mut c = Command::new(self.path.as_str()); if let Some(wd) = self.working_dir.as_ref() { c.current_dir(wd.as_str()); } - c.stdin(File::open(u).unwrap()); + c.stdin(File::open(u).ok()?); c.args(["--output-replacements-xml", format!("--assume-filename={f}").as_str()]); - c + Some(c) } fn output_to_textedit(&self, output: &str, content: &str) -> Option> { @@ -110,7 +110,8 @@ impl ClangFormatter { impl ProtoFormatter for ClangFormatter { fn format_document(&self, filename: &str, content: &str) -> Option> { let p = self.get_temp_file_path(content)?; - let output = self.get_command(filename, p.as_ref()).output().ok()?; + let mut cmd = self.get_command(filename, p.as_ref())?; + let output = cmd.output().ok()?; if !output.status.success() { tracing::error!( status = output.status.code(), @@ -126,7 +127,7 @@ impl ProtoFormatter for ClangFormatter { let start = r.start.line + 1; let end = r.end.line + 1; let output = self - .get_command(filename, p.as_ref()) + .get_command(filename, p.as_ref())? .args(["--lines", format!("{start}:{end}").as_str()]) .output() .ok()?;