From dac72eb39a846d15db7f1a7c54e9261675a90e53 Mon Sep 17 00:00:00 2001 From: coolkiid <73600915+coolkiid@users.noreply.github.com> Date: Sat, 10 Aug 2024 20:42:50 +0800 Subject: [PATCH] feat: start with multiple tabs with different paths (#1443) Co-authored-by: sxyazi --- cspell.json | 2 +- yazi-boot/src/args.rs | 4 +-- yazi-boot/src/boot.rs | 38 +++++++++++--------- yazi-core/src/manager/commands/tab_create.rs | 5 ++- yazi-core/src/manager/tabs.rs | 17 +++++---- 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/cspell.json b/cspell.json index ee4662c7..f858aecd 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek"],"version":"0.2","language":"en","flagWords":[]} \ No newline at end of file +{"language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds"],"version":"0.2"} \ No newline at end of file diff --git a/yazi-boot/src/args.rs b/yazi-boot/src/args.rs index 15b81b15..f2b4105a 100644 --- a/yazi-boot/src/args.rs +++ b/yazi-boot/src/args.rs @@ -6,8 +6,8 @@ use clap::{command, Parser}; #[command(name = "yazi")] pub struct Args { /// Set the current working entry - #[arg(index = 1)] - pub entry: Option, + #[arg(index = 1, num_args = 1..=9)] + pub entries: Vec, /// Write the cwd on exit to this file #[arg(long)] diff --git a/yazi-boot/src/boot.rs b/yazi-boot/src/boot.rs index 928d970f..9bbb142c 100644 --- a/yazi-boot/src/boot.rs +++ b/yazi-boot/src/boot.rs @@ -1,12 +1,12 @@ -use std::{collections::HashSet, ffi::OsString, path::{Path, PathBuf}}; +use std::{collections::HashSet, ffi::OsString, path::PathBuf}; use serde::Serialize; use yazi_shared::{fs::{current_cwd, expand_path}, Xdg}; #[derive(Debug, Default, Serialize)] pub struct Boot { - pub cwd: PathBuf, - pub file: Option, + pub cwds: Vec, + pub files: Vec, pub local_events: HashSet, pub remote_events: HashSet, @@ -18,25 +18,31 @@ pub struct Boot { } impl Boot { - fn parse_entry(entry: Option<&Path>) -> (PathBuf, Option) { - let entry = match entry { - Some(p) => expand_path(p), - None => return (current_cwd().unwrap(), None), - }; - - let parent = entry.parent(); - if parent.is_none() || entry.is_dir() { - return (entry, None); + fn parse_entries(entries: &[PathBuf]) -> (Vec, Vec) { + if entries.is_empty() { + return (vec![current_cwd().unwrap()], vec![OsString::new()]); } - (parent.unwrap().to_owned(), Some(entry.file_name().unwrap().to_owned())) + let mut cwds = Vec::with_capacity(entries.len()); + let mut files = Vec::with_capacity(entries.len()); + for entry in entries.iter().map(expand_path) { + if let Some(p) = entry.parent().filter(|_| !entry.is_dir()) { + cwds.push(p.to_owned()); + files.push(entry.file_name().unwrap().to_owned()); + } else { + cwds.push(entry); + files.push(OsString::new()); + } + } + + (cwds, files) } } impl From<&crate::Args> for Boot { fn from(args: &crate::Args) -> Self { let config_dir = Xdg::config_dir(); - let (cwd, file) = Self::parse_entry(args.entry.as_deref()); + let (cwds, files) = Self::parse_entries(&args.entries); let local_events = args .local_events @@ -50,8 +56,8 @@ impl From<&crate::Args> for Boot { .unwrap_or_default(); Self { - cwd, - file, + cwds, + files, local_events, remote_events, diff --git a/yazi-core/src/manager/commands/tab_create.rs b/yazi-core/src/manager/commands/tab_create.rs index b31814d4..d3216b1c 100644 --- a/yazi-core/src/manager/commands/tab_create.rs +++ b/yazi-core/src/manager/commands/tab_create.rs @@ -17,7 +17,10 @@ impl From for Opt { Self { url: Default::default(), current: true } } else { Self { - url: c.take_first().and_then(Data::into_url).unwrap_or_else(|| Url::from(&BOOT.cwd)), + url: c + .take_first() + .and_then(Data::into_url) + .unwrap_or_else(|| Url::from(&BOOT.cwds[0])), current: false, } } diff --git a/yazi-core/src/manager/tabs.rs b/yazi-core/src/manager/tabs.rs index 91cf11ea..a005e571 100644 --- a/yazi-core/src/manager/tabs.rs +++ b/yazi-core/src/manager/tabs.rs @@ -13,13 +13,18 @@ pub struct Tabs { impl Tabs { pub fn make() -> Self { - let mut tabs = Self { cursor: 0, items: vec![Tab::default()] }; - if let Some(file) = &BOOT.file { - tabs.items[0].reveal(Url::from(BOOT.cwd.join(file))); - } else { - tabs.items[0].cd(Url::from(&BOOT.cwd)); - } + 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]; + if file.is_empty() { + tab.cd(Url::from(&BOOT.cwds[i])); + } else { + tab.reveal(Url::from(BOOT.cwds[i].join(file))); + } + } tabs }