summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2022-11-17 19:42:39 -0500
committerJeff Zhao <jeff.no.zhao@gmail.com>2022-11-20 14:16:59 -0500
commit5d4cc2dd61b91db28aa127347450a05cb0f2d45d (patch)
treef4f899c8417070b718a035b3eb914fca0461aee8 /src
parent75081aae369feb8e71977701ec9cb467e2b166ba (diff)
add bookmark support
Diffstat (limited to 'src')
-rw-r--r--src/commands/bookmark.rs135
-rw-r--r--src/commands/mod.rs1
-rw-r--r--src/commands/show_tasks.rs3
-rw-r--r--src/config/bookmarks/bookmarks.rs37
-rw-r--r--src/config/bookmarks/bookmarks_raw.rs13
-rw-r--r--src/config/bookmarks/mod.rs5
-rw-r--r--src/config/general/display_raw.rs7
-rw-r--r--src/config/general/preview_raw.rs38
-rw-r--r--src/config/general/sort_raw.rs8
-rw-r--r--src/config/general/tab_raw.rs8
-rw-r--r--src/config/mod.rs4
-rw-r--r--src/config/option/display_option.rs11
-rw-r--r--src/config/option/sort_type.rs2
-rw-r--r--src/event/process_event.rs2
-rw-r--r--src/key_command/command.rs3
-rw-r--r--src/key_command/constants.rs2
-rw-r--r--src/key_command/impl_appcommand.rs3
-rw-r--r--src/key_command/impl_appexecute.rs3
-rw-r--r--src/key_command/impl_comment.rs3
-rw-r--r--src/key_command/impl_from_str.rs19
-rw-r--r--src/key_command/impl_interactive.rs1
-rw-r--r--src/main.rs9
-rw-r--r--src/run.rs3
-rw-r--r--src/tab/homepage.rs11
-rw-r--r--src/util/unix.rs8
25 files changed, 284 insertions, 55 deletions
diff --git a/src/commands/bookmark.rs b/src/commands/bookmark.rs
new file mode 100644
index 0000000..6c13752
--- /dev/null
+++ b/src/commands/bookmark.rs
@@ -0,0 +1,135 @@
+use std::fs::File;
+use std::io::Write;
+
+use termion::event::Event;
+use tui::layout::Rect;
+use tui::widgets::Clear;
+
+use crate::config::{search_directories, BookmarkRaw, BookmarksRaw};
+use crate::context::AppContext;
+use crate::error::JoshutoResult;
+use crate::event::{process_event, AppEvent};
+use crate::traits::ToString;
+use crate::ui::views::TuiView;
+use crate::ui::widgets::TuiMenu;
+use crate::ui::AppBackend;
+use crate::util::unix;
+
+use crate::{BOOKMARKS_FILE, BOOKMARKS_T, CONFIG_HIERARCHY};
+
+use super::change_directory::change_directory;
+
+pub fn add_bookmark(context: &mut AppContext, backend: &mut AppBackend) -> JoshutoResult {
+ let cwd = std::env::current_dir()?;
+
+ let bookmark_path = match search_directories(BOOKMARKS_FILE, &CONFIG_HIERARCHY) {
+ Some(file_path) => Some(file_path),
+ None => {
+ for p in CONFIG_HIERARCHY.iter() {
+ if p.exists() {
+ Some(p.clone());
+ }
+ }
+ None
+ }
+ };
+
+ if let Some(bookmark_path) = bookmark_path {
+ let key = poll_for_bookmark_key(context, backend);
+ if let Some(key) = key {
+ if let Ok(mut bookmark) = BOOKMARKS_T.lock() {
+ bookmark.insert(key, cwd.to_string_lossy().to_string());
+ }
+ let new_bookmarks_vec: Vec<BookmarkRaw> = BOOKMARKS_T
+ .lock()
+ .unwrap()
+ .clone()
+ .drain()
+ .map(|(k, v)| BookmarkRaw {
+ key: k.to_string(),
+ path: v,
+ })
+ .collect();
+ let bookmarks_raw = BookmarksRaw {
+ bookmark: new_bookmarks_vec,
+ };
+
+ if let Ok(content) = toml::to_string(&bookmarks_raw) {
+ let mut file = File::create(bookmark_path)?;
+ file.write_all(content.as_bytes())?;
+ }
+ }
+ }
+
+ Ok(())
+}
+
+pub fn change_directory_bookmark(
+ context: &mut AppContext,
+ backend: &mut AppBackend,
+) -> JoshutoResult {
+ let key = poll_for_bookmark_key(context, backend);
+
+ if let Some(key) = key {
+ if let Ok(bookmarks) = BOOKMARKS_T.lock() {
+ if let Some(p) = bookmarks.get(&key) {
+ let path = unix::expand_shell_string(p);
+ change_directory(context, &path)?;
+ }
+ }
+ }
+ Ok(())
+}
+
+fn poll_for_bookmark_key<'a>(context: &mut AppContext, backend: &mut AppBackend) -> Option<Event> {
+ context.flush_event();
+
+ let mut bookmarks: Vec<String> = BOOKMARKS_T
+ .lock()
+ .unwrap()
+ .iter()
+ .map(|(k, v)| format!(" {} {:?}", k.to_string(), v))
+ .collect();
+ bookmarks.sort();
+ let bookmarks_str: Vec<&str> = bookmarks.iter().map(|s| s.as_str()).collect();
+
+ let terminal = backend.terminal_mut();
+ loop {
+ let _ = terminal.draw(|frame| {
+ let area = frame.size();
+ if area.height < 5 {
+ return;
+ }
+ // redraw view
+ {
+ let mut view = TuiView::new(context);
+ view.show_bottom_status = false;
+ frame.render_widget(view, area);
+ }
+
+ let menu_widget = TuiMenu::new(bookmarks_str.as_slice());
+ let menu_len = menu_widget.len();
+ let menu_y = if menu_len + 1 > area.height as usize {
+ 0
+ } else {
+ (area.height as usize - menu_len - 1) as u16
+ };
+
+ let menu_rect = Rect {
+ x: 0,
+ y: menu_y - 1,
+ width: area.width,
+ height: menu_len as u16 + 1,
+ };
+ frame.render_widget(Clear, menu_rect);
+ frame.render_widget(menu_widget, menu_rect);
+ });
+
+ if let Ok(event) = context.poll_event() {
+ match event {
+ AppEvent::Termion(key) => return Some(key),
+ event => process_event::process_noninteractive(event, context),
+ };
+ }
+ }
+}
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index cf7ef53..5489a1c 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -1,3 +1,4 @@
+pub mod bookmark;
pub mod bulk_rename;
pub mod change_directory;
pub mod command_line;
diff --git a/src/commands/show_tasks.rs b/src/commands/show_tasks.rs
index 9dd8ddf..ea5f310 100644
--- a/src/commands/show_tasks.rs
+++ b/src/commands/show_tasks.rs
@@ -34,7 +34,8 @@ pub fn show_tasks(
}
}
Some(CommandKeybind::CompositeKeybind(m)) => {
- let cmd = process_event::get_input_while_composite(backend, context, m);
+ let cmd =
+ process_event::poll_event_until_simple_keybind(backend, context, m);
if let Some(Command::ShowTasks) = cmd {
break;
diff --git a/src/config/bookmarks/bookmarks.rs b/src/config/bookmarks/bookmarks.rs
new file mode 100644
index 0000000..a1d03a8
--- /dev/null
+++ b/src/config/bookmarks/bookmarks.rs
@@ -0,0 +1,37 @@
+use std::collections::HashMap;
+
+use termion::event::Event;
+
+use crate::config::{parse_to_config_file, TomlConfigFile};
+use crate::util::keyparse;
+
+use super::bookmarks_raw::BookmarksRaw;
+
+pub type Bookmarks = HashMap<Event, String>;
+
+impl From<BookmarksRaw> for Bookmarks {
+ fn from(raw: BookmarksRaw) -> Self {
+ let mut raw = raw;
+ let map: Bookmarks = raw
+ .bookmark
+ .drain(..)
+ .filter_map(|bookmark| match keyparse::str_to_event(&bookmark.key) {
+ Some(event) => Some((event, bookmark.path)),
+ None => None,
+ })
+ .collect();
+ map
+ }
+}
+
+impl TomlConfigFile for Bookmarks {
+ fn get_config(file_name: &str) -> Self {
+ match parse_to_config_file::<BookmarksRaw, Bookmarks>(file_name) {
+ Ok(s) => s,
+ Err(e) => {
+ eprintln!("Failed to parse app config: {}", e);
+ Self::default()
+ }
+ }
+ }
+}
diff --git a/src/config/bookmarks/bookmarks_raw.rs b/src/config/bookmarks/bookmarks_raw.rs
new file mode 100644
index 0000000..ba08430
--- /dev/null
+++ b/src/config/bookmarks/bookmarks_raw.rs
@@ -0,0 +1,13 @@
+use serde_derive::{Deserialize, Serialize};
+
+#[derive(Clone, Debug, Serialize, Deserialize)]
+pub struct BookmarkRaw {
+ pub key: String,
+ pub path: String,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize)]
+pub struct BookmarksRaw {
+ #[serde(default)]
+ pub bookmark: Vec<BookmarkRaw>,
+}
diff --git a/src/config/bookmarks/mod.rs b/src/config/bookmarks/mod.rs
new file mode 100644
index 0000000..050ac70
--- /dev/null
+++ b/src/config/bookmarks/mod.rs
@@ -0,0 +1,5 @@
+pub mod bookmarks;
+pub mod bookmarks_raw;
+
+pub use self::bookmarks::*;
+pub use self::bookmarks_raw::*;
diff --git a/src/config/general/display_raw.rs b/src/config/general/display_raw.rs
index a4edf1c..b6b8a89 100644
--- a/src/config/general/display_raw.rs
+++ b/src/config/general/display_raw.rs
@@ -105,11 +105,8 @@ impl From<DisplayOptionRaw> for DisplayOption {
Constraint::Ratio(0, total),
];
- let _line_nums = match raw.line_number_style.as_ref() {
- "absolute" => LineNumberStyle::Absolute,
- "relative" => LineNumberStyle::Relative,
- _ => LineNumberStyle::None,
- };
+ let _line_nums = LineNumberStyle::from_str(raw.line_number_style.as_str())
+ .unwrap_or_else(|| LineNumberStyle::None);
Self {
_mode: mode,
diff --git a/src/config/general/preview_raw.rs b/src/config/general/preview_raw.rs
index 6fb4e05..9204b5d 100644
--- a/src/config/general/preview_raw.rs
+++ b/src/config/general/preview_raw.rs
@@ -1,10 +1,10 @@
use std::convert::From;
-use std::path;
use serde_derive::Deserialize;
use crate::config::option::PreviewOption;
use crate::config::search_directories;
+use crate::util::unix;
use crate::CONFIG_HIERARCHY;
pub const fn default_max_preview_size() -> u64 {
@@ -36,30 +36,18 @@ impl std::default::Default for PreviewOptionRaw {
impl From<PreviewOptionRaw> for PreviewOption {
fn from(raw: PreviewOptionRaw) -> Self {
- let preview_script = match raw.preview_script {
- Some(s) => {
- let tilde_cow = shellexpand::tilde_with_context(s.as_str(), dirs_next::home_dir);
- let tilde_path = path::PathBuf::from(tilde_cow.as_ref());
- Some(tilde_path)
- }
- None => search_directories("preview.sh", &CONFIG_HIERARCHY),
- };
- let preview_shown_hook_script = match raw.preview_shown_hook_script {
- Some(s) => {
- let tilde_cow = shellexpand::tilde_with_context(s.as_str(), dirs_next::home_dir);
- let tilde_path = path::PathBuf::from(tilde_cow.as_ref());
- Some(tilde_path)
- }
- None => None,
- };
- let preview_removed_hook_script = match raw.preview_removed_hook_script {
- Some(s) => {
- let tilde_cow = shellexpand::tilde_with_context(s.as_str(), dirs_next::home_dir);
- let tilde_path = path::PathBuf::from(tilde_cow.as_ref());
- Some(tilde_path)
- }
- None => None,
- };
+ let preview_script = raw
+ .preview_script
+ .map(|s| unix::expand_shell_string(&s))
+ .or_else(|| search_directories("preview.sh", &CONFIG_HIERARCHY));
+
+ let preview_shown_hook_script = raw
+ .preview_shown_hook_script
+ .map(|s| unix::expand_shell_string(&s));
+
+ let preview_removed_hook_script = raw
+ .preview_removed_hook_script
+ .map(|s| unix::expand_shell_string(&s));
Self {
max_preview_size: raw.max_preview_size,
diff --git a/src/config/general/sort_raw.rs b/src/config/general/sort_raw.rs
index a75a9a5..2331534 100644
--- a/src/config/general/sort_raw.rs
+++ b/src/config/general/sort_raw.rs
@@ -33,10 +33,10 @@ impl std::default::Default for SortOptionRaw {
impl From<SortOptionRaw> for SortOption {
fn from(raw: SortOptionRaw) -> Self {
- let sort_method = match raw.sort_method.as_ref() {
- Some(s) => SortType::parse(s).unwrap_or(SortType::Natural),
- None => SortType::Natural,
- };
+ let sort_method = raw
+ .sort_method
+ .and_then(|s| SortType::from_str(&s))
+ .unwrap_or(SortType::Natural);
let mut sort_methods = SortTypes::default();
sort_methods.reorganize(sort_method);
diff --git a/src/config/general/tab_raw.rs b/src/config/general/tab_raw.rs
index 193c30d..9053a7c 100644
--- a/src/config/general/tab_raw.rs
+++ b/src/config/general/tab_raw.rs
@@ -25,12 +25,8 @@ impl std::default::Default for TabOptionRaw {
impl From<TabOptionRaw> for TabOption {
fn from(raw: TabOptionRaw) -> Self {
- let home_page = match raw.home_page.as_str() {
- "inherit" => TabHomePage::Inherit,
- "home" => TabHomePage::Home,
- "root" => TabHomePage::Root,
- _ => TabHomePage::Home,
- };
+ let home_page =
+ TabHomePage::from_str(raw.home_page.as_str()).unwrap_or_else(|| TabHomePage::Home);
Self::new(home_page)
}
diff --git a/src/config/mod.rs b/src/config/mod.rs
index fde1759..48f7ef0 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -1,3 +1,4 @@
+pub mod bookmarks;
pub mod general;
pub mod keymap;
pub mod mimetype;
@@ -5,7 +6,8 @@ pub mod option;
pub mod preview;
pub mod theme;
-pub use self::general::AppConfig;
+pub use self::bookmarks::*;
+pub use self::general::*;
pub use self::keymap::*;
pub use self::mimetype::*;
pub use self::preview::*;
diff --git a/src/config/option/display_option.rs b/src/config/option/display_option.rs
index a339d23..eaeb971 100644
--- a/src/config/option/display_option.rs
+++ b/src/config/option/display_option.rs
@@ -55,6 +55,17 @@ pub enum LineNumberStyle {
Absolute,
}
+impl LineNumberStyle {
+ pub fn from_str(s: &str) -> Option<Self> {
+ match s {
+ "absolute" => Some(Self::Absolute),
+ "relative" => Some(Self::Relative),
+ "none" => Some(Self::None),
+ _ => None,
+ }
+ }
+}
+
impl DirListDisplayOptions {
pub fn set_filter_string(&mut self, pattern: &str) {
self.filter_string = pattern.to_owned();
diff --git a/src/config/option/sort_type.rs b/src/config/option/sort_type.rs
index a00ad29..e8f5d29 100644
--- a/src/config/option/sort_type.rs
+++ b/src/config/option/sort_type.rs
@@ -18,7 +18,7 @@ pub enum SortType {
}
impl SortType {
- pub fn parse(s: &str) -> Option<Self> {
+ pub fn from_str(s: &str) -> Option<Self> {
match s {
"lexical" => Some(SortType::Lexical),
"mtime" => Some(SortType::Mtime),
diff --git a/src/event/process_event.rs b/src/event/process_event.rs
index 4f566ea..c207740 100644
--- a/src/event/process_event.rs
+++ b/src/event/process_event.rs
@@ -21,7 +21,7 @@ use crate::ui;
use crate::ui::views::TuiCommandMenu;
use crate::util::format;
-pub fn get_input_while_composite<'a>(
+pub fn poll_event_until_simple_keybind<'a>(
backend: &mut ui::AppBackend,
context: &mut AppContext,
keymap: &'a KeyMapping,
diff --git a/src/key_command/command.rs b/src/key_command/command.rs
index 6b2c389..d31aea6 100644
--- a/src/key_command/command.rs
+++ b/src/key_command/command.rs
@@ -145,4 +145,7 @@ pub enum Command {
SubdirFzf,
Zoxide(String),
ZoxideInteractive,
+
+ BookmarkAdd,
+ BookmarkChangeDirectory,
}
diff --git a/src/key_command/constants.rs b/src/key_command/constants.rs
index 5ec08d3..28b11ea 100644
--- a/src/key_command/constants.rs
+++ b/src/key_command/constants.rs
@@ -83,6 +83,8 @@ cmd_constants![
(CMD_FLAT, "flat"),
(CMD_ESCAPE, "escape"),
(CMD_FILTER, "filter"),
+ (CMD_BOOKMARK_ADD, "add_bookmark"),
+ (CMD_BOOKMARK_CHANGE_DIRECTORY, "cd_bookmark"),
];
pub fn complete_command(partial_command: &str) -> Vec<Pair> {
diff --git a/src/key_command/impl_appcommand.rs b/src/key_command/impl_appcommand.rs
index f267fea..cf4ce6d 100644
--- a/src/key_command/impl_appcommand.rs
+++ b/src/key_command/impl_appcommand.rs
@@ -91,6 +91,9 @@ impl AppCommand for Command {
Self::SubdirFzf => CMD_SUBDIR_FZF,
Self::Zoxide(_) => CMD_ZOXIDE,
Self::ZoxideInteractive => CMD_ZOXIDE_INTERACTIVE,
+
+ Self::BookmarkAdd => CMD_BOOKMARK_ADD,
+ Self::BookmarkChangeDirectory => CMD_BOOKMARK_CHANGE_DIRECTORY,
}
}
}
diff --git a/src/key_command/impl_appexecute.rs b/src/key_command/impl_appexecute.rs
index 52a3ae3..f9b34df 100644
--- a/src/key_command/impl_appexecute.rs
+++ b/src/key_command/impl_appexecute.rs
@@ -141,6 +141,9 @@ impl AppExecute for Command {
Self::SubdirFzf => subdir_fzf::subdir_fzf(context, backend),
Self::Zoxide(arg) => zoxide::zoxide_query(context, arg),
Self::ZoxideInteractive => zoxide::zoxide_query_interactive(context, backend),
+
+ Self::BookmarkAdd => bookmark::add_bookmark(context, backend),
+ Self::BookmarkChangeDirectory => bookmark::change_directory_bookmark(context, backend),
}
}
}
diff --git a/src/key_command/impl_comment.rs b/src/key_command/impl_comment.rs
index e1d004a..8d8eeb7 100644
--- a/src/key_command/impl_comment.rs
+++ b/src/key_command/impl_comment.rs
@@ -122,6 +122,9 @@ impl CommandComment for Command {
Self::SubdirFzf => "Switch to a child directory via fzf",
Self::Zoxide(_) => "Zoxide",
Self::ZoxideInteractive => "Zoxide interactive",
+
+ Self::BookmarkAdd => "Add a bookmark",
+ Self::BookmarkChangeDirectory => "Navigate to a bookmark",
}
}
}
diff --git a/src/key_command/impl_from_str.rs b/src/key_command/impl_from_str.rs
index 5cb6f29..563581a 100644
--- a/src/key_command/impl_from_str.rs
+++ b/src/key_command/impl_from_str.rs
@@ -1,12 +1,10 @@
use std::path;
-use dirs_next::home_dir;
-use shellexpand::tilde_with_context;
-
use crate::commands::quit::QuitAction;
use crate::config::option::{LineMode, LineNumberStyle, SelectOption, SortType};
use crate::error::{JoshutoError, JoshutoErrorKind};
use crate::io::FileOperationOptions;
+use crate::util::unix;
use crate::HOME_DIR;
@@ -46,9 +44,15 @@ impl std::str::FromStr for Command {
simple_command_conversion_case!(command, CMD_HELP, Self::Help);
+ simple_command_conversion_case!(command, CMD_BOOKMARK_ADD, Self::BookmarkAdd);
+ simple_command_conversion_case!(
+ command,
+ CMD_BOOKMARK_CHANGE_DIRECTORY,
+ Self::BookmarkChangeDirectory
+ );
+
simple_command_conversion_case!(command, CMD_CURSOR_MOVE_HOME, Self::CursorMoveHome);
simple_command_conversion_case!(command, CMD_CURSOR_MOVE_END, Self::CursorMoveEnd);
-
simple_command_conversion_case!(
command,
CMD_CURSOR_MOVE_PAGEHOME,
@@ -109,9 +113,8 @@ impl std::str::FromStr for Command {
".." => Ok(Self::ParentDirectory),
"-" => Ok(Self::PreviousDirectory),
arg => {
- let path_accepts_tilde = tilde_with_context(arg, home_dir);
- let path = path::PathBuf::from(path_accepts_tilde.as_ref());
- Ok(Self::ChangeDirectory { path })
+ let new_path = unix::expand_shell_string(arg);
+ Ok(Self::ChangeDirectory { path: new_path })
}
}
} else if command == CMD_CURSOR_MOVE_DOWN {
@@ -327,7 +330,7 @@ impl std::str::FromStr for Command {
} else if command == CMD_SORT {
match arg {
"reverse" => Ok(Self::SortReverse),
- arg => match SortType::parse(arg) {
+ arg => match SortType::from_str(arg) {
Some(s) => Ok(Self::Sort(s)),
None => Err(JoshutoError::new(
JoshutoErrorKind::InvalidParameters,
diff --git a/src/key_command/impl_interactive.rs b/src/key_command/impl_interactive.rs
index 8171ecb..de9664d 100644
--- a/src/key_command/impl_interactive.rs
+++ b/src/key_command/impl_interactive.rs
@@ -4,7 +4,6 @@ use crate::context::AppContext;
use super::{Command, InteractiveExecute};
impl InteractiveExecute for Command {
- #[allow(clippy::single_match)]
fn interactive_execute(&self, context: &mut AppContext) {
match self {
Self::SearchIncremental { pattern } => {
diff --git a/src/main.rs b/src/main.rs
index 1446474..8b73081 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,22 +19,26 @@ use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use std::process;
+use std::sync::Mutex;
use structopt::StructOpt;
use crate::commands::quit::QuitAction;
use crate::config::{
- AppConfig, AppKeyMapping, AppProgramRegistry, AppTheme, JoshutoPreview, TomlConfigFile,
+ AppConfig, AppKeyMapping, AppProgramRegistry, AppTheme, Bookmarks, JoshutoPreview,
+ TomlConfigFile,
};
use crate::context::AppContext;
use crate::error::JoshutoError;
const PROGRAM_NAME: &str = "joshuto";
const CONFIG_HOME: &str = "JOSHUTO_CONFIG_HOME";
+
const CONFIG_FILE: &str = "joshuto.toml";
const MIMETYPE_FILE: &str = "mimetype.toml";
const KEYMAP_FILE: &str = "keymap.toml";
const THEME_FILE: &str = "theme.toml";
const PREVIEW_FILE: &str = "preview.toml";
+const BOOKMARKS_FILE: &str = "bookmarks.toml";
lazy_static! {
// dynamically builds the config hierarchy
@@ -69,6 +73,7 @@ lazy_static! {
static ref THEME_T: AppTheme = AppTheme::get_config(THEME_FILE);
static ref MIMETYPE_T: AppProgramRegistry = AppProgramRegistry::get_config(MIMETYPE_FILE);
static ref PREVIEW_T: JoshutoPreview = JoshutoPreview::get_config(PREVIEW_FILE);
+ static ref BOOKMARKS_T: Mutex<Bookmarks> = Mutex::new(Bookmarks::get_config(BOOKMARKS_FILE));
static ref HOME_DIR: Option<PathBuf> = dirs_next::home_dir();
static ref USERNAME: String = whoami::username();
@@ -107,6 +112,8 @@ fn run_main(args: Args) -> Result<i32, JoshutoError> {
lazy_static::initialize(&THEME_T);
lazy_static::initialize(&MIMETYPE_T);
lazy_static::initialize(&PREVIEW_T);
+ lazy_static::initialize(&BOOKMARKS_T);
+
lazy_static::initialize(&HOME_DIR);
lazy_static::initialize(&USERNAME);
lazy_static::initialize(&HOSTNAME);
diff --git a/src/run.rs b/src/run.rs
index 988eae5..32a3093 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -89,7 +89,8 @@ pub fn run_loop(
}
}
Some(CommandKeybind::CompositeKeybind(m)) => {
- let cmd = process_event::get_input_while_composite(backend, context, m);
+ let cmd =
+ process_event::poll_event_until_simple_keybind(backend, context, m);
if let Some(command) = cmd {
if let Err(e) = command.execute(context, backend, &keymap_t) {
diff --git a/src/tab/homepage.rs b/src/tab/homepage.rs
index b762c3b..8970a0b 100644
--- a/src/tab/homepage.rs
+++ b/src/tab/homepage.rs
@@ -4,3 +4,14 @@ pub enum TabHomePage {
Home,
Root,
}
+
+impl TabHomePage {
+ pub fn from_str(s: &str) -> Option<Self> {
+ match s {
+ "inherit" => Some(Self::Inherit),
+ "home" => Some(Self::Home),
+ "root" => Some(Self::Root),
+ _ => None,
+ }
+ }
+}
diff --git a/src/util/unix.rs b/src/util/unix.rs
index 8553e6a..21ff0aa 100644
--- a/src/util/unix.rs
+++ b/src/util/unix.rs
@@ -1,3 +1,5 @@
+use std::path;
+
pub fn is_executable(mode: u32) -> bool {
const LIBC_PERMISSION_VALS: [u32; 3] = [
libc::S_IXUSR as u32,
@@ -50,3 +52,9 @@ pub fn mode_to_string(mode: u32) -> String {
}
mode_str
}
+
+pub fn expand_shell_string(s: &str) -> path::PathBuf {
+ let tilde_cow = shellexpand::tilde_with_context(s, dirs_next::home_dir);
+ let tilde_path = path::PathBuf::from(tilde_cow.as_ref());
+ tilde_path
+}