Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use a unique Id for each tab #1826

Merged
merged 2 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions yazi-core/src/manager/commands/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@ use std::{collections::HashSet, path::PathBuf};

use yazi_dds::Pubsub;
use yazi_macro::render;
use yazi_shared::{event::{Cmd, Data}, fs::{Url, Urn}};
use yazi_shared::{Id, event::{Cmd, Data}, fs::{Url, Urn}};

use crate::manager::Manager;

struct Opt {
url: Option<Url>,
tab: Option<usize>,
tab: Option<Id>,
}

impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self {
url: c.take_first().and_then(Data::into_url),
tab: c.get("tab").and_then(Data::as_usize),
}
Self { url: c.take_first().and_then(Data::into_url), tab: c.get("tab").and_then(Data::as_id) }
}
}
impl From<Option<Url>> for Opt {
Expand Down Expand Up @@ -49,10 +46,10 @@ impl Manager {
self.watcher.watch(to_watch);

// Publish through DDS
Pubsub::pub_from_hover(self.active().idx, self.hovered().map(|h| &h.url));
Pubsub::pub_from_hover(self.active().id, self.hovered().map(|h| &h.url));
}

fn hover_do(&mut self, url: Url, tab: Option<usize>) {
fn hover_do(&mut self, url: Url, tab: Option<Id>) {
// Hover on the file
if let Ok(p) = url.strip_prefix(&self.current_or(tab).url).map(PathBuf::from) {
render!(self.current_or_mut(tab).repos(Some(Urn::new(&p))));
Expand Down
1 change: 0 additions & 1 deletion yazi-core/src/manager/commands/tab_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ impl Tabs {
self.set_idx(self.absolute(1));
}

self.reorder();
render!();
}
}
4 changes: 1 addition & 3 deletions yazi-core/src/manager/commands/tab_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ impl Tabs {
return;
}

let mut tab = Tab { idx: self.cursor + 1, ..Default::default() };

let mut tab = Tab::default();
if !opt.current {
tab.cd(opt.url);
} else if let Some(h) = self.active().hovered() {
Expand All @@ -52,7 +51,6 @@ impl Tabs {

self.items.insert(self.cursor + 1, tab);
self.set_idx(self.cursor + 1);
self.reorder();
render!();
}
}
1 change: 0 additions & 1 deletion yazi-core/src/manager/commands/tab_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ impl Tabs {

self.items.swap(self.cursor, idx);
self.set_idx(idx);
self.reorder();
render!();
}
}
2 changes: 1 addition & 1 deletion yazi-core/src/manager/commands/update_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl Manager {
return;
}

ManagerProxy::hover(None, tab.idx); // Re-hover in next loop
ManagerProxy::hover(None, tab.id); // Re-hover in next loop
ManagerProxy::update_paged(); // Update for paged files in next loop
if calc {
tasks.prework_sorted(&tab.current.files);
Expand Down
10 changes: 5 additions & 5 deletions yazi-core/src/manager/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use ratatui::layout::Rect;
use yazi_adapter::Dimension;
use yazi_config::popup::{Origin, Position};
use yazi_fs::Folder;
use yazi_shared::fs::{File, Url};
use yazi_shared::{Id, fs::{File, Url}};

use super::{Mimetype, Tabs, Watcher, Yanked};
use crate::tab::Tab;
Expand Down Expand Up @@ -48,10 +48,10 @@ impl Manager {
pub fn active_mut(&mut self) -> &mut Tab { self.tabs.active_mut() }

#[inline]
pub fn active_or(&self, idx: Option<usize>) -> &Tab { self.tabs.active_or(idx) }
pub fn active_or(&self, id: Option<Id>) -> &Tab { self.tabs.active_or(id) }

#[inline]
pub fn active_or_mut(&mut self, idx: Option<usize>) -> &mut Tab { self.tabs.active_or_mut(idx) }
pub fn active_or_mut(&mut self, id: Option<Id>) -> &mut Tab { self.tabs.active_or_mut(id) }

#[inline]
pub fn current(&self) -> &Folder { &self.active().current }
Expand All @@ -60,10 +60,10 @@ impl Manager {
pub fn current_mut(&mut self) -> &mut Folder { &mut self.active_mut().current }

#[inline]
pub fn current_or(&self, idx: Option<usize>) -> &Folder { &self.active_or(idx).current }
pub fn current_or(&self, idx: Option<Id>) -> &Folder { &self.active_or(idx).current }

#[inline]
pub fn current_or_mut(&mut self, idx: Option<usize>) -> &mut Folder {
pub fn current_or_mut(&mut self, idx: Option<Id>) -> &mut Folder {
&mut self.active_or_mut(idx).current
}

Expand Down
18 changes: 6 additions & 12 deletions yazi-core/src/manager/tabs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut};
use yazi_boot::BOOT;
use yazi_dds::Pubsub;
use yazi_proxy::ManagerProxy;
use yazi_shared::fs::Url;
use yazi_shared::{Id, fs::Url};

use crate::tab::Tab;

Expand All @@ -16,7 +16,6 @@ impl Tabs {
pub fn make() -> Self {
let mut tabs =
Self { cursor: 0, items: (0..BOOT.cwds.len()).map(|_| Tab::default()).collect() };
tabs.reorder();

for (i, tab) in tabs.iter_mut().enumerate() {
let file = &BOOT.files[i];
Expand All @@ -37,11 +36,6 @@ impl Tabs {
}
}

#[inline]
pub(super) fn reorder(&mut self) {
self.items.iter_mut().enumerate().for_each(|(i, tab)| tab.idx = i);
}

pub(super) fn set_idx(&mut self, idx: usize) {
// Reset the preview of the last active tab
if let Some(active) = self.items.get_mut(self.cursor) {
Expand All @@ -63,16 +57,16 @@ impl Tabs {
pub(super) fn active_mut(&mut self) -> &mut Tab { &mut self.items[self.cursor] }

#[inline]
pub fn active_or(&self, idx: Option<usize>) -> &Tab {
idx.and_then(|i| self.items.get(i)).unwrap_or(&self.items[self.cursor])
pub fn active_or(&self, id: Option<Id>) -> &Tab {
id.and_then(|id| self.iter().find(|&t| t.id == id)).unwrap_or(self.active())
}

#[inline]
pub(super) fn active_or_mut(&mut self, idx: Option<usize>) -> &mut Tab {
if let Some(i) = idx.filter(|&i| i < self.items.len()) {
pub(super) fn active_or_mut(&mut self, id: Option<Id>) -> &mut Tab {
if let Some(i) = id.and_then(|id| self.iter().position(|t| t.id == id)) {
&mut self.items[i]
} else {
&mut self.items[self.cursor]
self.active_mut()
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/tab/commands/arrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Tab {
}
}

ManagerProxy::hover(None, self.idx);
ManagerProxy::hover(None, self.id);
render!();
}
}
2 changes: 1 addition & 1 deletion yazi-core/src/tab/commands/cd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl Tab {
self.backstack.push(opt.target.clone());
}

Pubsub::pub_from_cd(self.idx, self.cwd());
Pubsub::pub_from_cd(self.id, self.cwd());
ManagerProxy::refresh();
render!();
}
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/tab/commands/filter_do.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl Tab {

self.current.repos(hovered.as_ref().map(|u| u.as_urn()));
if self.hovered().map(|f| f.urn()) != hovered.as_ref().map(|u| u.as_urn()) {
ManagerProxy::hover(None, self.idx);
ManagerProxy::hover(None, self.id);
}

render!();
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/tab/commands/hidden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Tab {
self.apply_files_attrs();

if hovered.as_ref() != self.hovered().map(|f| &f.url) {
ManagerProxy::hover(hovered, self.idx);
ManagerProxy::hover(hovered, self.id);
} else if self.hovered().is_some_and(|f| f.is_dir()) {
ManagerProxy::peek(true);
}
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/tab/commands/reveal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ impl Tab {

self.cd(parent.clone());
FilesOp::Creating(parent, vec![File::from_dummy(opt.target.clone(), None)]).emit();
ManagerProxy::hover(Some(opt.target), self.idx);
ManagerProxy::hover(Some(opt.target), self.id);
}
}
27 changes: 24 additions & 3 deletions yazi-core/src/tab/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ use yazi_adapter::Dimension;
use yazi_config::{LAYOUT, popup::{Origin, Position}};
use yazi_fs::{Folder, FolderStage};
use yazi_macro::render;
use yazi_shared::fs::{File, Url};
use yazi_shared::{Id, Ids, fs::{File, Url}};

use super::{Backstack, Config, Finder, History, Mode, Preview};
use crate::tab::Selected;

#[derive(Default)]
pub struct Tab {
pub idx: usize,
pub id: Id,
pub mode: Mode,
pub conf: Config,
pub current: Folder,
Expand All @@ -29,6 +28,28 @@ pub struct Tab {
pub search: Option<JoinHandle<Result<()>>>,
}

impl Default for Tab {
fn default() -> Self {
static IDS: Ids = Ids::new();

Self {
id: IDS.next(),
mode: Default::default(),
conf: Default::default(),
current: Default::default(),
parent: Default::default(),

backstack: Default::default(),
history: Default::default(),
selected: Default::default(),

preview: Default::default(),
finder: Default::default(),
search: Default::default(),
}
}
}

impl Tab {
pub fn shutdown(&mut self) {
if let Some(handle) = self.search.take() {
Expand Down
12 changes: 6 additions & 6 deletions yazi-dds/src/body/cd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ use std::borrow::Cow;

use mlua::{IntoLua, Lua, Value};
use serde::{Deserialize, Serialize};
use yazi_shared::fs::Url;
use yazi_shared::{Id, fs::Url};

use super::Body;

#[derive(Debug, Serialize, Deserialize)]
pub struct BodyCd<'a> {
pub tab: usize,
pub tab: Id,
pub url: Cow<'a, Url>,
#[serde(skip)]
dummy: bool,
}

impl<'a> BodyCd<'a> {
#[inline]
pub fn borrowed(tab: usize, url: &'a Url) -> Body<'a> {
pub fn borrowed(tab: Id, url: &'a Url) -> Body<'a> {
Self { tab, url: Cow::Borrowed(url), dummy: false }.into()
}
}

impl BodyCd<'static> {
#[inline]
pub fn dummy(tab: usize) -> Body<'static> {
pub fn dummy(tab: Id) -> Body<'static> {
Self { tab, url: Default::default(), dummy: true }.into()
}
}
Expand All @@ -36,11 +36,11 @@ impl IntoLua<'_> for BodyCd<'static> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
if let Some(Cow::Owned(url)) = Some(self.url).filter(|_| !self.dummy) {
lua.create_table_from([
("tab", self.tab.into_lua(lua)?),
("tab", self.tab.get().into_lua(lua)?),
("url", lua.create_any_userdata(url)?.into_lua(lua)?),
])?
} else {
lua.create_table_from([("tab", self.tab)])?
lua.create_table_from([("tab", self.tab.get())])?
}
.into_lua(lua)
}
Expand Down
12 changes: 6 additions & 6 deletions yazi-dds/src/body/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ use std::borrow::Cow;

use mlua::{IntoLua, Lua, Value};
use serde::{Deserialize, Serialize};
use yazi_shared::fs::Url;
use yazi_shared::{Id, fs::Url};

use super::Body;

#[derive(Debug, Serialize, Deserialize)]
pub struct BodyHover<'a> {
pub tab: usize,
pub tab: Id,
pub url: Option<Cow<'a, Url>>,
}

impl<'a> BodyHover<'a> {
#[inline]
pub fn borrowed(tab: usize, url: Option<&'a Url>) -> Body<'a> {
pub fn borrowed(tab: Id, url: Option<&'a Url>) -> Body<'a> {
Self { tab, url: url.map(Cow::Borrowed) }.into()
}
}

impl BodyHover<'static> {
#[inline]
pub fn dummy(tab: usize) -> Body<'static> { Self { tab, url: None }.into() }
pub fn dummy(tab: Id) -> Body<'static> { Self { tab, url: None }.into() }
}

impl<'a> From<BodyHover<'a>> for Body<'a> {
Expand All @@ -32,11 +32,11 @@ impl IntoLua<'_> for BodyHover<'static> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
if let Some(Cow::Owned(url)) = self.url {
lua.create_table_from([
("tab", self.tab.into_lua(lua)?),
("tab", self.tab.get().into_lua(lua)?),
("url", lua.create_any_userdata(url)?.into_lua(lua)?),
])?
} else {
lua.create_table_from([("tab", self.tab)])?
lua.create_table_from([("tab", self.tab.get())])?
}
.into_lua(lua)
}
Expand Down
6 changes: 3 additions & 3 deletions yazi-dds/src/pubsub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet};
use mlua::Function;
use parking_lot::RwLock;
use yazi_boot::BOOT;
use yazi_shared::{RoCell, fs::Url};
use yazi_shared::{Id, RoCell, fs::Url};

use crate::{Client, ID, PEERS, body::{Body, BodyBulk, BodyCd, BodyDelete, BodyHi, BodyHover, BodyMove, BodyMoveItem, BodyRename, BodyTab, BodyTrash, BodyYank}};

Expand Down Expand Up @@ -88,7 +88,7 @@ impl Pubsub {
true
}

pub fn pub_from_cd(tab: usize, url: &Url) {
pub fn pub_from_cd(tab: Id, url: &Url) {
if LOCAL.read().contains_key("cd") {
Self::pub_(BodyCd::dummy(tab));
}
Expand All @@ -100,7 +100,7 @@ impl Pubsub {
}
}

pub fn pub_from_hover(tab: usize, url: Option<&Url>) {
pub fn pub_from_hover(tab: Id, url: Option<&Url>) {
if LOCAL.read().contains_key("hover") {
Self::pub_(BodyHover::dummy(tab));
}
Expand Down
2 changes: 1 addition & 1 deletion yazi-fm/src/lives/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl Tab {

pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
lua.register_userdata_type::<Self>(|reg| {
reg.add_field_method_get("idx", |_, me| Ok(me.idx + 1));
reg.add_field_method_get("id", |_, me| Ok(me.id.get()));
reg.add_method("name", |lua, me, ()| {
lua.create_string(me.current.url.name().as_encoded_bytes())
});
Expand Down
Loading