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
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ impl Input {
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
let snap = self.snap_mut();
|
let (limit, snap) = (self.limit(), self.snap_mut());
|
||||||
if snap.offset > snap.cursor {
|
if snap.offset > snap.cursor {
|
||||||
snap.offset = snap.cursor;
|
snap.offset = snap.cursor;
|
||||||
} else if snap.value.is_empty() {
|
} else if snap.value.is_empty() {
|
||||||
|
|
@ -46,9 +46,9 @@ impl Input {
|
||||||
} else {
|
} else {
|
||||||
let delta = snap.mode.delta();
|
let delta = snap.mode.delta();
|
||||||
let s = snap.slice(snap.offset..snap.cursor + 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>();
|
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 tokio::sync::mpsc::UnboundedSender;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
use yazi_config::popup::{InputOpt, Position};
|
use yazi_config::{popup::{InputOpt, Position}, INPUT};
|
||||||
use yazi_shared::InputError;
|
use yazi_shared::InputError;
|
||||||
|
|
||||||
use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps};
|
use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps};
|
||||||
|
|
@ -29,9 +29,7 @@ pub struct Input {
|
||||||
impl Input {
|
impl Input {
|
||||||
pub fn show(&mut self, opt: InputOpt, tx: UnboundedSender<Result<String, InputError>>) {
|
pub fn show(&mut self, opt: InputOpt, tx: UnboundedSender<Result<String, InputError>>) {
|
||||||
self.close(false);
|
self.close(false);
|
||||||
self.snaps.reset(opt.value);
|
|
||||||
self.visible = true;
|
self.visible = true;
|
||||||
|
|
||||||
self.title = opt.title;
|
self.title = opt.title;
|
||||||
self.position = opt.position;
|
self.position = opt.position;
|
||||||
|
|
||||||
|
|
@ -42,6 +40,14 @@ impl Input {
|
||||||
|
|
||||||
// Shell
|
// Shell
|
||||||
self.highlight = opt.highlight;
|
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 {
|
pub fn type_str(&mut self, s: &str) -> bool {
|
||||||
|
|
@ -93,7 +99,7 @@ impl Input {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !matches!(old.op, InputOp::None | InputOp::Select(_)) {
|
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
|
true
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +122,7 @@ impl Input {
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
#[inline]
|
#[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]
|
#[inline]
|
||||||
pub fn mode(&self) -> InputMode { self.snap().mode }
|
pub fn mode(&self) -> InputMode { self.snap().mode }
|
||||||
|
|
@ -134,7 +140,7 @@ impl Input {
|
||||||
let (start, end) =
|
let (start, end) =
|
||||||
if start < snap.cursor { (start, snap.cursor) } else { (snap.cursor + 1, start + 1) };
|
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 Range { start, end } = start.max(win.start)..end.min(win.end);
|
||||||
|
|
||||||
let s = snap.slice(snap.offset..start).width() as u16;
|
let s = snap.slice(snap.offset..start).width() as u16;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ pub(super) struct InputSnap {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputSnap {
|
impl InputSnap {
|
||||||
pub(super) fn new(value: String) -> Self {
|
pub(super) fn new(value: String, limit: usize) -> Self {
|
||||||
let mut snap = Self {
|
let mut snap = Self {
|
||||||
value,
|
value,
|
||||||
|
|
||||||
|
|
@ -26,15 +26,15 @@ impl InputSnap {
|
||||||
offset: usize::MAX,
|
offset: usize::MAX,
|
||||||
cursor: usize::MAX,
|
cursor: usize::MAX,
|
||||||
};
|
};
|
||||||
snap.reset();
|
snap.reset(limit);
|
||||||
snap
|
snap
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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.cursor = self.cursor.min(self.value.chars().count().saturating_sub(self.mode.delta()));
|
||||||
self.offset =
|
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>() }
|
pub(super) fn rev(&self) -> String { self.value.chars().rev().collect::<String>() }
|
||||||
|
|
||||||
#[inline]
|
#[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]
|
#[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 mut width = 0;
|
||||||
let v = s
|
let v = s
|
||||||
.chars()
|
.chars()
|
||||||
|
|
@ -76,7 +78,7 @@ impl InputSnap {
|
||||||
.skip(offset)
|
.skip(offset)
|
||||||
.map_while(|(i, c)| {
|
.map_while(|(i, c)| {
|
||||||
width += c.width().unwrap_or(0);
|
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<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,33 @@ pub(super) struct InputSnaps {
|
||||||
|
|
||||||
impl InputSnaps {
|
impl InputSnaps {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn reset(&mut self, value: String) {
|
pub(super) fn reset(&mut self, value: String, limit: usize) {
|
||||||
self.idx = 0;
|
self.idx = 0;
|
||||||
self.versions.clear();
|
self.versions.clear();
|
||||||
self.versions.push(InputSnap::new(value));
|
self.versions.push(InputSnap::new(value, limit));
|
||||||
self.current = self.versions[0].clone();
|
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 {
|
pub(super) fn undo(&mut self) -> bool {
|
||||||
if self.idx == 0 {
|
if self.idx == 0 {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -37,26 +57,6 @@ impl InputSnaps {
|
||||||
self.current = self.versions[self.idx].clone();
|
self.current = self.versions[self.idx].clone();
|
||||||
true
|
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 {
|
impl InputSnaps {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue