mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
Fix Input width
This commit is contained in:
parent
16473af4e6
commit
fe00017d5d
5 changed files with 47 additions and 39 deletions
|
|
@ -30,7 +30,7 @@ impl Input {
|
|||
}
|
||||
}
|
||||
}
|
||||
self.snaps.tag();
|
||||
self.snaps.tag(self.limit());
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::<String>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Result<String, InputError>>) {
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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::<String>() }
|
||||
|
||||
#[inline]
|
||||
pub(super) fn window(&self) -> Range<usize> { Self::find_window(&self.value, self.offset) }
|
||||
pub(super) fn window(&self, limit: usize) -> Range<usize> {
|
||||
Self::find_window(&self.value, self.offset, limit)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn find_window(s: &str, offset: usize) -> Range<usize> {
|
||||
pub(super) fn find_window(s: &str, offset: usize, limit: usize) -> Range<usize> {
|
||||
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::<Vec<_>>();
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue