mirror of
https://github.com/sxyazi/yazi.git
synced 2024-12-18 22:31:35 +03:00
feat: ui.Clear
component for UI plugins (#786)
This commit is contained in:
parent
37acd94345
commit
4e873e62f1
@ -1,8 +1,9 @@
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use ratatui::{backend::{Backend, CrosstermBackend}, CompletedFrame};
|
use ratatui::{backend::{Backend, CrosstermBackend}, CompletedFrame};
|
||||||
|
use yazi_plugin::elements::COLLISION;
|
||||||
|
|
||||||
use crate::{app::App, lives::Lives, root::{Root, COLLISION}};
|
use crate::{app::App, lives::Lives, root::Root};
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub(crate) fn render(&mut self) {
|
pub(crate) fn render(&mut self) {
|
||||||
|
@ -3,7 +3,7 @@ use std::path::MAIN_SEPARATOR;
|
|||||||
use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, List, ListItem, Widget}};
|
use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, List, ListItem, Widget}};
|
||||||
use yazi_config::{popup::{Offset, Position}, THEME};
|
use yazi_config::{popup::{Offset, Position}, THEME};
|
||||||
|
|
||||||
use crate::{widgets, Ctx};
|
use crate::Ctx;
|
||||||
|
|
||||||
pub(crate) struct Completion<'a> {
|
pub(crate) struct Completion<'a> {
|
||||||
cx: &'a Ctx,
|
cx: &'a Ctx,
|
||||||
@ -28,7 +28,7 @@ impl<'a> Widget for Completion<'a> {
|
|||||||
&THEME.completion.icon_file
|
&THEME.completion.icon_file
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut item = ListItem::new(format!(" {} {}", icon, x));
|
let mut item = ListItem::new(format!(" {icon} {x}"));
|
||||||
if i == self.cx.completion.rel_cursor() {
|
if i == self.cx.completion.rel_cursor() {
|
||||||
item = item.style(THEME.completion.active);
|
item = item.style(THEME.completion.active);
|
||||||
} else {
|
} else {
|
||||||
@ -54,7 +54,7 @@ impl<'a> Widget for Completion<'a> {
|
|||||||
area.height = rect.height.saturating_sub(area.y).min(area.height);
|
area.height = rect.height.saturating_sub(area.y).min(area.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
widgets::Clear.render(area, buf);
|
yazi_plugin::elements::Clear::default().render(area, buf);
|
||||||
List::new(items)
|
List::new(items)
|
||||||
.block(
|
.block(
|
||||||
Block::bordered().border_type(BorderType::Rounded).border_style(THEME.completion.border),
|
Block::bordered().border_type(BorderType::Rounded).border_style(THEME.completion.border),
|
||||||
|
@ -2,7 +2,7 @@ use ratatui::{buffer::Buffer, layout::{self, Constraint, Rect}, text::Line, widg
|
|||||||
use yazi_config::THEME;
|
use yazi_config::THEME;
|
||||||
|
|
||||||
use super::Bindings;
|
use super::Bindings;
|
||||||
use crate::{widgets, Ctx};
|
use crate::Ctx;
|
||||||
|
|
||||||
pub(crate) struct Layout<'a> {
|
pub(crate) struct Layout<'a> {
|
||||||
cx: &'a Ctx,
|
cx: &'a Ctx,
|
||||||
@ -15,7 +15,7 @@ impl<'a> Layout<'a> {
|
|||||||
impl<'a> Widget for Layout<'a> {
|
impl<'a> Widget for Layout<'a> {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
let help = &self.cx.help;
|
let help = &self.cx.help;
|
||||||
widgets::Clear.render(area, buf);
|
yazi_plugin::elements::Clear::default().render(area, buf);
|
||||||
|
|
||||||
let chunks = layout::Layout::vertical([Constraint::Fill(1), Constraint::Length(1)]).split(area);
|
let chunks = layout::Layout::vertical([Constraint::Fill(1), Constraint::Length(1)]).split(area);
|
||||||
Line::styled(
|
Line::styled(
|
||||||
|
@ -8,7 +8,7 @@ use yazi_core::input::InputMode;
|
|||||||
use yazi_plugin::external::Highlighter;
|
use yazi_plugin::external::Highlighter;
|
||||||
use yazi_shared::term::Term;
|
use yazi_shared::term::Term;
|
||||||
|
|
||||||
use crate::{widgets, Ctx};
|
use crate::Ctx;
|
||||||
|
|
||||||
pub(crate) struct Input<'a> {
|
pub(crate) struct Input<'a> {
|
||||||
cx: &'a Ctx,
|
cx: &'a Ctx,
|
||||||
@ -37,7 +37,7 @@ impl<'a> Widget for Input<'a> {
|
|||||||
let input = &self.cx.input;
|
let input = &self.cx.input;
|
||||||
let area = self.cx.area(&input.position);
|
let area = self.cx.area(&input.position);
|
||||||
|
|
||||||
widgets::Clear.render(area, buf);
|
yazi_plugin::elements::Clear::default().render(area, buf);
|
||||||
Paragraph::new(self.highlighted_value().unwrap_or_else(|_| Line::from(input.value())))
|
Paragraph::new(self.highlighted_value().unwrap_or_else(|_| Line::from(input.value())))
|
||||||
.block(
|
.block(
|
||||||
Block::bordered()
|
Block::bordered()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{collections::{btree_set, BTreeSet}, ops::Deref};
|
use std::{collections::{btree_set, BTreeSet}, ops::Deref};
|
||||||
|
|
||||||
use mlua::{AnyUserData, Lua, MetaMethod, UserDataMethods, UserDataRefMut};
|
use mlua::{AnyUserData, IntoLuaMulti, Lua, MetaMethod, UserDataMethods, UserDataRefMut};
|
||||||
use yazi_plugin::{bindings::Cast, url::Url};
|
use yazi_plugin::{bindings::Cast, url::Url};
|
||||||
|
|
||||||
use super::SCOPE;
|
use super::SCOPE;
|
||||||
@ -28,7 +28,12 @@ impl Selected {
|
|||||||
|
|
||||||
reg.add_meta_method(MetaMethod::Pairs, |lua, me, ()| {
|
reg.add_meta_method(MetaMethod::Pairs, |lua, me, ()| {
|
||||||
let iter = lua.create_function(|lua, mut iter: UserDataRefMut<SelectedIter>| {
|
let iter = lua.create_function(|lua, mut iter: UserDataRefMut<SelectedIter>| {
|
||||||
Ok(if let Some(url) = iter.0.next() { Some(Url::cast(lua, url.clone())?) } else { None })
|
if let Some(url) = iter.inner.next() {
|
||||||
|
iter.next += 1;
|
||||||
|
(iter.next, Url::cast(lua, url.clone())?).into_lua_multi(lua)
|
||||||
|
} else {
|
||||||
|
().into_lua_multi(lua)
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok((iter, SelectedIter::make(me.inner())))
|
Ok((iter, SelectedIter::make(me.inner())))
|
||||||
@ -42,11 +47,14 @@ impl Selected {
|
|||||||
fn inner(&self) -> &'static BTreeSet<yazi_shared::fs::Url> { unsafe { &*self.inner } }
|
fn inner(&self) -> &'static BTreeSet<yazi_shared::fs::Url> { unsafe { &*self.inner } }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SelectedIter(btree_set::Iter<'static, yazi_shared::fs::Url>);
|
struct SelectedIter {
|
||||||
|
next: usize,
|
||||||
|
inner: btree_set::Iter<'static, yazi_shared::fs::Url>,
|
||||||
|
}
|
||||||
|
|
||||||
impl SelectedIter {
|
impl SelectedIter {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn make(selected: &'static BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> {
|
fn make(selected: &'static BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> {
|
||||||
SCOPE.create_any_userdata(Self(selected.iter()))
|
SCOPE.create_any_userdata(Self { next: 0, inner: selected.iter() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ mod select;
|
|||||||
mod signals;
|
mod signals;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
mod which;
|
mod which;
|
||||||
mod widgets;
|
|
||||||
|
|
||||||
use context::*;
|
use context::*;
|
||||||
use executor::*;
|
use executor::*;
|
||||||
|
@ -5,7 +5,7 @@ use yazi_config::THEME;
|
|||||||
use yazi_core::notify::Message;
|
use yazi_core::notify::Message;
|
||||||
use yazi_proxy::options::NotifyLevel;
|
use yazi_proxy::options::NotifyLevel;
|
||||||
|
|
||||||
use crate::{widgets::Clear, Ctx};
|
use crate::Ctx;
|
||||||
|
|
||||||
pub(crate) struct Layout<'a> {
|
pub(crate) struct Layout<'a> {
|
||||||
cx: &'a Ctx,
|
cx: &'a Ctx,
|
||||||
@ -53,7 +53,7 @@ impl<'a> Widget for Layout<'a> {
|
|||||||
tile[i].offset(Offset { x: (100 - m.percent) as i32 * tile[i].width as i32 / 100, y: 0 });
|
tile[i].offset(Offset { x: (100 - m.percent) as i32 * tile[i].width as i32 / 100, y: 0 });
|
||||||
rect.width = area.width.saturating_sub(rect.x);
|
rect.width = area.width.saturating_sub(rect.x);
|
||||||
|
|
||||||
Clear.render(rect, buf);
|
yazi_plugin::elements::Clear::default().render(rect, buf);
|
||||||
Paragraph::new(m.content.as_str())
|
Paragraph::new(m.content.as_str())
|
||||||
.wrap(Wrap { trim: false })
|
.wrap(Wrap { trim: false })
|
||||||
.block(
|
.block(
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
use std::sync::atomic::AtomicBool;
|
|
||||||
|
|
||||||
use ratatui::{buffer::Buffer, layout::{Constraint, Layout, Rect}, widgets::Widget};
|
use ratatui::{buffer::Buffer, layout::{Constraint, Layout, Rect}, widgets::Widget};
|
||||||
|
|
||||||
use super::{completion, input, select, tasks, which};
|
use super::{completion, input, select, tasks, which};
|
||||||
use crate::{components, help, Ctx};
|
use crate::{components, help, Ctx};
|
||||||
|
|
||||||
pub(super) static COLLISION: AtomicBool = AtomicBool::new(false);
|
|
||||||
|
|
||||||
pub(super) struct Root<'a> {
|
pub(super) struct Root<'a> {
|
||||||
cx: &'a Ctx,
|
cx: &'a Ctx,
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, List, ListItem, Widget}};
|
use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, List, ListItem, Widget}};
|
||||||
use yazi_config::THEME;
|
use yazi_config::THEME;
|
||||||
|
|
||||||
use crate::{widgets, Ctx};
|
use crate::Ctx;
|
||||||
|
|
||||||
pub(crate) struct Select<'a> {
|
pub(crate) struct Select<'a> {
|
||||||
cx: &'a Ctx,
|
cx: &'a Ctx,
|
||||||
@ -29,7 +29,7 @@ impl<'a> Widget for Select<'a> {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
widgets::Clear.render(area, buf);
|
yazi_plugin::elements::Clear::default().render(area, buf);
|
||||||
List::new(items)
|
List::new(items)
|
||||||
.block(
|
.block(
|
||||||
Block::bordered()
|
Block::bordered()
|
||||||
|
@ -2,7 +2,7 @@ use ratatui::{buffer::Buffer, layout::{self, Alignment, Constraint, Rect}, text:
|
|||||||
use yazi_config::THEME;
|
use yazi_config::THEME;
|
||||||
use yazi_core::tasks::TASKS_PERCENT;
|
use yazi_core::tasks::TASKS_PERCENT;
|
||||||
|
|
||||||
use crate::{widgets, Ctx};
|
use crate::Ctx;
|
||||||
|
|
||||||
pub(crate) struct Layout<'a> {
|
pub(crate) struct Layout<'a> {
|
||||||
cx: &'a Ctx,
|
cx: &'a Ctx,
|
||||||
@ -32,7 +32,7 @@ impl<'a> Widget for Layout<'a> {
|
|||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
let area = Self::area(area);
|
let area = Self::area(area);
|
||||||
|
|
||||||
widgets::Clear.render(area, buf);
|
yazi_plugin::elements::Clear::default().render(area, buf);
|
||||||
let block = Block::bordered()
|
let block = Block::bordered()
|
||||||
.title(Line::styled("Tasks", THEME.tasks.title))
|
.title(Line::styled("Tasks", THEME.tasks.title))
|
||||||
.title_alignment(Alignment::Center)
|
.title_alignment(Alignment::Center)
|
||||||
|
@ -2,7 +2,7 @@ use ratatui::{buffer::Buffer, layout, layout::{Constraint, Rect}, widgets::{Bloc
|
|||||||
use yazi_config::THEME;
|
use yazi_config::THEME;
|
||||||
|
|
||||||
use super::Cand;
|
use super::Cand;
|
||||||
use crate::{widgets, Ctx};
|
use crate::Ctx;
|
||||||
|
|
||||||
const PADDING_X: u16 = 1;
|
const PADDING_X: u16 = 1;
|
||||||
const PADDING_Y: u16 = 1;
|
const PADDING_Y: u16 = 1;
|
||||||
@ -46,7 +46,7 @@ impl Widget for Which<'_> {
|
|||||||
.split(area)
|
.split(area)
|
||||||
};
|
};
|
||||||
|
|
||||||
widgets::Clear.render(area, buf);
|
yazi_plugin::elements::Clear::default().render(area, buf);
|
||||||
Block::new().style(THEME.which.mask).render(area, buf);
|
Block::new().style(THEME.which.mask).render(area, buf);
|
||||||
|
|
||||||
for y in 0..area.height {
|
for y in 0..area.height {
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
use std::sync::atomic::Ordering;
|
|
||||||
|
|
||||||
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
|
|
||||||
use yazi_adaptor::ADAPTOR;
|
|
||||||
|
|
||||||
use crate::root::COLLISION;
|
|
||||||
|
|
||||||
pub(crate) struct Clear;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
const fn is_overlapping(a: &Rect, b: &Rect) -> bool {
|
|
||||||
a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y
|
|
||||||
}
|
|
||||||
|
|
||||||
fn overlap(a: &Rect, b: &Rect) -> Option<Rect> {
|
|
||||||
if !is_overlapping(a, b) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let x = a.x.max(b.x);
|
|
||||||
let y = a.y.max(b.y);
|
|
||||||
let width = (a.x + a.width).min(b.x + b.width) - x;
|
|
||||||
let height = (a.y + a.height).min(b.y + b.height) - y;
|
|
||||||
Some(Rect { x, y, width, height })
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Widget for Clear {
|
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
|
||||||
ratatui::widgets::Clear.render(area, buf);
|
|
||||||
|
|
||||||
let Some(r) = ADAPTOR.shown_load().and_then(|r| overlap(&area, &r)) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
ADAPTOR.image_erase(r).ok();
|
|
||||||
COLLISION.store(true, Ordering::Relaxed);
|
|
||||||
for y in area.top()..area.bottom() {
|
|
||||||
for x in area.left()..area.right() {
|
|
||||||
buf.get_mut(x, y).set_skip(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
mod clear;
|
|
||||||
|
|
||||||
pub(super) use clear::*;
|
|
@ -12,6 +12,8 @@ pub fn cast_to_renderable(ud: AnyUserData) -> Option<Box<dyn Renderable + Send>>
|
|||||||
Some(Box::new(c))
|
Some(Box::new(c))
|
||||||
} else if let Ok(c) = ud.take::<crate::elements::Bar>() {
|
} else if let Ok(c) = ud.take::<crate::elements::Bar>() {
|
||||||
Some(Box::new(c))
|
Some(Box::new(c))
|
||||||
|
} else if let Ok(c) = ud.take::<crate::elements::Clear>() {
|
||||||
|
Some(Box::new(c))
|
||||||
} else if let Ok(c) = ud.take::<crate::elements::Border>() {
|
} else if let Ok(c) = ud.take::<crate::elements::Border>() {
|
||||||
Some(Box::new(c))
|
Some(Box::new(c))
|
||||||
} else if let Ok(c) = ud.take::<crate::elements::Gauge>() {
|
} else if let Ok(c) = ud.take::<crate::elements::Gauge>() {
|
||||||
@ -67,9 +69,10 @@ impl<'lua> IntoLua<'lua> for ValueSendable {
|
|||||||
ValueSendable::Number(n) => Ok(Value::Number(n)),
|
ValueSendable::Number(n) => Ok(Value::Number(n)),
|
||||||
ValueSendable::String(s) => Ok(Value::String(lua.create_string(s)?)),
|
ValueSendable::String(s) => Ok(Value::String(lua.create_string(s)?)),
|
||||||
ValueSendable::Table(t) => {
|
ValueSendable::Table(t) => {
|
||||||
let table = lua.create_table()?;
|
let seq_len = t.keys().filter(|&k| !k.is_numeric()).count();
|
||||||
|
let table = lua.create_table_with_capacity(seq_len, t.len() - seq_len)?;
|
||||||
for (k, v) in t {
|
for (k, v) in t {
|
||||||
table.raw_set(k.into_lua(lua)?, v.into_lua(lua)?)?;
|
table.raw_set(k, v)?;
|
||||||
}
|
}
|
||||||
Ok(Value::Table(table))
|
Ok(Value::Table(table))
|
||||||
}
|
}
|
||||||
@ -113,6 +116,11 @@ pub enum ValueSendableKey {
|
|||||||
String(Vec<u8>),
|
String(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ValueSendableKey {
|
||||||
|
#[inline]
|
||||||
|
fn is_numeric(&self) -> bool { matches!(self, Self::Integer(_) | Self::Number(_)) }
|
||||||
|
}
|
||||||
|
|
||||||
impl TryInto<ValueSendableKey> for ValueSendable {
|
impl TryInto<ValueSendableKey> for ValueSendable {
|
||||||
type Error = mlua::Error;
|
type Error = mlua::Error;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, Table, UserData, Value};
|
use mlua::{AnyUserData, ExternalError, Lua, Table, UserData, Value};
|
||||||
use ratatui::widgets::Borders;
|
use ratatui::widgets::Borders;
|
||||||
|
|
||||||
use super::{RectRef, Renderable, Style};
|
use super::{RectRef, Renderable, Style};
|
||||||
@ -26,12 +26,12 @@ impl Bar {
|
|||||||
|
|
||||||
let bar = lua.create_table_from([
|
let bar = lua.create_table_from([
|
||||||
// Direction
|
// Direction
|
||||||
("NONE", Borders::NONE.bits().into_lua(lua)?),
|
("NONE", Borders::NONE.bits()),
|
||||||
("TOP", Borders::TOP.bits().into_lua(lua)?),
|
("TOP", Borders::TOP.bits()),
|
||||||
("RIGHT", Borders::RIGHT.bits().into_lua(lua)?),
|
("RIGHT", Borders::RIGHT.bits()),
|
||||||
("BOTTOM", Borders::BOTTOM.bits().into_lua(lua)?),
|
("BOTTOM", Borders::BOTTOM.bits()),
|
||||||
("LEFT", Borders::LEFT.bits().into_lua(lua)?),
|
("LEFT", Borders::LEFT.bits()),
|
||||||
("ALL", Borders::ALL.bits().into_lua(lua)?),
|
("ALL", Borders::ALL.bits()),
|
||||||
])?;
|
])?;
|
||||||
|
|
||||||
bar.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
bar.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, Table, UserData, Value};
|
use mlua::{AnyUserData, ExternalError, Lua, Table, UserData, Value};
|
||||||
use ratatui::widgets::{Borders, Widget};
|
use ratatui::widgets::{Borders, Widget};
|
||||||
|
|
||||||
use super::{RectRef, Renderable, Style};
|
use super::{RectRef, Renderable, Style};
|
||||||
@ -32,19 +32,19 @@ impl Border {
|
|||||||
|
|
||||||
let border = lua.create_table_from([
|
let border = lua.create_table_from([
|
||||||
// Position
|
// Position
|
||||||
("NONE", Borders::NONE.bits().into_lua(lua)?),
|
("NONE", Borders::NONE.bits()),
|
||||||
("TOP", Borders::TOP.bits().into_lua(lua)?),
|
("TOP", Borders::TOP.bits()),
|
||||||
("RIGHT", Borders::RIGHT.bits().into_lua(lua)?),
|
("RIGHT", Borders::RIGHT.bits()),
|
||||||
("BOTTOM", Borders::BOTTOM.bits().into_lua(lua)?),
|
("BOTTOM", Borders::BOTTOM.bits()),
|
||||||
("LEFT", Borders::LEFT.bits().into_lua(lua)?),
|
("LEFT", Borders::LEFT.bits()),
|
||||||
("ALL", Borders::ALL.bits().into_lua(lua)?),
|
("ALL", Borders::ALL.bits()),
|
||||||
// Type
|
// Type
|
||||||
("PLAIN", PLAIN.into_lua(lua)?),
|
("PLAIN", PLAIN),
|
||||||
("ROUNDED", ROUNDED.into_lua(lua)?),
|
("ROUNDED", ROUNDED),
|
||||||
("DOUBLE", DOUBLE.into_lua(lua)?),
|
("DOUBLE", DOUBLE),
|
||||||
("THICK", THICK.into_lua(lua)?),
|
("THICK", THICK),
|
||||||
("QUADRANT_INSIDE", QUADRANT_INSIDE.into_lua(lua)?),
|
("QUADRANT_INSIDE", QUADRANT_INSIDE),
|
||||||
("QUADRANT_OUTSIDE", QUADRANT_OUTSIDE.into_lua(lua)?),
|
("QUADRANT_OUTSIDE", QUADRANT_OUTSIDE),
|
||||||
])?;
|
])?;
|
||||||
|
|
||||||
border.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
border.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||||
|
75
yazi-plugin/src/elements/clear.rs
Normal file
75
yazi-plugin/src/elements/clear.rs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
use mlua::{Lua, Table, UserData};
|
||||||
|
use ratatui::layout::Rect;
|
||||||
|
use yazi_adaptor::ADAPTOR;
|
||||||
|
|
||||||
|
use super::{RectRef, Renderable};
|
||||||
|
|
||||||
|
pub static COLLISION: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Default)]
|
||||||
|
pub struct Clear {
|
||||||
|
pub area: ratatui::layout::Rect,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clear {
|
||||||
|
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
||||||
|
let new = lua.create_function(|_, (_, area): (Table, RectRef)| Ok(Clear { area: *area }))?;
|
||||||
|
|
||||||
|
let clear = lua.create_table()?;
|
||||||
|
clear.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||||
|
|
||||||
|
ui.raw_set("Clear", clear)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ratatui::widgets::Widget for Clear {
|
||||||
|
fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer)
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
ratatui::widgets::Clear.render(area, buf);
|
||||||
|
|
||||||
|
let Some(r) = ADAPTOR.shown_load().and_then(|r| overlap(&area, &r)) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
ADAPTOR.image_erase(r).ok();
|
||||||
|
COLLISION.store(true, Ordering::Relaxed);
|
||||||
|
for y in area.top()..area.bottom() {
|
||||||
|
for x in area.left()..area.right() {
|
||||||
|
buf.get_mut(x, y).set_skip(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Renderable for Clear {
|
||||||
|
fn area(&self) -> ratatui::layout::Rect { self.area }
|
||||||
|
|
||||||
|
fn render(self: Box<Self>, buf: &mut ratatui::buffer::Buffer) {
|
||||||
|
<Self as ratatui::widgets::Widget>::render(Default::default(), self.area, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(*self).render(buf); }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserData for Clear {}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn is_overlapping(a: &Rect, b: &Rect) -> bool {
|
||||||
|
a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlap(a: &Rect, b: &Rect) -> Option<Rect> {
|
||||||
|
if !is_overlapping(a, b) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = a.x.max(b.x);
|
||||||
|
let y = a.y.max(b.y);
|
||||||
|
let width = (a.x + a.width).min(b.x + b.width) - x;
|
||||||
|
let height = (a.y + a.height).min(b.y + b.height) - y;
|
||||||
|
Some(Rect { x, y, width, height })
|
||||||
|
}
|
@ -12,6 +12,7 @@ pub fn pour(lua: &Lua) -> mlua::Result<()> {
|
|||||||
// Install
|
// Install
|
||||||
super::Bar::install(lua, &ui)?;
|
super::Bar::install(lua, &ui)?;
|
||||||
super::Border::install(lua, &ui)?;
|
super::Border::install(lua, &ui)?;
|
||||||
|
super::Clear::install(lua, &ui)?;
|
||||||
super::Constraint::install(lua, &ui)?;
|
super::Constraint::install(lua, &ui)?;
|
||||||
super::Gauge::install(lua, &ui)?;
|
super::Gauge::install(lua, &ui)?;
|
||||||
super::Layout::install(lua, &ui)?;
|
super::Layout::install(lua, &ui)?;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use mlua::{AnyUserData, IntoLua, Lua, Table, UserData, UserDataMethods};
|
use mlua::{AnyUserData, Lua, Table, UserData, UserDataMethods};
|
||||||
|
|
||||||
use super::{Constraint, Rect, RectRef};
|
use super::{Constraint, Rect, RectRef};
|
||||||
use crate::bindings::Cast;
|
use crate::bindings::Cast;
|
||||||
@ -17,10 +17,7 @@ impl Layout {
|
|||||||
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
|
||||||
let new = lua.create_function(|_, _: Table| Ok(Self::default()))?;
|
let new = lua.create_function(|_, _: Table| Ok(Self::default()))?;
|
||||||
|
|
||||||
let layout = lua.create_table_from([
|
let layout = lua.create_table_from([("HORIZONTAL", HORIZONTAL), ("VERTICAL", VERTICAL)])?;
|
||||||
("HORIZONTAL", HORIZONTAL.into_lua(lua)?),
|
|
||||||
("VERTICAL", VERTICAL.into_lua(lua)?),
|
|
||||||
])?;
|
|
||||||
|
|
||||||
layout.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
layout.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
mod bar;
|
mod bar;
|
||||||
mod border;
|
mod border;
|
||||||
|
mod clear;
|
||||||
mod constraint;
|
mod constraint;
|
||||||
mod elements;
|
mod elements;
|
||||||
mod gauge;
|
mod gauge;
|
||||||
@ -16,6 +17,7 @@ mod style;
|
|||||||
|
|
||||||
pub use bar::*;
|
pub use bar::*;
|
||||||
pub use border::*;
|
pub use border::*;
|
||||||
|
pub use clear::*;
|
||||||
pub use constraint::*;
|
pub use constraint::*;
|
||||||
pub use elements::*;
|
pub use elements::*;
|
||||||
pub use gauge::*;
|
pub use gauge::*;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use mlua::{AnyUserData, IntoLua, Lua, Table, UserDataFields, UserDataMethods, UserDataRef};
|
use mlua::{AnyUserData, Lua, Table, UserDataFields, UserDataMethods, UserDataRef};
|
||||||
|
|
||||||
use super::PaddingRef;
|
use super::PaddingRef;
|
||||||
use crate::bindings::Cast;
|
use crate::bindings::Cast;
|
||||||
@ -18,10 +18,7 @@ impl Rect {
|
|||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let rect = lua.create_table_from([(
|
let rect = lua.create_table_from([("default", Rect::cast(lua, Default::default())?)])?;
|
||||||
"default",
|
|
||||||
Rect::cast(lua, ratatui::layout::Rect::default())?.into_lua(lua)?,
|
|
||||||
)])?;
|
|
||||||
|
|
||||||
rect.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
rect.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use mlua::{IntoLua, Lua, Value};
|
use mlua::{IntoLuaMulti, Lua, Value};
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
use crate::{bindings::{Cast, Cha}, url::UrlRef};
|
use crate::{bindings::{Cast, Cha}, url::UrlRef};
|
||||||
@ -10,28 +10,28 @@ pub fn install(lua: &Lua) -> mlua::Result<()> {
|
|||||||
(
|
(
|
||||||
"write",
|
"write",
|
||||||
lua.create_async_function(|lua, (url, data): (UrlRef, mlua::String)| async move {
|
lua.create_async_function(|lua, (url, data): (UrlRef, mlua::String)| async move {
|
||||||
Ok(match fs::write(&*url, data).await {
|
match fs::write(&*url, data).await {
|
||||||
Ok(_) => (Value::Boolean(true), Value::Nil),
|
Ok(_) => (true, Value::Nil).into_lua_multi(lua),
|
||||||
Err(e) => (Value::Boolean(false), e.raw_os_error().into_lua(lua)?),
|
Err(e) => (false, e.raw_os_error()).into_lua_multi(lua),
|
||||||
})
|
}
|
||||||
})?,
|
})?,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"cha",
|
"cha",
|
||||||
lua.create_async_function(|lua, url: UrlRef| async move {
|
lua.create_async_function(|lua, url: UrlRef| async move {
|
||||||
Ok(match fs::symlink_metadata(&*url).await {
|
match fs::symlink_metadata(&*url).await {
|
||||||
Ok(m) => (Cha::cast(lua, m)?.into_lua(lua)?, Value::Nil),
|
Ok(m) => (Cha::cast(lua, m)?, Value::Nil).into_lua_multi(lua),
|
||||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua),
|
||||||
})
|
}
|
||||||
})?,
|
})?,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"cha_follow",
|
"cha_follow",
|
||||||
lua.create_async_function(|lua, url: UrlRef| async move {
|
lua.create_async_function(|lua, url: UrlRef| async move {
|
||||||
Ok(match fs::metadata(&*url).await {
|
match fs::metadata(&*url).await {
|
||||||
Ok(m) => (Cha::cast(lua, m)?.into_lua(lua)?, Value::Nil),
|
Ok(m) => (Cha::cast(lua, m)?, Value::Nil).into_lua_multi(lua),
|
||||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua),
|
||||||
})
|
}
|
||||||
})?,
|
})?,
|
||||||
),
|
),
|
||||||
])?,
|
])?,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use mlua::{IntoLua, Table, UserData, Value};
|
use mlua::{IntoLuaMulti, Table, UserData, Value};
|
||||||
use tokio::{io::{AsyncBufReadExt, AsyncReadExt, BufReader}, process::{ChildStderr, ChildStdin, ChildStdout}, select};
|
use tokio::{io::{AsyncBufReadExt, AsyncReadExt, BufReader}, process::{ChildStderr, ChildStdin, ChildStdout}, select};
|
||||||
|
|
||||||
use super::Status;
|
use super::Status;
|
||||||
@ -68,16 +68,14 @@ impl UserData for Child {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
methods.add_async_method_mut("wait", |lua, me, ()| async move {
|
methods.add_async_method_mut("wait", |lua, me, ()| async move {
|
||||||
Ok(match me.inner.wait().await {
|
match me.inner.wait().await {
|
||||||
Ok(status) => (Status::new(status).into_lua(lua)?, Value::Nil),
|
Ok(status) => (Status::new(status), Value::Nil).into_lua_multi(lua),
|
||||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua),
|
||||||
})
|
}
|
||||||
});
|
});
|
||||||
methods.add_method_mut("start_kill", |lua, me, ()| {
|
methods.add_method_mut("start_kill", |lua, me, ()| match me.inner.start_kill() {
|
||||||
Ok(match me.inner.start_kill() {
|
Ok(_) => (true, Value::Nil).into_lua_multi(lua),
|
||||||
Ok(_) => (true, Value::Nil),
|
Err(e) => (false, e.raw_os_error()).into_lua_multi(lua),
|
||||||
Err(e) => (false, e.raw_os_error().into_lua(lua)?),
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
use mlua::{AnyUserData, IntoLua, Lua, Table, UserData, Value};
|
use mlua::{AnyUserData, IntoLuaMulti, Lua, Table, UserData, Value};
|
||||||
|
|
||||||
use super::{output::Output, Child};
|
use super::{output::Output, Child};
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ impl Command {
|
|||||||
|
|
||||||
let command = lua.create_table_from([
|
let command = lua.create_table_from([
|
||||||
// Stdio
|
// Stdio
|
||||||
("NULL", NULL.into_lua(lua)?),
|
("NULL", NULL),
|
||||||
("PIPED", PIPED.into_lua(lua)?),
|
("PIPED", PIPED),
|
||||||
("INHERIT", INHERIT.into_lua(lua)?),
|
("INHERIT", INHERIT),
|
||||||
])?;
|
])?;
|
||||||
|
|
||||||
command.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
command.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
||||||
@ -86,17 +86,15 @@ impl UserData for Command {
|
|||||||
});
|
});
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
methods.add_method_mut("spawn", |lua, me, ()| {
|
methods.add_method_mut("spawn", |lua, me, ()| match me.inner.spawn() {
|
||||||
Ok(match me.inner.spawn() {
|
Ok(child) => (Child::new(child), Value::Nil).into_lua_multi(lua),
|
||||||
Ok(child) => (Child::new(child).into_lua(lua)?, Value::Nil),
|
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua),
|
||||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
methods.add_async_method_mut("output", |lua, me, ()| async move {
|
methods.add_async_method_mut("output", |lua, me, ()| async move {
|
||||||
Ok(match me.inner.output().await {
|
match me.inner.output().await {
|
||||||
Ok(output) => (Output::new(output).into_lua(lua)?, Value::Nil),
|
Ok(output) => (Output::new(output), Value::Nil).into_lua_multi(lua),
|
||||||
Err(e) => (Value::Nil, e.raw_os_error().into_lua(lua)?),
|
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua),
|
||||||
})
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user