WIP [no ci]

This commit is contained in:
sxyazi 2023-11-02 01:05:47 +08:00
parent 11d8ee6f5b
commit 208baffddd
No known key found for this signature in database
5 changed files with 34 additions and 22 deletions

View file

@ -4,14 +4,14 @@ use crate::completion::Completion;
pub struct Opt<'a> { pub struct Opt<'a> {
cands: &'a Vec<String>, cands: &'a Vec<String>,
version: usize, ticket: usize,
} }
impl<'a> From<&'a Exec> for Opt<'a> { impl<'a> From<&'a Exec> for Opt<'a> {
fn from(e: &'a Exec) -> Self { fn from(e: &'a Exec) -> Self {
Self { Self {
cands: &e.args, cands: &e.args,
version: e.named.get("version").and_then(|v| v.parse().ok()).unwrap_or(0), ticket: e.named.get("ticket").and_then(|v| v.parse().ok()).unwrap_or(0),
} }
} }
} }
@ -19,13 +19,13 @@ impl<'a> From<&'a Exec> for Opt<'a> {
impl Completion { impl Completion {
pub fn show<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn show<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into();
if self.version != opt.version { if self.ticket != opt.ticket {
return false; return false;
} }
self.close(false); self.close(false);
self.items = opt.cands.clone(); self.items = opt.cands.clone();
self.version = opt.version; self.ticket = opt.ticket;
self.visible = true; self.visible = true;
true true
} }

View file

@ -5,14 +5,14 @@ use crate::completion::Completion;
pub struct Opt<'a> { pub struct Opt<'a> {
word: &'a str, word: &'a str,
version: usize, ticket: usize,
} }
impl<'a> From<&'a Exec> for Opt<'a> { impl<'a> From<&'a Exec> for Opt<'a> {
fn from(e: &'a Exec) -> Self { fn from(e: &'a Exec) -> Self {
Self { Self {
word: e.args.get(0).map(|w| w.as_str()).unwrap_or_default(), word: e.args.get(0).map(|w| w.as_str()).unwrap_or_default(),
version: e.named.get("version").and_then(|v| v.parse().ok()).unwrap_or(0), ticket: e.named.get("ticket").and_then(|v| v.parse().ok()).unwrap_or(0),
} }
} }
} }
@ -20,12 +20,12 @@ impl<'a> From<&'a Exec> for Opt<'a> {
impl Completion { impl Completion {
pub fn trigger<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn trigger<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into();
if self.version >= opt.version { if self.ticket >= opt.ticket {
return false; return false;
} }
self.close(false); self.close(false);
self.version = opt.version; self.ticket = opt.ticket;
info!("trigger completion: {}", opt.word); info!("trigger completion: {}", opt.word);
tokio::spawn(async move {}); tokio::spawn(async move {});

View file

@ -3,7 +3,7 @@ pub struct Completion {
pub items: Vec<String>, pub items: Vec<String>,
pub cursor: usize, pub cursor: usize,
pub version: usize, pub ticket: usize,
pub visible: bool, pub visible: bool,
} }

View file

@ -12,9 +12,10 @@ use crate::{emit, external, Position};
#[derive(Default)] #[derive(Default)]
pub struct Input { pub struct Input {
snaps: InputSnaps, snaps: InputSnaps,
pub ticket: usize,
pub visible: bool, pub visible: bool,
title: String, pub title: String,
pub position: Position, pub position: Position,
// Typing // Typing
@ -30,6 +31,7 @@ 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.snaps.reset(opt.value);
self.ticket = self.ticket.wrapping_add(1);
self.visible = true; self.visible = true;
self.title = opt.title; self.title = opt.title;
@ -210,8 +212,9 @@ impl Input {
snap.value.insert_str(snap.idx(snap.cursor).unwrap(), s); snap.value.insert_str(snap.idx(snap.cursor).unwrap(), s);
} }
self.move_(s.chars().count() as isize);
self.flush_value(); self.flush_value();
self.move_(s.chars().count() as isize) true
} }
pub fn backspace(&mut self) -> bool { pub fn backspace(&mut self) -> bool {
@ -222,8 +225,9 @@ impl Input {
snap.value.remove(snap.idx(snap.cursor - 1).unwrap()); snap.value.remove(snap.idx(snap.cursor - 1).unwrap());
} }
self.move_(-1);
self.flush_value(); self.flush_value();
self.move_(-1) true
} }
pub fn delete(&mut self, cut: bool, insert: bool) -> bool { pub fn delete(&mut self, cut: bool, insert: bool) -> bool {
@ -322,14 +326,18 @@ impl Input {
} }
#[inline] #[inline]
fn flush_value(&self) { fn flush_value(&mut self) {
self.ticket = self.ticket.wrapping_add(1);
if self.realtime { if self.realtime {
let value = self.snap().value.clone(); let value = self.snap().value.clone();
self.callback.as_ref().unwrap().send(Err(InputError::Typed(value))).ok(); self.callback.as_ref().unwrap().send(Err(InputError::Typed(value))).ok();
} }
if self.completion { if self.completion {
emit!(Call( emit!(Call(
Exec::call("complete", vec!["".to_string()]).with("version", 1).vec(), Exec::call("complete", vec![self.partition()[0].to_owned()])
.with("ticket", self.ticket)
.vec(),
KeymapLayer::Input KeymapLayer::Input
)); ));
} }
@ -337,9 +345,6 @@ impl Input {
} }
impl Input { impl Input {
#[inline]
pub fn title(&self) -> String { self.title.clone() }
#[inline] #[inline]
pub fn value(&self) -> &str { self.snap().slice(self.snap().window()) } pub fn value(&self) -> &str { self.snap().slice(self.snap().window()) }
@ -366,6 +371,13 @@ impl Input {
Some(s..s + snap.slice(start..end).width() as u16) Some(s..s + snap.slice(start..end).width() as u16)
} }
#[inline]
pub fn partition(&self) -> [&str; 2] {
let snap = self.snap();
let idx = snap.idx(snap.cursor).unwrap();
[&snap.value[..idx], &snap.value[idx..]]
}
#[inline] #[inline]
fn snap(&self) -> &InputSnap { self.snaps.current() } fn snap(&self) -> &InputSnap { self.snaps.current() }

View file

@ -33,7 +33,7 @@ impl<'a> Widget for Input<'a> {
.border_type(BorderType::Rounded) .border_type(BorderType::Rounded)
.border_style(THEME.input.border.into()) .border_style(THEME.input.border.into())
.title({ .title({
let mut line = Line::from(input.title()); let mut line = Line::from(input.title.as_str());
line.patch_style(THEME.input.title.into()); line.patch_style(THEME.input.title.into());
line line
}), }),