From dbe03202a80eb99484d0afd4fdec9d0baf58c9ba Mon Sep 17 00:00:00 2001 From: rhysd Date: Thu, 13 Apr 2023 21:51:27 +0900 Subject: [PATCH] add `ratatui` crate support --- Cargo.toml | 1 - examples/minimal.rs | 19 ++++++++++++++++--- src/highlight.rs | 4 ++-- src/input.rs | 22 +++++++++++----------- src/lib.rs | 20 +++++++++++++++++++- src/search.rs | 2 +- src/textarea.rs | 8 ++++---- src/widget.rs | 8 ++++---- 8 files changed, 57 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 11df662..480befe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,6 @@ ratatui = { version = "0.20.1", default-features = false, optional = true } [[example]] name = "minimal" -required-features = ["crossterm"] [[example]] name = "termion" diff --git a/examples/minimal.rs b/examples/minimal.rs index 5d26a20..04d925e 100644 --- a/examples/minimal.rs +++ b/examples/minimal.rs @@ -1,13 +1,26 @@ +#[cfg(feature = "ratatui-crossterm")] +use crossterm_026 as crossterm; + use crossterm::event::{DisableMouseCapture, EnableMouseCapture}; use crossterm::terminal::{ disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, }; use std::io; -use tui::backend::CrosstermBackend; -use tui::widgets::{Block, Borders}; -use tui::Terminal; use tui_textarea::{Input, Key, TextArea}; +#[cfg(feature = "ratatui-crossterm")] +use ratatui::{ + backend::CrosstermBackend, + widgets::{Block, Borders}, + Terminal, +}; +#[cfg(feature = "crossterm")] +use tui::{ + backend::CrosstermBackend, + widgets::{Block, Borders}, + Terminal, +}; + fn main() -> io::Result<()> { let stdout = io::stdout(); let mut stdout = stdout.lock(); diff --git a/src/highlight.rs b/src/highlight.rs index 8fac916..bebb687 100644 --- a/src/highlight.rs +++ b/src/highlight.rs @@ -1,8 +1,8 @@ +use crate::tui::style::Style; +use crate::tui::text::{Span, Spans}; use crate::util::{num_digits, spaces}; use std::borrow::Cow; use std::cmp::Ordering; -use tui::style::Style; -use tui::text::{Span, Spans}; enum Boundary { Cursor(Style), diff --git a/src/input.rs b/src/input.rs index 2702a2b..aa099e3 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,11 +1,11 @@ -#[cfg(feature = "arbitrary")] -use arbitrary::Arbitrary; -#[cfg(feature = "crossterm")] -use crossterm::event::{ +#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))] +use crate::crossterm::event::{ Event as CrosstermEvent, KeyCode, KeyEvent, KeyModifiers, MouseEvent as CrosstermMouseEvent, MouseEventKind as CrosstermMouseEventKind, }; -#[cfg(feature = "termion")] +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; +#[cfg(any(feature = "termion", feature = "ratatui-termion"))] use termion::event::{Event as TermionEvent, Key as TermionKey, MouseEvent as TermionMouseEvent}; /// Backend-agnostic key input kind. @@ -95,7 +95,7 @@ impl Default for Input { } } -#[cfg(feature = "crossterm")] +#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))] impl From for Input { /// Convert [`crossterm::event::Event`] to [`Input`]. fn from(event: CrosstermEvent) -> Self { @@ -107,7 +107,7 @@ impl From for Input { } } -#[cfg(feature = "crossterm")] +#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))] impl From for Input { /// Convert [`crossterm::event::KeyEvent`] to [`Input`]. fn from(key: KeyEvent) -> Self { @@ -135,7 +135,7 @@ impl From for Input { } } -#[cfg(feature = "crossterm")] +#[cfg(any(feature = "crossterm", feature = "ratatui-crossterm"))] impl From for Input { /// Convert [`crossterm::event::MouseEvent`] to [`Input`]. fn from(mouse: CrosstermMouseEvent) -> Self { @@ -150,7 +150,7 @@ impl From for Input { } } -#[cfg(feature = "termion")] +#[cfg(any(feature = "termion", feature = "ratatui-termion"))] impl From for Input { /// Convert [`termion::event::Event`] to [`Input`]. fn from(event: TermionEvent) -> Self { @@ -162,7 +162,7 @@ impl From for Input { } } -#[cfg(feature = "termion")] +#[cfg(any(feature = "termion", feature = "ratatui-termion"))] impl From for Input { /// Convert [`termion::event::Key`] to [`Input`]. fn from(key: TermionKey) -> Self { @@ -201,7 +201,7 @@ impl From for Input { } } -#[cfg(feature = "termion")] +#[cfg(any(feature = "termion", feature = "ratatui-termion"))] impl From for Input { /// Convert [`termion::event::MouseEvent`] to [`Input`]. fn from(mouse: TermionMouseEvent) -> Self { diff --git a/src/lib.rs b/src/lib.rs index aa1d277..7374d3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,15 @@ -#![allow(clippy::needless_range_loop)] #![forbid(unsafe_code)] +#![allow(clippy::needless_range_loop)] #![warn(clippy::dbg_macro, clippy::print_stdout)] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc = include_str!("../README.md")] +#[cfg(all( + any(feature = "crossterm", feature = "termion"), + any(feature = "ratatui-crossterm", feature = "ratatui-termion"), +))] +compile_error!("tui-rs support and ratatui support are exclussive. only one of them can be enabled at the same time. see https://github.com/rhysd/tui-textarea"); + mod cursor; mod highlight; mod history; @@ -16,6 +22,18 @@ mod util; mod widget; mod word; +#[cfg(any(feature = "ratatui-crossterm", feature = "ratatui-termion"))] +use ratatui as tui; +#[cfg(not(any(feature = "ratatui-crossterm", feature = "ratatui-termion")))] +#[allow(clippy::single_component_path_imports)] +use tui; + +#[cfg(not(feature = "ratatui-crossterm"))] +#[allow(clippy::single_component_path_imports)] +use crossterm; +#[cfg(feature = "ratatui-crossterm")] +use crossterm_026 as crossterm; + pub use cursor::CursorMove; pub use input::{Input, Key}; pub use scroll::Scrolling; diff --git a/src/search.rs b/src/search.rs index b6aa53f..8c29f5e 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,5 +1,5 @@ +use crate::tui::style::{Color, Style}; use regex::Regex; -use tui::style::{Color, Style}; #[derive(Clone)] pub struct Search { diff --git a/src/textarea.rs b/src/textarea.rs index b8c77ca..9673cf3 100644 --- a/src/textarea.rs +++ b/src/textarea.rs @@ -5,13 +5,13 @@ use crate::input::{Input, Key}; use crate::scroll::Scrolling; #[cfg(feature = "search")] use crate::search::Search; +use crate::tui::layout::Alignment; +use crate::tui::style::{Modifier, Style}; +use crate::tui::text::Spans; +use crate::tui::widgets::{Block, Widget}; use crate::util::spaces; use crate::widget::{Renderer, Viewport}; use crate::word::{find_word_end_forward, find_word_start_backward}; -use tui::layout::Alignment; -use tui::style::{Modifier, Style}; -use tui::text::Spans; -use tui::widgets::{Block, Widget}; /// A type to manage state of textarea. /// diff --git a/src/widget.rs b/src/widget.rs index c71d71a..a0cdc58 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -1,11 +1,11 @@ use crate::textarea::TextArea; +use crate::tui::buffer::Buffer; +use crate::tui::layout::Rect; +use crate::tui::text::Text; +use crate::tui::widgets::{Paragraph, Widget}; use crate::util::num_digits; use std::cmp; use std::sync::atomic::{AtomicU64, Ordering}; -use tui::buffer::Buffer; -use tui::layout::Rect; -use tui::text::Text; -use tui::widgets::{Paragraph, Widget}; // &mut 'a (u16, u16, u16, u16) is not available since Renderer instance totally takes over the ownership of TextArea // instance. In the case, the TextArea instance cannot be accessed from any other objects since it is mutablly