зеркало из
https://github.com/glebtv/tui-textarea.git
synced 2026-09-08 00:15:50 +03:00
Merge branch 'termwiz'
Этот коммит содержится в:
5
.github/workflows/ci.yml
поставляемый
5
.github/workflows/ci.yml
поставляемый
@@ -16,6 +16,9 @@ jobs:
|
|||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
- run: cargo test --features=search
|
- run: cargo test --features=search
|
||||||
- run: cargo test --no-default-features --features=ratatui-crossterm,search -- --skip .rs
|
- run: cargo test --no-default-features --features=ratatui-crossterm,search -- --skip .rs
|
||||||
|
- run: cargo test --no-default-features --features=ratatui-termion,search -- --skip .rs
|
||||||
|
if: ${{ matrix.os != 'windows-latest' }}
|
||||||
|
- run: cargo test --no-default-features --features=ratatui-termwiz,search -- --skip .rs
|
||||||
- run: cargo test --no-default-features --features=your-backend,search -- --skip .rs
|
- run: cargo test --no-default-features --features=your-backend,search -- --skip .rs
|
||||||
- run: cargo test --no-default-features --features=ratatui-your-backend,search -- --skip .rs
|
- run: cargo test --no-default-features --features=ratatui-your-backend,search -- --skip .rs
|
||||||
lint:
|
lint:
|
||||||
@@ -33,6 +36,8 @@ jobs:
|
|||||||
- run: cargo clippy --examples --no-default-features --features ratatui-crossterm,search -- -D warnings
|
- run: cargo clippy --examples --no-default-features --features ratatui-crossterm,search -- -D warnings
|
||||||
- run: cargo clippy --examples --no-default-features --features ratatui-termion -- -D warnings
|
- run: cargo clippy --examples --no-default-features --features ratatui-termion -- -D warnings
|
||||||
- run: cargo clippy --examples --no-default-features --features ratatui-termion,search -- -D warnings
|
- run: cargo clippy --examples --no-default-features --features ratatui-termion,search -- -D warnings
|
||||||
|
- run: cargo clippy --examples --no-default-features --features ratatui-termwiz -- -D warnings
|
||||||
|
- run: cargo clippy --examples --no-default-features --features ratatui-termwiz,search -- -D warnings
|
||||||
- run: cargo clippy --examples --no-default-features --features termion -- -D warnings
|
- run: cargo clippy --examples --no-default-features --features termion -- -D warnings
|
||||||
- run: cargo clippy --examples --no-default-features --features termion,search -- -D warnings
|
- run: cargo clippy --examples --no-default-features --features termion,search -- -D warnings
|
||||||
- run: cargo clippy --examples --no-default-features --features your-backend -- -D warnings
|
- run: cargo clippy --examples --no-default-features --features your-backend -- -D warnings
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ your-backend = ["tui"]
|
|||||||
# Features to use ratatui
|
# Features to use ratatui
|
||||||
ratatui-crossterm = ["dep:crossterm-027", "ratatui/crossterm"]
|
ratatui-crossterm = ["dep:crossterm-027", "ratatui/crossterm"]
|
||||||
ratatui-termion = ["dep:termion", "ratatui/termion"]
|
ratatui-termion = ["dep:termion", "ratatui/termion"]
|
||||||
|
ratatui-termwiz = ["dep:termwiz", "ratatui/termwiz"]
|
||||||
ratatui-your-backend = ["ratatui"]
|
ratatui-your-backend = ["ratatui"]
|
||||||
# Other optional features
|
# Other optional features
|
||||||
search = ["dep:regex"]
|
search = ["dep:regex"]
|
||||||
@@ -44,6 +45,7 @@ arbitrary = { version = "1", features = ["derive"], optional = true }
|
|||||||
crossterm-027 = { package = "crossterm", version = "0.27", optional = true }
|
crossterm-027 = { package = "crossterm", version = "0.27", optional = true }
|
||||||
ratatui = { version = "0.23.0", default-features = false, optional = true }
|
ratatui = { version = "0.23.0", default-features = false, optional = true }
|
||||||
unicode-width = "0.1.11"
|
unicode-width = "0.1.11"
|
||||||
|
termwiz = { version = "0.20.0", optional = true }
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "minimal"
|
name = "minimal"
|
||||||
@@ -97,6 +99,10 @@ required-features = ["ratatui-crossterm", "search"]
|
|||||||
name = "ratatui_termion"
|
name = "ratatui_termion"
|
||||||
required-features = ["ratatui-termion"]
|
required-features = ["ratatui-termion"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "termwiz"
|
||||||
|
required-features = ["ratatui-termwiz"]
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"bench",
|
"bench",
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -17,7 +17,7 @@ Multi-line text editor can be easily put as part of your TUI application.
|
|||||||
- Search with regular expressions
|
- Search with regular expressions
|
||||||
- Mouse scrolling
|
- Mouse scrolling
|
||||||
- Yank support. Paste text deleted with `C-k`, `C-j`, ...
|
- Yank support. Paste text deleted with `C-k`, `C-j`, ...
|
||||||
- Backend agnostic. [crossterm][], [termion][], and your own backend are all supported
|
- Backend agnostic. [crossterm][], [termion][], [termwiz][], and your own backend are all supported
|
||||||
- Multiple textarea widgets in the same screen
|
- Multiple textarea widgets in the same screen
|
||||||
- Support both [tui-rs][] (the original) and [ratatui][] (the fork by community)
|
- Support both [tui-rs][] (the original) and [ratatui][] (the fork by community)
|
||||||
|
|
||||||
@@ -130,6 +130,14 @@ cargo run --example ratatui_termion --no-default-features --features=ratatui-ter
|
|||||||
cargo run --example ratatui_popup_placeholder --no-default-features --features=ratatui-crossterm
|
cargo run --example ratatui_popup_placeholder --no-default-features --features=ratatui-crossterm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### [`termwiz`](./examples/termwiz.rs)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo run --example termwiz --no-default-features --features=ratatui-termwiz
|
||||||
|
```
|
||||||
|
|
||||||
|
Minimal usage with [termwiz][] support.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add `tui-textarea` crate to dependencies in your `Cargo.toml`. This enables crossterm backend support by default.
|
Add `tui-textarea` crate to dependencies in your `Cargo.toml`. This enables crossterm backend support by default.
|
||||||
@@ -160,10 +168,10 @@ tui-textarea = { version = "*", default-features = false, features = ["termion"]
|
|||||||
If you're using [ratatui][] instead of [tui-rs][], you need to enable features for using ratatui crate. The following table
|
If you're using [ratatui][] instead of [tui-rs][], you need to enable features for using ratatui crate. The following table
|
||||||
shows feature names corresponding to the dependencies.
|
shows feature names corresponding to the dependencies.
|
||||||
|
|
||||||
| | crossterm | termion | Your own backend |
|
| | crossterm | termion | termwiz | Your own backend |
|
||||||
|---------|----------------------------------|-------------------|------------------------|
|
|---------|----------------------------------|-------------------|-------------------|------------------------|
|
||||||
| tui-rs | `crossterm` (enabled by default) | `termion` | `your-backend` |
|
| tui-rs | `crossterm` (enabled by default) | `termion` | N/A | `your-backend` |
|
||||||
| ratatui | `ratatui-crossterm` | `ratatui-termion` | `ratatui-your-backend` |
|
| ratatui | `ratatui-crossterm` | `ratatui-termion` | `ratatui-termwiz` | `ratatui-your-backend` |
|
||||||
|
|
||||||
For example, when you want to use the combination of [ratatui][] and [crossterm][],
|
For example, when you want to use the combination of [ratatui][] and [crossterm][],
|
||||||
|
|
||||||
@@ -176,9 +184,9 @@ tui-textarea = { version = "*", features = ["ratatui-crossterm"], default-featur
|
|||||||
Note that [tui-rs][] support and [ratatui][] support are exclusive. When you use [ratatui][] support, you must disable
|
Note that [tui-rs][] support and [ratatui][] support are exclusive. When you use [ratatui][] support, you must disable
|
||||||
[tui-rs][] support by `default-features = false`.
|
[tui-rs][] support by `default-features = false`.
|
||||||
|
|
||||||
In addition to above dependencies, you also need to install [crossterm][] or [termion][] to initialize your application
|
In addition to above dependencies, you also need to install [crossterm][] or [termion][] or [termwiz][] to initialize
|
||||||
and to receive key inputs. Note that version of [crossterm][] crate is different between [tui-rs][] and [ratatui][].
|
your application and to receive key inputs. Note that version of [crossterm][] crate is different between [tui-rs][]
|
||||||
Please select the correct version.
|
and [ratatui][]. Please select the correct version.
|
||||||
|
|
||||||
## Minimal Usage
|
## Minimal Usage
|
||||||
|
|
||||||
@@ -553,7 +561,7 @@ match read()?.into() {
|
|||||||
|
|
||||||
tui-rs allows to make your own backend by implementing [`tui::backend::Backend`][tui-backend] trait. tui-textarea also
|
tui-rs allows to make your own backend by implementing [`tui::backend::Backend`][tui-backend] trait. tui-textarea also
|
||||||
supports it. In this case, please use `your-backend` feature for [tui-rs][] or `ratatui-your-backend` feature for
|
supports it. In this case, please use `your-backend` feature for [tui-rs][] or `ratatui-your-backend` feature for
|
||||||
[ratatui][]. They avoid adding backend crates (crossterm and termion) since you're using your own backend.
|
[ratatui][]. They avoid adding backend crates (crossterm, termion, and termwiz) since you're using your own backend.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -696,9 +704,10 @@ tui-textarea is distributed under [The MIT License](./LICENSE.txt).
|
|||||||
[ci-badge]: https://github.com/rhysd/tui-textarea/actions/workflows/ci.yml/badge.svg?event=push
|
[ci-badge]: https://github.com/rhysd/tui-textarea/actions/workflows/ci.yml/badge.svg?event=push
|
||||||
[ci]: https://github.com/rhysd/tui-textarea/actions/workflows/ci.yml
|
[ci]: https://github.com/rhysd/tui-textarea/actions/workflows/ci.yml
|
||||||
[tui-rs]: https://github.com/fdehau/tui-rs
|
[tui-rs]: https://github.com/fdehau/tui-rs
|
||||||
[ratatui]: https://github.com/tui-rs-revival/ratatui
|
[ratatui]: https://github.com/ratatui-org/ratatui
|
||||||
[termion]: https://docs.rs/termion/latest/termion/
|
|
||||||
[crossterm]: https://docs.rs/crossterm/latest/crossterm/
|
[crossterm]: https://docs.rs/crossterm/latest/crossterm/
|
||||||
|
[termion]: https://docs.rs/termion/latest/termion/
|
||||||
|
[termwiz]: https://docs.rs/termwiz/latest/termwiz/
|
||||||
[tui-backend]: https://docs.rs/tui/latest/tui/backend/trait.Backend.html
|
[tui-backend]: https://docs.rs/tui/latest/tui/backend/trait.Backend.html
|
||||||
[repo]: https://github.com/rhysd/tui-textarea
|
[repo]: https://github.com/rhysd/tui-textarea
|
||||||
[new-issue]: https://github.com/rhysd/tui-textarea/issues/new
|
[new-issue]: https://github.com/rhysd/tui-textarea/issues/new
|
||||||
|
|||||||
67
examples/termwiz.rs
Обычный файл
67
examples/termwiz.rs
Обычный файл
@@ -0,0 +1,67 @@
|
|||||||
|
use ratatui::backend::TermwizBackend;
|
||||||
|
use ratatui::widgets::{Block, Borders};
|
||||||
|
use ratatui::Terminal;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
use termwiz::input::InputEvent;
|
||||||
|
use termwiz::terminal::Terminal as TermwizTerminal;
|
||||||
|
use tui_textarea::{Input, Key, TextArea};
|
||||||
|
|
||||||
|
const TICK_RATE: Duration = Duration::from_millis(100);
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let backend = TermwizBackend::new()?;
|
||||||
|
let mut term = Terminal::new(backend)?;
|
||||||
|
term.hide_cursor()?;
|
||||||
|
|
||||||
|
let mut textarea = TextArea::default();
|
||||||
|
textarea.set_block(
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.title("Termwiz Minimal Example"),
|
||||||
|
);
|
||||||
|
let mut last_tick = Instant::now();
|
||||||
|
|
||||||
|
// The event loop
|
||||||
|
loop {
|
||||||
|
term.draw(|f| {
|
||||||
|
let widget = textarea.widget();
|
||||||
|
f.render_widget(widget, f.size());
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let timeout = TICK_RATE
|
||||||
|
.checked_sub(last_tick.elapsed())
|
||||||
|
.unwrap_or_else(|| Duration::from_secs(0));
|
||||||
|
|
||||||
|
if let Some(input) = term
|
||||||
|
.backend_mut()
|
||||||
|
.buffered_terminal_mut()
|
||||||
|
.terminal()
|
||||||
|
.poll_input(Some(timeout))?
|
||||||
|
{
|
||||||
|
if let InputEvent::Resized { cols, rows } = input {
|
||||||
|
term.backend_mut()
|
||||||
|
.buffered_terminal_mut()
|
||||||
|
.resize(cols, rows);
|
||||||
|
} else {
|
||||||
|
match input.into() {
|
||||||
|
Input { key: Key::Esc, .. } => break,
|
||||||
|
input => {
|
||||||
|
textarea.input(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if last_tick.elapsed() >= TICK_RATE {
|
||||||
|
last_tick = Instant::now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
term.show_cursor()?;
|
||||||
|
term.flush()?;
|
||||||
|
drop(term); // Leave terminal raw mode to print the following line
|
||||||
|
|
||||||
|
println!("Lines: {:?}", textarea.lines());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ use crate::tui::style::Style;
|
|||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "ratatui-crossterm",
|
feature = "ratatui-crossterm",
|
||||||
feature = "ratatui-termion",
|
feature = "ratatui-termion",
|
||||||
|
feature = "ratatui-termwiz",
|
||||||
feature = "ratatui-your-backend",
|
feature = "ratatui-your-backend",
|
||||||
))]
|
))]
|
||||||
use crate::tui::text::Line as Spans;
|
use crate::tui::text::Line as Spans;
|
||||||
@@ -9,6 +10,7 @@ use crate::tui::text::Span;
|
|||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
feature = "ratatui-crossterm",
|
feature = "ratatui-crossterm",
|
||||||
feature = "ratatui-termion",
|
feature = "ratatui-termion",
|
||||||
|
feature = "ratatui-termwiz",
|
||||||
feature = "ratatui-your-backend",
|
feature = "ratatui-your-backend",
|
||||||
)))]
|
)))]
|
||||||
use crate::tui::text::Spans;
|
use crate::tui::text::Spans;
|
||||||
|
|||||||
115
src/input.rs
115
src/input.rs
@@ -1,12 +1,17 @@
|
|||||||
#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))]
|
#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))]
|
||||||
use crate::crossterm::event::{
|
use crate::crossterm::event::{
|
||||||
Event as CrosstermEvent, KeyCode, KeyEvent, KeyEventKind, KeyModifiers,
|
Event as CrosstermEvent, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseEvent,
|
||||||
MouseEvent as CrosstermMouseEvent, MouseEventKind as CrosstermMouseEventKind,
|
MouseEventKind as CrosstermMouseEventKind,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
use arbitrary::Arbitrary;
|
use arbitrary::Arbitrary;
|
||||||
#[cfg(any(feature = "termion", feature = "ratatui-termion"))]
|
#[cfg(any(feature = "termion", feature = "ratatui-termion"))]
|
||||||
use termion::event::{Event as TermionEvent, Key as TermionKey, MouseEvent as TermionMouseEvent};
|
use termion::event::{Event as TermionEvent, Key as TermionKey, MouseEvent as TermionMouseEvent};
|
||||||
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
|
use termwiz::input::{
|
||||||
|
InputEvent as TermwizInputEvent, KeyEvent as TermwizKeyEvent,
|
||||||
|
MouseButtons as TermwizMouseButtons, MouseEvent as TermwizMouseEvent, PixelMouseEvent,
|
||||||
|
};
|
||||||
|
|
||||||
/// Backend-agnostic key input kind.
|
/// Backend-agnostic key input kind.
|
||||||
///
|
///
|
||||||
@@ -42,7 +47,8 @@ pub enum Key {
|
|||||||
|
|
||||||
/// Backend-agnostic key input type.
|
/// Backend-agnostic key input type.
|
||||||
///
|
///
|
||||||
/// When `crossterm` and/or `termion` features are enabled, converting their key input types into this `Input` type is defined.
|
/// When `crossterm`, `termion`, `ratatui-termwiz` features are enabled, converting respective key input types into this
|
||||||
|
/// `Input` type is defined.
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use tui_textarea::{TextArea, Input, Key};
|
/// use tui_textarea::{TextArea, Input, Key};
|
||||||
/// use crossterm::event::{Event, read};
|
/// use crossterm::event::{Event, read};
|
||||||
@@ -136,9 +142,9 @@ impl From<KeyEvent> for Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))]
|
#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))]
|
||||||
impl From<CrosstermMouseEvent> for Input {
|
impl From<MouseEvent> for Input {
|
||||||
/// Convert [`crossterm::event::MouseEvent`] to [`Input`].
|
/// Convert [`crossterm::event::MouseEvent`] to [`Input`].
|
||||||
fn from(mouse: CrosstermMouseEvent) -> Self {
|
fn from(mouse: MouseEvent) -> Self {
|
||||||
let key = match mouse.kind {
|
let key = match mouse.kind {
|
||||||
CrosstermMouseEventKind::ScrollDown => Key::MouseScrollDown,
|
CrosstermMouseEventKind::ScrollDown => Key::MouseScrollDown,
|
||||||
CrosstermMouseEventKind::ScrollUp => Key::MouseScrollUp,
|
CrosstermMouseEventKind::ScrollUp => Key::MouseScrollUp,
|
||||||
@@ -218,3 +224,102 @@ impl From<TermionMouseEvent> for Input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
|
impl From<TermwizInputEvent> for Input {
|
||||||
|
/// Convert [`termwiz::input::InputEvent`] to [`Input`].
|
||||||
|
fn from(input: TermwizInputEvent) -> Self {
|
||||||
|
match input {
|
||||||
|
TermwizInputEvent::Key(key) => Self::from(key),
|
||||||
|
TermwizInputEvent::Mouse(mouse) => Self::from(mouse),
|
||||||
|
TermwizInputEvent::PixelMouse(mouse) => Self::from(mouse),
|
||||||
|
_ => Self::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
|
impl From<TermwizKeyEvent> for Input {
|
||||||
|
/// Convert [`termwiz::input::KeyEvent`] to [`Input`].
|
||||||
|
fn from(key: TermwizKeyEvent) -> Self {
|
||||||
|
use termwiz::input::{KeyCode, Modifiers};
|
||||||
|
|
||||||
|
let TermwizKeyEvent { key, modifiers } = key;
|
||||||
|
let key = match key {
|
||||||
|
KeyCode::Char(c) => Key::Char(c),
|
||||||
|
KeyCode::Backspace => Key::Backspace,
|
||||||
|
KeyCode::Tab => Key::Tab,
|
||||||
|
KeyCode::Enter => Key::Enter,
|
||||||
|
KeyCode::Escape => Key::Esc,
|
||||||
|
KeyCode::PageUp => Key::PageUp,
|
||||||
|
KeyCode::PageDown => Key::PageDown,
|
||||||
|
KeyCode::End => Key::End,
|
||||||
|
KeyCode::Home => Key::Home,
|
||||||
|
KeyCode::LeftArrow => Key::Left,
|
||||||
|
KeyCode::RightArrow => Key::Right,
|
||||||
|
KeyCode::UpArrow => Key::Up,
|
||||||
|
KeyCode::DownArrow => Key::Down,
|
||||||
|
KeyCode::Delete => Key::Delete,
|
||||||
|
KeyCode::Function(x) => Key::F(x),
|
||||||
|
_ => Key::Null,
|
||||||
|
};
|
||||||
|
let ctrl = modifiers.contains(Modifiers::CTRL);
|
||||||
|
let alt = modifiers.contains(Modifiers::ALT);
|
||||||
|
|
||||||
|
Self { key, ctrl, alt }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
|
impl From<TermwizMouseButtons> for Key {
|
||||||
|
/// Convert [`termwiz::input::MouseButtons`] to [`Key`].
|
||||||
|
fn from(buttons: TermwizMouseButtons) -> Self {
|
||||||
|
if buttons.contains(TermwizMouseButtons::VERT_WHEEL) {
|
||||||
|
if buttons.contains(TermwizMouseButtons::WHEEL_POSITIVE) {
|
||||||
|
Key::MouseScrollUp
|
||||||
|
} else {
|
||||||
|
Key::MouseScrollDown
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Key::Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
|
impl From<TermwizMouseEvent> for Input {
|
||||||
|
/// Convert [`termwiz::input::MouseEvent`] to [`Input`].
|
||||||
|
fn from(mouse: TermwizMouseEvent) -> Self {
|
||||||
|
use termwiz::input::Modifiers;
|
||||||
|
|
||||||
|
let TermwizMouseEvent {
|
||||||
|
mouse_buttons,
|
||||||
|
modifiers,
|
||||||
|
..
|
||||||
|
} = mouse;
|
||||||
|
let key = Key::from(mouse_buttons);
|
||||||
|
let ctrl = modifiers.contains(Modifiers::CTRL);
|
||||||
|
let alt = modifiers.contains(Modifiers::ALT);
|
||||||
|
|
||||||
|
Self { key, ctrl, alt }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
|
impl From<PixelMouseEvent> for Input {
|
||||||
|
/// Convert [`termwiz::input::PixelMouseEvent`] to [`Input`].
|
||||||
|
fn from(mouse: PixelMouseEvent) -> Self {
|
||||||
|
use termwiz::input::Modifiers;
|
||||||
|
|
||||||
|
let PixelMouseEvent {
|
||||||
|
mouse_buttons,
|
||||||
|
modifiers,
|
||||||
|
..
|
||||||
|
} = mouse;
|
||||||
|
let key = Key::from(mouse_buttons);
|
||||||
|
let ctrl = modifiers.contains(Modifiers::CTRL);
|
||||||
|
let alt = modifiers.contains(Modifiers::ALT);
|
||||||
|
|
||||||
|
Self { key, ctrl, alt }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
any(
|
any(
|
||||||
feature = "ratatui-crossterm",
|
feature = "ratatui-crossterm",
|
||||||
feature = "ratatui-termion",
|
feature = "ratatui-termion",
|
||||||
|
feature = "ratatui-termwiz",
|
||||||
feature = "ratatui-your-backend"
|
feature = "ratatui-your-backend"
|
||||||
),
|
),
|
||||||
))]
|
))]
|
||||||
@@ -29,12 +30,14 @@ mod word;
|
|||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "ratatui-crossterm",
|
feature = "ratatui-crossterm",
|
||||||
feature = "ratatui-termion",
|
feature = "ratatui-termion",
|
||||||
|
feature = "ratatui-termwiz",
|
||||||
feature = "ratatui-your-backend",
|
feature = "ratatui-your-backend",
|
||||||
))]
|
))]
|
||||||
use ratatui as tui;
|
use ratatui as tui;
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
feature = "ratatui-crossterm",
|
feature = "ratatui-crossterm",
|
||||||
feature = "ratatui-termion",
|
feature = "ratatui-termion",
|
||||||
|
feature = "ratatui-termwiz",
|
||||||
feature = "ratatui-your-backend",
|
feature = "ratatui-your-backend",
|
||||||
)))]
|
)))]
|
||||||
#[allow(clippy::single_component_path_imports)]
|
#[allow(clippy::single_component_path_imports)]
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ use crate::tui::style::{Color, Modifier, Style};
|
|||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "ratatui-crossterm",
|
feature = "ratatui-crossterm",
|
||||||
feature = "ratatui-termion",
|
feature = "ratatui-termion",
|
||||||
|
feature = "ratatui-termwiz",
|
||||||
feature = "ratatui-your-backend",
|
feature = "ratatui-your-backend",
|
||||||
))]
|
))]
|
||||||
use crate::tui::text::Line as Spans;
|
use crate::tui::text::Line as Spans;
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
feature = "ratatui-crossterm",
|
feature = "ratatui-crossterm",
|
||||||
feature = "ratatui-termion",
|
feature = "ratatui-termion",
|
||||||
|
feature = "ratatui-termwiz",
|
||||||
feature = "ratatui-your-backend",
|
feature = "ratatui-your-backend",
|
||||||
)))]
|
)))]
|
||||||
use crate::tui::text::Spans;
|
use crate::tui::text::Spans;
|
||||||
@@ -170,8 +172,8 @@ impl<'a> TextArea<'a> {
|
|||||||
|
|
||||||
/// Handle a key input with default key mappings. For default key mappings, see the table in
|
/// Handle a key input with default key mappings. For default key mappings, see the table in
|
||||||
/// [the module document](./index.html).
|
/// [the module document](./index.html).
|
||||||
/// `crossterm` and `termion` features enable conversion from their own key event types into [`Input`] so this
|
/// `crossterm`, `termion`, and `ratatui-termwiz` features enable conversion from their own key event types into
|
||||||
/// method can take the event values directly.
|
/// [`Input`] so this method can take the event values directly.
|
||||||
/// This method returns if the input modified text contents or not in the textarea.
|
/// This method returns if the input modified text contents or not in the textarea.
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// use tui_textarea::{TextArea, Key, Input};
|
/// use tui_textarea::{TextArea, Key, Input};
|
||||||
@@ -192,6 +194,13 @@ impl<'a> TextArea<'a> {
|
|||||||
/// textarea.input(key);
|
/// textarea.input(key);
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
/// // Handle termwiz key events
|
||||||
|
/// let event: termwiz::input::InputEvent = ...;
|
||||||
|
/// textarea.input(event);
|
||||||
|
/// if let termwiz::input::InputEvent::Key(key) = event {
|
||||||
|
/// textarea.input(key);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
/// // Handle backend-agnostic key input
|
/// // Handle backend-agnostic key input
|
||||||
/// let input = Input { key: Key::Char('a'), ctrl: false, alt: false };
|
/// let input = Input { key: Key::Char('a'), ctrl: false, alt: false };
|
||||||
/// let modified = textarea.input(input);
|
/// let modified = textarea.input(input);
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user