pub struct InputOutput { /* private fields */ }Expand description
Receives input from, and sends output to, the terminal. You can send
output from any number of threads
(see Output::clone_output), but
only one thread at a time may have ownership of the overlying InputOutput
type and therefore the ability to receive input.
Implementations§
Source§impl InputOutput
impl InputOutput
pub fn new() -> InputOutput
Sourcepub async fn die(self)
pub async fn die(self)
Erase the prompt/status lines, put the terminal in a sensible mode,
and otherwise clean up everything we’ve done to the terminal. This will
happen automatically when this InputOutput instance is dropped; you
only need this method if you want to shut Liso down asynchronously for
some reason.
If Outputs cloned from this InputOutput exist, they will be “dead”;
calling their methods will panic!
Sourcepub fn blocking_die(self)
pub fn blocking_die(self)
Erase the prompt/status lines, put the terminal in a sensible mode,
and otherwise clean up everything we’ve done to the terminal. This will
happen automatically when this InputOutput instance is dropped, so
you probably don’t need to call this manually.
If OutputOnlys cloned from this InputOutput exist, they will be
“dead”; calling their methods will panic!
Sourcepub async fn read_async(&mut self) -> Response
pub async fn read_async(&mut self) -> Response
Read a Response from the user, blocking this
task until something is received.
This is an asynchronous function. To read from non-asynchronous code,
you should use read_blocking instead.
If Response::Dead is received too many times, Liso will assume your
program is ignoring it and panic! Avoid this problem by handling
Response::Dead correctly.
Sourcepub fn read_timeout(&mut self, timeout: Duration) -> Option<Response>
pub fn read_timeout(&mut self, timeout: Duration) -> Option<Response>
Read a Response from the user, blocking this
thread until the given timeout elapses or something is received.
This is a synchronous function. To achieve the same effect
asynchronously, you can wrap read_async in tokio::time::timeout.
If Response::Dead is received too many times, Liso will assume your
program is ignoring it and panic! Avoid this problem by handling
Response::Dead correctly.
Sourcepub fn read_deadline(&mut self, deadline: Instant) -> Option<Response>
pub fn read_deadline(&mut self, deadline: Instant) -> Option<Response>
Read a Response from the user, blocking this
thread until the given deadline is reached or something is received.
This is a synchronous function. To achieve the same effect
asynchronously, you can wrap read_async in tokio::time::timeout_at.
If Response::Dead is received too many times, Liso will assume your
program is ignoring it and panic! Avoid this problem by handling
Response::Dead correctly.
Sourcepub fn read_blocking(&mut self) -> Response
pub fn read_blocking(&mut self) -> Response
Read a Response from the user, blocking this
thread until something is received.
This is a synchronous function. To read from asynchronous code, you
should use read_async instead.
If Response::Dead is received too many times, Liso will assume your
program is ignoring it and panic! Avoid this problem by handling
Response::Dead correctly.
Sourcepub fn try_read(&mut self) -> Option<Response>
pub fn try_read(&mut self) -> Option<Response>
Read a Response from the user, if one is
available. If no inputs are currently available, return immediately
instead of blocking or waiting.
If Response::Dead is received too many times, Liso will assume your
program is ignoring it and panic! Avoid this problem by handling
Response::Dead correctly.
Sourcepub fn swap_history(&self, history: History) -> History
pub fn swap_history(&self, history: History) -> History
Provide a new History for Liso to use. Returns the old History
instance.
Sourcepub fn read_history(&self) -> RwLockReadGuard<'_, History>
pub fn read_history(&self) -> RwLockReadGuard<'_, History>
Lock the History for reading and return a reference to it. Make it
brief!
Methods from Deref<Target = Output>§
Sourcepub fn echoln<T>(&self, line: T)
pub fn echoln<T>(&self, line: T)
Prints a (possibly styled) line of regular output to the screen, but only if we are being run interactively. Use this if you want to to echo commands entered by the user, so that echoed commands will not gum up the output when we are outputting to a pipe.
Note: As usual with Output methods, you can pass a
Line, a plain String/&str, or a Cow<str>
here. See also the liso! macro.
Sourcepub fn status<T>(&self, line: Option<T>)
pub fn status<T>(&self, line: Option<T>)
Sets the status line to the given (possibly styled) text. This will be displayed above the prompt, but below printed output. (Does nothing in pipe mode.)
Note: status(Some("")) and status(None) will have different
results! The former will display a blank status line, while the
latter will display no status line.
Note: As usual with Output methods, you can pass a
Line, a plain String/&str, or a Cow<str>
here. See also the liso! macro.
Sourcepub fn remove_status(&self)
pub fn remove_status(&self)
Removes the status line. This is equivalent to status(None) but
without needing a turbofish.
Sourcepub fn notice<T>(&self, line: T, max_duration: Duration)
pub fn notice<T>(&self, line: T, max_duration: Duration)
Displays a (possibly styled) notice that temporarily replaces the prompt. The notice will disappear when the allotted time elapses, when the user presses any key, or when another notice is displayed, whichever happens first. (Does nothing in pipe mode.)
You should only use this in direct response to user input; in fact, the
only legitimate use may be to complain about an unknown control
character. (See Response for an example of this use.)
Note: As usual with Output methods, you can pass a
Line, a plain String/&str, or a Cow<str>
here. See also the liso! macro.
Sourcepub fn prompt<T>(&self, line: T, input_allowed: bool, clear_input: bool)
pub fn prompt<T>(&self, line: T, input_allowed: bool, clear_input: bool)
Sets the prompt to the given (possibly styled) text. The prompt is displayed in front of the user’s input, unless we are running in pipe mode.
The default prompt is blank, with input allowed.
input_allowed: True if the user should be allowed to write input.clear_input: True if any existing partial input should be cleared when the new prompt is displayed. (Ifinput_allowedis false, this should probably betrue.)
Note: If the prompt is styled, whatever style is active at the end of
the prompt will be used when displaying the user’s input. This is the
only circumstance in which Liso will not automatically reset style
information for you at the end of a Line.
Note: When running in pipe mode, input is always allowed, there is no way to clear buffered input, and prompts are never displayed. In short, this function does nothing at all in pipe mode.
Note: As usual with Output methods, you can pass a
Line, a plain String/&str, or a Cow<str>
here. See also the liso! macro.
Sourcepub fn suspend_and_run<F: 'static + FnMut() + Send>(&self, f: F)
pub fn suspend_and_run<F: 'static + FnMut() + Send>(&self, f: F)
Use this when you need to perform some work that outputs directly to stdout/stderr and can’t run it through Liso. Prompt, status, and input in progress will be erased from the screen, and the terminal will be put back into normal mode. When the function returns, Liso will set up the terminal, display the prompt, and continue as normal.
Bear in mind that this will run in a separate thread, possibly after a short delay. If you need to return a value, wait for completion, or otherwise communicate with the main program, you should use the usual inter-thread communication primitives, such as channels or atomics.
Note that you cannot use this to create a subprocess that will read
from stdin! Even though output is suspended, Liso will still be
reading from stdin in another thread, and thus, will be competing with
the subprocess for user input. (On sane UNIXes, this will result in
your program being suspended by your shell, and then misbehaving when
it resumes.) If you want to create a subprocess that can use stdin and
stdout, you’ll have to write your own pipe handling based around Liso.
If you want to create a subprocess that can interactively use the
terminal—you have to drop the InputOutput instance, and all of the
existing Output instances will go dead as a result. Just don’t do it!
Sourcepub fn clone_output(&self) -> OutputOnly
pub fn clone_output(&self) -> OutputOnly
Make a new OutputOnly that can also output to the terminal. The clone
and the original can be stored in separate places, even in different
threads or tasks. All output will go to the same terminal, without any
conflict between other threads doing output simultaneously or with user
input.
For OutputOnly, this is the same as clone. For InputOutput, you
must call this method instead, as this makes it clear that you are not
trying to clone the Input half of that InputOutput.
Sourcepub fn send_custom<T: Any + Send>(&self, value: T)
pub fn send_custom<T: Any + Send>(&self, value: T)
Send the given value to the input thread, wrapped in a
Response::Custom.
Sourcepub fn send_custom_box(&self, value: Box<dyn Any + Send>)
pub fn send_custom_box(&self, value: Box<dyn Any + Send>)
Send the given already-boxed value to the input thread, wrapped in a
Response::Custom.
Sourcepub fn set_completor(&self, completor: Option<Box<dyn Completor>>)
pub fn set_completor(&self, completor: Option<Box<dyn Completor>>)
Provide a new Completor for doing tab completion.