This commit is contained in:
sxyazi 2024-03-02 19:35:39 +08:00
parent 9e05099a50
commit 6e1d88c3fa
No known key found for this signature in database
8 changed files with 150 additions and 20 deletions

1
Cargo.lock generated
View file

@ -2803,6 +2803,7 @@ dependencies = [
"yazi-boot", "yazi-boot",
"yazi-config", "yazi-config",
"yazi-prebuild", "yazi-prebuild",
"yazi-proxy",
"yazi-shared", "yazi-shared",
] ]

View file

@ -1,24 +1,63 @@
use std::{fmt::Display, str::FromStr};
use anyhow::bail;
use serde::Deserialize; use serde::Deserialize;
#[derive(Clone, Copy, Default, Deserialize, PartialEq, Eq)] #[derive(Clone, Copy, Default, Deserialize, PartialEq, Eq)]
#[serde(try_from = "String")]
pub enum Origin { pub enum Origin {
#[default] #[default]
#[serde(rename = "top-left")]
TopLeft, TopLeft,
#[serde(rename = "top-center")]
TopCenter, TopCenter,
#[serde(rename = "top-right")]
TopRight, TopRight,
#[serde(rename = "bottom-left")]
BottomLeft, BottomLeft,
#[serde(rename = "bottom-center")]
BottomCenter, BottomCenter,
#[serde(rename = "bottom-right")]
BottomRight, BottomRight,
#[serde(rename = "center")]
Center, Center,
#[serde(rename = "hovered")]
Hovered, Hovered,
} }
impl FromStr for Origin {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"top-left" => Self::TopLeft,
"top-center" => Self::TopCenter,
"top-right" => Self::TopRight,
"bottom-left" => Self::BottomLeft,
"bottom-center" => Self::BottomCenter,
"bottom-right" => Self::BottomRight,
"center" => Self::Center,
"hovered" => Self::Hovered,
_ => bail!("Invalid `origin` value: {s}"),
})
}
}
impl TryFrom<String> for Origin {
type Error = anyhow::Error;
fn try_from(value: String) -> Result<Self, Self::Error> { Self::from_str(&value) }
}
impl Display for Origin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::TopLeft => "top-left",
Self::TopCenter => "top-center",
Self::TopRight => "top-right",
Self::BottomLeft => "bottom-left",
Self::BottomCenter => "bottom-center",
Self::BottomRight => "bottom-right",
Self::Center => "center",
Self::Hovered => "hovered",
})
}
}

View file

@ -20,7 +20,7 @@ impl FromStr for SortBy {
"none" => Self::None, "none" => Self::None,
"key" => Self::Key, "key" => Self::Key,
"desc" => Self::Desc, "desc" => Self::Desc,
_ => bail!("Invalid sort option: {s}"), _ => bail!("Invalid `sort_by` value: {s}"),
}) })
} }
} }

View file

@ -12,6 +12,7 @@ repository = "https://github.com/sxyazi/yazi"
yazi-adaptor = { path = "../yazi-adaptor", version = "0.2.3" } yazi-adaptor = { path = "../yazi-adaptor", version = "0.2.3" }
yazi-boot = { path = "../yazi-boot", version = "0.2.3" } yazi-boot = { path = "../yazi-boot", version = "0.2.3" }
yazi-config = { path = "../yazi-config", version = "0.2.3" } yazi-config = { path = "../yazi-config", version = "0.2.3" }
yazi-proxy = { path = "../yazi-proxy", version = "0.2.3" }
yazi-shared = { path = "../yazi-shared", version = "0.2.3" } yazi-shared = { path = "../yazi-shared", version = "0.2.3" }
# External dependencies # External dependencies

View file

@ -0,0 +1,27 @@
use mlua::{prelude::LuaUserDataMethods, UserData};
use tokio::sync::mpsc::UnboundedReceiver;
use yazi_shared::InputError;
pub struct InputRx {
inner: UnboundedReceiver<Result<String, InputError>>,
}
impl InputRx {
pub fn new(inner: UnboundedReceiver<Result<String, InputError>>) -> Self { Self { inner } }
}
impl UserData for InputRx {
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(match res {
Ok(s) => (Some(s), 1),
Err(InputError::Typed(s)) => (Some(s), 2),
_ => (None, 0),
})
});
}
}

