Skip to content

Commit c92c3d4

Browse files
committed
This branch is behind on same changes.
2 parents 5bffdc9 + 2b2aeaa commit c92c3d4

File tree

12 files changed

+212
-148
lines changed

12 files changed

+212
-148
lines changed

Diff for: Cargo.lock

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ strum = { version = "0.19.5", features = ["derive"] }
2929
image = "0.23.10"
3030
regex = "1"
3131
futures = "0.3.6"
32-
tokio = { version = "0.3.0", features = ["full"] }
32+
tokio = { version = "0.3.1", features = ["full"] }
3333
error-chain = "0.12"
3434

3535
[target.'cfg(windows)'.dependencies]

Diff for: src/main.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// `error_chain!` can recurse deeply
22
#![recursion_limit = "1024"]
33

4-
use onefetch::{cli::Cli, error::*, info};
4+
use onefetch::{cli::Cli, cli_utils, error::*, info};
55

66
use {
77
process::{Command, Stdio},
8-
std::process,
8+
std::{io, process},
99
};
1010

1111
mod onefetch;
@@ -22,12 +22,15 @@ fn run() -> Result<()> {
2222
let options = Cli::new()?;
2323

2424
if options.print_languages {
25-
return Cli::print_supported_languages();
25+
return cli_utils::print_supported_languages();
2626
}
2727

2828
let info = info::Info::new(options)?;
2929

30-
print!("{}", info);
30+
let mut printer = cli_utils::Printer::new(io::BufWriter::new(io::stdout()), info);
31+
32+
printer.print()?;
33+
3134
Ok(())
3235
}
3336

@@ -38,7 +41,7 @@ fn main() {
3841
process::exit(0);
3942
}
4043
Err(error) => {
41-
let stderr = std::io::stderr();
44+
let stderr = io::stderr();
4245
default_error_handler(&error, &mut stderr.lock());
4346
process::exit(1);
4447
}

Diff for: src/onefetch/ascii_art.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use colored::{Color, Colorize};
22

