ronantakizawa/codereview-bench huggingface dataset:
Repository: sxyazi/yazi
File: yazi-plugin/preset/plugins/archive.lua (Lua)

Code before:
		if not dst then
			last_err = err
		end
		return src, dst
	end

	local src, dst = try("7zz")
	if not src then
		src, dst = try("7z")
	end
	if not dst then
		return ya.err("Failed to start either `7zz` or `7z`, error: " .. last_err)
	end
	return src, dst, last_err
end

---List files in an archive
---@param args table
---@param skip integer
---@param limit integer
---@return table files
---@return Error? err
function M.list_archive(args, skip, limit)
	local child = M.spawn_7z { "l", "-ba", "-slt", "-sccUTF-8", table.unpack(args) }
	if not child then
		return {}, 0, Err("Failed to start either `7zz` or `7z`. Do you have 7-zip installed?")
	end

	local files, err = M.parse_7z_slt(child, skip, limit)
	child:start_kill()

	return files, err
end

---List files in a compressed tarball
---@param args table
---@param skip integer
---@param limit integer
---@return table files
---@return Error? err
function M.list_compressed_tar(args, skip, limit)
	local src, dst = M.spawn_7z_piped(
		{ "x", "-so", table.unpack(args) },
		{ "l", "-ba", "-slt", "-ttar", "-sccUTF-8", "-si" }
	)
	if not dst then
		return {}, 0, Err("Failed to start either `7zz` or `7z`. Do you have 7-zip installed?")
	end

	local files, err = M.parse_7z_slt(dst, skip, limit)
	src:start_kill()

Review comment (suggestion):
The return statement includes an extra value `0` that doesn't match the updated function signature. This function now returns only `files` and `err`, but this error path returns three values: `{}`, `0`, and an Error. The `0` should be removed to match the new signature.

Code after:
		if not dst then
			last_err = err
		end
		return src, dst
	end

	local src, dst = try("7zz")
	if not src then
		src, dst = try("7z")
	end
	if not dst then
		return ya.err("Failed to start either `7zz` or `7z`, error: " .. last_err)
	end
	return src, dst, last_err
end

---List files in an archive
---@param args table
---@param skip integer
---@param limit integer
---@return table files
---@return Error? err
function M.list_archive(args, skip, limit)
	local child = M.spawn_7z { "l", "-ba", "-slt", "-sccUTF-8", table.unpack(args) }
	if not child then
		return {}, Err("Failed to start either `7zz` or `7z`. Do you have 7-zip installed?")
	end

	local files, err = M.parse_7z_slt(child, skip, limit)
	child:start_kill()

	return files, err
end

---List files in a compressed tarball
---@param args table
---@param skip integer
---@param limit integer
---@return table files
---@return Error? err
function M.list_compressed_tar(args, skip, limit)
	local src, dst = M.spawn_7z_piped(
		{ "x", "-so", table.unpack(args) },
		{ "l", "-ba", "-slt", "-ttar", "-sccUTF-8", "-si" }
	)
	if not dst then
		return {}, Err("Failed to start either `7zz` or `7z`. Do you have 7-zip installed?")
	end

	local files, err = M.parse_7z_slt(dst, skip, limit)
	src:start_kill()
Repository: sxyazi/yazi
File: yazi-shared/src/env.rs (Rust)

Code before:
use std::fmt::{Display, Formatter};

pub static LOG_LEVEL: crate::SyncCell<LogLevel> = crate::SyncCell::new(LogLevel::None);

#[inline]
pub fn env_exists(name: &str) -> bool { std::env::var_os(name).is_some_and(|s| !s.is_empty()) }

#[inline]
pub fn in_wsl() -> bool {
	#[cfg(target_os = "linux")]
	{
		std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok()
	}
	#[cfg(not(target_os = "linux"))]
	{
		false
	}
}

#[inline]
pub fn in_ssh_connection() -> bool {
	env_exists("SSH_CLIENT") || env_exists("SSH_TTY") || env_exists("SSH_CONNECTION")
}

// LogLevel
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogLevel {
	None,
	Error,
	Warn,
	Info,
	Debug,
}

