mirror of
https://github.com/eza-community/eza.git
synced 2025-08-04 17:08:42 +00:00
feat(json): starting to parse json as per asked in #768
This commit is contained in:
parent
285cd3ed0e
commit
18cace298e
6 changed files with 125 additions and 1 deletions
36
src/main.rs
36
src/main.rs
|
@ -396,6 +396,8 @@ impl<'args> Exa<'args> {
|
|||
..
|
||||
} = self.options.view;
|
||||
|
||||
debug!("matching on mode {:?}, {:?}", mode, self.console_width);
|
||||
|
||||
match (mode, self.console_width) {
|
||||
(Mode::Grid(ref opts), Some(console_width)) => {
|
||||
let filter = &self.options.filter;
|
||||
|
@ -490,6 +492,40 @@ impl<'args> Exa<'args> {
|
|||
};
|
||||
r.render(&mut self.writer)
|
||||
}
|
||||
|
||||
(Mode::Json(ref opts), _) => match opts {
|
||||
Some(o) => {
|
||||
let filter = &self.options.filter;
|
||||
let recurse = self.options.dir_action.recurse_options();
|
||||
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
|
||||
let git = self.git.as_ref();
|
||||
let git_repos = self.git_repos;
|
||||
|
||||
let r = details::Render {
|
||||
dir,
|
||||
files,
|
||||
theme,
|
||||
file_style,
|
||||
opts: o,
|
||||
recurse,
|
||||
filter,
|
||||
git_ignoring,
|
||||
git,
|
||||
git_repos,
|
||||
};
|
||||
r.render_as_json(&mut self.writer)
|
||||
}
|
||||
None => {
|
||||
let filter = &self.options.filter;
|
||||
let r = lines::Render {
|
||||
files,
|
||||
theme,
|
||||
file_style,
|
||||
filter,
|
||||
};
|
||||
r.render_as_json(&mut self.writer)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
use crate::options::parser::{Arg, Args, TakesValue, Values};
|
||||
|
||||
// exa options
|
||||
|
@ -6,6 +7,7 @@ pub static HELP: Arg = Arg { short: Some(b'?'), long: "help", takes_value
|
|||
|
||||
// display options
|
||||
pub static ONE_LINE: Arg = Arg { short: Some(b'1'), long: "oneline", takes_value: TakesValue::Forbidden };
|
||||
pub static JSON: Arg = Arg { short: None, long: "json", takes_value: TakesValue::Forbidden };
|
||||
pub static LONG: Arg = Arg { short: Some(b'l'), long: "long", takes_value: TakesValue::Forbidden };
|
||||
pub static GRID: Arg = Arg { short: Some(b'G'), long: "grid", takes_value: TakesValue::Forbidden };
|
||||
pub static ACROSS: Arg = Arg { short: Some(b'x'), long: "across", takes_value: TakesValue::Forbidden };
|
||||
|
@ -88,7 +90,7 @@ pub static FILE_FLAGS: Arg = Arg { short: Some(b'O'), long: "flags",
|
|||
pub static ALL_ARGS: Args = Args(&[
|
||||
&VERSION, &HELP,
|
||||
|
||||
&ONE_LINE, &LONG, &GRID, &ACROSS, &RECURSE, &TREE, &CLASSIFY, &DEREF_LINKS,
|
||||
&ONE_LINE, &JSON, &LONG, &GRID, &ACROSS, &RECURSE, &TREE, &CLASSIFY, &DEREF_LINKS,
|
||||
&COLOR, &COLOUR, &COLOR_SCALE, &COLOUR_SCALE, &COLOR_SCALE_MODE, &COLOUR_SCALE_MODE,
|
||||
&WIDTH, &NO_QUOTES, &ABSOLUTE,
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ impl Mode {
|
|||
|| f.matches(&flags::ONE_LINE)
|
||||
|| f.matches(&flags::GRID)
|
||||
|| f.matches(&flags::TREE)
|
||||
|| f.matches(&flags::JSON)
|
||||
});
|
||||
|
||||
let Some(flag) = flag else {
|
||||
|
@ -89,6 +90,17 @@ impl Mode {
|
|||
return Ok(Self::Lines);
|
||||
}
|
||||
|
||||
if flag.matches(&flags::JSON) && !flag.matches(&flags::ONE_LINE) {
|
||||
let _ = matches.has(&flags::JSON)?;
|
||||
let details = details::Options::deduce_long(matches, vars)?;
|
||||
return Ok(Self::Json(Some(details)));
|
||||
}
|
||||
|
||||
if flag.matches(&flags::JSON) && flag.matches(&flags::ONE_LINE) {
|
||||
let _ = matches.has(&flags::JSON)?;
|
||||
return Ok(Self::Json(None));
|
||||
}
|
||||
|
||||
let grid = grid::Options::deduce(matches)?;
|
||||
Ok(Self::Grid(grid))
|
||||
}
|
||||
|
|
|
@ -222,6 +222,64 @@ impl<'a> Render<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn render_as_json<W: Write>(mut self, w: &mut W) -> io::Result<()> {
|
||||
let n_cpus = match num_cpus::get() as u32 {
|
||||
0 => 1,
|
||||
n => n,
|
||||
};
|
||||
let mut pool = Pool::new(n_cpus);
|
||||
let mut rows = Vec::new();
|
||||
|
||||
if let Some(ref options) = self.opts.table {
|
||||
let mut table = Table::new(options, self.git, self.theme, self.git_repos);
|
||||
|
||||
if self.opts.header {
|
||||
let header = table.header_row();
|
||||
table.add_widths(&header);
|
||||
}
|
||||
|
||||
// This is weird, but I can’t find a way around it:
|
||||
// https://internals.rust-lang.org/t/should-option-mut-t-implement-copy/3715/6
|
||||
let mut table = Some(table);
|
||||
self.add_files_to_table(
|
||||
&mut pool,
|
||||
&mut table,
|
||||
&mut rows,
|
||||
&self.files,
|
||||
TreeDepth::root(),
|
||||
None,
|
||||
);
|
||||
|
||||
write!(w, "{}", "{\"files\":[")?;
|
||||
for (i, row) in self.iterate_with_table(table.unwrap(), rows).enumerate() {
|
||||
write!(w, "\"{}\"", row.strings())?;
|
||||
if (i + 1) < self.files.len() {
|
||||
write!(w, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(w, "{}", "]}}\n")?;
|
||||
} else {
|
||||
self.add_files_to_table(
|
||||
&mut pool,
|
||||
&mut None,
|
||||
&mut rows,
|
||||
&self.files,
|
||||
TreeDepth::root(),
|
||||
None,
|
||||
);
|
||||
|
||||
write!(w, "{}", "{\"files\":[")?;
|
||||
for (i, row) in self.iterate(rows).enumerate() {
|
||||
write!(w, "\"{}\"", row.strings())?;
|
||||
if (i + 1) < self.files.len() {
|
||||
write!(w, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(w, "{}", "]}}\n")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Whether to show the extended attribute hint
|
||||
pub fn show_xattr_hint(&self, file: &File<'_>) -> bool {
|
||||
// Do not show the hint '@' if the only extended attribute is the security
|
||||
|
|
|
@ -34,4 +34,19 @@ impl<'a> Render<'a> {
|
|||
.with_mount_details(false)
|
||||
.paint()
|
||||
}
|
||||
|
||||
pub fn render_as_json<W: Write>(mut self, w: &mut W) -> io::Result<()> {
|
||||
self.filter.sort_files(&mut self.files);
|
||||
write!(w, "{}", "{\"files\":[")?;
|
||||
for (i, file) in self.files.iter().enumerate() {
|
||||
let name_cell = self.render_file(file);
|
||||
write!(w, "\"{}\"", ANSIStrings(&name_cell))?;
|
||||
if (i + 1) < self.files.len() {
|
||||
write!(w, "{}", ",")?;
|
||||
}
|
||||
}
|
||||
write!(w, "{}", "]}\n")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ pub enum Mode {
|
|||
Details(details::Options),
|
||||
GridDetails(grid_details::Options),
|
||||
Lines,
|
||||
Json(Option<details::Options>),
|
||||
}
|
||||
|
||||
/// The width of the terminal requested by the user.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue