nu_explore/
lib.rs

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