impl LogLevel {
	#[inline]

Review comment (suggestion):
The WSL detection only checks the kernel osrelease file and doesn't include a fallback mechanism. The linked issue (3583) mentions that the WSL_INTEROP environment variable is also available and could serve as an additional detection method. Consider adding env_exists("WSL_INTEROP") as a fallback check to make the detection more robust across different WSL configurations.
```suggestion
	{
		if env_exists("WSL_INTEROP") {
			return true;
		}
```

Code after:
use std::fmt::{Display, Formatter};

pub static LOG_LEVEL: crate::SyncCell<LogLevel> = crate::SyncCell::new(LogLevel::None);

#[inline]
pub fn env_exists(name: &str) -> bool { std::env::var_os(name).is_some_and(|s| !s.is_empty()) }

#[inline]
pub fn in_wsl() -> bool {
	#[cfg(target_os = "linux")]
	{
		std::fs::read("/proc/sys/kernel/osrelease")
			.is_ok_and(|b| b.windows(11).any(|w| w == b"-microsoft-"))
	}
	#[cfg(not(target_os = "linux"))]
	{
		false
	}
}

#[inline]
pub fn in_ssh_connection() -> bool {
	env_exists("SSH_CLIENT") || env_exists("SSH_TTY") || env_exists("SSH_CONNECTION")
}

// LogLevel
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogLevel {
	None,
	Error,
	Warn,
	Info,
	Debug,
}

impl LogLevel {
Repository: sxyazi/yazi
File: yazi-plugin/preset/plugins/extract.lua (Lua)

Code before:
	end

	local only = #outs == 1
	if only and not outs[1].cha.is_dir and require("archive").is_tar(outs[1].url) then
		self:entry { args = { tostring(outs[1].url), tostring(to) } }
		fs.remove("file", outs[1].url)
		fs.remove("dir", tmp)
		return
	end

	local target
	if only then
		target = to:join(outs[1].name)
	else
		target = to:join(self.trim_ext(from.name))
	end

	target = fs.unique_name(target)
	if not target then
		fail("Failed to determine a target for '%s'", from)
	end

	target = tostring(target)
	if only and not os.rename(tostring(outs[1].url), target) then
		fail('Failed to move "%s" to "%s"', outs[1].url, target)
	elseif not only and not os.rename(tostring(tmp), target) then
		fail('Failed to move "%s" to "%s"', tmp, target)
	end
	fs.remove("dir", tmp)
end

function M.tmp_name(url) return ".tmp_" .. ya.hash(string.format("extract//%s//%.10f", url, ya.time())) end

function M.trim_ext(name)
	-- stylua: ignore
	local exts = { ["7z"] = true, apk = true, bz2 = true, bzip2 = true, cbr = true, cbz = true, exe = true, gz = true, gzip = true, iso = true, jar = true, rar = true, tar = true, tgz = true, xz = true, zip = true, zst = true }

	while true do
		local s = name:gsub("%.([a-zA-Z0-9]+)$", function(s) return (exts[s] or exts[s:lower()]) and "" end)
		if s == name or s == "" then
			break
		else
			name = s
		end
	end
	return name
end

return M


Review comment (bug):
`fs.rename()` returns `(ok, err)` (see `yazi-plugin/src/fs/fs.rs`), but this code only checks the boolean and discards the error details. Consider capturing the second return value and including it in the `fail()` message to make extraction failures easier to diagnose.

Code after:
	end

	local only = #outs == 1
	if only and not outs[1].cha.is_dir and require("archive").is_tar(outs[1].url) then
		self:entry { args = { tostring(outs[1].url), tostring(to) } }
		fs.remove("file", outs[1].url)
		fs.remove("dir", tmp)
		return
	end

	local target
	if only then
		target = to:join(outs[1].name)
	else
		target = to:join(self.trim_ext(from.name))
	end

	target = fs.unique_name(target)
	if not target then
		fail("Failed to determine a target for '%s'", from)
	end

	if only and not fs.rename(outs[1].url, target) then
		fail('Failed to move "%s" to "%s"', outs[1].url, target)
	elseif not only and not fs.rename(tmp, target) then
		fail('Failed to move "%s" to "%s"', tmp, target)
	end
	fs.remove("dir", tmp)
end

function M.tmp_name(url) return ".tmp_" .. ya.hash(string.format("extract//%s//%.10f", url, ya.time())) end

function M.trim_ext(name)
	-- stylua: ignore
	local exts = { ["7z"] = true, apk = true, bz2 = true, bzip2 = true, cbr = true, cbz = true, exe = true, gz = true, gzip = true, iso = true, jar = true, rar = true, tar = true, tgz = true, xz = true, zip = true, zst = true }

