nu_explore/
lib.rs

1#![doc = include_str!("../README.md")]
2mod commands;
3mod default_context;
4mod explore;
5mod explore_regex;
6mod nu_common;
7mod pager;
8mod registry;
9mod views;
10
11use anyhow::Result;
12use commands::{ExpandCmd, HelpCmd, NuCmd, QuitCmd, TableCmd, TryCmd};
13use crossterm::terminal::size;
14pub use default_context::add_explore_context;
15pub use explore::Explore;
16use explore::ExploreConfig;
17use explore_regex::ExploreRegex;
18use nu_common::{collect_pipeline, has_simple_value};
19use nu_protocol::{
20    PipelineData, Value,
21    engine::{EngineState, Stack},
22};
23use pager::{Page, Pager, PagerConfig};
24use registry::CommandRegistry;
25use views::{BinaryView, Orientation, Preview, RecordView};
26
27mod util {
28    pub use super::nu_common::{create_lscolors, create_map};
29}
30
31fn run_pager(
32    engine_state: &EngineState,
33    stack: &mut Stack,
34    input: PipelineData,
35    config: PagerConfig,
36) -> Result<Option<Value>> {
37    let mut p = Pager::new(config.clone());
38    let commands = create_command_registry();
39
40    let is_record = matches!(input, PipelineData::Value(Value::Record { .. }, ..));
41    let is_binary = matches!(
42        input,
43        PipelineData::Value(Value::Binary { .. }, ..) | PipelineData::ByteStream(..)
44    );
45
46    if is_binary {
47        p.show_message("For help type :help");
48
49        let view = binary_view(input, config.explore_config)?;
50        return p.run(engine_state, stack, Some(view), commands);
51    }
52
53    let (columns, data) = collect_pipeline(input)?;
54
55    let has_no_input = columns.is_empty() && data.is_empty();
56    if has_no_input {
57        return p.run(engine_state, stack, help_view(), commands);
58    }
59
60    p.show_message("For help type :help");
61
62    if let Some(value) = has_simple_value(&data) {
63        let text = value.to_abbreviated_string(config.nu_config);
64        let view = Some(Page::new(Preview::new(&text), false));
65        return p.run(engine_state, stack, view, commands);
66    }
67
68    let view = create_record_view(columns, data, is_record, config);
69    p.run(engine_state, stack, view, commands)
70}
71
72fn create_record_view(
73    columns: Vec<String>,
74    data: Vec<Vec<Value>>,
75    // wait, why would we use RecordView for something that isn't a record?
76    is_record: bool,
77    config: PagerConfig,
78) -> Option<Page> {
79    let mut view = RecordView::new(columns, data, config.explore_config.clone());
80    if is_record {
81        view.set_top_layer_orientation(Orientation::Left);
82    }
83
84    if config.tail
85        && let Ok((w, h)) = size()
86    {
87        view.tail(w, h);
88    }
89
90    Some(Page::new(view, true))
91}
92
93fn help_view() -> Option<Page> {
94    Some(Page::new(HelpCmd::view(), false))
95}
96
97fn binary_view(input: PipelineData, config: &ExploreConfig) -> Result<Page> {
98    let data = match input {
99        PipelineData::Value(Value::Binary { val, .. }, _) => val,
100        PipelineData::ByteStream(bs, _) => bs.into_bytes()?,
101        _ => unreachable!("checked beforehand"),
102    };
103
104    let view = BinaryView::new(data, config);
105
106    Ok(Page::new(view, true))
107}
108
109fn create_command_registry() -> CommandRegistry {
110    let mut registry = CommandRegistry::new();
111    create_commands(&mut registry);
112    create_aliases(&mut registry);
113
114    registry
115}
116
117fn create_commands(registry: &mut CommandRegistry) {
118    registry.register_command_view(NuCmd::new(), true);
119    registry.register_command_view(TableCmd::new(), true);
120
121    registry.register_command_view(ExpandCmd::new(), false);
122    registry.register_command_view(TryCmd::new(), false);
123    registry.register_command_view(HelpCmd::default(), false);
124
125    registry.register_command_reactive(QuitCmd);
126}
127
128fn create_aliases(registry: &mut CommandRegistry) {
129    registry.create_aliases("h", HelpCmd::NAME);
130    registry.create_aliases("e", ExpandCmd::NAME);
131    registry.create_aliases("q", QuitCmd::NAME);
132    registry.create_aliases("q!", QuitCmd::NAME);
133}