0.23 (#627)
This commit is contained in:
parent
979245da22
commit
9a50fd2ce2
@ -1,3 +1,10 @@
|
|||||||
|
# Version 0.23
|
||||||
|
- Update dependencies.
|
||||||
|
- Add 0 check for all cursor functions to prevent undefined behaviour.
|
||||||
|
- Add CSIu key parsing for unix.
|
||||||
|
- Improve control character window key parsing supporting (e.g. CTRL [ and ])
|
||||||
|
- Update library to 2021 edition.
|
||||||
|
|
||||||
# Version 0.22.1
|
# Version 0.22.1
|
||||||
- Update yanked version crossterm-winapi and move to crossterm-winapi 0.9.0.
|
- Update yanked version crossterm-winapi and move to crossterm-winapi 0.9.0.
|
||||||
- Changed panic to error when calling disable-mouse capture without setting it first.
|
- Changed panic to error when calling disable-mouse capture without setting it first.
|
||||||
|
16
Cargo.toml
16
Cargo.toml
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.22.1"
|
version = "0.23.0"
|
||||||
authors = ["T. Post"]
|
authors = ["T. Post"]
|
||||||
description = "A crossplatform terminal library for manipulating terminals."
|
description = "A crossplatform terminal library for manipulating terminals."
|
||||||
repository = "https://github.com/crossterm-rs/crossterm"
|
repository = "https://github.com/crossterm-rs/crossterm"
|
||||||
@ -9,7 +9,7 @@ license = "MIT"
|
|||||||
keywords = ["event", "color", "cli", "input", "terminal"]
|
keywords = ["event", "color", "cli", "input", "terminal"]
|
||||||
exclude = ["target", "Cargo.lock"]
|
exclude = ["target", "Cargo.lock"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
categories = ["command-line-interface", "command-line-utilities"]
|
categories = ["command-line-interface", "command-line-utilities"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
@ -34,7 +34,7 @@ event-stream = ["futures-core"]
|
|||||||
#
|
#
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1.3"
|
bitflags = "1.3"
|
||||||
parking_lot = "0.11"
|
parking_lot = "0.12"
|
||||||
|
|
||||||
# optional deps only added when requested
|
# optional deps only added when requested
|
||||||
futures-core = { version = "0.3", optional = true, default-features = false }
|
futures-core = { version = "0.3", optional = true, default-features = false }
|
||||||
@ -45,7 +45,7 @@ serde = { version = "1.0", features = ["derive"], optional = true }
|
|||||||
#
|
#
|
||||||
[target.'cfg(windows)'.dependencies.winapi]
|
[target.'cfg(windows)'.dependencies.winapi]
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
features = ["winuser"]
|
features = ["winuser", "winerror"]
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
crossterm_winapi = "0.9"
|
crossterm_winapi = "0.9"
|
||||||
@ -56,18 +56,18 @@ crossterm_winapi = "0.9"
|
|||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
mio = { version="0.7", features=["os-poll"] }
|
mio = { version="0.7", features=["os-poll"] }
|
||||||
signal-hook = { version = "0.3.8" }
|
signal-hook = { version = "0.3.13" }
|
||||||
signal-hook-mio = { version = "0.2.1", features = ["support-v0_7"] }
|
signal-hook-mio = { version = "0.2.1", features = ["support-v0_7"] }
|
||||||
|
|
||||||
#
|
#
|
||||||
# Dev dependencies (examples, ...)
|
# Dev dependencies (examples, ...)
|
||||||
#
|
#
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1.5", features = ["full"] }
|
tokio = { version = "1.16", features = ["full"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
futures-timer = "3.0"
|
futures-timer = "3.0"
|
||||||
async-std = "1.9"
|
async-std = "1.10"
|
||||||
serde_json = "1.0.45"
|
serde_json = "1.0"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Examples
|
# Examples
|
||||||
|
@ -134,7 +134,10 @@ pub struct MoveToColumn(pub u16);
|
|||||||
|
|
||||||
impl Command for MoveToColumn {
|
impl Command for MoveToColumn {
|
||||||
fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
||||||
write!(f, csi!("{}G"), self.0)
|
if self.0 != 0 {
|
||||||
|
write!(f, csi!("{}G"), self.0)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -153,7 +156,10 @@ pub struct MoveToRow(pub u16);
|
|||||||
|
|
||||||
impl Command for MoveToRow {
|
impl Command for MoveToRow {
|
||||||
fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
|
||||||
write!(f, csi!("{}d"), self.0)
|
if self.0 != 0 {
|
||||||
|
write!(f, csi!("{}d"), self.0)?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -264,23 +264,25 @@ pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result<Option<Inter
|
|||||||
let keycode = {
|
let keycode = {
|
||||||
if let Some(c) = char::from_u32(codepoint) {
|
if let Some(c) = char::from_u32(codepoint) {
|
||||||
match c {
|
match c {
|
||||||
'\x1B' => KeyCode::Esc.into(),
|
'\x1B' => KeyCode::Esc,
|
||||||
'\r' => KeyCode::Enter.into(),
|
'\r' => KeyCode::Enter,
|
||||||
// Issue #371: \n = 0xA, which is also the keycode for Ctrl+J. The only reason we get
|
// Issue #371: \n = 0xA, which is also the keycode for Ctrl+J. The only reason we get
|
||||||
// newlines as input is because the terminal converts \r into \n for us. When we
|
// newlines as input is because the terminal converts \r into \n for us. When we
|
||||||
// enter raw mode, we disable that, so \n no longer has any meaning - it's better to
|
// enter raw mode, we disable that, so \n no longer has any meaning - it's better to
|
||||||
// use Ctrl+J. Waiting to handle it here means it gets picked up later
|
// use Ctrl+J. Waiting to handle it here means it gets picked up later
|
||||||
'\n' if !crate::terminal::sys::is_raw_mode_enabled() => KeyCode::Enter.into(),
|
'\n' if !crate::terminal::sys::is_raw_mode_enabled() => KeyCode::Enter,
|
||||||
'\t' => if modifiers.contains(KeyModifiers::SHIFT) {
|
'\t' => {
|
||||||
KeyCode::BackTab.into()
|
if modifiers.contains(KeyModifiers::SHIFT) {
|
||||||
} else {
|
KeyCode::BackTab
|
||||||
KeyCode::Tab.into()
|
} else {
|
||||||
},
|
KeyCode::Tab
|
||||||
'\x7F' => KeyCode::Backspace.into(),
|
}
|
||||||
_ => KeyCode::Char(c).into(),
|
}
|
||||||
|
'\x7F' => KeyCode::Backspace,
|
||||||
|
_ => KeyCode::Char(c),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(could_not_parse_event_error())
|
return Err(could_not_parse_event_error());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,20 +30,18 @@ macro_rules! csi {
|
|||||||
/// use std::io::{Write, stdout};
|
/// use std::io::{Write, stdout};
|
||||||
/// use crossterm::{queue, style::Print};
|
/// use crossterm::{queue, style::Print};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// let mut stdout = stdout();
|
||||||
/// let mut stdout = stdout();
|
|
||||||
///
|
///
|
||||||
/// // `Print` will executed executed when `flush` is called.
|
/// // `Print` will executed executed when `flush` is called.
|
||||||
/// queue!(stdout, Print("foo".to_string()));
|
/// queue!(stdout, Print("foo".to_string()));
|
||||||
///
|
///
|
||||||
/// // some other code (no execution happening here) ...
|
/// // some other code (no execution happening here) ...
|
||||||
///
|
///
|
||||||
/// // when calling `flush` on `stdout`, all commands will be written to the stdout and therefore executed.
|
/// // when calling `flush` on `stdout`, all commands will be written to the stdout and therefore executed.
|
||||||
/// stdout.flush();
|
/// stdout.flush();
|
||||||
///
|
///
|
||||||
/// // ==== Output ====
|
/// // ==== Output ====
|
||||||
/// // foo
|
/// // foo
|
||||||
/// }
|
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Have a look over at the [Command API](./#command-api) for more details.
|
/// Have a look over at the [Command API](./#command-api) for more details.
|
||||||
@ -86,17 +84,15 @@ macro_rules! queue {
|
|||||||
/// use std::io::{Write, stdout};
|
/// use std::io::{Write, stdout};
|
||||||
/// use crossterm::{execute, style::Print};
|
/// use crossterm::{execute, style::Print};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// // will be executed directly
|
||||||
/// // will be executed directly
|
/// execute!(stdout(), Print("sum:\n".to_string()));
|
||||||
/// execute!(stdout(), Print("sum:\n".to_string()));
|
|
||||||
///
|
///
|
||||||
/// // will be executed directly
|
/// // will be executed directly
|
||||||
/// execute!(stdout(), Print("1 + 1= ".to_string()), Print((1+1).to_string()));
|
/// execute!(stdout(), Print("1 + 1= ".to_string()), Print((1+1).to_string()));
|
||||||
///
|
///
|
||||||
/// // ==== Output ====
|
/// // ==== Output ====
|
||||||
/// // sum:
|
/// // sum:
|
||||||
/// // 1 + 1 = 2
|
/// // 1 + 1 = 2
|
||||||
/// }
|
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Have a look over at the [Command API](./#command-api) for more details.
|
/// Have a look over at the [Command API](./#command-api) for more details.
|
||||||
|
@ -414,7 +414,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_raw_mode() {
|
fn test_raw_mode() {
|
||||||
// check we start from normal mode (may fail on some test harnesses)
|
// check we start from normal mode (may fail on some test harnesses)
|
||||||
assert_eq!(is_raw_mode_enabled().unwrap(), false);
|
assert!(!is_raw_mode_enabled().unwrap());
|
||||||
|
|
||||||
// enable the raw mode
|
// enable the raw mode
|
||||||
if enable_raw_mode().is_err() {
|
if enable_raw_mode().is_err() {
|
||||||
@ -425,18 +425,18 @@ mod tests {
|
|||||||
|
|
||||||
// check it worked (on unix it doesn't really check the underlying
|
// check it worked (on unix it doesn't really check the underlying
|
||||||
// tty but rather check that the code is consistent)
|
// tty but rather check that the code is consistent)
|
||||||
assert_eq!(is_raw_mode_enabled().unwrap(), true);
|
assert!(is_raw_mode_enabled().unwrap());
|
||||||
|
|
||||||
// enable it again, this should not change anything
|
// enable it again, this should not change anything
|
||||||
enable_raw_mode().unwrap();
|
enable_raw_mode().unwrap();
|
||||||
|
|
||||||
// check we're still in raw mode
|
// check we're still in raw mode
|
||||||
assert_eq!(is_raw_mode_enabled().unwrap(), true);
|
assert!(is_raw_mode_enabled().unwrap());
|
||||||
|
|
||||||
// now let's disable it
|
// now let's disable it
|
||||||
disable_raw_mode().unwrap();
|
disable_raw_mode().unwrap();
|
||||||
|
|
||||||
// check we're back to normal mode
|
// check we're back to normal mode
|
||||||
assert_eq!(is_raw_mode_enabled().unwrap(), false);
|
assert!(!is_raw_mode_enabled().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user