From e987855fcaa4215c7ad355db092fd2cc7a4e59a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Fri, 19 Jan 2024 00:49:15 +0800 Subject: [PATCH] fix: can't display file name with invalid utf-8 (#529) --- yazi-core/src/manager/commands/rename.rs | 6 ++--- yazi-fm/src/components/header.rs | 2 +- yazi-fm/src/components/manager.rs | 2 +- yazi-fm/src/components/preview.rs | 2 +- yazi-fm/src/help/bindings.rs | 2 +- yazi-fm/src/help/layout.rs | 2 +- yazi-fm/src/lives/tabs.rs | 12 ++++++---- yazi-fm/src/which/layout.rs | 2 +- yazi-fm/src/which/side.rs | 2 +- yazi-plugin/src/bindings/window.rs | 4 ++-- yazi-plugin/src/cast.rs | 6 ++--- yazi-plugin/src/elements/list.rs | 2 +- yazi-plugin/src/elements/span.rs | 4 +++- yazi-plugin/src/external/shell.rs | 2 +- yazi-plugin/src/process/child.rs | 15 ++++-------- yazi-plugin/src/process/command.rs | 30 ++++++++++++++++-------- yazi-plugin/src/process/output.rs | 4 ++-- yazi-plugin/src/process/status.rs | 2 +- yazi-plugin/src/utils/call.rs | 4 ++-- yazi-plugin/src/utils/text.rs | 26 +++++++++++--------- yazi-shared/src/fs/url.rs | 2 +- yazi-shared/src/mime.rs | 26 ++++++++++---------- 22 files changed, 86 insertions(+), 73 deletions(-) diff --git a/yazi-core/src/manager/commands/rename.rs b/yazi-core/src/manager/commands/rename.rs index 41ede85a..14f2e0f1 100644 --- a/yazi-core/src/manager/commands/rename.rs +++ b/yazi-core/src/manager/commands/rename.rs @@ -33,10 +33,10 @@ impl Manager { let ext = url.extension(); match by { - "name" => ext.map_or_else(String::new, |s| format!(".{}", s.to_string_lossy().to_string())), + "name" => ext.map_or_else(String::new, |s| format!(".{}", s.to_string_lossy().into_owned())), "ext" if ext.is_some() => format!("{}.", url.file_stem().unwrap().to_string_lossy()), - "dot_ext" if ext.is_some() => url.file_stem().unwrap().to_string_lossy().to_string(), - _ => url.file_name().map_or_else(String::new, |s| s.to_string_lossy().to_string()), + "dot_ext" if ext.is_some() => url.file_stem().unwrap().to_string_lossy().into_owned(), + _ => url.file_name().map_or_else(String::new, |s| s.to_string_lossy().into_owned()), } } diff --git a/yazi-fm/src/components/header.rs b/yazi-fm/src/components/header.rs index a9d22e2a..a71334fc 100644 --- a/yazi-fm/src/components/header.rs +++ b/yazi-fm/src/components/header.rs @@ -1,5 +1,5 @@ use mlua::{Table, TableExt}; -use ratatui::{prelude::Buffer, widgets::Widget}; +use ratatui::{buffer::Buffer, widgets::Widget}; use tracing::error; use yazi_plugin::{bindings::Cast, elements::{render_widgets, Rect}, LUA}; diff --git a/yazi-fm/src/components/manager.rs b/yazi-fm/src/components/manager.rs index b613196a..cca83e7f 100644 --- a/yazi-fm/src/components/manager.rs +++ b/yazi-fm/src/components/manager.rs @@ -1,5 +1,5 @@ use mlua::{Table, TableExt}; -use ratatui::{prelude::Buffer, widgets::Widget}; +use ratatui::{buffer::Buffer, widgets::Widget}; use tracing::error; use yazi_plugin::{bindings::Cast, elements::{render_widgets, Rect}, LUA}; diff --git a/yazi-fm/src/components/preview.rs b/yazi-fm/src/components/preview.rs index 5a0067ff..897a9f13 100644 --- a/yazi-fm/src/components/preview.rs +++ b/yazi-fm/src/components/preview.rs @@ -1,4 +1,4 @@ -use ratatui::{prelude::Buffer, widgets::Widget}; +use ratatui::{buffer::Buffer, widgets::Widget}; use crate::Ctx; diff --git a/yazi-fm/src/help/bindings.rs b/yazi-fm/src/help/bindings.rs index 18677542..1a4471c1 100644 --- a/yazi-fm/src/help/bindings.rs +++ b/yazi-fm/src/help/bindings.rs @@ -1,4 +1,4 @@ -use ratatui::{layout::{self, Constraint}, prelude::{Buffer, Direction, Rect}, widgets::{List, ListItem, Widget}}; +use ratatui::{buffer::Buffer, layout::{self, Constraint, Direction, Rect}, widgets::{List, ListItem, Widget}}; use yazi_config::THEME; use crate::Ctx; diff --git a/yazi-fm/src/help/layout.rs b/yazi-fm/src/help/layout.rs index b918bf03..0fcb59ca 100644 --- a/yazi-fm/src/help/layout.rs +++ b/yazi-fm/src/help/layout.rs @@ -1,4 +1,4 @@ -use ratatui::{buffer::Buffer, layout::{self, Rect}, prelude::{Constraint, Direction}, widgets::{Paragraph, Widget}}; +use ratatui::{buffer::Buffer, layout::{self, Constraint, Direction, Rect}, widgets::{Paragraph, Widget}}; use yazi_config::THEME; use super::Bindings; diff --git a/yazi-fm/src/lives/tabs.rs b/yazi-fm/src/lives/tabs.rs index c3461ce8..776412a4 100644 --- a/yazi-fm/src/lives/tabs.rs +++ b/yazi-fm/src/lives/tabs.rs @@ -19,12 +19,14 @@ impl<'a, 'b> Tabs<'a, 'b> { lua.register_userdata_type::(|reg| { reg.add_method("name", |lua, me, ()| { - Some(lua.create_string( - me.current.cwd.file_name().map_or_else( - || me.current.cwd.as_os_str().as_encoded_bytes(), - |n| n.as_encoded_bytes(), + Some( + lua.create_string( + me.current + .cwd + .file_name() + .map_or(me.current.cwd.as_os_str().as_encoded_bytes(), |n| n.as_encoded_bytes()), ), - )) + ) .transpose() }); diff --git a/yazi-fm/src/which/layout.rs b/yazi-fm/src/which/layout.rs index 91380d58..d260709d 100644 --- a/yazi-fm/src/which/layout.rs +++ b/yazi-fm/src/which/layout.rs @@ -1,4 +1,4 @@ -use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, widgets::{Block, Widget}}; +use ratatui::{buffer::Buffer, layout, layout::{Constraint, Direction, Rect}, widgets::{Block, Widget}}; use yazi_config::THEME; use super::Side; diff --git a/yazi-fm/src/which/side.rs b/yazi-fm/src/which/side.rs index bb04cfd5..666954a4 100644 --- a/yazi-fm/src/which/side.rs +++ b/yazi-fm/src/which/side.rs @@ -1,4 +1,4 @@ -use ratatui::{prelude::{Buffer, Rect}, text::{Line, Span}, widgets::{Block, List, ListItem, Padding, Widget}}; +use ratatui::{buffer::Buffer, layout::Rect, text::{Line, Span}, widgets::{Block, List, ListItem, Padding, Widget}}; use yazi_config::{keymap::Control, THEME}; pub(super) struct Side<'a> { diff --git a/yazi-plugin/src/bindings/window.rs b/yazi-plugin/src/bindings/window.rs index 3fcb2cf5..c8da6bde 100644 --- a/yazi-plugin/src/bindings/window.rs +++ b/yazi-plugin/src/bindings/window.rs @@ -1,4 +1,4 @@ -use mlua::{prelude::LuaUserDataFields, FromLua, UserData}; +use mlua::{FromLua, UserData}; use yazi_shared::term::Term; #[derive(Debug, Clone, Copy, FromLua)] @@ -17,7 +17,7 @@ impl Default for Window { } impl UserData for Window { - fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_method_get("rows", |_, me| Ok(me.rows)); fields.add_field_method_get("cols", |_, me| Ok(me.cols)); fields.add_field_method_get("width", |_, me| Ok(me.width)); diff --git a/yazi-plugin/src/cast.rs b/yazi-plugin/src/cast.rs index f06e424f..6388af4e 100644 --- a/yazi-plugin/src/cast.rs +++ b/yazi-plugin/src/cast.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use anyhow::bail; -use mlua::{prelude::{Lua, LuaResult}, AnyUserData, IntoLua, Value}; +use mlua::{AnyUserData, IntoLua, Lua, Value}; use yazi_shared::OrderedFloat; use crate::elements::Renderable; @@ -59,7 +59,7 @@ impl<'a> TryFrom> for ValueSendable { } impl<'lua> IntoLua<'lua> for ValueSendable { - fn into_lua(self, lua: &Lua) -> LuaResult { + fn into_lua(self, lua: &Lua) -> mlua::Result { match self { ValueSendable::Nil => Ok(Value::Nil), ValueSendable::Boolean(b) => Ok(Value::Boolean(b)), @@ -121,7 +121,7 @@ impl TryInto for ValueSendable { } impl<'lua> IntoLua<'lua> for ValueSendableKey { - fn into_lua(self, lua: &Lua) -> LuaResult { + fn into_lua(self, lua: &Lua) -> mlua::Result { match self { ValueSendableKey::Nil => Ok(Value::Nil), ValueSendableKey::Boolean(b) => Ok(Value::Boolean(b)), diff --git a/yazi-plugin/src/elements/list.rs b/yazi-plugin/src/elements/list.rs index becca99e..ee95741d 100644 --- a/yazi-plugin/src/elements/list.rs +++ b/yazi-plugin/src/elements/list.rs @@ -58,7 +58,7 @@ impl ListItem { return Ok(Self { content, style: None }); } Value::String(s) => { - return Ok(Self { content: s.to_str()?.to_string().into(), style: None }); + return Ok(Self { content: s.to_string_lossy().into_owned().into(), style: None }); } _ => {} } diff --git a/yazi-plugin/src/elements/span.rs b/yazi-plugin/src/elements/span.rs index e4f2fc83..5df4868a 100644 --- a/yazi-plugin/src/elements/span.rs +++ b/yazi-plugin/src/elements/span.rs @@ -10,7 +10,9 @@ impl Span { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { ui.set( "Span", - lua.create_function(|_, content: String| Ok(Self(ratatui::text::Span::raw(content))))?, + lua.create_function(|_, content: mlua::String| { + Ok(Self(ratatui::text::Span::raw(content.to_string_lossy().into_owned()))) + })?, ) } } diff --git a/yazi-plugin/src/external/shell.rs b/yazi-plugin/src/external/shell.rs index b0868f79..76d1ca73 100644 --- a/yazi-plugin/src/external/shell.rs +++ b/yazi-plugin/src/external/shell.rs @@ -54,7 +54,7 @@ pub fn shell(opt: ShellOpt) -> Result { #[cfg(windows)] { - let args: Vec = opt.args.iter().map(|s| s.to_string_lossy().to_string()).collect(); + let args: Vec = opt.args.iter().map(|s| s.to_string_lossy().into_owned()).collect(); let args_: Vec<&str> = args.iter().map(|s| s.as_ref()).collect(); let expanded = parser::parse(opt.cmd.to_string_lossy().as_ref(), &args_); Ok( diff --git a/yazi-plugin/src/process/child.rs b/yazi-plugin/src/process/child.rs index 4f447d49..f08f105b 100644 --- a/yazi-plugin/src/process/child.rs +++ b/yazi-plugin/src/process/child.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use mlua::{prelude::LuaUserDataMethods, IntoLua, Table, UserData, Value}; +use mlua::{IntoLua, Table, UserData, Value}; use tokio::{io::{AsyncBufReadExt, AsyncReadExt, BufReader}, process::{ChildStderr, ChildStdin, ChildStdout}, select}; use super::Status; @@ -22,14 +22,12 @@ impl Child { } impl UserData for Child { - fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { #[inline] + // TODO: return mlua::String instead of String async fn read_line(me: &mut Child) -> (String, u8) { async fn read(t: Option) -> Option { - let Some(mut r) = t else { - return None; - }; - + let mut r = t?; let mut buf = String::new(); match r.read_line(&mut buf).await { Ok(0) | Err(_) => None, @@ -46,10 +44,7 @@ impl UserData for Child { methods.add_async_method_mut("read", |_, me, len: usize| async move { async fn read(t: Option, len: usize) -> Option> { - let Some(mut r) = t else { - return None; - }; - + let mut r = t?; let mut buf = vec![0; len]; match r.read(&mut buf).await { Ok(0) | Err(_) => return None, diff --git a/yazi-plugin/src/process/command.rs b/yazi-plugin/src/process/command.rs index 39485456..6184a67e 100644 --- a/yazi-plugin/src/process/command.rs +++ b/yazi-plugin/src/process/command.rs @@ -1,6 +1,6 @@ use std::process::Stdio; -use mlua::{prelude::LuaUserDataMethods, AnyUserData, IntoLua, Lua, Table, UserData, Value}; +use mlua::{AnyUserData, IntoLua, Lua, Table, UserData, Value}; use super::{output::Output, Child}; @@ -35,19 +35,29 @@ impl Command { } impl UserData for Command { - fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_function("arg", |_, (ud, arg): (AnyUserData, String)| { - ud.borrow_mut::()?.inner.arg(arg); + fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_function("arg", |_, (ud, arg): (AnyUserData, mlua::String)| { + ud.borrow_mut::()?.inner.arg(arg.to_string_lossy().as_ref()); Ok(ud) }); - methods.add_function("args", |_, (ud, args): (AnyUserData, Vec)| { - ud.borrow_mut::()?.inner.args(args); - Ok(ud) - }); - methods.add_function("env", |_, (ud, key, value): (AnyUserData, String, String)| { - ud.borrow_mut::()?.inner.env(key, value); + methods.add_function("args", |_, (ud, args): (AnyUserData, Vec)| { + { + let mut me = ud.borrow_mut::()?; + for arg in args { + me.inner.arg(arg.to_string_lossy().as_ref()); + } + } Ok(ud) }); + methods.add_function( + "env", + |_, (ud, key, value): (AnyUserData, mlua::String, mlua::String)| { + ud.borrow_mut::()? + .inner + .env(key.to_string_lossy().as_ref(), value.to_string_lossy().as_ref()); + Ok(ud) + }, + ); methods.add_function("stdin", |_, (ud, stdio): (AnyUserData, u8)| { ud.borrow_mut::()?.inner.stdin(match stdio { PIPED => Stdio::piped(), diff --git a/yazi-plugin/src/process/output.rs b/yazi-plugin/src/process/output.rs index 88f7ca84..66ef04ce 100644 --- a/yazi-plugin/src/process/output.rs +++ b/yazi-plugin/src/process/output.rs @@ -1,4 +1,4 @@ -use mlua::{prelude::LuaUserDataFields, UserData}; +use mlua::UserData; use super::Status; @@ -11,7 +11,7 @@ impl Output { } impl UserData for Output { - fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_method_get("status", |_, me| Ok(Status::new(me.inner.status))); fields.add_field_method_get("stdout", |lua, me| lua.create_string(&me.inner.stdout)); fields.add_field_method_get("stderr", |lua, me| lua.create_string(&me.inner.stderr)); diff --git a/yazi-plugin/src/process/status.rs b/yazi-plugin/src/process/status.rs index 93d45aae..7c8e05f7 100644 --- a/yazi-plugin/src/process/status.rs +++ b/yazi-plugin/src/process/status.rs @@ -9,7 +9,7 @@ impl Status { } impl UserData for Status { - fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_method("success", |_, me, ()| Ok(me.inner.success())); methods.add_method("code", |_, me, ()| Ok(me.inner.code())); } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index 30d2ed68..f4cb282b 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -17,10 +17,10 @@ impl Utils { match k { Value::Integer(_) => { - args.push(v.to_str()?.to_owned()); + args.push(v.to_string_lossy().into_owned()); } Value::String(s) => { - named.insert(s.to_str()?.replace('_', "-"), v.to_str()?.to_owned()); + named.insert(s.to_str()?.replace('_', "-"), v.to_string_lossy().into_owned()); } _ => return Err("invalid key in exec".into_lua_err()), } diff --git a/yazi-plugin/src/utils/text.rs b/yazi-plugin/src/utils/text.rs index 101578b5..11bb43b2 100644 --- a/yazi-plugin/src/utils/text.rs +++ b/yazi-plugin/src/utils/text.rs @@ -10,17 +10,18 @@ impl Utils { pub(super) fn text(lua: &Lua, ya: &Table) -> mlua::Result<()> { ya.set( "truncate", - lua.create_function(|_, (text, max): (String, usize)| { + lua.create_function(|_, (text, max): (mlua::String, usize)| { let mut width = 0; - let flow = text.chars().try_fold(String::with_capacity(max), |mut s, c| { - width += c.width().unwrap_or(0); - if s.width() < max { - s.push(c); - ControlFlow::Continue(s) - } else { - ControlFlow::Break(s) - } - }); + let flow = + text.to_string_lossy().chars().try_fold(String::with_capacity(max), |mut s, c| { + width += c.width().unwrap_or(0); + if s.width() < max { + s.push(c); + ControlFlow::Continue(s) + } else { + ControlFlow::Break(s) + } + }); Ok(match flow { ControlFlow::Break(s) => s, @@ -29,7 +30,10 @@ impl Utils { })?, )?; - ya.set("mime_valid", lua.create_function(|_, mime: String| Ok(mime_valid(&mime)))?)?; + ya.set( + "mime_valid", + lua.create_function(|_, mime: mlua::String| Ok(mime_valid(mime.as_bytes())))?, + )?; Ok(()) } diff --git a/yazi-shared/src/fs/url.rs b/yazi-shared/src/fs/url.rs index a71cd4f4..46dea1ab 100644 --- a/yazi-shared/src/fs/url.rs +++ b/yazi-shared/src/fs/url.rs @@ -98,7 +98,7 @@ impl AsRef for Url { impl ToString for Url { fn to_string(&self) -> String { if self.scheme == UrlScheme::Regular { - return self.path.to_string_lossy().to_string(); + return self.path.to_string_lossy().into_owned(); } let scheme = match self.scheme { diff --git a/yazi-shared/src/mime.rs b/yazi-shared/src/mime.rs index 9d803a89..022c1d3e 100644 --- a/yazi-shared/src/mime.rs +++ b/yazi-shared/src/mime.rs @@ -1,23 +1,23 @@ pub const MIME_DIR: &str = "inode/directory"; -pub fn mime_valid(s: &str) -> bool { - let parts = s.split('/').collect::>(); +pub fn mime_valid(b: &[u8]) -> bool { + let parts = b.split(|&b| b == b'/').collect::>(); if parts.len() != 2 || parts[1].is_empty() { return false; } matches!( parts[0], - "application" - | "audio" - | "example" - | "font" - | "image" - | "inode" - | "message" - | "model" - | "multipart" - | "text" - | "video" + b"application" + | b"audio" + | b"example" + | b"font" + | b"image" + | b"inode" + | b"message" + | b"model" + | b"multipart" + | b"text" + | b"video" ) }