From 1182ce69ec1cbdcbf5d6d3f0c8b0eb70918a4baf Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Sun, 30 Jun 2024 20:04:59 +1000 Subject: [PATCH] fix: support cjk --- yazi-core/src/input/commands/move_.rs | 5 +++-- yazi-core/src/input/snap.rs | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index 3973779a..b050455d 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -39,8 +39,9 @@ impl Input { )); let (limit, snap) = (self.limit(), self.snap_mut()); - let offset = - snap.cursor.saturating_sub(limit / 2).min(snap.len().saturating_sub(limit.saturating_sub(1))); + let offset = InputSnap::find_window_backward(&snap.value, snap.cursor, limit / 2) + .start + .min(InputSnap::find_window_backward(&snap.value, snap.value.chars().count(), limit).start); if snap.offset != offset { snap.offset = offset; } else if snap.value.is_empty() { diff --git a/yazi-core/src/input/snap.rs b/yazi-core/src/input/snap.rs index e6f98232..d23cf3cd 100644 --- a/yazi-core/src/input/snap.rs +++ b/yazi-core/src/input/snap.rs @@ -87,4 +87,25 @@ impl InputSnap { } *v.first().unwrap()..v.last().unwrap() + 1 } + + #[inline] + pub(super) fn find_window_backward(s: &str, offset: usize, limit: usize) -> Range { + let mut width = 0; + let len = s.chars().count(); + let v: Vec<_> = s + .chars() + .rev() + .enumerate() + .skip(len.saturating_sub(offset + 1)) + .map_while(|(i, c)| { + width += c.width().unwrap_or(0); + if width < limit { Some(len.saturating_sub(i + 1)) } else { None } + }) + .collect(); + + if v.is_empty() { + return 0..0; + } + *v.last().unwrap()..v.first().unwrap() + 1 + } }