mirror of
https://github.com/nushell/nushell.git
synced 2025-01-11 16:58:41 +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,
|
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,
|
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::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
Category, Config, Example, IntoPipelineData, PipelineData, ShellError, Signature, Spanned,
|
Category, Config, DataSource, Example, IntoPipelineData, PipelineData, PipelineMetadata,
|
||||||
SyntaxShape, Type, Value,
|
ShellError, Signature, Spanned, SyntaxShape, Type, Value,
|
||||||
};
|
};
|
||||||
use rust_embed::RustEmbed;
|
use rust_embed::RustEmbed;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -109,7 +109,11 @@ impl Command for ToHtml {
|
|||||||
"the name of the theme to use (github, blulocolight, ...)",
|
"the name of the theme to use (github, blulocolight, ...)",
|
||||||
Some('t'),
|
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)
|
.category(Category::Formats)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +147,10 @@ impl Command for ToHtml {
|
|||||||
"Convert table into simple HTML"
|
"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(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
engine_state: &EngineState,
|
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(
|
fn to_html(
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
@ -251,17 +253,76 @@ fn to_html(
|
|||||||
let mut output_string = String::new();
|
let mut output_string = String::new();
|
||||||
let mut regex_hm: HashMap<u32, (&str, String)> = HashMap::with_capacity(17);
|
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 {
|
if list {
|
||||||
// Get the list of theme names
|
// If asset doesn't work, make sure to return the default theme
|
||||||
let theme_names = get_list_of_theme_names();
|
let html_themes = get_html_themes("228_themes.json").unwrap_or_default();
|
||||||
|
|
||||||
// Put that list into the output string
|
let cols = vec![
|
||||||
for s in &theme_names {
|
"name".into(),
|
||||||
writeln!(&mut output_string, "{}", s).unwrap();
|
"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,
|
||||||
}
|
}
|
||||||
|
.into_pipeline_data_with_metadata(PipelineMetadata {
|
||||||
output_string.push_str("\nScreenshots of themes can be found here:\n");
|
data_source: DataSource::HtmlThemes,
|
||||||
output_string.push_str("https://github.com/mbadolato/iTerm2-Color-Schemes\n");
|
}));
|
||||||
} else {
|
} else {
|
||||||
let theme_span = match &theme {
|
let theme_span = match &theme {
|
||||||
Some(v) => v.span,
|
Some(v) => v.span,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use lscolors::{LsColors, Style};
|
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_engine::{column::get_columns, env_to_string, CallExt};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Call, PathMember},
|
ast::{Call, PathMember},
|
||||||
@ -558,6 +558,7 @@ fn handle_row_stream(
|
|||||||
metadata: Option<PipelineMetadata>,
|
metadata: Option<PipelineMetadata>,
|
||||||
) -> Result<PipelineData, nu_protocol::ShellError> {
|
) -> Result<PipelineData, nu_protocol::ShellError> {
|
||||||
let stream = match metadata {
|
let stream = match metadata {
|
||||||
|
// First, `ls` sources:
|
||||||
Some(PipelineMetadata {
|
Some(PipelineMetadata {
|
||||||
data_source: DataSource::Ls,
|
data_source: DataSource::Ls,
|
||||||
}) => {
|
}) => {
|
||||||
@ -575,6 +576,7 @@ fn handle_row_stream(
|
|||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
|
|
||||||
while idx < cols.len() {
|
while idx < cols.len() {
|
||||||
|
// Only the name column gets special colors, for now
|
||||||
if cols[idx] == "name" {
|
if cols[idx] == "name" {
|
||||||
if let Some(Value::String { val, span }) = vals.get(idx) {
|
if let Some(Value::String { val, span }) = vals.get(idx) {
|
||||||
let val = render_path_name(val, &config, &ls_colors, *span);
|
let val = render_path_name(val, &config, &ls_colors, *span);
|
||||||
@ -594,6 +596,46 @@ fn handle_row_stream(
|
|||||||
ctrlc,
|
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,
|
_ => 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>"
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum DataSource {
|
pub enum DataSource {
|
||||||
Ls,
|
Ls,
|
||||||
|
HtmlThemes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineData {
|
impl PipelineData {
|
||||||
@ -595,6 +596,7 @@ impl Iterator for PipelineIterator {
|
|||||||
|
|
||||||
pub trait IntoPipelineData {
|
pub trait IntoPipelineData {
|
||||||
fn into_pipeline_data(self) -> PipelineData;
|
fn into_pipeline_data(self) -> PipelineData;
|
||||||
|
fn into_pipeline_data_with_metadata(self, metadata: PipelineMetadata) -> PipelineData;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V> IntoPipelineData for V
|
impl<V> IntoPipelineData for V
|
||||||
@ -604,6 +606,9 @@ where
|
|||||||
fn into_pipeline_data(self) -> PipelineData {
|
fn into_pipeline_data(self) -> PipelineData {
|
||||||
PipelineData::Value(self.into(), None)
|
PipelineData::Value(self.into(), None)
|
||||||
}
|
}
|
||||||
|
fn into_pipeline_data_with_metadata(self, metadata: PipelineMetadata) -> PipelineData {
|
||||||
|
PipelineData::Value(self.into(), Some(metadata))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IntoInterruptiblePipelineData {
|
pub trait IntoInterruptiblePipelineData {
|
||||||
|
Loading…
Reference in New Issue
Block a user