	while true do
		local s = name:gsub("%.([a-zA-Z0-9]+)$", function(s) return (exts[s] or exts[s:lower()]) and "" end)
		if s == name or s == "" then
			break
		else
			name = s
		end
	end
	return name
end

return M
Repository: sxyazi/yazi
File: yazi-parser/src/app/notify.rs (Rust)

Code before:
use std::{str::FromStr, time::Duration};

use anyhow::anyhow;
use mlua::{ExternalError, ExternalResult};
use serde::Deserialize;
use yazi_config::{Style, THEME};
use yazi_shared::event::CmdCow;

#[derive(Clone)]
pub struct NotifyOpt {
	pub title:   String,
	pub content: String,
	pub level:   NotifyLevel,
	pub timeout: Duration,
}

impl TryFrom<CmdCow> for NotifyOpt {
	type Error = anyhow::Error;

	fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
		c.take_any("opt").ok_or_else(|| anyhow!("Invalid 'opt' in NotifyOpt"))
	}
}

impl TryFrom<mlua::Table> for NotifyOpt {
	type Error = mlua::Error;

	fn try_from(t: mlua::Table) -> Result<Self, Self::Error> {
		let timeout = t.raw_get("timeout")?;
		if timeout < 0.0 {
			return Err("timeout must be non-negative".into_lua_err());
		}

		let level = if let Ok(s) = t.raw_get::<mlua::String>("level") {
			s.to_str()?.parse().into_lua_err()?
		} else {
			Default::default()
		};

		Ok(Self {
			title: t.raw_get("title")?,
			content: t.raw_get("content")?,

Review comment (bug):
The previous implementation validated that timeout was non-negative and returned an error for negative values. The new serde-based deserialization using DurationSeconds may not perform this validation, potentially allowing negative durations to be created (which would panic or cause undefined behavior when used). Consider adding a custom deserializer or validation to ensure timeout remains non-negative.

Code after:
use std::{str::FromStr, time::Duration};

use anyhow::anyhow;
use mlua::{FromLua, IntoLua, Lua, LuaSerdeExt, Value};
use serde::{Deserialize, Serialize};
use serde_with::{DurationSeconds, serde_as};
use yazi_config::{Style, THEME};
use yazi_shared::event::CmdCow;

#[serde_as]
#[derive(Clone, Deserialize, Serialize)]
pub struct NotifyOpt {
	pub title:   String,
	pub content: String,
	pub level:   NotifyLevel,
	#[serde_as(as = "DurationSeconds<f64>")]  // FIXME
	pub timeout: Duration,
}

impl TryFrom<CmdCow> for NotifyOpt {
	type Error = anyhow::Error;

	fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
		c.take_any("opt").ok_or_else(|| anyhow!("Invalid 'opt' in NotifyOpt"))
	}
}

impl FromLua for NotifyOpt {
	fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> { lua.from_value(value) }
}

impl IntoLua for NotifyOpt {
	fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { lua.to_value(&self) }
}

// --- Level
#[derive(Clone, Copy, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum NotifyLevel {
	#[default]
	Info,
	Warn,
Repository: sxyazi/yazi
File: yazi-binding/src/macros.rs (Rust)

Code before:
#[macro_export]
macro_rules! runtime {
	($lua:ident) => {{
		use mlua::ExternalError;
		$lua.app_data_ref::<$crate::Runtime>().ok_or_else(|| "Runtime not found".into_lua_err())
	}};
}

#[macro_export]
macro_rules! runtime_mut {
	($lua:ident) => {{
		use mlua::ExternalError;
		$lua.app_data_mut::<$crate::Runtime>().ok_or_else(|| "Runtime not found".into_lua_err())
	}};
}

#[macro_export]
macro_rules! runtime_scope {
	($lua:ident, $id:expr, $block:expr) => {{
		let mut f = || {
			let blocking = $crate::runtime_mut!($lua)?.critical_push($id, true);
			let result = $block;
			$crate::runtime_mut!($lua)?.critical_pop(blocking)?;
			result
		};
		f()
	}};
}

#[macro_export]
macro_rules! deprecate {
	($lua:ident, $tt:tt) => {{
		static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
		if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) {
			let id = match $crate::runtime!($lua)?.current() {
				Some(id) => &format!("`{id}.yazi` plugin"),
				None => "`init.lua` config",
			};
			yazi_macro::emit!(Call(
				yazi_macro::relay!(app:deprecate).with("content", format!($tt, id))
			));
		}
	}};
}

#[macro_export]
macro_rules! cached_field {

Review comment (suggestion):
`runtime_scope!` can leave the runtime in a pushed/critical state when the `$block` contains `?`. Because `$block` is evaluated directly inside the closure, a `?` inside `$block` returns early from `f()` before `critical_pop()` runs (e.g. current usage in `yazi-actor/src/app/mouse.rs` wraps a block that uses `?`). Wrap `$block` in an inner closure (so `?` returns from that inner closure) or otherwise guarantee `critical_pop()` runs even on early-return/error (e.g. scope guard / `match` on the result).
```suggestion
			let result = (|| { $block })();
```

Code after:
#[macro_export]
macro_rules! runtime {
	($lua:ident) => {{
		use mlua::ExternalError;
		$lua.app_data_ref::<$crate::Runtime>().ok_or_else(|| "Runtime not found".into_lua_err())
	}};
}

#[macro_export]
macro_rules! runtime_mut {
	($lua:ident) => {{
		use mlua::ExternalError;
		$lua.app_data_mut::<$crate::Runtime>().ok_or_else(|| "Runtime not found".into_lua_err())
	}};
}

#[macro_export]
macro_rules! runtime_scope {
	($lua:ident, $id:expr, $block:expr) => {{
		let mut f = || {
			let blocking = $crate::runtime_mut!($lua)?.critical_push($id, true);
			let result = (|| $block)();
			$crate::runtime_mut!($lua)?.critical_pop(blocking)?;
			result
		};
		f()
	}};
}

#[macro_export]
macro_rules! deprecate {
	($lua:ident, $tt:tt) => {{
		static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
		if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) {
			let id = match $crate::runtime!($lua)?.current() {
				Some(id) => &format!("`{id}.yazi` plugin"),
				None => "`init.lua` config",
			};
			yazi_macro::emit!(Call(
				yazi_macro::relay!(app:deprecate).with("content", format!($tt, id))
			));
		}
	}};
}

#[macro_export]
macro_rules! cached_field {
Repository: sxyazi/yazi
File: yazi-actor/src/mgr/tab_rename.rs (Rust)

Code before:
use std::borrow::Cow;

use anyhow::Result;
use yazi_config::popup::InputCfg;
use yazi_macro::{render, succ};
use yazi_parser::mgr::TabRenameOpt;
use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::data::Data;

use crate::{Actor, Ctx};

pub struct TabRename;

impl Actor for TabRename {
	type Options = TabRenameOpt;

	const NAME: &str = "tab_rename";

	fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
		let tab = cx.active().id;
		let pref = &mut cx.active_mut().pref;

		if !opt.interactive {
			pref.name = opt.name.unwrap_or_default().into_owned();
			succ!(render!());
		}

		let mut input = InputProxy::show(
			InputCfg::tab_rename().with_value(opt.name.unwrap_or(Cow::Borrowed(&pref.name))),
		);
		tokio::spawn(async move {
			if let Some(Ok(name)) = input.recv().await {
				MgrProxy::tab_rename(tab, name);
			}
		});
		succ!();
	}
}


Review comment (bug):
`Ctx::new` supports targeting a specific tab via the command's `tab` field, but this actor uses `cx.active()` / `cx.active_mut()` (cursor tab) instead of `cx.tab()` / `cx.tab_mut()`. When the rename is sent back asynchronously with `MgrProxy::tab_rename(tab_id, ...)`, this can rename the wrong tab if the cursor changed. Use the tab selected by `cx.tab` for both the captured id and the mutated preference.
```suggestion
		let tab = cx.tab().id;
		let pref = &mut cx.tab_mut().pref;
```

Code after:
use std::borrow::Cow;

use anyhow::Result;
use yazi_config::popup::InputCfg;
use yazi_macro::{render, succ};
use yazi_parser::mgr::TabRenameOpt;
use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::data::Data;

use crate::{Actor, Ctx};

pub struct TabRename;

impl Actor for TabRename {
	type Options = TabRenameOpt;

	const NAME: &str = "tab_rename";

	fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
		let tab = cx.tab().id;
		let pref = &mut cx.tab_mut().pref;

		if !opt.interactive {
			pref.name = opt.name.unwrap_or_default().into_owned();
			succ!(render!());
		}

		let mut input = InputProxy::show(
			InputCfg::tab_rename().with_value(opt.name.unwrap_or(Cow::Borrowed(&pref.name))),
		);
		tokio::spawn(async move {
			if let Some(Ok(name)) = input.recv().await {
				MgrProxy::tab_rename(tab, name);
			}
		});
		succ!();
	}
}
Repository: sxyazi/yazi
File: yazi-actor/src/mgr/tab_rename.rs (Rust)

Code before:
use yazi_config::popup::InputCfg;
use yazi_macro::{render, succ};
use yazi_parser::mgr::TabRenameOpt;
use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::data::Data;

use crate::{Actor, Ctx};

pub struct TabRename;

impl Actor for TabRename {
	type Options = TabRenameOpt;

