From 1b8ca8eac356267f224223e0762fdb7b45067695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20F=C3=B6rster?= Date: Tue, 21 Jan 2025 20:43:01 +0100 Subject: [PATCH] Add tex-fmt as formatter option (#1321) --- CHANGELOG.md | 1 + crates/base-db/src/config.rs | 1 + crates/texlab/src/features/formatting.rs | 8 ++++- .../texlab/src/features/formatting/texfmt.rs | 34 +++++++++++++++++++ crates/texlab/src/server/options.rs | 2 ++ crates/texlab/src/util/from_proto.rs | 2 ++ 6 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 crates/texlab/src/features/formatting/texfmt.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b097899f..958ad263b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `texlab.symbols.customEnvironments` setting for specifying additional environments that will be included in the document symbols ([#1292](https://github.com/latex-lsp/texlab/issues/1292)) - Add `texlab.experimental.labelReferenceRangeCommands` setting ([#1210](https://github.com/latex-lsp/texlab/issues/1210)) +- Add `tex-fmt` as a formatter for `latex` and `bibtex` ([#1320](https://github.com/latex-lsp/texlab/issues/1320)) ### Fixed diff --git a/crates/base-db/src/config.rs b/crates/base-db/src/config.rs index 23e232c15..d206c81c9 100644 --- a/crates/base-db/src/config.rs +++ b/crates/base-db/src/config.rs @@ -63,6 +63,7 @@ pub enum Formatter { Null, Server, LatexIndent, + TexFmt, } #[derive(Debug, Default)] diff --git a/crates/texlab/src/features/formatting.rs b/crates/texlab/src/features/formatting.rs index 9d152f6e8..462ed6f2f 100644 --- a/crates/texlab/src/features/formatting.rs +++ b/crates/texlab/src/features/formatting.rs @@ -1,10 +1,14 @@ mod bibtex_internal; mod latexindent; +mod texfmt; use base_db::{Formatter, Workspace}; use distro::Language; -use self::{bibtex_internal::format_bibtex_internal, latexindent::format_with_latexindent}; +use self::{ + bibtex_internal::format_bibtex_internal, latexindent::format_with_latexindent, + texfmt::format_with_texfmt, +}; pub fn format_source_code( workspace: &Workspace, @@ -17,11 +21,13 @@ pub fn format_source_code( Formatter::Null => None, Formatter::Server => None, Formatter::LatexIndent => format_with_latexindent(workspace, document), + Formatter::TexFmt => format_with_texfmt(document), }, Language::Bib => match workspace.config().formatting.bib_formatter { Formatter::Null => None, Formatter::Server => format_bibtex_internal(workspace, document, options), Formatter::LatexIndent => format_with_latexindent(workspace, document), + Formatter::TexFmt => format_with_texfmt(document), }, Language::Aux | Language::Log diff --git a/crates/texlab/src/features/formatting/texfmt.rs b/crates/texlab/src/features/formatting/texfmt.rs new file mode 100644 index 000000000..964e3d14a --- /dev/null +++ b/crates/texlab/src/features/formatting/texfmt.rs @@ -0,0 +1,34 @@ +use std::{ + io::Write, + process::{Command, Stdio}, +}; + +use base_db::Document; +use rowan::{TextLen, TextRange}; + +use crate::util::line_index_ext::LineIndexExt; + +pub fn format_with_texfmt(document: &Document) -> Option> { + let mut child = Command::new("tex-fmt") + .arg("--stdin") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::null()) + .spawn() + .ok()?; + + let mut stdin = child.stdin.take()?; + std::thread::scope(|s| { + s.spawn(move || { + let _ = stdin.write_all(document.text.clone().as_bytes()); + }); + + let output = child.wait_with_output().ok()?; + let new_text = String::from_utf8(output.stdout).ok()?; + let range = document + .line_index + .line_col_lsp_range(TextRange::new(0.into(), document.text.text_len()))?; + + Some(vec![lsp_types::TextEdit { range, new_text }]) + }) +} diff --git a/crates/texlab/src/server/options.rs b/crates/texlab/src/server/options.rs index cce037a0c..96de9f137 100644 --- a/crates/texlab/src/server/options.rs +++ b/crates/texlab/src/server/options.rs @@ -28,6 +28,7 @@ pub enum BibtexFormatter { None, Texlab, Latexindent, + TexFmt, } impl Default for BibtexFormatter { @@ -42,6 +43,7 @@ pub enum LatexFormatter { None, Texlab, Latexindent, + TexFmt, } impl Default for LatexFormatter { diff --git a/crates/texlab/src/util/from_proto.rs b/crates/texlab/src/util/from_proto.rs index e54abf77a..85bf91694 100644 --- a/crates/texlab/src/util/from_proto.rs +++ b/crates/texlab/src/util/from_proto.rs @@ -281,12 +281,14 @@ pub fn config(value: Options) -> Config { LatexFormatter::None => Formatter::Null, LatexFormatter::Texlab => Formatter::Server, LatexFormatter::Latexindent => Formatter::LatexIndent, + LatexFormatter::TexFmt => Formatter::TexFmt, }; config.formatting.bib_formatter = match value.bibtex_formatter { BibtexFormatter::None => Formatter::Null, BibtexFormatter::Texlab => Formatter::Server, BibtexFormatter::Latexindent => Formatter::LatexIndent, + BibtexFormatter::TexFmt => Formatter::TexFmt, }; config.formatting.line_length =