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::{
19	errors::LisaError,
20	input::{autocomplete::AutocompleteProvider, history::HistoryProvider},
21};
22
23/// An input provider is something that is capable of receiving input from
24/// users, holding it, and producing a value to some console at some point
25/// in time.
26///
27/// The input providers job is to provide input events to displays (and
28/// potentially others) and keep state of the current input.
29pub trait InputProvider: Send + Sync {
30	/// If this input is coming from STDIN, and as such an input
31	/// display should be rendered.
32	#[must_use]
33	fn is_stdin(&self) -> bool;
34
35	/// If the input provider is active, and accepting input.
36	#[must_use]
37	fn is_active(&self) -> bool;
38	/// Set this terminal as 'active'.
39	///
40	/// ## Errors
41	///
42	/// If the underlying provider cannot do what it needs to be made active.
43	fn set_active(&mut self, active: bool) -> Result<(), LisaError>;
44
45	/// If this provider has some active input, and someone is actively
46	/// 'typing'.
47	#[must_use]
48	fn input_in_progress(&self) -> bool;
49	/// Get any current input that has been provided.
50	#[must_use]
51	fn current_input(&self) -> String;
52	/// Poll for any active input events.
53	#[must_use]
54	fn poll_for_input(&mut self, ansi_supported: bool) -> Vec<TerminalInputEvent>;
55
56	/// Set the current autocomplete provider for this input provider.
57	fn set_autocomplete_provider(&mut self, autocomplete: Box<dyn AutocompleteProvider>);
58	/// Get the current autocomplete suggestion.
59	#[must_use]
60	fn current_autocomplete_suggestion(&self) -> Option<String>;
61	/// If an autocomplete suggestion is pending, but not yet completed.
62	#[must_use]
63	fn autocomplete_suggestion_pending(&self) -> bool;
64
65	/// Set the current history provider.
66	fn set_history_provider(&mut self, history: Box<dyn HistoryProvider>);
67	/// Get the current history search value that is being found.
68	#[must_use]
69	fn current_history_search_value(&self) -> Option<String>;
70	// If we're actively doing a history search.
71	#[must_use]
72	fn is_doing_history_search(&self) -> bool;
73
74	/// Get any fully complete inputs that have occured since things last ran.
75	#[must_use]
76	fn inputs(&mut self) -> Vec<String>;
77}
78
79/// A terminal input event has occured.
80#[derive(Clone, Debug, PartialEq, Eq, Hash)]
81pub enum TerminalInputEvent {
82	/// Clear the screen if the renderer supports this.
83	ClearScreen,
84	/// Input has been cancelled.
85	InputCancelled,
86	/// The input has had text appended to the end of it.
87	///
88	/// This will only ever be fired when a user has typed/pasted text at the end
89	/// of the line (e.g. not in the midddle).
90	InputAppend(char),
91	/// A lot of inputs have been appended all at once.
92	InputMassAppend(String),
93	/// The input has changed in a way that wasn't an append.
94	///
95	/// A character has been removed, text has been pasted in the middle, etc.
96	InputChanged(usize),
97	/// The input has finished being applied.
98	InputFinished,
99	/// Input has started being input by the user.
100	InputStarted,
101	/// Cursor goes ahead and moves left 'backwards' through the input N spaces.
102	CursorMoveLeft(usize),
103	/// Cursor goes ahead and moves right 'forwards' through the input N spaces.
104	CursorMoveRight(usize),
105	/// Toggle pausing or un-pausing STDOUT/STDERR.
106	ToggleOutputPause,
107}