refactor: 🔨 fix linting issues

This commit is contained in:
Lucas Colombo 2024-09-20 19:55:23 -03:00
parent 97457af448
commit 0c765a608b
Signed by: lucas
GPG Key ID: EF34786CFEFFAE35
13 changed files with 108 additions and 38 deletions

View File

@ -0,0 +1,77 @@
use {
lool::tui::{
ratatui::{
backend::CrosstermBackend,
crossterm::{
event::{self},
execute,
terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
},
},
layout::{Constraint, Direction, Layout},
Terminal,
},
widgets::textarea::{Input, Key, TextArea},
},
ratatui::widgets::{Block, BorderType, Borders, Padding, Paragraph},
std::{cmp, io},
};
fn main() -> io::Result<()> {
let stdout = io::stdout();
let mut stdout = stdout.lock();
enable_raw_mode()?;
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let mut term = Terminal::new(backend)?;
let mut textarea = TextArea::default().with_block(
Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.title(" Your name ")
.padding(Padding::horizontal(1)),
);
loop {
term.draw(|f| {
const MIN_HEIGHT: usize = 1;
let height = cmp::max(textarea.lines().len(), MIN_HEIGHT) as u16 + 2;
let layout = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(height), Constraint::Min(1)])
.split(f.area());
// Render the textarea
f.render_widget(&textarea, layout[0]);
f.render_widget(Paragraph::new("Press <Esc> to exit"), layout[1]);
})?;
match event::read()?.into() {
Input { key: Key::Esc, .. }
| Input {
key: Key::Char('c'),
shift: false,
ctrl: true,
alt: false,
}
| Input {
key: Key::Enter,
ctrl: false,
shift: false,
alt: false,
} => break,
input => {
textarea.input(input);
}
}
}
disable_raw_mode()?;
execute!(term.backend_mut(), LeaveAlternateScreen)?;
term.show_cursor()?;
println!("Lines: {:?}", textarea.lines());
Ok(())
}

View File

@ -261,6 +261,7 @@ pub trait Component: Downcast {
/// ///
/// # Returns /// # Returns
/// * `Option<&Box<dyn Component>>` - A reference to the child component or none. /// * `Option<&Box<dyn Component>>` - A reference to the child component or none.
#[allow(clippy::borrowed_box)]
fn child(&mut self, name: &str) -> Option<&Box<dyn Component>> { fn child(&mut self, name: &str) -> Option<&Box<dyn Component>> {
if let Some(children) = self.get_children() { if let Some(children) = self.get_children() {
children.get(name) children.get(name)

View File

@ -1,6 +1,6 @@
use { use {
super::util::{find_word_start_backward, find_word_start_forward}, super::util::{find_word_start_backward, find_word_start_forward},
crate::tui::widgets::textarea::textarea::widget::Viewport, crate::tui::widgets::textarea::core::widget::Viewport,
std::cmp, std::cmp,
}; };

View File

@ -3,7 +3,7 @@ use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
/// Backend-agnostic key input kind. /// Backend-agnostic key input kind.
/// ///
/// This type is marked as `#[non_exhaustive]` since more keys may be supported in the future. /// This type is marked as `#[non_exhaustive]` since more keys may be supported in the future.
#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Hash, Eq, Default)]
pub enum Key { pub enum Key {
/// Normal letter key input /// Normal letter key input
Char(char), Char(char),
@ -38,15 +38,10 @@ pub enum Key {
/// Paste key. This key is supported by termwiz only /// Paste key. This key is supported by termwiz only
Paste, Paste,
/// An invalid key input (this key is always ignored by [`TextArea`](crate::TextArea)) /// An invalid key input (this key is always ignored by [`TextArea`](crate::TextArea))
#[default]
Null, Null,
} }
impl Default for Key {
fn default() -> Self {
Key::Null
}
}
/// Backend-agnostic key input type. /// Backend-agnostic key input type.
/// ///
/// When `crossterm`, `termion`, `termwiz` features are enabled, converting respective key input types into this /// When `crossterm`, `termion`, `termwiz` features are enabled, converting respective key input types into this
@ -104,7 +99,7 @@ impl Input {
ctrl: false, ctrl: false,
alt: false, alt: false,
.. ..
} => Some(c.clone()), } => Some(*c),
_ => None, _ => None,
} }
} }
@ -117,30 +112,27 @@ impl Input {
/// - Char is \n or \r /// - Char is \n or \r
#[inline] #[inline]
pub fn is_newline_except_enter(&self) -> bool { pub fn is_newline_except_enter(&self) -> bool {
match self { matches!(
self,
Input { Input {
key: Key::Char('\n' | '\r'), key: Key::Char('\n' | '\r'),
ctrl: false, ctrl: false,
alt: false, alt: false,
.. ..
} } | Input {
| Input {
key: Key::Enter, key: Key::Enter,
ctrl: true, ctrl: true,
.. ..
} } | Input {
| Input {
key: Key::Enter, key: Key::Enter,
alt: true, alt: true,
.. ..
} } | Input {
| Input {
key: Key::Enter, key: Key::Enter,
shift: true, shift: true,
.. ..
} => true, }
_ => false, )
}
} }
/// Returns `true` if the Input represents a new line (including Enter key). /// Returns `true` if the Input represents a new line (including Enter key).
@ -170,67 +162,67 @@ impl Input {
/// Returns `true` if the Input is a Tab /// Returns `true` if the Input is a Tab
#[inline] #[inline]
pub fn is_tab(&self) -> bool { pub fn is_tab(&self) -> bool {
return self.key == Key::Tab && !self.ctrl && !self.alt; self.key == Key::Tab && !self.ctrl && !self.alt
} }
/// Returns `true` if the Input is Backspace /// Returns `true` if the Input is Backspace
#[inline] #[inline]
pub fn is_backspace(&self) -> bool { pub fn is_backspace(&self) -> bool {
return self.key == Key::Backspace && !self.ctrl && !self.alt; self.key == Key::Backspace && !self.ctrl && !self.alt
} }
/// Returns `true` if the Input is Delete /// Returns `true` if the Input is Delete
#[inline] #[inline]
pub fn is_delete(&self) -> bool { pub fn is_delete(&self) -> bool {
return self.key == Key::Delete && !self.ctrl && !self.alt; self.key == Key::Delete && !self.ctrl && !self.alt
} }
/// Returns `true` if the Input is key down arrow /// Returns `true` if the Input is key down arrow
#[inline] #[inline]
pub fn is_down(&self) -> bool { pub fn is_down(&self) -> bool {
return self.key == Key::Down && !self.ctrl && !self.alt; self.key == Key::Down && !self.ctrl && !self.alt
} }
/// Returns `true` if the Input is key up arrow /// Returns `true` if the Input is key up arrow
#[inline] #[inline]
pub fn is_up(&self) -> bool { pub fn is_up(&self) -> bool {
return self.key == Key::Up && !self.ctrl && !self.alt; self.key == Key::Up && !self.ctrl && !self.alt
} }
/// Returns `true` if the Input is key left arrow /// Returns `true` if the Input is key left arrow
#[inline] #[inline]
pub fn is_left(&self) -> bool { pub fn is_left(&self) -> bool {
return self.key == Key::Left && !self.ctrl && !self.alt; self.key == Key::Left && !self.ctrl && !self.alt
} }
/// Returns `true` if the Input is key right arrow /// Returns `true` if the Input is key right arrow
#[inline] #[inline]
pub fn is_right(&self) -> bool { pub fn is_right(&self) -> bool {
return self.key == Key::Right && !self.ctrl && !self.alt; self.key == Key::Right && !self.ctrl && !self.alt
} }
/// Returns `true` if the Input is key Home /// Returns `true` if the Input is key Home
#[inline] #[inline]
pub fn is_home(&self) -> bool { pub fn is_home(&self) -> bool {
return self.key == Key::Home; self.key == Key::Home
} }
/// Returns `true` if the Input is key End /// Returns `true` if the Input is key End
#[inline] #[inline]
pub fn is_end(&self) -> bool { pub fn is_end(&self) -> bool {
return self.key == Key::End; self.key == Key::End
} }
/// Returns `true` if the Input is ctrl+left /// Returns `true` if the Input is ctrl+left
#[inline] #[inline]
pub fn is_ctrl_left(&self) -> bool { pub fn is_ctrl_left(&self) -> bool {
return self.key == Key::Left && self.ctrl && !self.alt; self.key == Key::Left && self.ctrl && !self.alt
} }
/// Returns `true` if the Input is ctrl+right /// Returns `true` if the Input is ctrl+right
#[inline] #[inline]
pub fn is_ctrl_right(&self) -> bool { pub fn is_ctrl_right(&self) -> bool {
return self.key == Key::Right && self.ctrl && !self.alt; self.key == Key::Right && self.ctrl && !self.alt
} }
/// Returns a string representing the kind of key input. /// Returns a string representing the kind of key input.

View File

@ -1,4 +1,4 @@
use crate::tui::widgets::textarea::textarea::widget::Viewport; use crate::tui::widgets::textarea::core::widget::Viewport;
/// Specify how to scroll the textarea. /// Specify how to scroll the textarea.
/// ///

View File

@ -59,5 +59,5 @@ pub fn find_word_start_backward(line: &str, start_col: usize) -> Option<usize> {
} }
cur = next; cur = next;
} }
(cur != CharKind::Space).then(|| 0) (cur != CharKind::Space).then_some(0)
} }

View File

@ -512,5 +512,3 @@ impl<'a> TextArea<'a> {
hl.into_spans() hl.into_spans()
} }
} }
// Builder-Pattern methods

View File

@ -7,8 +7,10 @@ pub enum ValidationResult {
Invalid(Vec<String>), Invalid(Vec<String>),
} }
type ValidatorFnType = Arc<dyn Fn(&str) -> Result<(), String> + Send + Sync>;
#[derive(Clone)] #[derive(Clone)]
pub struct ValidatorFn(Arc<dyn Fn(&str) -> Result<(), String> + Send + Sync>); pub struct ValidatorFn(ValidatorFnType);
impl ValidatorFn { impl ValidatorFn {
pub fn new<F>(f: F) -> Self pub fn new<F>(f: F) -> Self

View File

@ -1,6 +1,6 @@
pub fn required_validator(input: &str) -> Result<(), String> { pub fn required_validator(input: &str) -> Result<(), String> {
if input.is_empty() { if input.is_empty() {
Err(format!("This field is required")) Err("This field is required".to_string())
} else { } else {
Ok(()) Ok(())
} }

View File

@ -6,11 +6,11 @@ pub(super) mod behaviour {
pub(super) mod util; pub(super) mod util;
} }
mod textarea; mod core;
pub use { pub use {
behaviour::input::{Input, Key}, behaviour::input::{Input, Key},
textarea::{ core::{
validation::{validators, ValidationResult}, validation::{validators, ValidationResult},
TextArea, TextArea,
}, },