to html --list now returns a table (#7080)

* `to html --list` now returns a table

* Re-add screenshots link
This commit is contained in:
Leon 2022-11-16 03:12:56 +10:00 committed by GitHub
parent a783a084d4
commit f856e64fb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 156 additions and 18 deletions

View File

@ -86,6 +86,15 @@ impl Command for Metadata {
span: head,
})
}
PipelineMetadata {
data_source: DataSource::HtmlThemes,
} => {
cols.push("source".into());
vals.push(Value::String {
val: "into html --list".into(),
span: head,
})
}
}
}
@ -148,6 +157,15 @@ fn build_metadata_record(arg: &Value, metadata: &Option<PipelineMetadata>, head:
span: head,
})
}
PipelineMetadata {
data_source: DataSource::HtmlThemes,
} => {
cols.push("source".into());
vals.push(Value::String {
val: "into html --list".into(),
span: head,
})
}
}
}

View File

@ -4,8 +4,8 @@ use nu_engine::CallExt;
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
Category, Config, Example, IntoPipelineData, PipelineData, ShellError, Signature, Spanned,
SyntaxShape, Type, Value,
Category, Config, DataSource, Example, IntoPipelineData, PipelineData, PipelineMetadata,
ShellError, Signature, Spanned, SyntaxShape, Type, Value,
};
use rust_embed::RustEmbed;
use serde::{Deserialize, Serialize};
@ -109,7 +109,11 @@ impl Command for ToHtml {
"the name of the theme to use (github, blulocolight, ...)",
Some('t'),
)
.switch("list", "list the names of all available themes", Some('l'))
.switch(
"list",
"produce a color table of all available themes",
Some('l'),
)
.category(Category::Formats)
}
@ -143,6 +147,10 @@ impl Command for ToHtml {
"Convert table into simple HTML"
}
fn extra_usage(&self) -> &str {
"Screenshots of the themes can be browsed here: https://github.com/mbadolato/iTerm2-Color-Schemes"
}
fn run(
&self,
engine_state: &EngineState,
@ -223,12 +231,6 @@ fn get_html_themes(json_name: &str) -> Result<HtmlThemes, Box<dyn Error>> {
}
}
fn get_list_of_theme_names() -> Vec<String> {
// If asset doesn't work, make sure to return the default theme
let html_themes = get_html_themes("228_themes.json").unwrap_or_default();
html_themes.themes.into_iter().map(|n| n.name).collect()
}
fn to_html(
input: PipelineData,
call: &Call,
@ -251,17 +253,76 @@ fn to_html(
let mut output_string = String::new();
let mut regex_hm: HashMap<u32, (&str, String)> = HashMap::with_capacity(17);
// Being essentially a 'help' option, this can afford to be relatively unoptimised
if list {
// Get the list of theme names
let theme_names = get_list_of_theme_names();
// If asset doesn't work, make sure to return the default theme
let html_themes = get_html_themes("228_themes.json").unwrap_or_default();
// Put that list into the output string
for s in &theme_names {
writeln!(&mut output_string, "{}", s).unwrap();
let cols = vec![
"name".into(),
"black".into(),
"red".into(),
"green".into(),
"yellow".into(),
"blue".into(),
"purple".into(),
"cyan".into(),
"white".into(),
"brightBlack".into(),
"brightRed".into(),
"brightGreen".into(),
"brightYellow".into(),
"brightBlue".into(),
"brightPurple".into(),
"brightCyan".into(),
"brightWhite".into(),
"background".into(),
"foreground".into(),
];
let result: Vec<Value> = html_themes
.themes
.into_iter()
.map(|n| {
let vals = vec![
n.name,
n.black,
n.red,
n.green,
n.yellow,
n.blue,
n.purple,
n.cyan,
n.white,
n.brightBlack,
n.brightRed,
n.brightGreen,
n.brightYellow,
n.brightBlue,
n.brightPurple,
n.brightCyan,
n.brightWhite,
n.background,
n.foreground,
]
.into_iter()
.map(|val| Value::String { val, span: head })
.collect();
Value::Record {
cols: cols.clone(),
vals,
span: head,
}
})
.collect();
return Ok(Value::List {
vals: result,
span: head,
}
output_string.push_str("\nScreenshots of themes can be found here:\n");
output_string.push_str("https://github.com/mbadolato/iTerm2-Color-Schemes\n");
.into_pipeline_data_with_metadata(PipelineMetadata {
data_source: DataSource::HtmlThemes,
}));
} else {
let theme_span = match &theme {
Some(v) => v.span,

View File

@ -1,5 +1,5 @@
use lscolors::{LsColors, Style};
use nu_color_config::{get_color_config, style_primitive};
use nu_color_config::{color_from_hex, get_color_config, style_primitive};
use nu_engine::{column::get_columns, env_to_string, CallExt};
use nu_protocol::{
ast::{Call, PathMember},
@ -558,6 +558,7 @@ fn handle_row_stream(
metadata: Option<PipelineMetadata>,
) -> Result<PipelineData, nu_protocol::ShellError> {
let stream = match metadata {
// First, `ls` sources:
Some(PipelineMetadata {
data_source: DataSource::Ls,
}) => {
@ -575,6 +576,7 @@ fn handle_row_stream(
let mut idx = 0;
while idx < cols.len() {
// Only the name column gets special colors, for now
if cols[idx] == "name" {
if let Some(Value::String { val, span }) = vals.get(idx) {
let val = render_path_name(val, &config, &ls_colors, *span);
@ -594,6 +596,46 @@ fn handle_row_stream(
ctrlc,
)
}
// Next, `into html -l` sources:
Some(PipelineMetadata {
data_source: DataSource::HtmlThemes,
}) => {
let ctrlc = ctrlc.clone();
ListStream::from_stream(
stream.map(move |mut x| match &mut x {
Value::Record { cols, vals, .. } => {
let mut idx = 0;
// Every column in the HTML theme table except 'name' is colored
while idx < cols.len() {
if cols[idx] != "name" {
// Simple routine to grab the hex code, convert to a style,
// then place it in a new Value::String.
if let Some(Value::String { val, span }) = vals.get(idx) {
let s = match color_from_hex(val) {
Ok(c) => match c {
// .normal() just sets the text foreground color.
Some(c) => c.normal(),
None => nu_ansi_term::Style::default(),
},
Err(_) => nu_ansi_term::Style::default(),
};
vals[idx] = Value::String {
// Apply the style (ANSI codes) to the string
val: s.paint(val).to_string(),
span: *span,
};
}
}
idx += 1;
}
x
}
_ => x,
}),
ctrlc,
)
}
_ => stream,
};

View File

@ -75,3 +75,15 @@ fn test_no_color_flag() {
r"<html><style>body { background-color:white;color:black; }</style><body>Change directory.<br><br>Usage:<br> &gt; cd (path) <br><br>Flags:<br> -h, --help - Display the help message for this command<br><br>Parameters:<br> (optional) path &lt;Directory&gt;: the path to change to<br><br>Examples:<br> Change to your home directory<br> &gt; cd ~<br><br> Change to a directory via abbreviations<br> &gt; cd d/s/9<br><br> Change to the previous working directory ($OLDPWD)<br> &gt; cd -<br><br></body></html>"
);
}
#[test]
fn test_list() {
let actual = nu!(
cwd: ".",
r#"to html --list | where name == C64 | get 0 | to nuon"#
);
assert_eq!(
actual.out,
r##"{name: C64, black: "#090300", red: "#883932", green: "#55a049", yellow: "#bfce72", blue: "#40318d", purple: "#8b3f96", cyan: "#67b6bd", white: "#ffffff", brightBlack: "#000000", brightRed: "#883932", brightGreen: "#55a049", brightYellow: "#bfce72", brightBlue: "#40318d", brightPurple: "#8b3f96", brightCyan: "#67b6bd", brightWhite: "#f7f7f7", background: "#40318d", foreground: "#7869c4"}"##
);
}

View File

@ -56,6 +56,7 @@ pub struct PipelineMetadata {
#[derive(Debug, Clone)]
pub enum DataSource {
Ls,
HtmlThemes,
}
impl PipelineData {
@ -595,6 +596,7 @@ impl Iterator for PipelineIterator {
pub trait IntoPipelineData {
fn into_pipeline_data(self) -> PipelineData;
fn into_pipeline_data_with_metadata(self, metadata: PipelineMetadata) -> PipelineData;
}
impl<V> IntoPipelineData for V
@ -604,6 +606,9 @@ where
fn into_pipeline_data(self) -> PipelineData {
PipelineData::Value(self.into(), None)
}
fn into_pipeline_data_with_metadata(self, metadata: PipelineMetadata) -> PipelineData {
PipelineData::Value(self.into(), Some(metadata))
}
}
pub trait IntoInterruptiblePipelineData {