Files
coop/crates/ui/src/input/mode.rs
2026-07-27 08:38:25 +07:00

146 lines
3.5 KiB
Rust

use super::display_map::DisplayMap;
#[derive(Clone)]
pub(crate) enum InputMode {
/// A plain text input mode.
PlainText {
multi_line: bool,
tab: crate::input::indent::TabSize,
rows: usize,
},
/// An auto grow input mode.
AutoGrow {
rows: usize,
min_rows: usize,
max_rows: usize,
},
}
impl Default for InputMode {
fn default() -> Self {
InputMode::plain_text()
}
}
#[allow(unused)]
impl InputMode {
/// Create a plain input mode with default settings.
pub(super) fn plain_text() -> Self {
InputMode::PlainText {
multi_line: false,
tab: crate::input::indent::TabSize::default(),
rows: 1,
}
}
/// Create an auto grow input mode with given min and max rows.
pub(super) fn auto_grow(min_rows: usize, max_rows: usize) -> Self {
InputMode::AutoGrow {
rows: min_rows,
min_rows,
max_rows,
}
}
pub(super) fn multi_line(mut self, multi_line: bool) -> Self {
match &mut self {
InputMode::PlainText { multi_line: ml, .. } => *ml = multi_line,
InputMode::AutoGrow { .. } => {}
}
self
}
#[inline]
pub(super) fn is_single_line(&self) -> bool {
!self.is_multi_line()
}
#[inline]
pub(super) fn is_auto_grow(&self) -> bool {
matches!(self, InputMode::AutoGrow { .. })
}
#[inline]
pub(super) fn is_multi_line(&self) -> bool {
match self {
InputMode::PlainText { multi_line, .. } => *multi_line,
InputMode::AutoGrow { max_rows, .. } => *max_rows > 1,
}
}
pub(super) fn set_rows(&mut self, new_rows: usize) {
match self {
InputMode::PlainText { rows, .. } => {
*rows = new_rows;
}
InputMode::AutoGrow {
rows,
min_rows,
max_rows,
} => {
*rows = new_rows.clamp(*min_rows, *max_rows);
}
}
}
pub(super) fn update_auto_grow(&mut self, display_map: &DisplayMap) {
if self.is_single_line() {
return;
}
let wrapped_lines = display_map.wrap_row_count();
self.set_rows(wrapped_lines);
}
/// At least 1 row be return.
pub(super) fn rows(&self) -> usize {
if !self.is_multi_line() {
return 1;
}
match self {
InputMode::PlainText { rows, .. } => *rows,
InputMode::AutoGrow { rows, .. } => *rows,
}
.max(1)
}
/// At least 1 row be return.
#[allow(unused)]
pub(super) fn min_rows(&self) -> usize {
match self {
InputMode::AutoGrow { min_rows, .. } => *min_rows,
_ => 1,
}
.max(1)
}
#[allow(unused)]
pub(super) fn max_rows(&self) -> usize {
if !self.is_multi_line() {
return 1;
}
match self {
InputMode::AutoGrow { max_rows, .. } => *max_rows,
_ => usize::MAX,
}
}
#[inline]
pub(super) fn is_indentable(&self) -> bool {
match self {
InputMode::PlainText { multi_line, .. } => *multi_line,
_ => false,
}
}
#[inline]
pub(super) fn tab_size(&self) -> crate::input::indent::TabSize {
match self {
InputMode::PlainText { tab, .. } => *tab,
_ => crate::input::indent::TabSize::default(),
}
}
}