Cleanup Some Mess for next Release (#304)

This commit is contained in:
Timon 2019-11-01 18:09:05 +01:00 committed by GitHub
parent c23a6ddf38
commit f2a4df20db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 227 additions and 159 deletions

View File

@ -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
- Derive 'Copy' for 'KeyEvent'
- Add the `EnableMouseCapture` and `EnableMouseCapture` commands
- `cursor` module
- Remove `TerminalCursor`, `cursor`, `Crossterm::cursor()`
- Introduce static function `crossterm::cursor::position` in place of `TerminalCursor::pos`
- Rename `Goto` to `MoveTo`
- Rename `Up` to `MoveLeft`
@ -14,34 +18,29 @@
- Rename `BlinkOff` to `DisableBlinking`
- Rename `ResetPos` to `ResetPosition`
- Rename `SavePos` to `SavePosition`
- Remove re-export cursor module types at root level, are now accessible from `crossterm::cursor`
- `terminal`
- Remove `Terminal`, `terminal`, `Crossterm::terminal()`
- Introduce static function `crossterm::terminal::size` in place of `Terminal::size`
- 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`
- Rename `ObjectStyle` to `ContentStyle`. Now full names are used for methods.
- Rename `StyledObject` to `StyledContent` and made members private.
- Rename `ObjectStyle` to `ContentStyle`. Now full names are used for methods
- Rename `StyledObject` to `StyledContent` and made members private
- Rename `PrintStyledFont` to `PrintStyledContent`
- Rename `attr` method to `attribute`.
- 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
- Made `Colored` private, user should use commands instead.
- Made `Colored` private, user should use commands instead
- Rename `SetFg` -> `SetForegroundColor`
- Rename `SetBg` -> `SetBackgroundColor`
- Rename `SetAttr` -> `SetAttribute`
- Rename `ContentStyle::fg_color` -> `ContentStyle::foreground_color`
- Rename `ContentStyle::bg_color` -> `ContentStyle::background_color`
- Rename `ContentStyle::attrs` -> `ContentStyle::attributes`
- Improve documentation
- Unix terminal size calculation with TPUT
# 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.
- All these modules are public
- No public API breaking changes
@ -58,34 +57,27 @@
## `crossterm_cursor` 0.4.0
- Internal refactoring ([PR #2](https://github.com/crossterm-rs/crossterm-cursor/pull/2))
- Improved public documentation
- `sys` module is no longer public
- Fixed examples link ([PR #6](https://github.com/crossterm-rs/crossterm-cursor/pull/6))
- Fix 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))
- Removed 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))
- Remove all references to the crossterm book ([PR #8](https://github.com/crossterm-rs/crossterm-cursor/pull/8))
- 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))
## `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 `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))
- Mouse coordinates synchronized with the cursor ([PR #7](https://github.com/crossterm-rs/crossterm-input/pull/7))
- 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))
- Refactored UNIX readers ([PR #9](https://github.com/crossterm-rs/crossterm-input/pull/9))
- Fix bug that read sync didn't block (Windows) ([PR #8](https://github.com/crossterm-rs/crossterm-input/pull/8))
- Refactor UNIX readers ([PR #9](https://github.com/crossterm-rs/crossterm-input/pull/9))
- AsyncReader produces mouse events
- One reading thread per application, not per `AsyncReader`
- Cursor position no longer consumed by another `AsyncReader`
- Implemented sync reader for read_char (requires raw mode)
- Fixed `SIGTTIN` when executed under the LLDB
- Added mio for reading from FD and more efficient polling (UNIX only)
- Implement sync reader for read_char (requires raw mode)
- Fix `SIGTTIN` when executed under the LLDB
- 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))
- Top is always reported as `0`
@ -103,10 +95,9 @@
## `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
- 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 `StyledObject`, used stdout for resetting terminal color
- 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`
* Maybe I forgot something, a lot of functions have changed
- Removed all unwraps/expects from library
- Added KeyEvent::Enter and KeyEvent::Tab: [added-key-event-enter], [added-key-event-tab]
- Synced set/get terminal size behaviour: [fixed-get-set-terminal-size]
- Add KeyEvent::Enter and KeyEvent::Tab: [added-key-event-enter], [added-key-event-tab]
- Sync set/get terminal size behaviour: [fixed-get-set-terminal-size]
- Method renames:
* `AsyncReader::stop_reading()` to `stop()`
* `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.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)
- Fixed 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)
- 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)
- Fix showing, hiding cursor windows implementation
- 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)
- Added some derive implementation
- Add some derives
# 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
- 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

