feat: add in-place mode

Resolves #376
This commit is contained in:
Yu Sun 2024-04-18 18:09:45 +08:00
parent 3bf7f9376a
commit d5a859c659
3 changed files with 89 additions and 38 deletions

82
Cargo.lock generated
View File

@ -68,6 +68,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "byteorder"
version = "1.4.3"
@ -92,7 +98,7 @@ version = "4.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"clap_derive",
"clap_lex",
"is-terminal",
@ -133,6 +139,7 @@ dependencies = [
"derive_builder",
"emojis",
"entities",
"in-place",
"memchr",
"ntest",
"once_cell",
@ -295,12 +302,9 @@ dependencies = [
[[package]]
name = "fastrand"
version = "1.8.0"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
dependencies = [
"instant",
]
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
[[package]]
name = "flate2"
@ -367,6 +371,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "in-place"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cdb69f3adfd5f493210cece799f4620417bf9965bc1536c22ae0e29ba27a8c0"
dependencies = [
"tempfile",
]
[[package]]
name = "indexmap"
version = "1.9.2"
@ -377,15 +390,6 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "io-lifetimes"
version = "1.0.3"
@ -404,7 +408,7 @@ checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
dependencies = [
"hermit-abi",
"io-lifetimes",
"rustix",
"rustix 0.36.17",
"windows-sys 0.42.0",
]
@ -422,9 +426,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.139"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "line-wrap"
@ -447,6 +451,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "linux-raw-sys"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "memchr"
version = "2.5.0"
@ -516,7 +526,7 @@ version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"libc",
"once_cell",
"onig_sys",
@ -654,7 +664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12e6c80c1139113c28ee4670dc50cc42915228b51f56a9e407f0ec60f966646f"
dependencies = [
"bit-set",
"bitflags",
"bitflags 1.3.2",
"byteorder",
"lazy_static",
"num-traits",
@ -738,7 +748,7 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@ -775,14 +785,27 @@ version = "0.36.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"linux-raw-sys 0.1.4",
"windows-sys 0.45.0",
]
[[package]]
name = "rustix"
version = "0.38.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
dependencies = [
"bitflags 2.5.0",
"errno",
"libc",
"linux-raw-sys 0.4.13",
"windows-sys 0.52.0",
]
[[package]]
name = "rusty-fork"
version = "0.3.0"
@ -889,7 +912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8"
dependencies = [
"bincode",
"bitflags",
"bitflags 1.3.2",
"fancy-regex",
"flate2",
"fnv",
@ -908,15 +931,14 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.4.0"
version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall",
"rustix",
"windows-sys 0.42.0",
"rustix 0.38.32",
"windows-sys 0.52.0",
]
[[package]]
@ -934,7 +956,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb20089a8ba2b69debd491f8d2d023761cbf196e999218c591fa1e7e15a21907"
dependencies = [
"rustix",
"rustix 0.36.17",
"windows-sys 0.42.0",
]

View File

@ -45,6 +45,7 @@ slug = "0.1.4"
emojis = { version = "0.5.2", optional = true }
arbitrary = { version = "1", optional = true, features = ["derive"] }
derive_builder = "0.12.0"
in-place = "0.2.0"
[dev-dependencies]
ntest = "0.9"

View File

@ -14,10 +14,12 @@ use std::path::PathBuf;
use std::process;
use clap::{Parser, ValueEnum};
use in_place::InPlace;
const EXIT_SUCCESS: i32 = 0;
const EXIT_PARSE_CONFIG: i32 = 2;
const EXIT_READ_INPUT: i32 = 3;
const EXIT_CHECK_FILE_NUM: i32 = 4;
#[derive(Debug, Parser)]
#[command(about, author, version)]
@ -35,6 +37,10 @@ struct Cli {
#[arg(short, long, value_name = "PATH", default_value = get_default_config_path())]
config_file: String,
/// To perform an in-place formatting
#[arg(short, long, conflicts_with_all(["format", "output"]))]
inplace: bool,
/// Treat newlines as hard line breaks
#[arg(long)]
hardbreaks: bool,
@ -204,6 +210,18 @@ fn cli_with_config() -> Cli {
fn main() -> Result<(), Box<dyn Error>> {
let cli = cli_with_config();
if cli.inplace {
if let Some(ref files) = cli.files {
if files.len() != 1 {
eprintln!("cannot have more than 1 input file with in-place mode");
process::exit(EXIT_CHECK_FILE_NUM);
}
} else {
eprintln!("no input file specified: cannot use standard input with in-place mode");
process::exit(EXIT_CHECK_FILE_NUM);
}
}
let exts = &cli.extensions;
let mut extension = ExtensionOptionsBuilder::default();
@ -272,8 +290,8 @@ fn main() -> Result<(), Box<dyn Error>> {
None => {
std::io::stdin().read_to_end(&mut s)?;
}
Some(fs) => {
for f in &fs {
Some(ref fs) => {
for f in fs {
match fs::File::open(f) {
Ok(mut io) => {
io.read_to_end(&mut s)?;
@ -290,19 +308,29 @@ fn main() -> Result<(), Box<dyn Error>> {
let arena = Arena::new();
let root = comrak::parse_document(&arena, &String::from_utf8(s)?, &options);
let formatter = match cli.format {
Format::Html => {
plugins.render.codefence_syntax_highlighter = syntax_highlighter;
comrak::format_html_with_plugins
let formatter = if cli.inplace {
comrak::format_commonmark_with_plugins
} else {
match cli.format {
Format::Html => {
plugins.render.codefence_syntax_highlighter = syntax_highlighter;
comrak::format_html_with_plugins
}
Format::Xml => comrak::format_xml_with_plugins,
Format::CommonMark => comrak::format_commonmark_with_plugins,
}
Format::Xml => comrak::format_xml_with_plugins,
Format::CommonMark => comrak::format_commonmark_with_plugins,
};
if let Some(output_filename) = cli.output {
let mut bw = BufWriter::new(fs::File::create(output_filename)?);
formatter(root, &options, &mut bw, &plugins)?;
bw.flush()?;
} else if cli.inplace {
let inp: in_place::InPlaceFile =
InPlace::new(unsafe { cli.files.unwrap_unchecked().get_unchecked(0) }).open()?;
let mut bw = inp.writer();
formatter(root, &options, &mut bw, &plugins)?;
inp.save()?;
} else {
let stdout = std::io::stdout();
let mut bw = BufWriter::new(stdout.lock());