Repository: dtolnay/cargo-expand (language: rust)

Issue:
adjust the default color disposition in .cargo/config
It would be great if I could set `--color always` to be the default. Maybe like this:

```toml
[expand]
theme = "TwoDark"
color = "always"
```

If that sounds reasonable I'd be happy to submit a PR--and thanks for building this!


Discussion / hints:
Sure, I would accept a PR for this. Please also include it in the Configuration section of the readme. Cheers!

Fix patch:
diff --git a/README.md b/README.md
index 668c007..caf6c9b 100644
--- a/README.md
+++ b/README.md
@@ -107,8 +107,9 @@ To expand a specific module or type or function only:
 ## Configuration
 
 The cargo expand command reads the `[expand]` section of $CARGO_HOME/config if
-there is one (usually ~/.cargo/config). Currently the only configuration option
-is the syntax highlighting theme.
+there is one (usually ~/.cargo/config).
+
+Set the default syntax highlighting theme with the `theme` setting:
 
 ```toml
 [expand]
@@ -118,6 +119,14 @@ theme = "TwoDark"
 Run `cargo expand --themes` to print a list of available themes. Use `theme =
 "none"` to disable coloring.
 
+Change the default coloring disposition (normally `auto`) with the `color`
+setting:
+
+```toml
+[expand]
+color = "always"
+```
+
 ## Disclaimer
 
 Be aware that macro expansion to text is a lossy process. This is a debugging
diff --git a/src/config.rs b/src/config.rs
index 2573f8e..20add0a 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -14,6 +14,7 @@ struct Sections {
 #[derive(Deserialize, Default)]
 pub struct Config {
     pub theme: Option<String>,
+    pub color: Option<String>,
 }
 
 pub fn deserialize() -> Config {
diff --git a/src/main.rs b/src/main.rs
index 8751c6c..04cb35f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,6 +11,7 @@ use std::fs;
 use std::io::{self, BufRead, Write};
 use std::path::{Path, PathBuf};
 use std::process::{self, Command, Stdio};
+use std::str::FromStr;
 
 use atty::Stream::{Stderr, Stdout};
 use prettyprint::{PagingMode, PrettyPrinter};
@@ -19,6 +20,7 @@ use structopt::StructOpt;
 use termcolor::{Color::Green, ColorChoice, ColorSpec, StandardStream, WriteColor};
 
 use crate::cmd::Line;
+use crate::config::Config;
 use crate::error::Result;
 use crate::opts::Coloring::*;
 use crate::opts::{Args, Coloring, Opts};
@@ -140,10 +142,11 @@ fn cargo_expand() -> Result<i32> {
     builder.prefix("cargo-expand");
     let outdir = builder.tempdir().expect("failed to create tmp file");
     let outfile_path = outdir.path().join("expanded");
+    let color = get_color(&args, &config);
 
     // Run cargo
     let mut cmd = Command::new(cargo_binary());
-    apply_args(&mut cmd, &args, &outfile_path);
+    apply_args(&mut cmd, &args, &color, &outfile_path);
     let code = filter_err(&mut cmd, ignore_cargo_err)?;
 
     if !outfile_path.exists() {
@@ -196,10 +199,10 @@ fn cargo_expand() -> Result<i32> {
     // Run pretty printer
     let theme = args.theme.or(config.theme);
     let none_theme = theme.as_ref().map(String::as_str) == Some("none");
-    let do_color = match args.color {
-        Some(Always) => true,
-        Some(Never) => false,
-        None | Some(Auto) => !none_theme && atty::is(Stdout),
+    let do_color = match color {
+        Always => true,
+        Never => false,
+        Auto => !none_theme && atty::is(Stdout),
     };
     let _ = writeln!(io::stderr());
     if do_color {
@@ -244,7 +247,7 @@ fn which_rustfmt() -> Option<PathBuf> {
 }
 
 // Based on https://github.com/rsolomo/cargo-check
-fn apply_args(cmd: &mut Command, args: &Args, outfile: &Path) {
+fn apply_args(cmd: &mut Command, args: &Args, color: &Coloring, outfile: &Path) {
     let mut line = Line::new("cargo");
 
     line.arg("rustc");
@@ -322,10 +325,9 @@ fn apply_args(cmd: &mut Command, args: &Args, outfile: &Path) {
     }
 
     line.arg("--color");
-    if let Some(color) = &args.color {
-        line.arg(color.to_string());
-    } else {
-        line.arg(if atty::is(Stderr) { "always" } else { "never" });
+    match color {
+        Coloring::Auto => line.arg(if atty::is(Stderr) { "always" } else { "never" }),
+        color => line.arg(color.to_string()),
     }
 
     if args.frozen {
@@ -351,17 +353,17 @@ fn apply_args(cmd: &mut Command, args: &Args, outfile: &Path) {
     if args.verbose {
         let mut display = line.clone();
         display.insert(0, "+nightly");
-        print_command(display, args);
+        print_command(display, color);
     }
 
     cmd.args(line);
 }
 
-fn print_command(line: Line, args: &Args) {
-    let color_choice = match args.color {
-        Some(Coloring::Auto) | None => ColorChoice::Auto,
-        Some(Coloring::Always) => ColorChoice::Always,
-        Some(Coloring::Never) => ColorChoice::Never,
+fn print_command(line: Line, color: &Coloring) {
+    let color_choice = match color {
+        Coloring::Auto => ColorChoice::Auto,
+        Coloring::Always => ColorChoice::Always,
+        Coloring::Never => ColorChoice::Never,
     };
 
     let mut stream = StandardStream::stderr(color_choice);
@@ -411,3 +413,24 @@ fn ignore_cargo_err(line: &str) -> bool {
 
     false
 }
+
+fn get_color(args: &Args, config: &Config) -> Coloring {
+    if let Some(value) = args.color {
+        return value;
+    }
+
+    if let Some(value) = config.color.as_ref() {
+        match Coloring::from_str(value.as_str()) {
+            Ok(color) => return color,
+            Err(err) => {
+                let _ = writeln!(
+                    io::stderr(),
+                    "WARNING: invalid color in cargo config: {}",
+                    err
+                );
+            }
+        }
+    }
+
+    Coloring::Auto // default
+}
diff --git a/src/opts.rs b/src/opts.rs
index 2df005f..b06bc3e 100644
--- a/src/opts.rs
+++ b/src/opts.rs
@@ -115,7 +115,7 @@ pub struct Args {
     pub item: Option<Selector>,
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
 pub enum Coloring {
     Auto,
     Always,


Test patch: