mirror of
https://github.com/nushell/nushell.git
synced 2025-08-16 23:41:40 +02:00
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 🤔  ## After The database gets displayed like a record  ## 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:
@ -6,20 +6,19 @@ mod pager;
|
||||
mod registry;
|
||||
mod views;
|
||||
|
||||
use anyhow::Result;
|
||||
use commands::{ExpandCmd, HelpCmd, NuCmd, QuitCmd, TableCmd, TryCmd};
|
||||
pub use default_context::add_explore_context;
|
||||
pub use explore::Explore;
|
||||
|
||||
use commands::{ExpandCmd, HelpCmd, HelpManual, NuCmd, QuitCmd, TableCmd, TryCmd};
|
||||
use nu_common::{collect_pipeline, has_simple_value, CtrlC};
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, Stack},
|
||||
PipelineData, Value,
|
||||
};
|
||||
use pager::{Page, Pager, PagerConfig, StyleConfig};
|
||||
use registry::{Command, CommandRegistry};
|
||||
use std::io;
|
||||
use registry::CommandRegistry;
|
||||
use terminal_size::{Height, Width};
|
||||
use views::{BinaryView, InformationView, Orientation, Preview, RecordView};
|
||||
use views::{BinaryView, Orientation, Preview, RecordView};
|
||||
|
||||
mod util {
|
||||
pub use super::nu_common::{create_lscolors, create_map, map_into_value};
|
||||
@ -31,7 +30,7 @@ fn run_pager(
|
||||
ctrlc: CtrlC,
|
||||
input: PipelineData,
|
||||
config: PagerConfig,
|
||||
) -> io::Result<Option<Value>> {
|
||||
) -> Result<Option<Value>> {
|
||||
let mut p = Pager::new(config.clone());
|
||||
let commands = create_command_registry();
|
||||
|
||||
@ -45,18 +44,18 @@ fn run_pager(
|
||||
return p.run(engine_state, stack, ctrlc, view, commands);
|
||||
}
|
||||
|
||||
let (columns, data) = collect_pipeline(input);
|
||||
let (columns, data) = collect_pipeline(input)?;
|
||||
|
||||
let has_no_input = columns.is_empty() && data.is_empty();
|
||||
if has_no_input {
|
||||
return p.run(engine_state, stack, ctrlc, information_view(), commands);
|
||||
return p.run(engine_state, stack, ctrlc, help_view(), commands);
|
||||
}
|
||||
|
||||
p.show_message("For help type :help");
|
||||
|
||||
if let Some(value) = has_simple_value(&data) {
|
||||
let text = value.to_abbreviated_string(config.nu_config);
|
||||
let view = Some(Page::new(Preview::new(&text), true));
|
||||
let view = Some(Page::new(Preview::new(&text), false));
|
||||
return p.run(engine_state, stack, ctrlc, view, commands);
|
||||
}
|
||||
|
||||
@ -67,6 +66,7 @@ fn run_pager(
|
||||
fn create_record_view(
|
||||
columns: Vec<String>,
|
||||
data: Vec<Vec<Value>>,
|
||||
// wait, why would we use RecordView for something that isn't a record?
|
||||
is_record: bool,
|
||||
config: PagerConfig,
|
||||
) -> Option<Page> {
|
||||
@ -75,17 +75,17 @@ fn create_record_view(
|
||||
view.set_orientation_current(Orientation::Left);
|
||||
}
|
||||
|
||||
if config.reverse {
|
||||
if config.tail {
|
||||
if let Some((Width(w), Height(h))) = terminal_size::terminal_size() {
|
||||
view.reverse(w, h);
|
||||
view.tail(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
Some(Page::new(view, false))
|
||||
Some(Page::new(view, true))
|
||||
}
|
||||
|
||||
fn information_view() -> Option<Page> {
|
||||
Some(Page::new(InformationView, true))
|
||||
fn help_view() -> Option<Page> {
|
||||
Some(Page::new(HelpCmd::view(), false))
|
||||
}
|
||||
|
||||
fn binary_view(input: PipelineData) -> Option<Page> {
|
||||
@ -96,7 +96,7 @@ fn binary_view(input: PipelineData) -> Option<Page> {
|
||||
|
||||
let view = BinaryView::new(data);
|
||||
|
||||
Some(Page::new(view, false))
|
||||
Some(Page::new(view, true))
|
||||
}
|
||||
|
||||
fn create_command_registry() -> CommandRegistry {
|
||||
@ -104,24 +104,16 @@ fn create_command_registry() -> CommandRegistry {
|
||||
create_commands(&mut registry);
|
||||
create_aliases(&mut registry);
|
||||
|
||||
// reregister help && config commands
|
||||
let commands = registry.get_commands().cloned().collect::<Vec<_>>();
|
||||
let aliases = registry.get_aliases().collect::<Vec<_>>();
|
||||
|
||||
let help_cmd = create_help_command(&commands, &aliases);
|
||||
|
||||
registry.register_command_view(help_cmd, true);
|
||||
|
||||
registry
|
||||
}
|
||||
|
||||
fn create_commands(registry: &mut CommandRegistry) {
|
||||
registry.register_command_view(NuCmd::new(), false);
|
||||
registry.register_command_view(TableCmd::new(), false);
|
||||
registry.register_command_view(NuCmd::new(), true);
|
||||
registry.register_command_view(TableCmd::new(), true);
|
||||
|
||||
registry.register_command_view(ExpandCmd::new(), true);
|
||||
registry.register_command_view(TryCmd::new(), true);
|
||||
registry.register_command_view(HelpCmd::default(), true);
|
||||
registry.register_command_view(ExpandCmd::new(), false);
|
||||
registry.register_command_view(TryCmd::new(), false);
|
||||
registry.register_command_view(HelpCmd::default(), false);
|
||||
|
||||
registry.register_command_reactive(QuitCmd);
|
||||
}
|
||||
@ -132,34 +124,3 @@ fn create_aliases(registry: &mut CommandRegistry) {
|
||||
registry.create_aliases("q", QuitCmd::NAME);
|
||||
registry.create_aliases("q!", QuitCmd::NAME);
|
||||
}
|
||||
|
||||
fn create_help_command(commands: &[Command], aliases: &[(&str, &str)]) -> HelpCmd {
|
||||
let help_manuals = create_help_manuals(commands);
|
||||
|
||||
HelpCmd::new(help_manuals, aliases)
|
||||
}
|
||||
|
||||
fn create_help_manuals(cmd_list: &[Command]) -> Vec<HelpManual> {
|
||||
cmd_list.iter().map(create_help_manual).collect()
|
||||
}
|
||||
|
||||
fn create_help_manual(cmd: &Command) -> HelpManual {
|
||||
let name = match cmd {
|
||||
Command::Reactive(cmd) => cmd.name(),
|
||||
Command::View { cmd, .. } => cmd.name(),
|
||||
};
|
||||
|
||||
let manual = match cmd {
|
||||
Command::Reactive(cmd) => cmd.help(),
|
||||
Command::View { cmd, .. } => cmd.help(),
|
||||
};
|
||||
|
||||
__create_help_manual(manual, name)
|
||||
}
|
||||
|
||||
fn __create_help_manual(manual: Option<HelpManual>, name: &'static str) -> HelpManual {
|
||||
manual.unwrap_or(HelpManual {
|
||||
name,
|
||||
..HelpManual::default()
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user