	const NAME: &str = "tab_rename";

	fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
		let tab = cx.active().id;
		let pref = &mut cx.active_mut().pref;

		if !opt.interactive {
			pref.name = opt.name.unwrap_or_default().into_owned();
			succ!(render!());
		}

		let mut input = InputProxy::show(
			InputCfg::tab_rename().with_value(opt.name.unwrap_or(Cow::Borrowed(&pref.name))),
		);
		tokio::spawn(async move {
			if let Some(Ok(name)) = input.recv().await {
				MgrProxy::tab_rename(tab, name);
			}
		});
		succ!();
	}
}


Review comment (suggestion):
`opt.name` is `Option<SStr>` where `SStr = Cow<'static, str>`. `unwrap_or(Cow::Borrowed(&pref.name))` attempts to borrow `pref.name` with a non-`'static` lifetime, which won’t type-check. Convert the fallback to an owned value (e.g., clone `pref.name` into an owned `Cow`/`String`) before passing it to `with_value`.
```suggestion
			InputCfg::tab_rename().with_value(
				opt.name.unwrap_or_else(|| Cow::Owned(pref.name.clone())),
			),
```

Code after:
use yazi_config::popup::InputCfg;
use yazi_macro::{render, succ};
use yazi_parser::mgr::TabRenameOpt;
use yazi_proxy::{InputProxy, MgrProxy};
use yazi_shared::data::Data;

use crate::{Actor, Ctx};

pub struct TabRename;

impl Actor for TabRename {
	type Options = TabRenameOpt;

