From 574ee27993d09e2f541caabd1d8a5d53a46d710c Mon Sep 17 00:00:00 2001 From: Shupeng Xue Date: Mon, 24 Jun 2024 17:20:56 +1000 Subject: [PATCH 1/8] feature: make backward content visible when moving cursor back in input field --- yazi-core/src/input/commands/move_.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index aac48b7eb..8ff68f0a8 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -39,8 +39,8 @@ impl Input { )); let (limit, snap) = (self.limit(), self.snap_mut()); - if snap.offset > snap.cursor { - snap.offset = snap.cursor; + if snap.offset + limit / 2 > snap.cursor { + snap.offset = snap.cursor.saturating_sub(limit / 2); } else if snap.value.is_empty() { snap.offset = 0; } else { From 73d90db51dd17ffb0fc526d2fa99ab50d861c5c3 Mon Sep 17 00:00:00 2001 From: Shupeng Xue Date: Mon, 24 Jun 2024 17:30:53 +1000 Subject: [PATCH 2/8] fix: adjust snap offset calculation in move command --- yazi-core/src/input/commands/move_.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index 8ff68f0a8..441ac1271 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -39,7 +39,7 @@ impl Input { )); let (limit, snap) = (self.limit(), self.snap_mut()); - if snap.offset + limit / 2 > snap.cursor { + if snap.offset > snap.cursor.saturating_sub(limit / 2) { snap.offset = snap.cursor.saturating_sub(limit / 2); } else if snap.value.is_empty() { snap.offset = 0; From fa9e17306c1d00cc251816b20f56b336e78872ca Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Wed, 26 Jun 2024 20:06:44 +1000 Subject: [PATCH 3/8] apply this feature to moving forward --- yazi-core/src/input/commands/move_.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index 441ac1271..6a2619516 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -39,8 +39,13 @@ impl Input { )); let (limit, snap) = (self.limit(), self.snap_mut()); - if snap.offset > snap.cursor.saturating_sub(limit / 2) { - snap.offset = snap.cursor.saturating_sub(limit / 2); + let half_limit = limit / 2; + let max_offset = snap.cursor.saturating_sub(half_limit); + let min_offset = max_offset.min(snap.len().saturating_sub(limit)); + if snap.offset > max_offset { + snap.offset = max_offset; + } else if snap.offset < min_offset { + snap.offset = min_offset; } else if snap.value.is_empty() { snap.offset = 0; } else { From 7fa9c4da7283478f4b4a15823ba361f6e9049498 Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Wed, 26 Jun 2024 20:20:49 +1000 Subject: [PATCH 4/8] fix edge case --- yazi-core/src/input/commands/move_.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index 6a2619516..557f17eba 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -41,7 +41,7 @@ impl Input { let (limit, snap) = (self.limit(), self.snap_mut()); let half_limit = limit / 2; let max_offset = snap.cursor.saturating_sub(half_limit); - let min_offset = max_offset.min(snap.len().saturating_sub(limit)); + let min_offset = max_offset.min(snap.len().saturating_sub(limit - 1)); if snap.offset > max_offset { snap.offset = max_offset; } else if snap.offset < min_offset { From 499f5f4c73ad29f7ae29d640f73b00af5fd57f2a Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Fri, 28 Jun 2024 11:49:06 +1000 Subject: [PATCH 5/8] simplify offset logic, make it deterministic --- yazi-core/src/input/commands/move_.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index 557f17eba..c5b471c90 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -39,15 +39,9 @@ impl Input { )); let (limit, snap) = (self.limit(), self.snap_mut()); - let half_limit = limit / 2; - let max_offset = snap.cursor.saturating_sub(half_limit); - let min_offset = max_offset.min(snap.len().saturating_sub(limit - 1)); - if snap.offset > max_offset { - snap.offset = max_offset; - } else if snap.offset < min_offset { - snap.offset = min_offset; - } else if snap.value.is_empty() { - snap.offset = 0; + let offset = snap.cursor.saturating_sub(limit / 2).min(snap.len().saturating_sub(limit - 1)); + if snap.offset != offset { + snap.offset = offset; } else { let delta = snap.mode.delta(); let s = snap.slice(snap.offset..snap.cursor + delta); From 5ba632b6f9c60dca301aa1a55bf3e2296740a4f3 Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Fri, 28 Jun 2024 11:50:50 +1000 Subject: [PATCH 6/8] avoid overflow --- yazi-core/src/input/commands/move_.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index c5b471c90..e6b7a77e5 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -39,7 +39,8 @@ impl Input { )); let (limit, snap) = (self.limit(), self.snap_mut()); - let offset = snap.cursor.saturating_sub(limit / 2).min(snap.len().saturating_sub(limit - 1)); + let offset = + snap.cursor.saturating_sub(limit / 2).min(snap.len().saturating_sub(limit.saturating_sub(1))); if snap.offset != offset { snap.offset = offset; } else { From 8f414a4c6b7209972030223e86f8add145d01c4e Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Fri, 28 Jun 2024 12:02:19 +1000 Subject: [PATCH 7/8] empty check should not be ignored --- yazi-core/src/input/commands/move_.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index e6b7a77e5..3973779a5 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -43,6 +43,8 @@ impl Input { snap.cursor.saturating_sub(limit / 2).min(snap.len().saturating_sub(limit.saturating_sub(1))); if snap.offset != offset { snap.offset = offset; + } else if snap.value.is_empty() { + snap.offset = 0; } else { let delta = snap.mode.delta(); let s = snap.slice(snap.offset..snap.cursor + delta); From 1182ce69ec1cbdcbf5d6d3f0c8b0eb70918a4baf Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Sun, 30 Jun 2024 20:04:59 +1000 Subject: [PATCH 8/8] 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 3973779a5..b050455dc 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 e6f98232e..d23cf3cd6 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 + } }