diff --git a/yazi-core/src/input/commands/escape.rs b/yazi-core/src/input/commands/escape.rs index 4e260bc8..1e8767fb 100644 --- a/yazi-core/src/input/commands/escape.rs +++ b/yazi-core/src/input/commands/escape.rs @@ -30,7 +30,7 @@ impl Input { } } } - self.snaps.tag(); + self.snaps.tag(self.limit()); true } } diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index b58e2a48..4bccecd4 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -38,7 +38,7 @@ impl Input { false, ); - let snap = self.snap_mut(); + let (limit, snap) = (self.limit(), self.snap_mut()); if snap.offset > snap.cursor { snap.offset = snap.cursor; } else if snap.value.is_empty() { @@ -46,9 +46,9 @@ impl Input { } else { let delta = snap.mode.delta(); let s = snap.slice(snap.offset..snap.cursor + delta); - if s.width() >= /*TODO: hardcode*/ 50 - 2 { + if s.width() >= limit { let s = s.chars().rev().collect::(); - snap.offset = snap.cursor - InputSnap::find_window(&s, 0).end.saturating_sub(delta); + snap.offset = snap.cursor - InputSnap::find_window(&s, 0, limit).end.saturating_sub(delta); } } diff --git a/yazi-core/src/input/input.rs b/yazi-core/src/input/input.rs index 52b437b7..0709f4e1 100644 --- a/yazi-core/src/input/input.rs +++ b/yazi-core/src/input/input.rs @@ -2,7 +2,7 @@ use std::ops::Range; use tokio::sync::mpsc::UnboundedSender; use unicode_width::UnicodeWidthStr; -use yazi_config::popup::{InputOpt, Position}; +use yazi_config::{popup::{InputOpt, Position}, INPUT}; use yazi_shared::InputError; use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps}; @@ -29,9 +29,7 @@ pub struct Input { impl Input { pub fn show(&mut self, opt: InputOpt, tx: UnboundedSender>) { self.close(false); - self.snaps.reset(opt.value); self.visible = true; - self.title = opt.title; self.position = opt.position; @@ -42,6 +40,14 @@ impl Input { // Shell self.highlight = opt.highlight; + + // Reset snaps + self.snaps.reset(opt.value, self.limit()); + } + + #[inline] + pub(super) fn limit(&self) -> usize { + self.position.offset.width.saturating_sub(INPUT.border()) as usize } pub fn type_str(&mut self, s: &str) -> bool { @@ -93,7 +99,7 @@ impl Input { return false; } if !matches!(old.op, InputOp::None | InputOp::Select(_)) { - self.snaps.tag().then(|| self.flush_value()); + self.snaps.tag(self.limit()).then(|| self.flush_value()); } true } @@ -116,7 +122,7 @@ impl Input { impl Input { #[inline] - pub fn value(&self) -> &str { self.snap().slice(self.snap().window()) } + pub fn value(&self) -> &str { self.snap().slice(self.snap().window(self.limit())) } #[inline] pub fn mode(&self) -> InputMode { self.snap().mode } @@ -134,7 +140,7 @@ impl Input { let (start, end) = if start < snap.cursor { (start, snap.cursor) } else { (snap.cursor + 1, start + 1) }; - let win = snap.window(); + let win = snap.window(self.limit()); let Range { start, end } = start.max(win.start)..end.min(win.end); let s = snap.slice(snap.offset..start).width() as u16; diff --git a/yazi-core/src/input/snap.rs b/yazi-core/src/input/snap.rs index 21c06f2d..59d405b9 100644 --- a/yazi-core/src/input/snap.rs +++ b/yazi-core/src/input/snap.rs @@ -16,7 +16,7 @@ pub(super) struct InputSnap { } impl InputSnap { - pub(super) fn new(value: String) -> Self { + pub(super) fn new(value: String, limit: usize) -> Self { let mut snap = Self { value, @@ -26,15 +26,15 @@ impl InputSnap { offset: usize::MAX, cursor: usize::MAX, }; - snap.reset(); + snap.reset(limit); snap } #[inline] - pub(super) fn reset(&mut self) { + pub(super) fn reset(&mut self, limit: usize) { self.cursor = self.cursor.min(self.value.chars().count().saturating_sub(self.mode.delta())); self.offset = - self.offset.min(self.cursor.saturating_sub(Self::find_window(&self.rev(), 0).end)); + self.offset.min(self.cursor.saturating_sub(Self::find_window(&self.rev(), 0, limit).end)); } } @@ -65,10 +65,12 @@ impl InputSnap { pub(super) fn rev(&self) -> String { self.value.chars().rev().collect::() } #[inline] - pub(super) fn window(&self) -> Range { Self::find_window(&self.value, self.offset) } + pub(super) fn window(&self, limit: usize) -> Range { + Self::find_window(&self.value, self.offset, limit) + } #[inline] - pub(super) fn find_window(s: &str, offset: usize) -> Range { + pub(super) fn find_window(s: &str, offset: usize, limit: usize) -> Range { let mut width = 0; let v = s .chars() @@ -76,7 +78,7 @@ impl InputSnap { .skip(offset) .map_while(|(i, c)| { width += c.width().unwrap_or(0); - if width < /*TODO: hardcode*/ 50 - 2 { Some(i) } else { None } + if width < limit { Some(i) } else { None } }) .collect::>(); diff --git a/yazi-core/src/input/snaps.rs b/yazi-core/src/input/snaps.rs index f1721c0b..14b8b444 100644 --- a/yazi-core/src/input/snaps.rs +++ b/yazi-core/src/input/snaps.rs @@ -11,13 +11,33 @@ pub(super) struct InputSnaps { impl InputSnaps { #[inline] - pub(super) fn reset(&mut self, value: String) { + pub(super) fn reset(&mut self, value: String, limit: usize) { self.idx = 0; self.versions.clear(); - self.versions.push(InputSnap::new(value)); + self.versions.push(InputSnap::new(value, limit)); self.current = self.versions[0].clone(); } + pub(super) fn tag(&mut self, limit: usize) -> bool { + // Sync *current* cursor position to the *last* version: + // Save offset/cursor/ect. of the *current* as the last version, + // while keeping the *last* value unchanged. + let value = mem::take(&mut self.versions[self.idx].value); + self.versions[self.idx] = self.current.clone(); + self.versions[self.idx].value = value; + self.versions[self.idx].reset(limit); + + // If the *current* value is the same as the *last* version + if self.versions[self.idx].value == self.current.value { + return false; + } + + self.versions.truncate(self.idx + 1); + self.versions.push(self.current().clone()); + self.idx += 1; + true + } + pub(super) fn undo(&mut self) -> bool { if self.idx == 0 { return false; @@ -37,26 +57,6 @@ impl InputSnaps { self.current = self.versions[self.idx].clone(); true } - - pub(super) fn tag(&mut self) -> bool { - // Sync *current* cursor position to the *last* version: - // Save offset/cursor/ect. of the *current* as the last version, - // while keeping the *last* value unchanged. - let value = mem::take(&mut self.versions[self.idx].value); - self.versions[self.idx] = self.current.clone(); - self.versions[self.idx].value = value; - self.versions[self.idx].reset(); - - // If the *current* value is the same as the *last* version - if self.versions[self.idx].value == self.current.value { - return false; - } - - self.versions.truncate(self.idx + 1); - self.versions.push(self.current().clone()); - self.idx += 1; - true - } } impl InputSnaps {