Cleanup Some Mess for next Release (#304)
This commit is contained in:
parent
c23a6ddf38
commit
f2a4df20db
67
CHANGELOG.md
67
CHANGELOG.md
@ -1,10 +1,14 @@
|
|||||||
# Master
|
# Version 0.13.0
|
||||||
|
**Major API-change, removed old-api**
|
||||||
|
|
||||||
|
- Remove `Crossterm` type
|
||||||
|
- Remove `TerminalCursor`, `TerminalColor`, `Terminal`
|
||||||
|
- Remove `cursor()`, `color()` , `terminal()`
|
||||||
|
- Remove re-exports at root, accessible via `module::types` (`cursor::MoveTo`)
|
||||||
- `input` module
|
- `input` module
|
||||||
- Derive 'Copy' for 'KeyEvent'
|
- Derive 'Copy' for 'KeyEvent'
|
||||||
- Add the `EnableMouseCapture` and `EnableMouseCapture` commands
|
- Add the `EnableMouseCapture` and `EnableMouseCapture` commands
|
||||||
- `cursor` module
|
- `cursor` module
|
||||||
- Remove `TerminalCursor`, `cursor`, `Crossterm::cursor()`
|
|
||||||
- Introduce static function `crossterm::cursor::position` in place of `TerminalCursor::pos`
|
- Introduce static function `crossterm::cursor::position` in place of `TerminalCursor::pos`
|
||||||
- Rename `Goto` to `MoveTo`
|
- Rename `Goto` to `MoveTo`
|
||||||
- Rename `Up` to `MoveLeft`
|
- Rename `Up` to `MoveLeft`
|
||||||
@ -14,34 +18,29 @@
|
|||||||
- Rename `BlinkOff` to `DisableBlinking`
|
- Rename `BlinkOff` to `DisableBlinking`
|
||||||
- Rename `ResetPos` to `ResetPosition`
|
- Rename `ResetPos` to `ResetPosition`
|
||||||
- Rename `SavePos` to `SavePosition`
|
- Rename `SavePos` to `SavePosition`
|
||||||
- Remove re-export cursor module types at root level, are now accessible from `crossterm::cursor`
|
|
||||||
- `terminal`
|
- `terminal`
|
||||||
- Remove `Terminal`, `terminal`, `Crossterm::terminal()`
|
|
||||||
- Introduce static function `crossterm::terminal::size` in place of `Terminal::size`
|
- Introduce static function `crossterm::terminal::size` in place of `Terminal::size`
|
||||||
- Introduce static function `crossterm::terminal::exit` in place of `Terminal::exit`
|
- Introduce static function `crossterm::terminal::exit` in place of `Terminal::exit`
|
||||||
- Remove re-export terminal module types at root level, are move those to `crossterm::terminal`
|
|
||||||
- `style module`
|
- `style module`
|
||||||
- Rename `ObjectStyle` to `ContentStyle`. Now full names are used for methods.
|
- Rename `ObjectStyle` to `ContentStyle`. Now full names are used for methods
|
||||||
- Rename `StyledObject` to `StyledContent` and made members private.
|
- Rename `StyledObject` to `StyledContent` and made members private
|
||||||
- Rename `PrintStyledFont` to `PrintStyledContent`
|
- Rename `PrintStyledFont` to `PrintStyledContent`
|
||||||
- Rename `attr` method to `attribute`.
|
- Rename `attr` method to `attribute`.
|
||||||
- Rename `Attribute::NoInverse` to `NoReverse`
|
- Rename `Attribute::NoInverse` to `NoReverse`
|
||||||
- `Crossterm::style()` and `Crossterm::color()`
|
|
||||||
- Remove re-exports from style module at at root and only expose those in the `crossterm::style` module.
|
|
||||||
- Remove `TerminalColor` (/style.rs),
|
|
||||||
- Remove `color` (style.rs)
|
|
||||||
- Update documentation
|
- Update documentation
|
||||||
- Made `Colored` private, user should use commands instead.
|
- Made `Colored` private, user should use commands instead
|
||||||
- Rename `SetFg` -> `SetForegroundColor`
|
- Rename `SetFg` -> `SetForegroundColor`
|
||||||
- Rename `SetBg` -> `SetBackgroundColor`
|
- Rename `SetBg` -> `SetBackgroundColor`
|
||||||
- Rename `SetAttr` -> `SetAttribute`
|
- Rename `SetAttr` -> `SetAttribute`
|
||||||
- Rename `ContentStyle::fg_color` -> `ContentStyle::foreground_color`
|
- Rename `ContentStyle::fg_color` -> `ContentStyle::foreground_color`
|
||||||
- Rename `ContentStyle::bg_color` -> `ContentStyle::background_color`
|
- Rename `ContentStyle::bg_color` -> `ContentStyle::background_color`
|
||||||
- Rename `ContentStyle::attrs` -> `ContentStyle::attributes`
|
- Rename `ContentStyle::attrs` -> `ContentStyle::attributes`
|
||||||
|
- Improve documentation
|
||||||
|
- Unix terminal size calculation with TPUT
|
||||||
|
|
||||||
# Version 0.12.1
|
# Version 0.12.1
|
||||||
|
|
||||||
- All the `crossterm_` crates code was moved to the `crossterm` crate
|
- Move all the `crossterm_` crates code was moved to the `crossterm` crate
|
||||||
- `crossterm_cursor` is in the `cursor` module, etc.
|
- `crossterm_cursor` is in the `cursor` module, etc.
|
||||||
- All these modules are public
|
- All these modules are public
|
||||||
- No public API breaking changes
|
- No public API breaking changes
|
||||||
@ -58,34 +57,27 @@
|
|||||||
|
|
||||||
## `crossterm_cursor` 0.4.0
|
## `crossterm_cursor` 0.4.0
|
||||||
|
|
||||||
- Internal refactoring ([PR #2](https://github.com/crossterm-rs/crossterm-cursor/pull/2))
|
- Fix examples link ([PR #6](https://github.com/crossterm-rs/crossterm-cursor/pull/6))
|
||||||
- Improved public documentation
|
|
||||||
- `sys` module is no longer public
|
|
||||||
- Fixed examples link ([PR #6](https://github.com/crossterm-rs/crossterm-cursor/pull/6))
|
|
||||||
- Sync documentation style ([PR #7](https://github.com/crossterm-rs/crossterm-cursor/pull/7))
|
- Sync documentation style ([PR #7](https://github.com/crossterm-rs/crossterm-cursor/pull/7))
|
||||||
- Removed all references to the crossterm book ([PR #8](https://github.com/crossterm-rs/crossterm-cursor/pull/8))
|
- Remove all references to the crossterm book ([PR #8](https://github.com/crossterm-rs/crossterm-cursor/pull/8))
|
||||||
- Replaced `RAW_MODE_ENABLED` with `is_raw_mode_enabled` ([PR #9](https://github.com/crossterm-rs/crossterm-cursor/pull/9))
|
- Replace `RAW_MODE_ENABLED` with `is_raw_mode_enabled` ([PR #9](https://github.com/crossterm-rs/crossterm-cursor/pull/9))
|
||||||
- Use `SyncReader` & `InputEvent::CursorPosition` for `pos_raw()` ([PR #10](https://github.com/crossterm-rs/crossterm-cursor/pull/10))
|
- Use `SyncReader` & `InputEvent::CursorPosition` for `pos_raw()` ([PR #10](https://github.com/crossterm-rs/crossterm-cursor/pull/10))
|
||||||
|
|
||||||
## `crossterm_input` 0.5.0
|
## `crossterm_input` 0.5.0
|
||||||
|
|
||||||
- Internal refactoring ([PR #3](https://github.com/crossterm-rs/crossterm-input/pull/3))
|
|
||||||
- Removed unsafe `static mut`
|
|
||||||
- Documentation update
|
|
||||||
- Remove all references to the crossterm book
|
|
||||||
- Sync documentation style ([PR #4](https://github.com/crossterm-rs/crossterm-input/pull/4))
|
- Sync documentation style ([PR #4](https://github.com/crossterm-rs/crossterm-input/pull/4))
|
||||||
- Sync `SyncReader::next()` Windows and UNIX behavior ([PR #5](https://github.com/crossterm-rs/crossterm-input/pull/5))
|
- Sync `SyncReader::next()` Windows and UNIX behavior ([PR #5](https://github.com/crossterm-rs/crossterm-input/pull/5))
|
||||||
- Remove all references to the crossterm book ([PR #6](https://github.com/crossterm-rs/crossterm-input/pull/6))
|
- Remove all references to the crossterm book ([PR #6](https://github.com/crossterm-rs/crossterm-input/pull/6))
|
||||||
- Mouse coordinates synchronized with the cursor ([PR #7](https://github.com/crossterm-rs/crossterm-input/pull/7))
|
- Mouse coordinates synchronized with the cursor ([PR #7](https://github.com/crossterm-rs/crossterm-input/pull/7))
|
||||||
- Upper/left reported as `(0, 0)`
|
- Upper/left reported as `(0, 0)`
|
||||||
- Fixed bug that read sync didn't block (Windows) ([PR #8](https://github.com/crossterm-rs/crossterm-input/pull/8))
|
- Fix bug that read sync didn't block (Windows) ([PR #8](https://github.com/crossterm-rs/crossterm-input/pull/8))
|
||||||
- Refactored UNIX readers ([PR #9](https://github.com/crossterm-rs/crossterm-input/pull/9))
|
- Refactor UNIX readers ([PR #9](https://github.com/crossterm-rs/crossterm-input/pull/9))
|
||||||
- AsyncReader produces mouse events
|
- AsyncReader produces mouse events
|
||||||
- One reading thread per application, not per `AsyncReader`
|
- One reading thread per application, not per `AsyncReader`
|
||||||
- Cursor position no longer consumed by another `AsyncReader`
|
- Cursor position no longer consumed by another `AsyncReader`
|
||||||
- Implemented sync reader for read_char (requires raw mode)
|
- Implement sync reader for read_char (requires raw mode)
|
||||||
- Fixed `SIGTTIN` when executed under the LLDB
|
- Fix `SIGTTIN` when executed under the LLDB
|
||||||
- Added mio for reading from FD and more efficient polling (UNIX only)
|
- Add mio for reading from FD and more efficient polling (UNIX only)
|
||||||
- Sync UNIX and Windows vertical mouse position ([PR #11](https://github.com/crossterm-rs/crossterm-input/pull/11))
|
- Sync UNIX and Windows vertical mouse position ([PR #11](https://github.com/crossterm-rs/crossterm-input/pull/11))
|
||||||
- Top is always reported as `0`
|
- Top is always reported as `0`
|
||||||
|
|
||||||
@ -103,10 +95,9 @@
|
|||||||
|
|
||||||
## `crossterm_style` 0.5.2
|
## `crossterm_style` 0.5.2
|
||||||
|
|
||||||
- Refactoring ([PR #2](https://github.com/crossterm-rs/crossterm-style/pull/2))
|
- Refactor ([PR #2](https://github.com/crossterm-rs/crossterm-style/pull/2))
|
||||||
- Added unit tests
|
- Added unit tests
|
||||||
- Restructured files
|
- Improved documentation and added book page to `lib.rs`
|
||||||
- Improved documentation and added book page to lib.rs
|
|
||||||
- Fixed bug with `SetBg` command, WinApi logic
|
- Fixed bug with `SetBg` command, WinApi logic
|
||||||
- Fixed bug with `StyledObject`, used stdout for resetting terminal color
|
- Fixed bug with `StyledObject`, used stdout for resetting terminal color
|
||||||
- Introduced `ResetColor` command
|
- Introduced `ResetColor` command
|
||||||
@ -166,8 +157,8 @@ As a preparation for crossterm 0.1.0 we have moved crossterm to an organisation
|
|||||||
* `TerminalInput::read_char` returns `crossterm::Result` instead of `io::Result`
|
* `TerminalInput::read_char` returns `crossterm::Result` instead of `io::Result`
|
||||||
* Maybe I forgot something, a lot of functions have changed
|
* Maybe I forgot something, a lot of functions have changed
|
||||||
- Removed all unwraps/expects from library
|
- Removed all unwraps/expects from library
|
||||||
- Added KeyEvent::Enter and KeyEvent::Tab: [added-key-event-enter], [added-key-event-tab]
|
- Add KeyEvent::Enter and KeyEvent::Tab: [added-key-event-enter], [added-key-event-tab]
|
||||||
- Synced set/get terminal size behaviour: [fixed-get-set-terminal-size]
|
- Sync set/get terminal size behaviour: [fixed-get-set-terminal-size]
|
||||||
- Method renames:
|
- Method renames:
|
||||||
* `AsyncReader::stop_reading()` to `stop()`
|
* `AsyncReader::stop_reading()` to `stop()`
|
||||||
* `RawScreen::disable_raw_mode_on_drop` to `keep_raw_mode_on_drop`
|
* `RawScreen::disable_raw_mode_on_drop` to `keep_raw_mode_on_drop`
|
||||||
@ -210,11 +201,11 @@ As a preparation for crossterm 0.1.0 we have moved crossterm to an organisation
|
|||||||
# Version 0.10.1
|
# Version 0.10.1
|
||||||
|
|
||||||
# Version 0.10.0 ~ yanked
|
# Version 0.10.0 ~ yanked
|
||||||
- Implemented command API, to have better performance and more control over how and when commands are executed. [PR](https://github.com/crossterm-rs/crossterm/commit/1a60924abd462ab169b6706aab68f4cca31d7bc2), [issue](https://github.com/crossterm-rs/crossterm/issues/171)
|
- Implement command API, to have better performance and more control over how and when commands are executed. [PR](https://github.com/crossterm-rs/crossterm/commit/1a60924abd462ab169b6706aab68f4cca31d7bc2), [issue](https://github.com/crossterm-rs/crossterm/issues/171)
|
||||||
- Fixed showing, hiding cursor windows implementation
|
- Fix showing, hiding cursor windows implementation
|
||||||
- Removed some of the parsing logic from windows keys to ansi codes to key events [PR](https://github.com/crossterm-rs/crossterm/commit/762c3a9b8e3d1fba87acde237f8ed09e74cd9ecd)
|
- Remove some of the parsing logic from windows keys to ansi codes to key events [PR](https://github.com/crossterm-rs/crossterm/commit/762c3a9b8e3d1fba87acde237f8ed09e74cd9ecd)
|
||||||
- Made terminal size 1-based [PR](https://github.com/crossterm-rs/crossterm/commit/d689d7e8ed46a335474b8262bd76f21feaaf0c50)
|
- Made terminal size 1-based [PR](https://github.com/crossterm-rs/crossterm/commit/d689d7e8ed46a335474b8262bd76f21feaaf0c50)
|
||||||
- Added some derive implementation
|
- Add some derives
|
||||||
|
|
||||||
# Version 0.9.6
|
# Version 0.9.6
|
||||||
|
|
||||||
@ -225,7 +216,7 @@ As a preparation for crossterm 0.1.0 we have moved crossterm to an organisation
|
|||||||
|
|
||||||
# Version 0.9.5
|
# Version 0.9.5
|
||||||
|
|
||||||
- Prefetching buffer size for more efficient windows input reads. [PR](https://github.com/crossterm-rs/crossterm/pull/144)
|
- Prefetch buffer size for more efficient windows input reads. [PR](https://github.com/crossterm-rs/crossterm/pull/144)
|
||||||
|
|
||||||
# Version 0.9.4
|
# Version 0.9.4
|
||||||
|
|
||||||
|
39
README.md
39
README.md
@ -14,6 +14,19 @@ worry about the platform you are working with.
|
|||||||
This crate supports all UNIX and Windows terminals down to Windows 7 (not all terminals are tested,
|
This crate supports all UNIX and Windows terminals down to Windows 7 (not all terminals are tested,
|
||||||
see [Tested Terminals](#tested-terminals) for more info).
|
see [Tested Terminals](#tested-terminals) for more info).
|
||||||
|
|
||||||
|
## Note on Migration
|
||||||
|
|
||||||
|
You may have noticed that Crossterm has been [changing](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) very quickly with the latest versions.
|
||||||
|
We have done a lot of API-breaking things by renaming functions, commands, changing the exports, improving the encapsulation, etc..
|
||||||
|
However, all of this happens to improve the library and make it ready for a possible [1.0 release](#287).
|
||||||
|
We want to stick to the [Command API](https://docs.rs/crossterm/#command-api) and remove all other ways to use crossterm.
|
||||||
|
Try to use this API and change your code accordingly.
|
||||||
|
This way you will survive or overcome major migration problems ;).
|
||||||
|
We want to reduce the ways crossterm can be used to make it simpler and easier to maintain.
|
||||||
|
|
||||||
|
We hope you can understand this, feel free to ask around in [discord ](https://discord.gg/K4nyTDB) if you have questions on how to migrate.
|
||||||
|
Also, for up-to-date examples, have a look at the [examples](https://github.com/crossterm-rs/examples/tree/masteri) repository.
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
* [Features](#features)
|
* [Features](#features)
|
||||||
@ -30,6 +43,7 @@ see [Tested Terminals](#tested-terminals) for more info).
|
|||||||
- Multi-threaded (send, sync)
|
- Multi-threaded (send, sync)
|
||||||
- Detailed documentation
|
- Detailed documentation
|
||||||
- Few dependencies
|
- Few dependencies
|
||||||
|
- Full control over output buffer
|
||||||
- Cursor (feature `cursor`)
|
- Cursor (feature `cursor`)
|
||||||
- Move the cursor N times (up, down, left, right)
|
- Move the cursor N times (up, down, left, right)
|
||||||
- Set/get the cursor position
|
- Set/get the cursor position
|
||||||
@ -94,22 +108,31 @@ crossterm = "0.12"
|
|||||||
```rust
|
```rust
|
||||||
use std::io::{stdout, Write};
|
use std::io::{stdout, Write};
|
||||||
|
|
||||||
use crossterm::{execute, Attribute, Color, Output, ResetColor, Result, SetBg, SetFg};
|
use crossterm::{execute, ExecutableCommand, style::{Attribute, Color, SetForegroundColor, SetBackgroundColor, ResetColor}, Output, Result};
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
// using the macro
|
||||||
execute!(
|
execute!(
|
||||||
stdout(),
|
stdout(),
|
||||||
// Blue foreground
|
SetForegroundColor(Color::Blue),
|
||||||
SetFg(Color::Blue),
|
SetBackgroundColor(Color::Red),
|
||||||
// Red background
|
Output("Styled text here."),
|
||||||
SetBg(Color::Red),
|
|
||||||
Output("Styled text here.".to_string()),
|
|
||||||
// Reset to default colors
|
|
||||||
ResetColor
|
ResetColor
|
||||||
)
|
)?;
|
||||||
|
|
||||||
|
// or using functions
|
||||||
|
stdout()
|
||||||
|
.execute(SetForegroundColor(Color::Blue))?
|
||||||
|
.execute(SetBackgroundColor(Color::Red))?
|
||||||
|
.execute(Output("Styled text here."))?
|
||||||
|
.execute(ResetColor)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Checkout this [list](https://docs.rs/crossterm/0.13.0/crossterm/index.html#supported-commands) with all possible commands.
|
||||||
|
|
||||||
### Feature Flags
|
### Feature Flags
|
||||||
|
|
||||||
All features are enabled by default. You can disable default features and enable some of them only.
|
All features are enabled by default. You can disable default features and enable some of them only.
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
/// A crossterm functionality wrapper.
|
|
||||||
pub struct Crossterm;
|
|
||||||
|
|
||||||
impl Crossterm {
|
|
||||||
/// Creates a new `Crossterm`.
|
|
||||||
pub fn new() -> Crossterm {
|
|
||||||
Crossterm
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new `TerminalInput`.
|
|
||||||
#[cfg(feature = "input")]
|
|
||||||
pub fn input(&self) -> crate::input::TerminalInput {
|
|
||||||
crate::input::TerminalInput::new()
|
|
||||||
}
|
|
||||||
}
|
|
16
src/input.rs
16
src/input.rs
@ -205,7 +205,7 @@ impl From<InternalEvent> for Option<InputEvent> {
|
|||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// // You can replace the following line with `use crossterm::...;`
|
/// // You can replace the following line with `use crossterm::...;`
|
||||||
/// // if you're using the `crossterm` crate with the `input` feature enabled.
|
/// // if you're using the `crossterm` crate with the `input` feature enabled.
|
||||||
/// use crossterm::{Result, TerminalInput, RawScreen};
|
/// use crossterm::{Result, input::{TerminalInput}, screen::RawScreen};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// let input = TerminalInput::new();
|
/// let input = TerminalInput::new();
|
||||||
@ -261,7 +261,7 @@ impl TerminalInput {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// let input = crossterm::input();
|
/// let input = crossterm::input::input();
|
||||||
/// match input.read_line() {
|
/// match input.read_line() {
|
||||||
/// Ok(s) => println!("string typed: {}", s),
|
/// Ok(s) => println!("string typed: {}", s),
|
||||||
/// Err(e) => println!("error: {}", e),
|
/// Err(e) => println!("error: {}", e),
|
||||||
@ -276,7 +276,7 @@ impl TerminalInput {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// let input = crossterm::input();
|
/// let input = crossterm::input::input();
|
||||||
/// match input.read_char() {
|
/// match input.read_char() {
|
||||||
/// Ok(c) => println!("character pressed: {}", c),
|
/// Ok(c) => println!("character pressed: {}", c),
|
||||||
/// Err(e) => println!("error: {}", e),
|
/// Err(e) => println!("error: {}", e),
|
||||||
@ -302,7 +302,7 @@ impl TerminalInput {
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::{thread, time::Duration};
|
/// use std::{thread, time::Duration};
|
||||||
/// use crossterm::input;
|
/// use crossterm::input::input;
|
||||||
///
|
///
|
||||||
/// let mut async_stdin = input().read_async();
|
/// let mut async_stdin = input().read_async();
|
||||||
///
|
///
|
||||||
@ -335,8 +335,9 @@ impl TerminalInput {
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::{thread, time::Duration};
|
/// use std::{thread, time::Duration};
|
||||||
|
/// use crossterm::input::input;
|
||||||
///
|
///
|
||||||
/// let mut async_stdin = crossterm::input().read_until_async(b'x');
|
/// let mut async_stdin = input().read_until_async(b'x');
|
||||||
///
|
///
|
||||||
/// loop {
|
/// loop {
|
||||||
/// if let Some(key_event) = async_stdin.next() {
|
/// if let Some(key_event) = async_stdin.next() {
|
||||||
@ -360,8 +361,9 @@ impl TerminalInput {
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::{thread, time::Duration};
|
/// use std::{thread, time::Duration};
|
||||||
|
/// use crossterm::input::input;
|
||||||
///
|
///
|
||||||
/// let mut sync_stdin = crossterm::input().read_sync();
|
/// let mut sync_stdin = input().read_sync();
|
||||||
///
|
///
|
||||||
/// loop {
|
/// loop {
|
||||||
/// if let Some(key_event) = sync_stdin.next() {
|
/// if let Some(key_event) = sync_stdin.next() {
|
||||||
@ -397,7 +399,7 @@ impl TerminalInput {
|
|||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// // You can replace the following line with `use crossterm::...;`
|
/// // You can replace the following line with `use crossterm::...;`
|
||||||
/// // if you're using the `crossterm` crate with the `input` feature enabled.
|
/// // if you're using the `crossterm` crate with the `input` feature enabled.
|
||||||
/// use crossterm::{input, RawScreen, Result};
|
/// use crossterm::{input::input, screen::RawScreen, Result};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// let input = input();
|
/// let input = input();
|
||||||
|
@ -39,7 +39,7 @@ pub(crate) trait Input {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// let input = crossterm::input();
|
/// let input = crossterm::input::input();
|
||||||
/// match input.read_line() {
|
/// match input.read_line() {
|
||||||
/// Ok(s) => println!("string typed: {}", s),
|
/// Ok(s) => println!("string typed: {}", s),
|
||||||
/// Err(e) => println!("error: {}", e),
|
/// Err(e) => println!("error: {}", e),
|
||||||
|
@ -92,7 +92,7 @@ impl Input for UnixInput {
|
|||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::{thread, time::Duration};
|
/// use std::{thread, time::Duration};
|
||||||
///
|
///
|
||||||
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
|
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// println!("Press 'ESC' to quit.");
|
/// println!("Press 'ESC' to quit.");
|
||||||
@ -221,7 +221,7 @@ impl Iterator for AsyncReader {
|
|||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::{thread, time::Duration};
|
/// use std::{thread, time::Duration};
|
||||||
///
|
///
|
||||||
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
|
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// println!("Press 'ESC' to quit.");
|
/// println!("Press 'ESC' to quit.");
|
||||||
|
@ -29,13 +29,9 @@ use winapi::um::{
|
|||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use crate::input::{input::Input, InputEvent, KeyEvent, MouseButton};
|
||||||
use crate::utils::Result;
|
use crate::utils::Result;
|
||||||
|
|
||||||
use super::{
|
|
||||||
super::{InputEvent, KeyEvent, MouseButton},
|
|
||||||
Input,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ENABLE_MOUSE_MODE: u32 = 0x0010 | 0x0080 | 0x0008;
|
const ENABLE_MOUSE_MODE: u32 = 0x0010 | 0x0080 | 0x0008;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -172,7 +168,7 @@ impl Input for WindowsInput {
|
|||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::{thread, time::Duration};
|
/// use std::{thread, time::Duration};
|
||||||
///
|
///
|
||||||
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
|
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// println!("Press 'ESC' to quit.");
|
/// println!("Press 'ESC' to quit.");
|
||||||
@ -245,7 +241,7 @@ impl Iterator for SyncReader {
|
|||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::{thread, time::Duration};
|
/// use std::{thread, time::Duration};
|
||||||
///
|
///
|
||||||
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
|
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// println!("Press 'ESC' to quit.");
|
/// println!("Press 'ESC' to quit.");
|
||||||
@ -534,7 +530,7 @@ fn parse_key_event_record(key_event: &KeyEventRecord) -> Option<KeyEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEvent>> {
|
fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::input::MouseEvent>> {
|
||||||
// NOTE (@imdaveho): xterm emulation takes the digits of the coords and passes them
|
// NOTE (@imdaveho): xterm emulation takes the digits of the coords and passes them
|
||||||
// individually as bytes into a buffer; the below cxbs and cybs replicates that and
|
// individually as bytes into a buffer; the below cxbs and cybs replicates that and
|
||||||
// mimicks the behavior; additionally, in xterm, mouse move is only handled when a
|
// mimicks the behavior; additionally, in xterm, mouse move is only handled when a
|
||||||
@ -554,10 +550,12 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
|
|||||||
EventFlags::PressOrRelease => {
|
EventFlags::PressOrRelease => {
|
||||||
// Single click
|
// Single click
|
||||||
match event.button_state {
|
match event.button_state {
|
||||||
ButtonState::Release => Some(crate::MouseEvent::Release(xpos as u16, ypos as u16)),
|
ButtonState::Release => {
|
||||||
|
Some(crate::input::MouseEvent::Release(xpos as u16, ypos as u16))
|
||||||
|
}
|
||||||
ButtonState::FromLeft1stButtonPressed => {
|
ButtonState::FromLeft1stButtonPressed => {
|
||||||
// left click
|
// left click
|
||||||
Some(crate::MouseEvent::Press(
|
Some(crate::input::MouseEvent::Press(
|
||||||
MouseButton::Left,
|
MouseButton::Left,
|
||||||
xpos as u16,
|
xpos as u16,
|
||||||
ypos as u16,
|
ypos as u16,
|
||||||
@ -565,7 +563,7 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
|
|||||||
}
|
}
|
||||||
ButtonState::RightmostButtonPressed => {
|
ButtonState::RightmostButtonPressed => {
|
||||||
// right click
|
// right click
|
||||||
Some(crate::MouseEvent::Press(
|
Some(crate::input::MouseEvent::Press(
|
||||||
MouseButton::Right,
|
MouseButton::Right,
|
||||||
xpos as u16,
|
xpos as u16,
|
||||||
ypos as u16,
|
ypos as u16,
|
||||||
@ -573,7 +571,7 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
|
|||||||
}
|
}
|
||||||
ButtonState::FromLeft2ndButtonPressed => {
|
ButtonState::FromLeft2ndButtonPressed => {
|
||||||
// middle click
|
// middle click
|
||||||
Some(crate::MouseEvent::Press(
|
Some(crate::input::MouseEvent::Press(
|
||||||
MouseButton::Middle,
|
MouseButton::Middle,
|
||||||
xpos as u16,
|
xpos as u16,
|
||||||
ypos as u16,
|
ypos as u16,
|
||||||
@ -586,7 +584,7 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
|
|||||||
// Click + Move
|
// Click + Move
|
||||||
// NOTE (@imdaveho) only register when mouse is not released
|
// NOTE (@imdaveho) only register when mouse is not released
|
||||||
if event.button_state != ButtonState::Release {
|
if event.button_state != ButtonState::Release {
|
||||||
Some(crate::MouseEvent::Hold(xpos as u16, ypos as u16))
|
Some(crate::input::MouseEvent::Hold(xpos as u16, ypos as u16))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -596,13 +594,13 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
|
|||||||
// NOTE (@imdaveho) from https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
|
// NOTE (@imdaveho) from https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
|
||||||
// if `button_state` is negative then the wheel was rotated backward, toward the user.
|
// if `button_state` is negative then the wheel was rotated backward, toward the user.
|
||||||
if event.button_state != ButtonState::Negative {
|
if event.button_state != ButtonState::Negative {
|
||||||
Some(crate::MouseEvent::Press(
|
Some(crate::input::MouseEvent::Press(
|
||||||
MouseButton::WheelUp,
|
MouseButton::WheelUp,
|
||||||
xpos as u16,
|
xpos as u16,
|
||||||
ypos as u16,
|
ypos as u16,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Some(crate::MouseEvent::Press(
|
Some(crate::input::MouseEvent::Press(
|
||||||
MouseButton::WheelDown,
|
MouseButton::WheelDown,
|
||||||
xpos as u16,
|
xpos as u16,
|
||||||
ypos as u16,
|
ypos as u16,
|
||||||
|
138
src/lib.rs
138
src/lib.rs
@ -16,7 +16,9 @@
|
|||||||
//! ## Command API
|
//! ## Command API
|
||||||
//!
|
//!
|
||||||
//! The command API makes the use of `crossterm` much easier and offers more control over when and how a
|
//! The command API makes the use of `crossterm` much easier and offers more control over when and how a
|
||||||
//! command such as moving the cursor is executed. The command API offers:
|
//! command is executed. An command is just an action you can perform on the terminal e.g. cursor movement.
|
||||||
|
//!
|
||||||
|
//! The command API offers:
|
||||||
//!
|
//!
|
||||||
//! * Better Performance.
|
//! * Better Performance.
|
||||||
//! * Complete control over when to flush.
|
//! * Complete control over when to flush.
|
||||||
@ -30,31 +32,70 @@
|
|||||||
//! * Macros are generally seen as more difficult but offer an API with less boilerplate code. If you are
|
//! * Macros are generally seen as more difficult but offer an API with less boilerplate code. If you are
|
||||||
//! not afraid of macros, this is a recommendation.
|
//! not afraid of macros, this is a recommendation.
|
||||||
//!
|
//!
|
||||||
//! Before `crossterm` 10.0 was released, `crossterm` had some performance issues. It did a `flush` after each command
|
|
||||||
//! (cursor movement). A `flush` is heavy action on the terminal, and if it is done more often the performance
|
|
||||||
//! will go down quickly.
|
|
||||||
//!
|
|
||||||
//! Linux and Windows 10 systems support ANSI escape codes. Those ANSI escape codes are strings or rather a
|
//! Linux and Windows 10 systems support ANSI escape codes. Those ANSI escape codes are strings or rather a
|
||||||
//! byte sequence. When we `write` and `flush` those to the terminal we can perform some action.
|
//! byte sequence. When we `write` and `flush` those to the terminal we can perform some action.
|
||||||
|
//! For older windows systems a WinApi call is made.
|
||||||
|
//!
|
||||||
|
//! ### Supported Commands
|
||||||
|
//!
|
||||||
|
//!| *Command Name* | *Description* |
|
||||||
|
//!| :------------------------------ | :---------------------------- |
|
||||||
|
//!| **crossterm::cursor module** | |
|
||||||
|
//!| `cursor::DisableBlinking` | disables blinking of the terminal cursor. |
|
||||||
|
//!| `cursor::EnableBlinking` | enables blinking of the terminal cursor. |
|
||||||
|
//!| `cursor::Hide` | hides the terminal cursor. |
|
||||||
|
//!| `cursor::MoveDown` | moves the terminal cursor a given number of rows down. |
|
||||||
|
//!| `cursor::MoveLeft` | moves the terminal cursor a given number of columns to the left. |
|
||||||
|
//!| `cursor::MoveRight` | moves the terminal cursor a given number of columns to the right. |
|
||||||
|
//!| `cursor::MoveTo` | moves the terminal cursor to the given position (column, row). |
|
||||||
|
//!| `cursor::MoveUp` | moves the terminal cursor a given number of rows up. |
|
||||||
|
//!| `cursor::RestorePosition` | restores the saved terminal cursor position. |
|
||||||
|
//!| `cursor::SavePosition` | saves the current terminal cursor position. |
|
||||||
|
//!| `cursor::Show` | shows the terminal cursor. |
|
||||||
|
//!| **crossterm::input module** | |
|
||||||
|
//!| `input::DisableMouseCapture` | disables mouse event monitoring. |
|
||||||
|
//!| `input::EnableMouseCapture` | enables mouse mode |
|
||||||
|
//!| | |
|
||||||
|
//!| `screen::EnterAlternateScreen` | switches to the alternate screen. |
|
||||||
|
//!| `screen::LeaveAlternateScreen` | switches back to the main screen. |
|
||||||
|
//!| **crossterm::style module** | |
|
||||||
|
//!| `style::PrintStyledContent` | prints styled content. |
|
||||||
|
//!| `style::ResetColor` | resets the colors back to default. |
|
||||||
|
//!| `style::SetAttribute` | sets an attribute. |
|
||||||
|
//!| `style::SetBackgroundColor` | sets the the background color. |
|
||||||
|
//!| `style::SetForegroundColor` | sets the the foreground color. |
|
||||||
|
//!| **crossterm::terminal module** | |
|
||||||
|
//!| `terminal::Clear` | clears the terminal screen buffer. |
|
||||||
|
//!| `terminal::ScrollDown` | scrolls the terminal screen a given number of rows down. |
|
||||||
|
//!| `terminal::ScrollUp` | scrolls the terminal screen a given number of rows up. |
|
||||||
|
//!| `terminal::SetSize` | sets the terminal size (columns, rows). |
|
||||||
|
//!
|
||||||
|
//! There are two different way's to execute commands.
|
||||||
|
//! * [Lazy Execution](#lazy-execution)
|
||||||
|
//! * [Direct Execution](#direct-execution)
|
||||||
//!
|
//!
|
||||||
//! ## Lazy Execution
|
//! ## Lazy Execution
|
||||||
//!
|
//!
|
||||||
//! Because `flush` is a heavy system call we can instead `write` the commands to the `stdout` without flushing.
|
//! Flushing bytes to the terminal buffer is a heavy system call. If we perform a lot of actions with the terminal,
|
||||||
//! When can do a `flush` when we do want to execute the commands.
|
//! we want to do this periodically - like with a TUI editor - so that we can flush more data to the terminal buffer at the same time.
|
||||||
//!
|
//!
|
||||||
//! If you create a terminal editor or TUI, it is wise to use this option. For example, you can `write` commands
|
//! Crossterm offers the possibility to do this with `queue`.
|
||||||
//! to the terminal `stdout` and `flush` the `stdout` at every frame. By doing this you can make efficient use of the
|
//! With `queue` you can queue commands, and when you call [Write::flush][flush] these commands will be executed.
|
||||||
//! terminal buffer and get better performance because you are not calling `flush` after every command.
|
//!
|
||||||
|
//! You can pass a custom buffer implementing [std::io::Write][write] to this `queue` operation.
|
||||||
|
//! The commands will be executed on that buffer.
|
||||||
|
//! The most common buffer is [std::io::stdout][stdout] however, [std::io::stderr][stderr] is used sometimes as well.
|
||||||
//!
|
//!
|
||||||
//! ### Examples
|
//! ### Examples
|
||||||
|
//! A simple demonstration that shows the command API in action with cursor commands.
|
||||||
//!
|
//!
|
||||||
//! Functions:
|
//! **Functions**
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::Write;
|
//! use std::io::{Write, stdout};
|
||||||
//! use crossterm::{QueueableCommand, cursor};
|
//! use crossterm::{QueueableCommand, cursor};
|
||||||
//!
|
//!
|
||||||
//! let mut stdout = std::io::stdout();
|
//! let mut stdout = stdout();
|
||||||
//! stdout.queue(cursor::MoveTo(5,5));
|
//! stdout.queue(cursor::MoveTo(5,5));
|
||||||
//!
|
//!
|
||||||
//! // some other code ...
|
//! // some other code ...
|
||||||
@ -62,58 +103,68 @@
|
|||||||
//! stdout.flush();
|
//! stdout.flush();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The `queue` function returns itself, therefore you can use this to queue another command. Like
|
//! The [queue](./trait.QueueableCommand.html) function returns itself, therefore you can use this to queue another command. Like
|
||||||
//! `stdout.queue(Goto(5,5)).queue(Clear(ClearType::All))`.
|
//! `stdout.queue(Goto(5,5)).queue(Clear(ClearType::All))`.
|
||||||
//!
|
//!
|
||||||
//! Macros:
|
//! **Macros**
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::Write;
|
//! use std::io::{Write, stdout};
|
||||||
//! use crossterm::{queue, QueueableCommand, cursor};
|
//! use crossterm::{queue, QueueableCommand, cursor};
|
||||||
//!
|
//!
|
||||||
//! let mut stdout = std::io::stdout();
|
//! let mut stdout = stdout();
|
||||||
//! queue!(stdout, cursor::MoveTo(5, 5));
|
//! queue!(stdout, cursor::MoveTo(5, 5));
|
||||||
//!
|
//!
|
||||||
//! // some other code ...
|
//! // some other code ...
|
||||||
//!
|
//!
|
||||||
|
//! // move operation is performed only if we flush the buffer.
|
||||||
//! stdout.flush();
|
//! stdout.flush();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! You can pass more than one command into the macro like `queue!(stdout, Goto(5, 5), Clear(ClearType::All))` and
|
//! You can pass more than one command into the [queue](./macro.queue.html) macro like `queue!(stdout, MoveTo(5, 5), Clear(ClearType::All))` and
|
||||||
//! they will be executed in the given order from left to right.
|
//! they will be executed in the given order from left to right.
|
||||||
//!
|
//!
|
||||||
//! ## Direct Execution
|
//! ## Direct Execution
|
||||||
//!
|
//!
|
||||||
//! If you want to execute commands directly, this is also possible. You don't have to flush the 'stdout',
|
//! For many applications it is not at all important to be efficient with 'flush' operations.
|
||||||
//! as described above. This is fine if you are not executing lots of commands.
|
//! For this use case there is the `execute` operation.
|
||||||
|
//! This operation executes the command immediately, and calls the `flush` under water.
|
||||||
|
//!
|
||||||
|
//! You can pass a custom buffer implementing [std::io::Write][write] to this `execute` operation.
|
||||||
|
//! The commands will be executed on that buffer.
|
||||||
|
//! The most common buffer is [std::io::stdout][stdout] however, [std::io::stderr][stderr] is used sometimes as well.
|
||||||
//!
|
//!
|
||||||
//! ### Examples
|
//! ### Examples
|
||||||
//!
|
//!
|
||||||
//! Functions:
|
//! **Functions**
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::Write;
|
//! use std::io::{Write, stdout};
|
||||||
//! use crossterm::{ExecutableCommand, cursor};
|
//! use crossterm::{ExecutableCommand, cursor};
|
||||||
//!
|
//!
|
||||||
//! let mut stdout = std::io::stdout();
|
//! let mut stdout = stdout();
|
||||||
//! stdout.execute(cursor::MoveTo(5,5));
|
//! stdout.execute(cursor::MoveTo(5,5));
|
||||||
//! ```
|
//! ```
|
||||||
|
//! The [execute](./trait.ExecutableCommand.html) function returns itself, therefore you can use this to queue another command. Like
|
||||||
|
//! `stdout.queue(Goto(5,5)).queue(Clear(ClearType::All))`.
|
||||||
//!
|
//!
|
||||||
//! Macros:
|
//! **Macros**
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::Write;
|
//! use std::io::{Write, stdout};
|
||||||
//! use crossterm::{execute, ExecutableCommand, cursor};
|
//! use crossterm::{execute, ExecutableCommand, cursor};
|
||||||
//!
|
//!
|
||||||
//! let mut stdout = std::io::stdout();
|
//! let mut stdout = stdout();
|
||||||
//! execute!(stdout, cursor::MoveTo(5, 5));
|
//! execute!(stdout, cursor::MoveTo(5, 5));
|
||||||
//! ```
|
//! ```
|
||||||
|
//! You can pass more than one command into the [execute](./macro.execute.html) macro like `execute!(stdout, MoveTo(5, 5), Clear(ClearType::All))` and
|
||||||
|
//! they will be executed in the given order from left to right.
|
||||||
//!
|
//!
|
||||||
//! ## Examples
|
//! ## Examples
|
||||||
//!
|
//!
|
||||||
//! Print a rectangle colored with magenta and use both direct execution and lazy execution.
|
//! Print a rectangle colored with magenta and use both direct execution and lazy execution.
|
||||||
//!
|
//!
|
||||||
//! Functions:
|
//! **Functions**
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::{stdout, Write};
|
//! use std::io::{stdout, Write};
|
||||||
@ -130,6 +181,7 @@
|
|||||||
//! for y in 0..40 {
|
//! for y in 0..40 {
|
||||||
//! for x in 0..150 {
|
//! for x in 0..150 {
|
||||||
//! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
//! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
||||||
|
//! // in this loop we are more efficient by not flushing the buffer.
|
||||||
//! stdout
|
//! stdout
|
||||||
//! .queue(cursor::MoveTo(x,y))?
|
//! .queue(cursor::MoveTo(x,y))?
|
||||||
//! .queue(style::PrintStyledContent( "█".magenta()))?;
|
//! .queue(style::PrintStyledContent( "█".magenta()))?;
|
||||||
@ -141,7 +193,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Macros:
|
//! **Macros:**
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::{stdout, Write};
|
//! use std::io::{stdout, Write};
|
||||||
@ -158,6 +210,7 @@
|
|||||||
//! for y in 0..40 {
|
//! for y in 0..40 {
|
||||||
//! for x in 0..150 {
|
//! for x in 0..150 {
|
||||||
//! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
//! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
|
||||||
|
//! // in this loop we are more efficient by not flushing the buffer.
|
||||||
//! queue!(stdout, cursor::MoveTo(x,y), style::PrintStyledContent( "█".magenta()))?;
|
//! queue!(stdout, cursor::MoveTo(x,y), style::PrintStyledContent( "█".magenta()))?;
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
@ -166,35 +219,30 @@
|
|||||||
//! Ok(())
|
//! Ok(())
|
||||||
//! }
|
//! }
|
||||||
//!```
|
//!```
|
||||||
|
//!
|
||||||
|
//! [write]: https://doc.rust-lang.org/std/io/trait.Write.html
|
||||||
|
//! [stdout]: https://doc.rust-lang.org/std/io/fn.stdout.html
|
||||||
|
//! [stderr]: https://doc.rust-lang.org/std/io/fn.stderr.html
|
||||||
|
//! [flush]: https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.flush
|
||||||
|
|
||||||
#[cfg(feature = "input")]
|
|
||||||
pub use input::{
|
|
||||||
input, AsyncReader, DisableMouseCapture, EnableMouseCapture, InputEvent, KeyEvent, MouseButton,
|
|
||||||
MouseEvent, SyncReader, TerminalInput,
|
|
||||||
};
|
|
||||||
#[cfg(feature = "screen")]
|
|
||||||
pub use screen::{
|
|
||||||
AlternateScreen, EnterAlternateScreen, IntoRawMode, LeaveAlternateScreen, RawScreen,
|
|
||||||
};
|
|
||||||
pub use utils::{Command, ErrorKind, ExecutableCommand, Output, QueueableCommand, Result};
|
pub use utils::{Command, ErrorKind, ExecutableCommand, Output, QueueableCommand, Result};
|
||||||
|
|
||||||
pub use self::crossterm::Crossterm;
|
#[cfg(windows)]
|
||||||
|
pub use utils::functions::supports_ansi;
|
||||||
|
|
||||||
mod crossterm;
|
/// A module to work with the terminal cursor
|
||||||
|
|
||||||
/// A functionality to work with the terminal cursor
|
|
||||||
#[cfg(feature = "cursor")]
|
#[cfg(feature = "cursor")]
|
||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
/// A functionality to read the input events.
|
/// A module to read the input events.
|
||||||
#[cfg(feature = "input")]
|
#[cfg(feature = "input")]
|
||||||
pub mod input;
|
pub mod input;
|
||||||
/// A functionality to work with the terminal screen.
|
/// A module to work with the terminal screen.
|
||||||
#[cfg(feature = "screen")]
|
#[cfg(feature = "screen")]
|
||||||
pub mod screen;
|
pub mod screen;
|
||||||
/// A functionality to apply attributes and colors on your text.
|
/// A module to apply attributes and colors on your text.
|
||||||
#[cfg(feature = "style")]
|
#[cfg(feature = "style")]
|
||||||
pub mod style;
|
pub mod style;
|
||||||
/// A functionality to work with the terminal.
|
/// A module to work with the terminal.
|
||||||
#[cfg(feature = "terminal")]
|
#[cfg(feature = "terminal")]
|
||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
/// Shared utilities.
|
/// Shared utilities.
|
||||||
|
@ -76,7 +76,7 @@ mod sys;
|
|||||||
/// Alternate screen with raw mode enabled:
|
/// Alternate screen with raw mode enabled:
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use crossterm::{AlternateScreen, Result};
|
/// use crossterm::{screen::{AlternateScreen}, Result};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// let _alternate = AlternateScreen::to_alternate(true)?;
|
/// let _alternate = AlternateScreen::to_alternate(true)?;
|
||||||
@ -145,7 +145,7 @@ impl Drop for AlternateScreen {
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::io::{stdout, Write};
|
/// use std::io::{stdout, Write};
|
||||||
/// use crossterm::{execute, Result, EnterAlternateScreen, LeaveAlternateScreen};
|
/// use crossterm::{execute, Result,screen::{EnterAlternateScreen, LeaveAlternateScreen}};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// execute!(stdout(), EnterAlternateScreen)?;
|
/// execute!(stdout(), EnterAlternateScreen)?;
|
||||||
@ -181,7 +181,7 @@ impl Command for EnterAlternateScreen {
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::io::{stdout, Write};
|
/// use std::io::{stdout, Write};
|
||||||
/// use crossterm::{execute, Result, EnterAlternateScreen, LeaveAlternateScreen};
|
/// use crossterm::{execute, Result, screen::{EnterAlternateScreen, LeaveAlternateScreen}};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// execute!(stdout(), EnterAlternateScreen)?;
|
/// execute!(stdout(), EnterAlternateScreen)?;
|
||||||
|
@ -3,7 +3,7 @@ pub(crate) use ansi::AnsiAlternateScreen;
|
|||||||
pub(crate) use windows::WinApiAlternateScreen;
|
pub(crate) use windows::WinApiAlternateScreen;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::utils::supports_ansi;
|
use crate::supports_ansi;
|
||||||
use crate::utils::Result;
|
use crate::utils::Result;
|
||||||
|
|
||||||
pub(crate) mod ansi;
|
pub(crate) mod ansi;
|
||||||
|
@ -15,7 +15,7 @@ use super::sys;
|
|||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use crossterm::{RawScreen, Result};
|
/// use crossterm::{screen::RawScreen, Result};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// let _raw = RawScreen::into_raw_mode()?;
|
/// let _raw = RawScreen::into_raw_mode()?;
|
||||||
@ -27,7 +27,7 @@ use super::sys;
|
|||||||
/// Do not disable the raw mode implicitly:
|
/// Do not disable the raw mode implicitly:
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use crossterm::{RawScreen, Result};
|
/// use crossterm::{screen::RawScreen, Result};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// let mut raw = RawScreen::into_raw_mode()?;
|
/// let mut raw = RawScreen::into_raw_mode()?;
|
||||||
@ -93,7 +93,7 @@ impl RawScreen {
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::io::stdout;
|
/// use std::io::stdout;
|
||||||
/// use crossterm::{IntoRawMode, Result};
|
/// use crossterm::{screen::IntoRawMode, Result};
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// let stdout = stdout();
|
/// let stdout = stdout();
|
||||||
|
24
src/style.rs
24
src/style.rs
@ -16,10 +16,14 @@
|
|||||||
//! * [Attribute](enum.Attribute.html#platform-specific-notes)
|
//! * [Attribute](enum.Attribute.html#platform-specific-notes)
|
||||||
//!
|
//!
|
||||||
//! ## Examples
|
//! ## Examples
|
||||||
|
//! A few examples of how to use the style module.
|
||||||
//!
|
//!
|
||||||
//! ### Colors
|
//! ### Colors
|
||||||
|
//! How to change the terminal text color.
|
||||||
//!
|
//!
|
||||||
//! The command API:
|
//! **Command API**
|
||||||
|
//!
|
||||||
|
//! Using the Command API to color text.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::{stdout, Write};
|
//! use std::io::{stdout, Write};
|
||||||
@ -42,7 +46,9 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The [`Colorize`](trait.Colorize.html) trait:
|
//! **Functions**
|
||||||
|
//!
|
||||||
|
//! Using functions from [`Colorize`](trait.Colorize.html) on a `String` or `&'static str` to color it.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use crossterm::style::Colorize;
|
//! use crossterm::style::Colorize;
|
||||||
@ -51,8 +57,11 @@
|
|||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ### Attributes
|
//! ### Attributes
|
||||||
|
//! How to appy terminal attributes to text.
|
||||||
//!
|
//!
|
||||||
//! The command API:
|
//! **Command API**
|
||||||
|
//!
|
||||||
|
//! Using the Command API to set attributes.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::io::{stdout, Write};
|
//! use std::io::{stdout, Write};
|
||||||
@ -72,7 +81,9 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The [`Styler`](trait.Styler.html) trait:
|
//! **Functions**:
|
||||||
|
//!
|
||||||
|
//! Using [`Styler`](trait.Styler.html) functions on a `String` or `&'static str` to set attributes to it.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use crossterm::style::Styler;
|
//! use crossterm::style::Styler;
|
||||||
@ -82,7 +93,9 @@
|
|||||||
//! println!("{}", "Negative".negative());
|
//! println!("{}", "Negative".negative());
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The [`Attribute`](enum.Attribute.html) enum:
|
//! **Displayable**
|
||||||
|
//!
|
||||||
|
//! [`Attribute`](enum.Attribute.html) implements [Display](https://doc.rust-lang.org/beta/std/fmt/trait.Display.html) and therefore it can be formatted like:
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use crossterm::style::Attribute;
|
//! use crossterm::style::Attribute;
|
||||||
@ -99,7 +112,6 @@ use std::fmt::Display;
|
|||||||
|
|
||||||
use crate::impl_display;
|
use crate::impl_display;
|
||||||
use crate::utils::Command;
|
use crate::utils::Command;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use std::fmt::Display;
|
|||||||
|
|
||||||
use crate::style::{Attribute, Color, StyledContent};
|
use crate::style::{Attribute, Color, StyledContent};
|
||||||
|
|
||||||
/// A content style.
|
/// The style that can be put on content.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ContentStyle {
|
pub struct ContentStyle {
|
||||||
/// The foreground color.
|
/// The foreground color.
|
||||||
|
@ -4,13 +4,12 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
use std::result;
|
use std::result;
|
||||||
|
|
||||||
use crate::queue;
|
use crate::queue;
|
||||||
|
|
||||||
use crate::style::{
|
use crate::style::{
|
||||||
Attribute, Color, Colorize, ContentStyle, ResetColor, SetAttribute, SetBackgroundColor,
|
Attribute, Color, Colorize, ContentStyle, ResetColor, SetAttribute, SetBackgroundColor,
|
||||||
SetForegroundColor, Styler,
|
SetForegroundColor, Styler,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A styled content.
|
/// The style with the content to be styled.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -180,10 +180,11 @@ impl From<Colored> for u16 {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::style::sys::windows::set_foreground_color;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Color, Colored, BG_INTENSITY, BG_RED, FG_INTENSITY, FG_RED, ORIGINAL_CONSOLE_COLOR,
|
Color, Colored, BG_INTENSITY, BG_RED, FG_INTENSITY, FG_RED, ORIGINAL_CONSOLE_COLOR,
|
||||||
};
|
};
|
||||||
use crate::style::sys::windows::set_foreground_color;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_fg_color() {
|
fn test_parse_fg_color() {
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
pub use self::command::{Command, ExecutableCommand, Output, QueueableCommand};
|
pub use self::command::{Command, ExecutableCommand, Output, QueueableCommand};
|
||||||
pub use self::error::{ErrorKind, Result};
|
pub use self::error::{ErrorKind, Result};
|
||||||
#[cfg(windows)]
|
|
||||||
pub use self::functions::supports_ansi;
|
|
||||||
|
|
||||||
mod command;
|
mod command;
|
||||||
mod error;
|
mod error;
|
||||||
mod functions;
|
pub(crate) mod functions;
|
||||||
pub(crate) mod macros;
|
pub(crate) mod macros;
|
||||||
pub(crate) mod sys;
|
pub(crate) mod sys;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::{execute, impl_display, queue, write_cout};
|
use crate::{execute, queue, write_cout};
|
||||||
|
|
||||||
use super::error::Result;
|
use super::error::Result;
|
||||||
|
|
||||||
@ -93,13 +93,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When executed, this command will output the given string to the terminal.
|
/// When executed, this command will output the given displayable to the buffer.
|
||||||
///
|
///
|
||||||
/// See `crossterm/examples/command.rs` for more information on how to execute commands.
|
/// See `crossterm/examples/command.rs` for more information on how to execute commands.
|
||||||
pub struct Output(pub String);
|
pub struct Output<T: Display + Clone>(pub T);
|
||||||
|
|
||||||
impl Command for Output {
|
impl<T: Display + Clone> Command for Output<T> {
|
||||||
type AnsiType = String;
|
type AnsiType = T;
|
||||||
|
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
return self.0.clone();
|
return self.0.clone();
|
||||||
@ -112,4 +112,11 @@ impl Command for Output {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_display!(for Output);
|
impl<T: Display + Clone> Display for Output<T> {
|
||||||
|
fn fmt(
|
||||||
|
&self,
|
||||||
|
f: &mut ::std::fmt::Formatter<'_>,
|
||||||
|
) -> ::std::result::Result<(), ::std::fmt::Error> {
|
||||||
|
write!(f, "{}", self.ansi_code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
/// Append a the first few characters of an ANSI escape code to the given string.
|
/// Append a the first few characters of an ANSI escape code to the given string.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
#[doc(hidden)]
|
||||||
macro_rules! csi {
|
macro_rules! csi {
|
||||||
($( $l:expr ),*) => { concat!("\x1B[", $( $l ),*) };
|
($( $l:expr ),*) => { concat!("\x1B[", $( $l ),*) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a string to standard output whereafter the stdout will be flushed.
|
/// Write a string to standard output whereafter the stdout will be flushed.
|
||||||
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! write_cout {
|
macro_rules! write_cout {
|
||||||
($write:expr, $string:expr) => {{
|
($write:expr, $string:expr) => {{
|
||||||
@ -77,7 +79,7 @@ macro_rules! queue {
|
|||||||
$(
|
$(
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
if $crate::utils::supports_ansi() {
|
if $crate::supports_ansi() {
|
||||||
match write!($write, "{}", $command.ansi_code()) {
|
match write!($write, "{}", $command.ansi_code()) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error = Some(Err($crate::ErrorKind::from(e)));
|
error = Some(Err($crate::ErrorKind::from(e)));
|
||||||
@ -149,7 +151,7 @@ macro_rules! execute {
|
|||||||
$(
|
$(
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
if $crate::utils::supports_ansi() {
|
if $crate::supports_ansi() {
|
||||||
if let Err(e) = write_cout!($write, $command.ansi_code()) {
|
if let Err(e) = write_cout!($write, $command.ansi_code()) {
|
||||||
error = Some($crate::ErrorKind::from(e));
|
error = Some($crate::ErrorKind::from(e));
|
||||||
};
|
};
|
||||||
@ -175,6 +177,7 @@ macro_rules! execute {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_display {
|
macro_rules! impl_display {
|
||||||
(for $($t:ty),+) => {
|
(for $($t:ty),+) => {
|
||||||
@ -187,6 +190,7 @@ macro_rules! impl_display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_from {
|
macro_rules! impl_from {
|
||||||
($from:path, $to:expr) => {
|
($from:path, $to:expr) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user