	const NAME: &str = "tab_rename";

	fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
		let tab = cx.tab().id;
		let pref = &mut cx.tab_mut().pref;

		if !opt.interactive {
			pref.name = opt.name.unwrap_or_default().into_owned();
			succ!(render!());
		}

		let mut input = InputProxy::show(
			InputCfg::tab_rename().with_value(opt.name.unwrap_or(Cow::Borrowed(&pref.name))),
		);
		tokio::spawn(async move {
			if let Some(Ok(name)) = input.recv().await {
				MgrProxy::tab_rename(tab, name);
			}
		});
		succ!();
	}
}
Repository: sxyazi/yazi
File: yazi-binding/src/fd.rs (Rust)

Code before:
use mlua::{IntoLuaMulti, UserData, UserDataMethods};
use tokio::io::AsyncWriteExt;

use crate::Error;

pub struct Fd(pub yazi_vfs::provider::RwFile);

impl UserData for Fd {
	fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
		methods.add_async_method_mut("write_all", |lua, mut me, src: mlua::String| async move {
			match me.0.write_all(&*src.as_bytes()).await {
				Ok(()) => true.into_lua_multi(&lua),
				Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
			}
		});
		methods.add_async_method_mut("flush", |lua, mut me, ()| async move {
			match me.0.flush().await {
				Ok(()) => true.into_lua_multi(&lua),
				Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
			}
		});
	}
}


Review comment (suggestion):
`Fd:read(len)` allocates a `Vec<u8>` of size `len` directly from the Lua-provided argument. Since Lua code can pass arbitrarily large values here, this can lead to excessive allocations / OOM. Consider capping `len` to a reasonable maximum (or reading in fixed-size chunks internally) and returning a Lua error when the requested size exceeds the cap.

Code after:
use mlua::{IntoLuaMulti, UserData, UserDataMethods, Value};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

use crate::Error;

pub struct Fd(pub yazi_vfs::provider::RwFile);