View file

@ -4,6 +4,8 @@ mod bindings;
mod cha; mod cha;
mod file; mod file;
mod icon; mod icon;
mod input;
mod position;
mod range; mod range;
mod window; mod window;
@ -11,5 +13,7 @@ pub use bindings::*;
pub use cha::*; pub use cha::*;
pub use file::*; pub use file::*;
pub use icon::*; pub use icon::*;
pub use input::*;
pub use position::*;
pub use range::*; pub use range::*;
pub use window::*; pub use window::*;

View file

@ -0,0 +1,47 @@
use std::{ops::Deref, str::FromStr};
use mlua::{ExternalResult, IntoLua};
pub struct Position(yazi_config::popup::Position);
impl Deref for Position {
type Target = yazi_config::popup::Position;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl From<Position> for yazi_config::popup::Position {
fn from(value: Position) -> Self { value.0 }
}
impl<'a> TryFrom<mlua::Table<'a>> for Position {
type Error = mlua::Error;
fn try_from(t: mlua::Table<'a>) -> Result<Self, Self::Error> {
use yazi_config::popup::{Offset, Origin, Position};
Ok(Self(Position {
origin: Origin::from_str(t.raw_get::<_, mlua::String>(1)?.to_str()?).into_lua_err()?,
offset: Offset {
x: t.raw_get("x").unwrap_or_default(),
y: t.raw_get("y").unwrap_or_default(),
width: t.raw_get("w").unwrap_or_default(),
height: 3,
},
}))
}
}
impl<'lua> IntoLua<'lua> for Position {
fn into_lua(self, lua: &'lua mlua::Lua) -> mlua::Result<mlua::Value> {
lua
.create_table_from([
(1.into_lua(lua)?, self.origin.to_string().into_lua(lua)?),
("x".into_lua(lua)?, self.offset.x.into_lua(lua)?),
("y".into_lua(lua)?, self.offset.y.into_lua(lua)?),
("w".into_lua(lua)?, self.offset.width.into_lua(lua)?),
("h".into_lua(lua)?, self.offset.height.into_lua(lua)?),
])?
.into_lua(lua)
}
}

View file

@ -1,11 +1,13 @@
use std::str::FromStr; use std::str::FromStr;
use mlua::{ExternalError, ExternalResult, Lua, Table, Value}; use mlua::{ExternalError, ExternalResult, IntoLua, Lua, Table, Value};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use yazi_config::keymap::{Control, Key}; use yazi_config::{keymap::{Control, Key}, popup::InputCfg};
use yazi_proxy::InputProxy;
use yazi_shared::{emit, event::Cmd, Layer}; use yazi_shared::{emit, event::Cmd, Layer};
use super::Utils; use super::Utils;
use crate::bindings::{InputRx, Position};
impl Utils { impl Utils {
fn parse_keys(value: Value) -> mlua::Result<Vec<Key>> { fn parse_keys(value: Value) -> mlua::Result<Vec<Key>> {
@ -55,16 +57,25 @@ impl Utils {
ya.raw_set( ya.raw_set(
"input", "input",
lua.create_async_function(|_, t: Table| async move { lua.create_async_function(|lua, t: Table| async move {
// pub title: String, let realtime = t.raw_get("realtime").unwrap_or_default();
// pub value: String, let mut rx = InputProxy::show(InputCfg {
// pub cursor: Option<usize>, title: t.raw_get("title")?,
// pub position: Position, value: t.raw_get("value").unwrap_or_default(),
// pub realtime: bool, cursor: None, // TODO
// pub completion: bool, position: Position::try_from(t.raw_get::<_, Table>("position")?)?.into(),
// pub highlight: bool, realtime,
completion: false,
highlight: false,
});
Ok(()) Ok(if realtime {
(InputRx::new(rx).into_lua(lua)?, Value::Nil)
} else if let Some(Ok(res)) = rx.recv().await {
(res.into_lua(lua)?, 1.into_lua(lua)?)
} else {
(Value::Nil, 0.into_lua(lua)?)
})
})?, })?,
)?; )?;