explore: adopt anyhow, support CustomValue, remove help system (#12692)

This PR:
1. Adds basic support for `CustomValue` to `explore`. Previously `open
foo.db | explore` didn't really work, now we "materialize" the whole
database to a `Value` before loading it
2. Adopts `anyhow` for error handling in `explore`. Previously we were
kind of rolling our own version of `anyhow` by shoving all errors into a
`std::io::Error`; I think this is much nicer. This was necessary because
as part of 1), collecting input is now fallible...
3. Removes a lot of `explore`'s fancy command help system.
- Previously each command (`:help`, `:try`, etc.) had a sophisticated
help system with examples etc... but this was not very visible to users.
You had to know to run `:help :try` or view a list of commands with
`:help :`
- As discussed previously, we eventually want to move to a less modal
approach for `explore`, without the Vim-like commands. And so I don't
think it's worth keeping this command help system around (it's
intertwined with other stuff, and making these changes would have been
harder if keeping it).
4. Rename the `--reverse` flag to `--tail`. The flag scrolls to the end
of the data, which IMO is described better by "tail"
5. Does some renaming+commenting to clear up things I found difficult to
understand when navigating the `explore` code


I initially thought 1) would be just a few lines, and then this PR blew
up into much more extensive changes 😅


## Before
The whole database was being displayed as a single Nuon/JSON line 🤔 

![image](https://github.com/nushell/nushell/assets/26268125/6383f43b-fdff-48b4-9604-398438ad1499)


## After
The database gets displayed like a record

![image](https://github.com/nushell/nushell/assets/26268125/2f00ed7b-a3c4-47f4-a08c-98d07efc7bb4)


## Future work

It is sort of annoying that we have to load a whole SQLite database into
memory to make this work; it will be impractical for large databases.
I'd like to explore improvements to `CustomValue` that can make this
work more efficiently.
This commit is contained in:
Reilly Wood
2024-05-01 15:34:37 -07:00
committed by GitHub
parent bc18cc12d5
commit 3d340657b5
21 changed files with 283 additions and 842 deletions

View File

@ -1,9 +1,9 @@
use super::pager::{Pager, Transition};
use anyhow::Result;
use nu_protocol::{
engine::{EngineState, Stack},
Value,
};
use std::{borrow::Cow, io::Result};
mod expand;
mod help;
@ -24,8 +24,6 @@ pub trait SimpleCommand {
fn usage(&self) -> &'static str;
fn help(&self) -> Option<HelpManual>;
fn parse(&mut self, args: &str) -> Result<()>;
fn react(
@ -44,8 +42,6 @@ pub trait ViewCommand {
fn usage(&self) -> &'static str;
fn help(&self) -> Option<HelpManual>;
fn parse(&mut self, args: &str) -> Result<()>;
fn spawn(
@ -56,116 +52,9 @@ pub trait ViewCommand {
) -> Result<Self::View>;
}
#[derive(Debug, Default, Clone)]
pub struct HelpManual {
pub name: &'static str,
pub description: &'static str,
pub arguments: Vec<HelpExample>,
pub examples: Vec<HelpExample>,
pub config_options: Vec<ConfigOption>,
pub input: Vec<Shortcode>,
}
#[derive(Debug, Default, Clone)]
pub struct HelpExample {
pub example: Cow<'static, str>,
pub description: Cow<'static, str>,
}
impl HelpExample {
pub fn new(
example: impl Into<Cow<'static, str>>,
description: impl Into<Cow<'static, str>>,
) -> Self {
Self {
example: example.into(),
description: description.into(),
}
}
}
#[derive(Debug, Default, Clone)]
pub struct Shortcode {
pub code: &'static str,
pub context: &'static str,
pub description: &'static str,
}
impl Shortcode {
pub fn new(code: &'static str, context: &'static str, description: &'static str) -> Self {
Self {
code,
context,
description,
}
}
}
#[derive(Debug, Default, Clone)]
pub struct ConfigOption {
pub group: String,
pub description: String,
pub key: String,
pub values: Vec<HelpExample>,
}
impl ConfigOption {
pub fn new<N, D, K>(group: N, description: D, key: K, values: Vec<HelpExample>) -> Self
where
N: Into<String>,
D: Into<String>,
K: Into<String>,
{
Self {
group: group.into(),
description: description.into(),
key: key.into(),
values,
}
}
pub fn boolean<N, D, K>(group: N, description: D, key: K) -> Self
where
N: Into<String>,
D: Into<String>,
K: Into<String>,
{
Self {
group: group.into(),
description: description.into(),
key: key.into(),
values: vec![
HelpExample::new("true", "Turn the flag on"),
HelpExample::new("false", "Turn the flag on"),
],
}
}
}
#[rustfmt::skip]
pub fn default_color_list() -> Vec<HelpExample> {
vec![
HelpExample::new("red", "Red foreground"),
HelpExample::new("blue", "Blue foreground"),
HelpExample::new("green", "Green foreground"),
HelpExample::new("yellow", "Yellow foreground"),
HelpExample::new("magenta", "Magenta foreground"),
HelpExample::new("black", "Black foreground"),
HelpExample::new("white", "White foreground"),
HelpExample::new("#AA4433", "#AA4433 HEX foreground"),
HelpExample::new(r#"{bg: "red"}"#, "Red background"),
HelpExample::new(r#"{bg: "blue"}"#, "Blue background"),
HelpExample::new(r#"{bg: "green"}"#, "Green background"),
HelpExample::new(r#"{bg: "yellow"}"#, "Yellow background"),
HelpExample::new(r#"{bg: "magenta"}"#, "Magenta background"),
HelpExample::new(r#"{bg: "black"}"#, "Black background"),
HelpExample::new(r#"{bg: "white"}"#, "White background"),
HelpExample::new(r##"{bg: "#AA4433"}"##, "#AA4433 HEX background"),
]
}
pub fn default_int_list() -> Vec<HelpExample> {
(0..20)
.map(|i| HelpExample::new(i.to_string(), format!("A value equal to {i}")))
.collect()
}