mirror of
https://github.com/nushell/nushell.git
synced 2024-12-24 16:09:11 +01:00
to html --list
now returns a table (#7080)
* `to html --list` now returns a table * Re-add screenshots link
This commit is contained in:
parent
a783a084d4
commit
f856e64fb3
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
output_string.push_str("\nScreenshots of themes can be found here:\n");
|
||||
output_string.push_str("https://github.com/mbadolato/iTerm2-Color-Schemes\n");
|
||||
})
|
||||
.collect();
|
||||
return Ok(Value::List {
|
||||
vals: result,
|
||||
span: head,
|
||||
}
|
||||
.into_pipeline_data_with_metadata(PipelineMetadata {
|
||||
data_source: DataSource::HtmlThemes,
|
||||
}));
|
||||
} else {
|
||||
let theme_span = match &theme {
|
||||
Some(v) => v.span,
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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> > cd (path) <br><br>Flags:<br> -h, --help - Display the help message for this command<br><br>Parameters:<br> (optional) path <Directory>: the path to change to<br><br>Examples:<br> Change to your home directory<br> > cd ~<br><br> Change to a directory via abbreviations<br> > cd d/s/9<br><br> Change to the previous working directory ($OLDPWD)<br> > 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"}"##
|
||||
);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user