rm_lisa/input/mod.rs
1//! Handle receiving input from somewhere, and use it to produce strings
2//! somewhere else.
3//!
4//! NOTE: Inputs do not actually have to come from STDIN. They can come from
5//! anywhere, e.g. a server listening on a unix socket. Of course accepting
6//! commands from remote places that aren't on STDIN could introduce security
7//! concerns, that's for you to deal with, but is possible.
8//!
9//! Input Providers also _are not in charge_ of rendering inputs, and should
10//! _hide_ any input that users are putting in. They should instead keep a
11//! buffer of the current input string, and pass it the display when asked for.
12//! The display will then render the command however it sees fit.
13
14pub mod autocomplete;
15pub mod history;
16pub mod stdin;
17
18use crate::errors::LisaError;
19
20/// An input provider is something that is capable of receiving input from
21/// users, holding it, and producing a value to some console at some point
22/// in time.
23///
24/// The input providers job is to provide input events to displays (and
25/// potentially others) and keep state of the current input.
26pub trait InputProvider: Send + Sync {
27 /// If this input is coming from STDIN, and as such an input
28 /// display should be rendered.
29 #[must_use]
30 fn is_stdin(&self) -> bool;
31
32 /// If the input provider is active, and accepting input.
33 #[must_use]
34 fn is_active(&self) -> bool;
35 /// Set this terminal as 'active'.
36 ///
37 /// ## Errors
38 ///
39 /// If the underlying provider cannot do what it needs to be made active.
40 fn set_active(&mut self, active: bool) -> Result<(), LisaError>;
41
42 /// If this provider has some active input, and someone is actively
43 /// 'typing'.
44 #[must_use]
45 fn input_in_progress(&self) -> bool;
46 /// Get any current input that has been provided.
47 #[must_use]
48 fn current_input(&self) -> String;
49 /// Poll for any active input events.
50 #[must_use]
51 fn poll_for_input(&mut self, ansi_supported: bool) -> Vec<TerminalInputEvent>;
52
53 /// Get the current autocomplete suggestion.
54 #[must_use]
55 fn current_autocomplete_suggestion(&self) -> Option<String>;
56 /// If an autocomplete suggestion is pending, but not yet completed.
57 #[must_use]
58 fn autocomplete_suggestion_pending(&self) -> bool;
59
60 /// Get the current history search value that is being found.
61 #[must_use]
62 fn current_history_search_value(&self) -> Option<String>;
63 // If we're actively doing a history search.
64 #[must_use]
65 fn is_doing_history_search(&self) -> bool;
66
67 /// Get any fully complete inputs that have occured since things last ran.
68 #[must_use]
69 fn inputs(&mut self) -> Vec<String>;
70}
71
72/// A terminal input event has occured.
73#[derive(Clone, Debug, PartialEq, Eq, Hash)]
74pub enum TerminalInputEvent {
75 /// Clear the screen if the renderer supports this.
76 ClearScreen,
77 /// Input has been cancelled.
78 InputCancelled,
79 /// The input has had text appended to the end of it.
80 ///
81 /// This will only ever be fired when a user has typed/pasted text at the end
82 /// of the line (e.g. not in the midddle).
83 InputAppend(char),
84 /// A lot of inputs have been appended all at once.
85 InputMassAppend(String),
86 /// The input has changed in a way that wasn't an append.
87 ///
88 /// A character has been removed, text has been pasted in the middle, etc.
89 InputChanged(usize),
90 /// The input has finished being applied.
91 InputFinished,
92 /// Input has started being input by the user.
93 InputStarted,
94 /// Cursor goes ahead and moves left 'backwards' through the input N spaces.
95 CursorMoveLeft(usize),
96 /// Cursor goes ahead and moves right 'forwards' through the input N spaces.
97 CursorMoveRight(usize),
98 /// Toggle pausing or un-pausing STDOUT/STDERR.
99 ToggleOutputPause,
100}