git.delta.rocks / jrsonnet / refs/commits / 752087cb9057

difftreelog

feat more formatter options

uqnknwssYaroslav Bolyukin2026-05-06parent: #aa77bfb.patch.diff
in: master

3 files changed

modifiedbindings/jrsonnet-web/src/lib.rsdiffbeforeafterboth
--- a/bindings/jrsonnet-web/src/lib.rs
+++ b/bindings/jrsonnet-web/src/lib.rs
@@ -614,17 +614,25 @@
 #[wasm_bindgen(js_name = FormatOptions)]
 pub struct WasmFormatOptions {
 	indent: u8,
+	use_tabs: bool,
+	max_width: u32,
 }
 #[wasm_bindgen(js_class = FormatOptions)]
 impl WasmFormatOptions {
 	#[wasm_bindgen(constructor)]
 	pub fn new() -> Self {
-		Self { indent: 0 }
+		Self {
+			indent: 4,
+			use_tabs: true,
+			max_width: 100,
+		}
 	}
 
 	fn build(&self) -> FormatOptions {
 		FormatOptions {
 			indent: self.indent,
+			use_tabs: self.use_tabs,
+			max_width: self.max_width,
 		}
 	}
 }
modifiedcmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth
before · cmds/jrsonnet-fmt/src/main.rs
1use std::{2	fs,3	io::{self, Write as _},4	path::PathBuf,5	process,6};78use clap::Parser;9use jrsonnet_formatter::{FormatOptions, format};1011#[derive(Parser)]12#[allow(clippy::struct_excessive_bools)]13struct Opts {14	/// Treat input as code, reformat it instead of reading file.15	#[clap(long, short = 'e')]16	exec: bool,17	/// Path to be reformatted if `--exec` if unset, otherwise code itself.18	input: String,19	/// Replace code with formatted in-place, instead of printing it to stdout.20	/// Only applicable if `--exec` is unset.21	#[clap(long, short = 'i')]22	in_place: bool,2324	/// Exit with error if formatted does not match input25	#[arg(long)]26	test: bool,27	/// Number of spaces to indent with28	#[arg(long, default_value = "2")]29	indent: u8,30	/// Force hard tab for indentation31	#[arg(long)]32	hard_tabs: bool,3334	/// Debug option: how many times to call reformatting in case of unstable dprint output resolution.35	///36	/// 0 for not retrying to reformat.37	#[arg(long, default_value = "0")]38	conv_limit: usize,39}4041#[derive(thiserror::Error, Debug)]42enum Error {43	#[error("--in-place is incompatible with --exec")]44	InPlaceExec,45	#[error("io: {0}")]46	Io(#[from] io::Error),47	#[error("persist: {0}")]48	Persist(#[from] tempfile::PersistError),49	#[error("parsing failed, refusing to reformat corrupted input")]50	Parse,51}5253fn main_result() -> Result<(), Error> {54	eprintln!(55		"jrsonnet-fmt is a prototype of a jsonnet code formatter, do not expect it to produce meaningful results right now."56	);57	eprintln!(58		"It is not expected for its output to match other implementations, it will be completly separate implementation with maybe different name."59	);60	let mut opts = Opts::parse();61	let input = if opts.exec {62		if opts.in_place {63			return Err(Error::InPlaceExec);64		}65		opts.input.clone()66	} else {67		fs::read_to_string(&opts.input)?68	};6970	if opts.indent == 0 {71		// Sane default.72		// TODO: Implement actual guessing.73		opts.hard_tabs = true;74	}7576	let mut iteration = 0;77	let mut formatted = input.clone();78	let mut convergence_tmp;79	// https://github.com/dprint/dprint/pull/42380	loop {81		let reformatted = match format(82			&formatted,83			&FormatOptions {84				indent: if opts.indent == 0 || opts.hard_tabs {85					086				} else {87					opts.indent88				},89			},90		) {91			Ok(v) => v,92			Err(e) => {93				let snippet = e.build();94				let ansi = hi_doc::source_to_ansi(&snippet);95				eprintln!("{ansi}");96				return Err(Error::Parse);97			}98		};99		convergence_tmp = reformatted.trim().to_owned();100		if formatted == convergence_tmp {101			break;102		}103		formatted = convergence_tmp;104		if opts.conv_limit == 0 {105			break;106		}107		iteration += 1;108		assert!(iteration <= opts.conv_limit, "formatting not converged");109	}110	formatted.push('\n');111	if opts.test && formatted != input {112		process::exit(1);113	}114	if opts.in_place {115		let path = PathBuf::from(opts.input);116		let mut temp = tempfile::NamedTempFile::new_in(path.parent().expect(117			"not failed during read, this path is not a directory, and there is a parent",118		))?;119		temp.write_all(formatted.as_bytes())?;120		temp.flush()?;121		temp.persist(&path)?;122	} else {123		print!("{formatted}");124	}125	Ok(())126}127128fn main() {129	if let Err(e) = main_result() {130		eprintln!("{e}");131		process::exit(1);132	}133}
after · cmds/jrsonnet-fmt/src/main.rs
1use std::{2	fs,3	io::{self, Write as _},4	path::PathBuf,5	process,6};78use clap::Parser;9use jrsonnet_formatter::{FormatOptions, format};1011#[derive(Parser)]12#[allow(clippy::struct_excessive_bools)]13struct Opts {14	/// Treat input as code, reformat it instead of reading file.15	#[clap(long, short = 'e')]16	exec: bool,17	/// Path to be reformatted if `--exec` if unset, otherwise code itself.18	input: String,19	/// Replace code with formatted in-place, instead of printing it to stdout.20	/// Only applicable if `--exec` is unset.21	#[clap(long, short = 'i')]22	in_place: bool,2324	/// Exit with error if formatted does not match input25	#[arg(long)]26	test: bool,27	/// Number of spaces to indent with28	#[arg(long, default_value = "4")]29	indent: u8,30	/// Force hard tab for indentation31	#[arg(long, default_value = "true")]32	use_tabs: bool,33	/// Max formatted source width34	#[arg(long, default_value = "100")]35	max_width: u32,3637	/// Debug option: how many times to call reformatting in case of unstable dprint output resolution.38	///39	/// 0 for not retrying to reformat.40	#[arg(long, default_value = "0")]41	conv_limit: usize,42}4344#[derive(thiserror::Error, Debug)]45enum Error {46	#[error("--in-place is incompatible with --exec")]47	InPlaceExec,48	#[error("io: {0}")]49	Io(#[from] io::Error),50	#[error("persist: {0}")]51	Persist(#[from] tempfile::PersistError),52	#[error("parsing failed, refusing to reformat corrupted input")]53	Parse,54}5556fn main_result() -> Result<(), Error> {57	let opts = Opts::parse();58	let input = if opts.exec {59		if opts.in_place {60			return Err(Error::InPlaceExec);61		}62		opts.input.clone()63	} else {64		fs::read_to_string(&opts.input)?65	};6667	let mut iteration = 0;68	let mut formatted = input.clone();69	let mut convergence_tmp;70	// https://github.com/dprint/dprint/pull/42371	loop {72		let reformatted = match format(73			&formatted,74			&FormatOptions {75				indent: opts.indent,76				use_tabs: opts.use_tabs,77				max_width: opts.max_width,78			},79		) {80			Ok(v) => v,81			Err(e) => {82				let snippet = e.build();83				let ansi = hi_doc::source_to_ansi(&snippet);84				eprintln!("{ansi}");85				return Err(Error::Parse);86			}87		};88		convergence_tmp = reformatted.trim().to_owned();89		if formatted == convergence_tmp {90			break;91		}92		formatted = convergence_tmp;93		if opts.conv_limit == 0 {94			break;95		}96		iteration += 1;97		assert!(iteration <= opts.conv_limit, "formatting not converged");98	}99	formatted.push('\n');100	if opts.test && formatted != input {101		process::exit(1);102	}103	if opts.in_place {104		let path = PathBuf::from(opts.input);105		let mut temp = tempfile::NamedTempFile::new_in(path.parent().expect(106			"not failed during read, this path is not a directory, and there is a parent",107		))?;108		temp.write_all(formatted.as_bytes())?;109		temp.flush()?;110		temp.persist(&path)?;111	} else {112		print!("{formatted}");113	}114	Ok(())115}116117fn main() {118	if let Err(e) = main_result() {119		eprintln!("{e}");120		process::exit(1);121	}122}
modifiedcrates/jrsonnet-formatter/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-formatter/src/lib.rs
+++ b/crates/jrsonnet-formatter/src/lib.rs
@@ -901,14 +901,25 @@
 	}
 }
 
-#[derive(Default)]
 pub struct FormatOptions {
-	// 0 for hard tabs, otherwise number of spaces
 	pub indent: u8,
+	pub use_tabs: bool,
+	pub max_width: u32,
 }
+
 impl FormatOptions {
 	pub fn new() -> Self {
-		Self::default()
+		Self {
+			indent: 4,
+			use_tabs: true,
+			max_width: 100,
+		}
+	}
+}
+
+impl Default for FormatOptions {
+	fn default() -> Self {
+		Self::new()
 	}
 }
 
@@ -947,14 +958,9 @@
 			out
 		},
 		PrintOptions {
-			indent_width: if opts.indent == 0 {
-				// Reasonable max length for both 2 and 4 space sized tabs.
-				3
-			} else {
-				opts.indent
-			},
-			max_width: 100,
-			use_tabs: opts.indent == 0,
+			indent_width: opts.indent,
+			max_width: opts.max_width,
+			use_tabs: opts.use_tabs,
 			new_line_text: "\n",
 		},
 	))