impl UserData for Fd {
	fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
		methods.add_async_method_mut("flush", |lua, mut me, ()| async move {
			match me.0.flush().await {
				Ok(()) => true.into_lua_multi(&lua),
				Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
			}
		});
		methods.add_async_method_mut("read", |lua, mut me, len: usize| async move {
			let mut buf = vec![0; len];
			match me.0.read(&mut buf).await {
				Ok(n) => {
					buf.truncate(n);
					lua.create_external_string(buf)?.into_lua_multi(&lua)
				}
				Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
			}
		});
		methods.add_async_method_mut("write_all", |lua, mut me, src: mlua::String| async move {
			match me.0.write_all(&*src.as_bytes()).await {
				Ok(()) => true.into_lua_multi(&lua),
				Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
			}
		});
	}
}
Repository: sxyazi/yazi
File: yazi-shared/src/loc/buf.rs (Rust)

Code before:
		let Loc { inner, uri, urn, _phantom } = Loc::floated(&loc.inner, base);

		debug_assert!(inner.as_encoded_bytes() == loc.inner.as_encoded_bytes());
		Self { inner: loc.inner, uri, urn }
	}

	pub fn saturated(path: P, kind: SchemeKind) -> Self {
		let loc = Self::from(path);
		let Loc { inner, uri, urn, _phantom } = Loc::saturated(&loc.inner, kind);

		debug_assert!(inner.as_encoded_bytes() == loc.inner.as_encoded_bytes());
		Self { inner: loc.inner, uri, urn }
	}

	#[inline]
	pub fn as_loc<'a>(&'a self) -> Loc<'a, P::Borrowed<'a>> {
		Loc {
			inner:    self.inner.as_path_view(),
			uri:      self.uri,
			urn:      self.urn,
			_phantom: PhantomData,
		}
	}

	#[inline]
	pub fn to_inner(&self) -> P
	where
		P: Clone,
	{
		self.inner.clone()
	}

	#[inline]
	pub fn into_inner(self) -> P { self.inner }

	pub fn try_set_name<'a, T>(&mut self, name: T) -> Result<(), SetNameError>
	where
		T: AsStrandView<'a, P::Strand<'a>>,
	{
		let old = self.inner.len();
		self.mutate(|path| path.set_file_name(name));

		let new = self.inner.len();
		if new == old {
			return Ok(());
		}

		if self.uri != 0 {
			if new > old {
				self.uri += new - old;
			} else {

Review comment (suggestion):
`LocBuf::to_inner(&self) -> P` was removed. Since `yazi-shared` is a published crate, removing a `pub` method is an API-breaking change for downstream users even if the workspace no longer calls it. Consider keeping it as a deprecated wrapper around `self.clone().into_inner()`, or provide an equivalent non-breaking replacement and bump versioning accordingly.

Code after:
		let Loc { inner, uri, urn, _phantom } = Loc::floated(&loc.inner, base);

		debug_assert!(inner.as_encoded_bytes() == loc.inner.as_encoded_bytes());
		Self { inner: loc.inner, uri, urn }
	}

	pub fn saturated(path: P, kind: SchemeKind) -> Self {
		let loc = Self::from(path);
		let Loc { inner, uri, urn, _phantom } = Loc::saturated(&loc.inner, kind);

		debug_assert!(inner.as_encoded_bytes() == loc.inner.as_encoded_bytes());
		Self { inner: loc.inner, uri, urn }
	}

	#[inline]
	pub fn as_loc<'a>(&'a self) -> Loc<'a, P::Borrowed<'a>> {
		Loc {
			inner:    self.inner.as_path_view(),
			uri:      self.uri,
			urn:      self.urn,
			_phantom: PhantomData,
		}
	}

	#[inline]
	pub fn into_inner(self) -> P { self.inner }

	pub fn try_set_name<'a, T>(&mut self, name: T) -> Result<(), SetNameError>
	where
		T: AsStrandView<'a, P::Strand<'a>>,
	{
		let old = self.inner.len();
		self.mutate(|path| path.set_file_name(name));

		let new = self.inner.len();
		if new == old {
			return Ok(());
		}

		if self.uri != 0 {
			if new > old {
				self.uri += new - old;
			} else {
				self.uri -= old - new;
			}
		}
		if self.urn != 0 {
			if new > old {
				self.urn += new - old;
			} else {
				self.urn -= old - new;