Skip to content

Commit

Permalink
feat: add new debounce option to ya.input() API (#1025)
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi committed May 11, 2024
1 parent eed82c1 commit c1e1f26
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 20 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions yazi-plugin/Cargo.toml
Expand Up @@ -36,6 +36,7 @@ shell-escape = "0.1.5"
shell-words = "1.1.0"
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
tokio = { version = "1.37.0", features = [ "full" ] }
tokio-stream = "0.1.15"
tokio-util = "0.7.11"
unicode-width = "0.1.12"
yazi-prebuild = "0.1.2"
Expand Down
29 changes: 17 additions & 12 deletions yazi-plugin/src/bindings/input.rs
@@ -1,15 +1,23 @@
use std::pin::Pin;

use mlua::{prelude::LuaUserDataMethods, UserData};
use tokio::sync::mpsc::UnboundedReceiver;
use tokio::pin;
use tokio_stream::StreamExt;
use yazi_shared::InputError;

pub struct InputRx {
inner: UnboundedReceiver<Result<String, InputError>>,
pub struct InputRx<T: StreamExt<Item = Result<String, InputError>>> {
inner: T,
}

impl InputRx {
pub fn new(inner: UnboundedReceiver<Result<String, InputError>>) -> Self { Self { inner } }
impl<T: StreamExt<Item = Result<String, InputError>>> InputRx<T> {
pub fn new(inner: T) -> Self { Self { inner } }

pub async fn consume(inner: T) -> (Option<String>, u8) {
pin!(inner);
inner.next().await.map(Self::parse).unwrap_or((None, 0))
}

pub fn parse(res: Result<String, InputError>) -> (Option<String>, u8) {
fn parse(res: Result<String, InputError>) -> (Option<String>, u8) {
match res {
Ok(s) => (Some(s), 1),
Err(InputError::Canceled(s)) => (Some(s), 2),
Expand All @@ -19,14 +27,11 @@ impl InputRx {
}
}

impl UserData for InputRx {
impl<T: StreamExt<Item = Result<String, InputError>> + 'static> UserData for InputRx<T> {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_async_method_mut("recv", |_, me, ()| async move {
let Some(res) = me.inner.recv().await else {
return Ok((None, 0));
};

Ok(Self::parse(res))
let mut inner = unsafe { Pin::new_unchecked(&mut me.inner) };
Ok(inner.next().await.map(Self::parse).unwrap_or((None, 0)))
});
}
}
23 changes: 15 additions & 8 deletions yazi-plugin/src/utils/layer.rs
@@ -1,10 +1,11 @@
use std::str::FromStr;
use std::{str::FromStr, time::Duration};

use mlua::{ExternalError, ExternalResult, IntoLuaMulti, Lua, Table, Value};
use tokio::sync::mpsc;
use tokio_stream::wrappers::UnboundedReceiverStream;
use yazi_config::{keymap::{Control, Key}, popup::InputCfg};
use yazi_proxy::{AppProxy, InputProxy};
use yazi_shared::{emit, event::Cmd, Layer};
use yazi_shared::{emit, event::Cmd, Debounce, Layer};

use super::Utils;
use crate::bindings::{InputRx, Position};
Expand Down Expand Up @@ -59,22 +60,28 @@ impl Utils {
"input",
lua.create_async_function(|lua, t: Table| async move {
let realtime = t.raw_get("realtime").unwrap_or_default();
let mut rx = InputProxy::show(InputCfg {
let rx = UnboundedReceiverStream::new(InputProxy::show(InputCfg {
title: t.raw_get("title")?,
value: t.raw_get("value").unwrap_or_default(),
cursor: None, // TODO
position: Position::try_from(t.raw_get::<_, Table>("position")?)?.into(),
realtime,
completion: false,
highlight: false,
});
}));

if realtime {
if !realtime {
return InputRx::consume(rx).await.into_lua_multi(lua);
}

let debounce = t.raw_get::<_, f64>("debounce").unwrap_or_default();
if debounce < 0.0 {
Err("negative debounce duration".into_lua_err())
} else if debounce == 0.0 {
(InputRx::new(rx), Value::Nil).into_lua_multi(lua)
} else if let Some(res) = rx.recv().await {
InputRx::parse(res).into_lua_multi(lua)
} else {
(Value::Nil, 0).into_lua_multi(lua)
(InputRx::new(Debounce::new(rx, Duration::from_secs_f64(debounce))), Value::Nil)
.into_lua_multi(lua)
}
})?,
)?;
Expand Down

0 comments on commit c1e1f26

Please sign in to comment.