View File

@ -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,
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
* [Features](#features)
@ -30,6 +43,7 @@ see [Tested Terminals](#tested-terminals) for more info).
- Multi-threaded (send, sync)
- Detailed documentation
- Few dependencies
- Full control over output buffer
- Cursor (feature `cursor`)
- Move the cursor N times (up, down, left, right)
- Set/get the cursor position
@ -94,22 +108,31 @@ crossterm = "0.12"
```rust
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<()> {
// using the macro
execute!(
stdout(),
// Blue foreground
SetFg(Color::Blue),
// Red background
SetBg(Color::Red),
Output("Styled text here.".to_string()),
// Reset to default colors
SetForegroundColor(Color::Blue),
SetBackgroundColor(Color::Red),
Output("Styled text here."),
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
All features are enabled by default. You can disable default features and enable some of them only.

View File

@ -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()
}
}

View File

@ -205,7 +205,7 @@ impl From<InternalEvent> for Option<InputEvent> {
/// ```no_run
/// // You can replace the following line with `use crossterm::...;`
/// // 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<()> {
/// let input = TerminalInput::new();
@ -261,7 +261,7 @@ impl TerminalInput {
/// # Examples
///
/// ```no_run
/// let input = crossterm::input();
/// let input = crossterm::input::input();
/// match input.read_line() {
/// Ok(s) => println!("string typed: {}", s),
/// Err(e) => println!("error: {}", e),
@ -276,7 +276,7 @@ impl TerminalInput {
/// # Examples
///
/// ```no_run
/// let input = crossterm::input();
/// let input = crossterm::input::input();
/// match input.read_char() {
/// Ok(c) => println!("character pressed: {}", c),
/// Err(e) => println!("error: {}", e),
@ -302,7 +302,7 @@ impl TerminalInput {
///
/// ```no_run
/// use std::{thread, time::Duration};
/// use crossterm::input;
/// use crossterm::input::input;
///
/// let mut async_stdin = input().read_async();
///
@ -335,8 +335,9 @@ impl TerminalInput {
///
/// ```no_run
/// 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 {
/// if let Some(key_event) = async_stdin.next() {
@ -360,8 +361,9 @@ impl TerminalInput {
///
/// ```no_run
/// 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 {
/// if let Some(key_event) = sync_stdin.next() {
@ -397,7 +399,7 @@ impl TerminalInput {
/// ```no_run
/// // You can replace the following line with `use crossterm::...;`
/// // 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<()> {
/// let input = input();

View File

@ -39,7 +39,7 @@ pub(crate) trait Input {
/// # Examples
///
/// ```no_run
/// let input = crossterm::input();
/// let input = crossterm::input::input();
/// match input.read_line() {
/// Ok(s) => println!("string typed: {}", s),
/// Err(e) => println!("error: {}", e),

View File

@ -92,7 +92,7 @@ impl Input for UnixInput {
/// ```no_run
/// use std::{thread, time::Duration};
///
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
///
/// fn main() {
/// println!("Press 'ESC' to quit.");
@ -221,7 +221,7 @@ impl Iterator for AsyncReader {
/// ```no_run
/// use std::{thread, time::Duration};
///
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
///
/// fn main() {
/// println!("Press 'ESC' to quit.");

View File

@ -29,13 +29,9 @@ use winapi::um::{
use lazy_static::lazy_static;
use crate::input::{input::Input, InputEvent, KeyEvent, MouseButton};
use crate::utils::Result;
use super::{
super::{InputEvent, KeyEvent, MouseButton},
Input,
};
const ENABLE_MOUSE_MODE: u32 = 0x0010 | 0x0080 | 0x0008;
lazy_static! {
@ -172,7 +168,7 @@ impl Input for WindowsInput {
/// ```no_run
/// use std::{thread, time::Duration};
///
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
///
/// fn main() {
/// println!("Press 'ESC' to quit.");
@ -245,7 +241,7 @@ impl Iterator for SyncReader {
/// ```no_run
/// use std::{thread, time::Duration};
///
/// use crossterm::{input, InputEvent, KeyEvent, RawScreen};
/// use crossterm::{screen::RawScreen, input::{input, InputEvent, KeyEvent}};
///
/// fn main() {
/// 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
// 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
@ -554,10 +550,12 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
EventFlags::PressOrRelease => {
// Single click
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 => {
// left click
Some(crate::MouseEvent::Press(
Some(crate::input::MouseEvent::Press(
MouseButton::Left,
xpos as u16,
ypos as u16,
@ -565,7 +563,7 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
}
ButtonState::RightmostButtonPressed => {
// right click
Some(crate::MouseEvent::Press(
Some(crate::input::MouseEvent::Press(
MouseButton::Right,
xpos as u16,
ypos as u16,
@ -573,7 +571,7 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
}
ButtonState::FromLeft2ndButtonPressed => {
// middle click
Some(crate::MouseEvent::Press(
Some(crate::input::MouseEvent::Press(
MouseButton::Middle,
xpos as u16,
ypos as u16,
@ -586,7 +584,7 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::MouseEve
// Click + Move
// NOTE (@imdaveho) only register when mouse is not released
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 {
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
// if `button_state` is negative then the wheel was rotated backward, toward the user.
if event.button_state != ButtonState::Negative {
Some(crate::MouseEvent::Press(
Some(crate::input::MouseEvent::Press(
MouseButton::WheelUp,
xpos as u16,
ypos as u16,
))
} else {
Some(crate::MouseEvent::Press(
Some(crate::input::MouseEvent::Press(
MouseButton::WheelDown,
xpos as u16,
ypos as u16,

View File

@ -16,7 +16,9 @@
//! ## Command API
//!
//! 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.
//! * 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
//! 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
//! 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
//!
//! Because `flush` is a heavy system call we can instead `write` the commands to the `stdout` without flushing.
//! When can do a `flush` when we do want to execute the commands.
//! Flushing bytes to the terminal buffer is a heavy system call. If we perform a lot of actions with the terminal,
//! 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
//! to the terminal `stdout` and `flush` the `stdout` at every frame. By doing this you can make efficient use of the
//! terminal buffer and get better performance because you are not calling `flush` after every command.
//! Crossterm offers the possibility to do this with `queue`.
//! With `queue` you can queue commands, and when you call [Write::flush][flush] these commands will be executed.
//!
//! 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
//! A simple demonstration that shows the command API in action with cursor commands.
//!
//! Functions:
//! **Functions**
//!
//! ```no_run
//! use std::io::Write;
//! use std::io::{Write, stdout};
//! use crossterm::{QueueableCommand, cursor};
//!
//! let mut stdout = std::io::stdout();
//! let mut stdout = stdout();
//! stdout.queue(cursor::MoveTo(5,5));
//!
//! // some other code ...
@ -62,58 +103,68 @@
//! 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))`.
//!
//! Macros:
//! **Macros**
//!
//! ```no_run
//! use std::io::Write;
//! use std::io::{Write, stdout};
//! use crossterm::{queue, QueueableCommand, cursor};
//!
//! let mut stdout = std::io::stdout();
//! let mut stdout = stdout();
//! queue!(stdout, cursor::MoveTo(5, 5));
//!
//! // some other code ...
//!
//! // move operation is performed only if we flush the buffer.
//! 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.
//!
//! ## Direct Execution
//!
//! If you want to execute commands directly, this is also possible. You don't have to flush the 'stdout',
//! as described above. This is fine if you are not executing lots of commands.
//! For many applications it is not at all important to be efficient with 'flush' operations.
//! 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
//!
//! Functions:
//! **Functions**
//!
//! ```no_run
//! use std::io::Write;
//! use std::io::{Write, stdout};
//! use crossterm::{ExecutableCommand, cursor};
//!
//! let mut stdout = std::io::stdout();
//! let mut stdout = stdout();
//! 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
//! use std::io::Write;
//! use std::io::{Write, stdout};
//! use crossterm::{execute, ExecutableCommand, cursor};
//!
//! let mut stdout = std::io::stdout();
//! let mut stdout = stdout();
//! 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
//!
//! Print a rectangle colored with magenta and use both direct execution and lazy execution.
//!
//! Functions:
//! **Functions**
//!
//! ```no_run
//! use std::io::{stdout, Write};
@ -130,6 +181,7 @@
//! for y in 0..40 {
//! for x in 0..150 {
//! if (y == 0 || y == 40 - 1) || (x == 0 || x == 150 - 1) {
//! // in this loop we are more efficient by not flushing the buffer.
//! stdout
//! .queue(cursor::MoveTo(x,y))?
//! .queue(style::PrintStyledContent( "█".magenta()))?;
@ -141,7 +193,7 @@
//! }
//! ```
//!
//! Macros:
//! **Macros:**
//!
//! ```no_run
//! use std::io::{stdout, Write};
@ -158,6 +210,7 @@
//! for y in 0..40 {
//! for x in 0..150 {
//! 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()))?;
//! }
//! }
@ -166,35 +219,30 @@
//! 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 self::crossterm::Crossterm;
#[cfg(windows)]
pub use utils::functions::supports_ansi;
mod crossterm;
/// A functionality to work with the terminal cursor
/// A module to work with the terminal cursor
#[cfg(feature = "cursor")]
pub mod cursor;
/// A functionality to read the input events.
/// A module to read the input events.
#[cfg(feature = "input")]
pub mod input;
/// A functionality to work with the terminal screen.
/// A module to work with the terminal screen.
#[cfg(feature = "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")]
pub mod style;
/// A functionality to work with the terminal.
/// A module to work with the terminal.
#[cfg(feature = "terminal")]
pub mod terminal;
/// Shared utilities.

View File

@ -76,7 +76,7 @@ mod sys;
/// Alternate screen with raw mode enabled:
///
/// ```no_run
/// use crossterm::{AlternateScreen, Result};
/// use crossterm::{screen::{AlternateScreen}, Result};
///
/// fn main() -> Result<()> {
/// let _alternate = AlternateScreen::to_alternate(true)?;
@ -145,7 +145,7 @@ impl Drop for AlternateScreen {
///
/// ```no_run
/// use std::io::{stdout, Write};
/// use crossterm::{execute, Result, EnterAlternateScreen, LeaveAlternateScreen};
/// use crossterm::{execute, Result,screen::{EnterAlternateScreen, LeaveAlternateScreen}};
///
/// fn main() -> Result<()> {
/// execute!(stdout(), EnterAlternateScreen)?;
@ -181,7 +181,7 @@ impl Command for EnterAlternateScreen {
///
/// ```no_run
/// use std::io::{stdout, Write};
/// use crossterm::{execute, Result, EnterAlternateScreen, LeaveAlternateScreen};
/// use crossterm::{execute, Result, screen::{EnterAlternateScreen, LeaveAlternateScreen}};
///
/// fn main() -> Result<()> {
/// execute!(stdout(), EnterAlternateScreen)?;

View File

@ -3,7 +3,7 @@ pub(crate) use ansi::AnsiAlternateScreen;
pub(crate) use windows::WinApiAlternateScreen;
#[cfg(windows)]
use crate::utils::supports_ansi;
use crate::supports_ansi;
use crate::utils::Result;
pub(crate) mod ansi;

View File

@ -15,7 +15,7 @@ use super::sys;
/// Basic usage:
///
/// ```no_run
/// use crossterm::{RawScreen, Result};
/// use crossterm::{screen::RawScreen, Result};
///
/// fn main() -> Result<()> {
/// let _raw = RawScreen::into_raw_mode()?;
@ -27,7 +27,7 @@ use super::sys;
/// Do not disable the raw mode implicitly:
///
/// ```no_run
/// use crossterm::{RawScreen, Result};
/// use crossterm::{screen::RawScreen, Result};
///
/// fn main() -> Result<()> {
/// let mut raw = RawScreen::into_raw_mode()?;
@ -93,7 +93,7 @@ impl RawScreen {
///
/// ```no_run
/// use std::io::stdout;
/// use crossterm::{IntoRawMode, Result};
/// use crossterm::{screen::IntoRawMode, Result};
///
/// fn main() -> Result<()> {
/// let stdout = stdout();

View File

@ -16,10 +16,14 @@
//! * [Attribute](enum.Attribute.html#platform-specific-notes)
//!
//! ## Examples
//! A few examples of how to use the style module.
//!
//! ### Colors
//! How to change the terminal text color.
//!
//! The command API:
//! **Command API**
//!
//! Using the Command API to color text.
//!
//! ```no_run
//! 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
//! use crossterm::style::Colorize;
@ -51,8 +57,11 @@
//! ```
//!
//! ### Attributes
//! How to appy terminal attributes to text.
//!
//! The command API:
//! **Command API**
//!
//! Using the Command API to set attributes.
//!
//! ```no_run
//! 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
//! use crossterm::style::Styler;
@ -82,7 +93,9 @@
//! 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
//! use crossterm::style::Attribute;
@ -99,7 +112,6 @@ use std::fmt::Display;
use crate::impl_display;
use crate::utils::Command;
#[cfg(windows)]
use crate::Result;

View File

@ -4,7 +4,7 @@ use std::fmt::Display;
use crate::style::{Attribute, Color, StyledContent};
/// A content style.
/// The style that can be put on content.
#[derive(Debug, Clone, Default)]
pub struct ContentStyle {
/// The foreground color.

View File

@ -4,13 +4,12 @@ use std::fmt::{self, Display, Formatter};
use std::result;
use crate::queue;
use crate::style::{
Attribute, Color, Colorize, ContentStyle, ResetColor, SetAttribute, SetBackgroundColor,
SetForegroundColor, Styler,
};
/// A styled content.
/// The style with the content to be styled.
///
/// # Examples
///

View File

@ -180,10 +180,11 @@ impl From<Colored> for u16 {
#[cfg(test)]
mod tests {
use crate::style::sys::windows::set_foreground_color;
use super::{
Color, Colored, BG_INTENSITY, BG_RED, FG_INTENSITY, FG_RED, ORIGINAL_CONSOLE_COLOR,
};
use crate::style::sys::windows::set_foreground_color;
#[test]
fn test_parse_fg_color() {

View File

@ -2,11 +2,9 @@
pub use self::command::{Command, ExecutableCommand, Output, QueueableCommand};
pub use self::error::{ErrorKind, Result};
#[cfg(windows)]
pub use self::functions::supports_ansi;
mod command;
mod error;
mod functions;
pub(crate) mod functions;
pub(crate) mod macros;
pub(crate) mod sys;

View File

@ -1,7 +1,7 @@
use std::fmt::Display;
use std::io::Write;
use crate::{execute, impl_display, queue, write_cout};
use crate::{execute, queue, write_cout};
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.
pub struct Output(pub String);
pub struct Output<T: Display + Clone>(pub T);
impl Command for Output {
type AnsiType = String;
impl<T: Display + Clone> Command for Output<T> {
type AnsiType = T;
fn ansi_code(&self) -> Self::AnsiType {
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())
}
}

View File

@ -1,10 +1,12 @@
/// Append a the first few characters of an ANSI escape code to the given string.
#[macro_export]
#[doc(hidden)]
macro_rules! csi {
($( $l:expr ),*) => { concat!("\x1B[", $( $l ),*) };
}
/// Write a string to standard output whereafter the stdout will be flushed.
#[doc(hidden)]
#[macro_export]
macro_rules! write_cout {
($write:expr, $string:expr) => {{
@ -77,7 +79,7 @@ macro_rules! queue {
$(
#[cfg(windows)]
{
if $crate::utils::supports_ansi() {
if $crate::supports_ansi() {
match write!($write, "{}", $command.ansi_code()) {
Err(e) => {
error = Some(Err($crate::ErrorKind::from(e)));
@ -149,7 +151,7 @@ macro_rules! execute {
$(
#[cfg(windows)]
{
if $crate::utils::supports_ansi() {
if $crate::supports_ansi() {
if let Err(e) = write_cout!($write, $command.ansi_code()) {
error = Some($crate::ErrorKind::from(e));
};
@ -175,6 +177,7 @@ macro_rules! execute {
}}
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_display {
(for $($t:ty),+) => {
@ -187,6 +190,7 @@ macro_rules! impl_display {
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_from {
($from:path, $to:expr) => {