33
pub struct AsciiArt<'a> {
44
content: Box<dyn 'a + Iterator<Item = &'a str>>,
5-
colors: Vec<Color>,
5+
colors: &'a [Color],
66
bold: bool,
77
start: usize,
88
end: usize,
99
}
1010
impl<'a> AsciiArt<'a> {
11-
pub fn new(input: &'a str, colors: Vec<Color>, bold: bool) -> AsciiArt<'a> {
11+
pub fn new(input: &'a str, colors: &'a [Color], bold: bool) -> AsciiArt<'a> {
1212
let mut lines: Vec<_> = input.lines().skip_while(|line| line.is_empty()).collect();
1313
while let Some(line) = lines.last() {
1414
if Tokens(line).is_empty() {

Diff for: src/onefetch/cli.rs

+38-27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use {
22
crate::onefetch::{
3-
error::*, image_backends, info_fields, info_fields::InfoFields, language::Language,
3+
cli_utils,
4+
error::*,
5+
image_backends,
6+
info_fields::{self, InfoFields},
7+
language::Language,
48
},
59
clap::{crate_description, crate_name, crate_version, App, AppSettings, Arg},
610
image::DynamicImage,
@@ -17,12 +21,14 @@ pub struct Cli {
1721
pub no_bold: bool,
1822
pub image: Option<DynamicImage>,
1923
pub image_backend: Option<Box<dyn image_backends::ImageBackend>>,
24+
pub image_colors: usize,
2025
pub no_merges: bool,
2126
pub no_color_blocks: bool,
2227
pub number_of_authors: usize,
2328
pub excluded: Vec<String>,
2429
pub print_languages: bool,
2530
pub true_color: bool,
31+
pub art_off: bool,
2632
}
2733

2834
impl Cli {
@@ -116,7 +122,7 @@ impl Cli {
116122
Arg::with_name("languages")
117123
.short("l")
118124
.long("languages")
119-
.help("Prints out supported languages"),
125+
.help("Prints out supported languages."),
120126
)
121127
.arg(
122128
Arg::with_name("image")
@@ -125,7 +131,7 @@ impl Cli {
125131
.value_name("IMAGE")
126132
.takes_value(true)
127133
.max_values(1)
128-
.help("Path to the IMAGE file"),
134+
.help("Path to the IMAGE file."),
129135
)
130136
.arg(
131137
Arg::with_name("image-backend")
@@ -136,15 +142,25 @@ impl Cli {
136142
.possible_values(&possible_backends)
137143
.help("Which image BACKEND to use."),
138144
)
145+
.arg(
146+
Arg::with_name("color-resolution")
147+
.long("color-resolution")
148+
.value_name("VALUE")
149+
.requires("image")
150+
.takes_value(true)
151+
.max_values(1)
152+
.possible_values(&["16", "32", "64", "128", "256"])
153+
.help("VALUE of color resolution to use with SIXEL backend."),
154+
)
139155
.arg(
140156
Arg::with_name("no-merge-commits")
141157
.long("no-merge-commits")
142-
.help("Ignores merge commits"),
158+
.help("Ignores merge commits."),
143159
)
144160
.arg(
145161
Arg::with_name("no-color-blocks")
146162
.long("no-color-blocks")
147-
.help("Hides the color blocks"),
163+
.help("Hides the color blocks."),
148164
)
149165
.arg(
150166
Arg::with_name("authors-number")
@@ -172,13 +188,20 @@ impl Cli {
172188
.multiple(true)
173189
.takes_value(true)
174190
.help("Ignore all files & directories matching EXCLUDE."),
191+
)
192+
.arg(
193+
Arg::with_name("off")
194+
.long("off")
195+
.help("Only shows the info lines.")
196+
.conflicts_with_all(&["image", "ascii-language", "ascii-input"]),
175197
).get_matches();
176198

177199
let no_bold = matches.is_present("no-bold");
178200
let no_merges = matches.is_present("no-merge-commits");
179201
let no_color_blocks = matches.is_present("no-color-blocks");
180202
let print_languages = matches.is_present("languages");
181-
let true_color = is_truecolor_terminal();
203+
let art_off = matches.is_present("off");
204+
let true_color = cli_utils::is_truecolor_terminal();
182205

183206
let fields_to_hide: Vec<String> = if let Some(values) = matches.values_of("disable-fields")
184207
{
@@ -203,6 +226,12 @@ impl Cli {
203226
None
204227
};
205228

229+
let image_colors = if let Some(value) = matches.value_of("color-resolution") {
230+
usize::from_str(value).unwrap()
231+
} else {
232+
16
233+
};
234+
206235
let path = String::from(matches.value_of("input").unwrap());
207236

208237
let ascii_input = matches.value_of("ascii-input").map(String::from);
@@ -221,11 +250,7 @@ impl Cli {
221250

222251
let disabled_fields = info_fields::get_disabled_fields(fields_to_hide)?;
223252

224-
let number_of_authors = if let Some(value) = matches.value_of("authors-number") {
225-
usize::from_str(value).unwrap()
226-
} else {
227-
3
228-
};
253+
let number_of_authors: usize = matches.value_of("authors-number").unwrap().parse().unwrap();
229254

230255
let excluded = if let Some(user_ignored) = matches.values_of("exclude") {
231256
user_ignored.map(String::from).collect()
@@ -242,28 +267,14 @@ impl Cli {
242267
no_bold,
243268
image,
244269
image_backend,
270+
image_colors,
245271
no_merges,
246272
no_color_blocks,
247273
number_of_authors,
248274
excluded,
249275
print_languages,
250276
true_color,
277+
art_off,
251278
})
252279
}
253-
254-
pub fn print_supported_languages() -> Result<()> {
255-
let iterator = Language::iter().filter(|x| *x != Language::Unknown);
256-
257-
for l in iterator {
258-
println!("{}", l);
259-
}
260-
261-
Ok(())
262-
}
263-
}
264-
265-
fn is_truecolor_terminal() -> bool {
266-
env::var("COLORTERM")
267-
.map(|colorterm| colorterm == "truecolor" || colorterm == "24bit")
268-
.unwrap_or(false)
269280
}

Diff for: src/onefetch/cli_utils.rs

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
use crate::onefetch::{ascii_art::AsciiArt, error::*, info::Info, language::Language};
2+
use colored::Color;
3+
use std::env;
4+
use std::io::Write;
5+
use strum::IntoEnumIterator;
6+
7+
pub struct Printer<W> {
8+
writer: W,
9+
info: Info,
10+
}
11+
12+
impl<W: Write> Printer<W> {
13+
pub fn new(writer: W, info: Info) -> Self {
14+
Self { writer, info }
15+
}
16+
17+
pub fn print(&mut self) -> Result<()> {
18+
let center_pad = " ";
19+
let info_str = format!("{}", &self.info);
20+
let mut info_lines = info_str.lines();
21+
let colors: Vec<Color> = Vec::new();
22+
let mut buf = String::new();
23+
24+
if self.info.config.art_off {
25+
buf.push_str(&info_str);
26+
} else if let Some(custom_image) = &self.info.config.image {
27+
if let Some(image_backend) = &self.info.config.image_backend {
28+
buf.push_str(&image_backend.add_image(
29+
info_lines.map(|s| format!("{}{}", center_pad, s)).collect(),
30+
custom_image,
31+
self.info.config.image_colors,
32+
));
33+
} else {
34+
panic!("No image backend found")
35+
}
36+
} else {
37+
let mut logo_lines = if let Some(custom_ascii) = &self.info.config.ascii_input {
38+
AsciiArt::new(custom_ascii, &colors, !self.info.config.no_bold)
39+
} else {
40+
AsciiArt::new(
41+
self.get_ascii(),
42+
&self.info.colors,
43+
!self.info.config.no_bold,
44+
)
45+
};
46+
47+
loop {
48+
match (logo_lines.next(), info_lines.next()) {
49+
(Some(logo_line), Some(info_line)) => {
50+
buf.push_str(&format!("{}{}{:^}\n", logo_line, center_pad, info_line))
51+
}
52+
(Some(logo_line), None) => buf.push_str(&format!("{}\n", logo_line)),
53+
(None, Some(info_line)) => buf.push_str(&format!(
54+
"{:<width$}{}{:^}\n",
55+
"",
56+
center_pad,
57+
info_line,
58+
width = logo_lines.width()
59+
)),
60+
(None, None) => {
61+
buf.push('\n');
62+
break;
63+
}
64+
}
65+
}
66+
}
67+
68+
write!(self.writer, "{}", buf)?;
69+
70+
Ok(())
71+
}
72+
73+
fn get_ascii(&self) -> &str {
74+
let language = if let Language::Unknown = self.info.config.ascii_language {
75+
&self.info.dominant_language
76+
} else {
77+
&self.info.config.ascii_language
78+
};
79+
80+
language.get_ascii_art()
81+
}
82+
}
83+
84+
pub fn print_supported_languages() -> Result<()> {
85+
let iterator = Language::iter().filter(|x| *x != Language::Unknown);
86+
87+
for l in iterator {
88+
println!("{}", l);
89+
}
90+
91+
Ok(())
92+
}
93+
94+
pub fn is_truecolor_terminal() -> bool {
95+
env::var("COLORTERM")
96+
.map(|colorterm| colorterm == "truecolor" || colorterm == "24bit")
97+
.unwrap_or(false)
98+
}

Diff for: src/onefetch/image_backends/kitty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl KittyBackend {
7777
}
7878

7979
impl super::ImageBackend for KittyBackend {
80-
fn add_image(&self, lines: Vec<String>, image: &DynamicImage) -> String {
80+
fn add_image(&self, lines: Vec<String>, image: &DynamicImage, _colors: usize) -> String {
8181
let tty_size = unsafe {
8282
let tty_size: winsize = std::mem::zeroed();
8383
ioctl(STDOUT_FILENO, TIOCGWINSZ, &tty_size);

Diff for: src/onefetch/image_backends/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub mod kitty;
66
pub mod sixel;
77

88
pub trait ImageBackend {
9-
fn add_image(&self, lines: Vec<String>, image: &DynamicImage) -> String;
9+
fn add_image(&self, lines: Vec<String>, image: &DynamicImage, colors: usize) -> String;
1010
}
1111

1212
#[cfg(not(windows))]

Diff for: src/onefetch/image_backends/sixel.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl SixelBackend {
7171
}
7272

7373
impl super::ImageBackend for SixelBackend {
74-
fn add_image(&self, lines: Vec<String>, image: &DynamicImage) -> String {
74+
fn add_image(&self, lines: Vec<String>, image: &DynamicImage, colors: usize) -> String {
7575
let tty_size = unsafe {
7676
let tty_size: winsize = std::mem::zeroed();
7777
ioctl(STDOUT_FILENO, TIOCGWINSZ, &tty_size);
@@ -97,7 +97,7 @@ impl super::ImageBackend for SixelBackend {
9797
// reduce the amount of colors using dithering
9898
colorops::dither(
9999
&mut rgba_image,
100-
&NeuQuant::new(10, 16, flat_samples.image_slice().unwrap()),
100+
&NeuQuant::new(10, colors, flat_samples.image_slice().unwrap()),
101101
);
102102
let rgb_image = ImageBuffer::from_fn(rgba_image.width(), rgba_image.height(), |x, y| {
103103
let rgba_pixel = rgba_image.get_pixel(x, y);

0 commit comments

Comments
 (0)