perf: use FxHash instead of SipHash where it makes sense

This commit is contained in:
alexpasmantier 2025-01-07 02:07:47 +01:00
parent 263e88beb6
commit f416d39009
39 changed files with 193 additions and 157 deletions

4
Cargo.lock generated
View File

@ -3038,6 +3038,7 @@ dependencies = [
"ignore", "ignore",
"lazy_static", "lazy_static",
"regex", "regex",
"rustc-hash",
"serde", "serde",
"strum", "strum",
"television-derive", "television-derive",
@ -3076,6 +3077,7 @@ dependencies = [
"parking_lot", "parking_lot",
"ratatui", "ratatui",
"regex", "regex",
"rustc-hash",
"simdutf8", "simdutf8",
"smallvec", "smallvec",
"syntect", "syntect",
@ -3092,6 +3094,7 @@ version = "0.0.18"
dependencies = [ dependencies = [
"color-eyre", "color-eyre",
"ratatui", "ratatui",
"rustc-hash",
"serde", "serde",
"syntect", "syntect",
"television-channels", "television-channels",
@ -3109,6 +3112,7 @@ dependencies = [
"gag", "gag",
"ignore", "ignore",
"lazy_static", "lazy_static",
"rustc-hash",
"syntect", "syntect",
"tracing", "tracing",
"unicode-width 0.2.0", "unicode-width 0.2.0",

View File

@ -4,13 +4,14 @@ use ratatui::layout::Alignment;
use ratatui::prelude::{Line, Style}; use ratatui::prelude::{Line, Style};
use ratatui::style::Color; use ratatui::style::Color;
use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding}; use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding};
use rustc_hash::FxHashMap;
use television_channels::entry::merge_ranges; use television_channels::entry::merge_ranges;
use television_channels::entry::{Entry, PreviewType}; use television_channels::entry::{Entry, PreviewType};
use television_screen::colors::ResultsColorscheme; use television_screen::colors::ResultsColorscheme;
use television_screen::results::build_results_list; use television_screen::results::build_results_list;
pub fn results_list_benchmark(c: &mut Criterion) { pub fn results_list_benchmark(c: &mut Criterion) {
let mut icon_color_cache = std::collections::HashMap::default(); let mut icon_color_cache = FxHashMap::default();
// FIXME: there's probably a way to have this as a benchmark asset // FIXME: there's probably a way to have this as a benchmark asset
// possible as a JSON file and to load it for the benchmark using Serde // possible as a JSON file and to load it for the benchmark using Serde
// I don't know how exactly right now just having it here instead // I don't know how exactly right now just having it here instead
@ -634,6 +635,7 @@ pub fn results_list_benchmark(c: &mut Criterion) {
result_name_fg: Color::Indexed(222), result_name_fg: Color::Indexed(222),
result_preview_fg: Color::Indexed(222), result_preview_fg: Color::Indexed(222),
result_line_number_fg: Color::Indexed(222), result_line_number_fg: Color::Indexed(222),
result_selected_fg: Color::Indexed(222),
result_selected_bg: Color::Indexed(222), result_selected_bg: Color::Indexed(222),
match_foreground_color: Color::Indexed(222), match_foreground_color: Color::Indexed(222),
}; };
@ -651,6 +653,7 @@ pub fn results_list_benchmark(c: &mut Criterion) {
.style(Style::default()) .style(Style::default())
.padding(Padding::right(1)), .padding(Padding::right(1)),
&entries, &entries,
None,
ListDirection::BottomToTop, ListDirection::BottomToTop,
false, false,
&mut icon_color_cache, &mut icon_color_cache,

View File

@ -25,6 +25,7 @@ color-eyre = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
lazy_static = { workspace = true } lazy_static = { workspace = true }
toml = { workspace = true } toml = { workspace = true }
rustc-hash = { workspace = true }
devicons = "0.6.11" devicons = "0.6.11"
ignore = "0.4.23" ignore = "0.4.23"

View File

@ -1,5 +1,5 @@
use rustc_hash::FxHashMap;
use std::{ use std::{
collections::HashMap,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
ops::Deref, ops::Deref,
}; };
@ -27,10 +27,10 @@ impl Display for CableChannelPrototype {
} }
#[derive(Debug, serde::Deserialize, Default)] #[derive(Debug, serde::Deserialize, Default)]
pub struct CableChannels(pub HashMap<String, CableChannelPrototype>); pub struct CableChannels(pub FxHashMap<String, CableChannelPrototype>);
impl Deref for CableChannels { impl Deref for CableChannels {
type Target = HashMap<String, CableChannelPrototype>; type Target = FxHashMap<String, CableChannelPrototype>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0

View File

@ -1,7 +1,6 @@
use std::collections::HashSet;
use crate::entry::Entry; use crate::entry::Entry;
use color_eyre::Result; use color_eyre::Result;
use rustc_hash::FxHashSet;
use television_derive::{Broadcast, ToCliChannel, ToUnitChannel}; use television_derive::{Broadcast, ToCliChannel, ToUnitChannel};
mod alias; mod alias;
@ -68,7 +67,7 @@ pub trait OnAir: Send {
fn get_result(&self, index: u32) -> Option<Entry>; fn get_result(&self, index: u32) -> Option<Entry>;
/// Get the currently selected entries. /// Get the currently selected entries.
fn selected_entries(&self) -> &HashSet<Entry>; fn selected_entries(&self) -> &FxHashSet<Entry>;
/// Toggles selection for the entry under the cursor. /// Toggles selection for the entry under the cursor.
fn toggle_selection(&mut self, entry: &Entry); fn toggle_selection(&mut self, entry: &Entry);

View File

@ -4,6 +4,8 @@ use crate::channels::OnAir;
use crate::entry::Entry; use crate::entry::Entry;
use crate::entry::PreviewType; use crate::entry::PreviewType;
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::FxBuildHasher;
use rustc_hash::FxHashSet;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher}; use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
use television_utils::indices::sep_name_and_value_indices; use television_utils::indices::sep_name_and_value_indices;
use tracing::debug; use tracing::debug;
@ -23,7 +25,7 @@ impl Alias {
pub struct Channel { pub struct Channel {
matcher: Matcher<Alias>, matcher: Matcher<Alias>,
file_icon: FileIcon, file_icon: FileIcon,
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
const NUM_THREADS: usize = 1; const NUM_THREADS: usize = 1;
@ -55,7 +57,7 @@ impl Channel {
Self { Self {
matcher, matcher,
file_icon: FileIcon::from(FILE_ICON_STR), file_icon: FileIcon::from(FILE_ICON_STR),
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -119,7 +121,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -1,7 +1,9 @@
use std::collections::HashSet;
use color_eyre::Result; use color_eyre::Result;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use regex::Regex; use regex::Regex;
use std::collections::HashSet; use rustc_hash::{FxBuildHasher, FxHashSet};
use tracing::debug; use tracing::debug;
use crate::cable::{CableChannelPrototype, DEFAULT_DELIMITER}; use crate::cable::{CableChannelPrototype, DEFAULT_DELIMITER};
@ -26,7 +28,7 @@ pub struct Channel {
matcher: Matcher<String>, matcher: Matcher<String>,
entries_command: String, entries_command: String,
preview_kind: PreviewKind, preview_kind: PreviewKind,
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
impl Default for Channel { impl Default for Channel {
@ -94,7 +96,7 @@ impl Channel {
entries_command: entries_command.to_string(), entries_command: entries_command.to_string(),
preview_kind, preview_kind,
name: name.to_string(), name: name.to_string(),
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -164,7 +166,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -1,6 +1,7 @@
use crate::channels::{OnAir, TelevisionChannel}; use crate::channels::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewCommand, PreviewType}; use crate::entry::{Entry, PreviewCommand, PreviewType};
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
use std::path::PathBuf; use std::path::PathBuf;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher}; use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
@ -11,7 +12,7 @@ pub struct Channel {
crawl_handle: tokio::task::JoinHandle<()>, crawl_handle: tokio::task::JoinHandle<()>,
// PERF: cache results (to make deleting characters smoother) with // PERF: cache results (to make deleting characters smoother) with
// a shallow stack of sub-patterns as keys (e.g. "a", "ab", "abc") // a shallow stack of sub-patterns as keys (e.g. "a", "ab", "abc")
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
impl Channel { impl Channel {
@ -22,7 +23,7 @@ impl Channel {
Channel { Channel {
matcher, matcher,
crawl_handle, crawl_handle,
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -114,7 +115,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -1,6 +1,7 @@
use std::collections::HashSet; use std::collections::HashSet;
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use super::OnAir; use super::OnAir;
use crate::entry::{Entry, PreviewType}; use crate::entry::{Entry, PreviewType};
@ -17,7 +18,7 @@ struct EnvVar {
pub struct Channel { pub struct Channel {
matcher: Matcher<EnvVar>, matcher: Matcher<EnvVar>,
file_icon: FileIcon, file_icon: FileIcon,
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
const NUM_THREADS: usize = 1; const NUM_THREADS: usize = 1;
@ -35,7 +36,7 @@ impl Channel {
Channel { Channel {
matcher, matcher,
file_icon: FileIcon::from(FILE_ICON_STR), file_icon: FileIcon::from(FILE_ICON_STR),
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -99,7 +100,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -1,6 +1,7 @@
use crate::channels::{OnAir, TelevisionChannel}; use crate::channels::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewType}; use crate::entry::{Entry, PreviewType};
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
use std::path::PathBuf; use std::path::PathBuf;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher}; use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
@ -11,7 +12,7 @@ pub struct Channel {
crawl_handle: tokio::task::JoinHandle<()>, crawl_handle: tokio::task::JoinHandle<()>,
// PERF: cache results (to make deleting characters smoother) with // PERF: cache results (to make deleting characters smoother) with
// a shallow stack of sub-patterns as keys (e.g. "a", "ab", "abc") // a shallow stack of sub-patterns as keys (e.g. "a", "ab", "abc")
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
impl Channel { impl Channel {
@ -22,7 +23,7 @@ impl Channel {
Channel { Channel {
matcher, matcher,
crawl_handle, crawl_handle,
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -72,7 +73,7 @@ impl From<&mut TelevisionChannel> for Channel {
entries entries
.iter() .iter()
.map(|entry| PathBuf::from(&entry.name)) .map(|entry| PathBuf::from(&entry.name))
.collect::<HashSet<_>>() .collect::<FxHashSet<_>>()
.into_iter() .into_iter()
.collect(), .collect(),
) )
@ -83,7 +84,7 @@ impl From<&mut TelevisionChannel> for Channel {
entries entries
.iter() .iter()
.map(|entry| PathBuf::from(&entry.name)) .map(|entry| PathBuf::from(&entry.name))
.collect::<HashSet<_>>() .collect::<FxHashSet<_>>()
.into_iter() .into_iter()
.collect(), .collect(),
) )
@ -120,7 +121,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -2,6 +2,7 @@ use devicons::FileIcon;
use directories::BaseDirs; use directories::BaseDirs;
use ignore::overrides::OverrideBuilder; use ignore::overrides::OverrideBuilder;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
use std::path::PathBuf; use std::path::PathBuf;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
@ -16,7 +17,7 @@ pub struct Channel {
matcher: Matcher<String>, matcher: Matcher<String>,
icon: FileIcon, icon: FileIcon,
crawl_handle: JoinHandle<()>, crawl_handle: JoinHandle<()>,
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
impl Channel { impl Channel {
@ -31,7 +32,7 @@ impl Channel {
matcher, matcher,
icon: FileIcon::from("git"), icon: FileIcon::from("git"),
crawl_handle, crawl_handle,
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -84,7 +85,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -7,6 +7,7 @@ use crate::entry::{Entry, PreviewType};
use clap::ValueEnum; use clap::ValueEnum;
use color_eyre::Result; use color_eyre::Result;
use devicons::FileIcon; use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use television_fuzzy::matcher::{config::Config, Matcher}; use television_fuzzy::matcher::{config::Config, Matcher};
use super::cable; use super::cable;
@ -14,7 +15,7 @@ use super::cable;
pub struct RemoteControl { pub struct RemoteControl {
matcher: Matcher<RCButton>, matcher: Matcher<RCButton>,
cable_channels: Option<CableChannels>, cable_channels: Option<CableChannels>,
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -61,7 +62,7 @@ impl RemoteControl {
RemoteControl { RemoteControl {
matcher, matcher,
cable_channels, cable_channels,
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
@ -143,7 +144,7 @@ impl OnAir for RemoteControl {
.collect() .collect()
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -4,6 +4,7 @@ use std::{
thread::spawn, thread::spawn,
}; };
use rustc_hash::{FxBuildHasher, FxHashSet};
use tracing::debug; use tracing::debug;
use super::OnAir; use super::OnAir;
@ -13,7 +14,7 @@ use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
pub struct Channel { pub struct Channel {
matcher: Matcher<String>, matcher: Matcher<String>,
preview_type: PreviewType, preview_type: PreviewType,
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
impl Channel { impl Channel {
@ -26,7 +27,7 @@ impl Channel {
Self { Self {
matcher, matcher,
preview_type: preview_type.unwrap_or_default(), preview_type: preview_type.unwrap_or_default(),
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -93,7 +94,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -2,6 +2,7 @@ use super::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewType}; use crate::entry::{Entry, PreviewType};
use devicons::FileIcon; use devicons::FileIcon;
use ignore::WalkState; use ignore::WalkState;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::{ use std::{
collections::HashSet, collections::HashSet,
fs::File, fs::File,
@ -37,7 +38,7 @@ impl CandidateLine {
pub struct Channel { pub struct Channel {
matcher: Matcher<CandidateLine>, matcher: Matcher<CandidateLine>,
crawl_handle: tokio::task::JoinHandle<()>, crawl_handle: tokio::task::JoinHandle<()>,
selected_entries: HashSet<Entry>, selected_entries: FxHashSet<Entry>,
} }
impl Channel { impl Channel {
@ -51,7 +52,7 @@ impl Channel {
Channel { Channel {
matcher, matcher,
crawl_handle, crawl_handle,
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
@ -76,7 +77,7 @@ impl Channel {
Channel { Channel {
matcher, matcher,
crawl_handle, crawl_handle,
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
@ -101,7 +102,7 @@ impl Channel {
Channel { Channel {
matcher, matcher,
crawl_handle: load_handle, crawl_handle: load_handle,
selected_entries: HashSet::new(), selected_entries: HashSet::with_hasher(FxBuildHasher),
} }
} }
} }
@ -216,7 +217,7 @@ impl OnAir for Channel {
}) })
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries &self.selected_entries
} }

View File

@ -213,7 +213,7 @@ fn impl_tv_channel(ast: &syn::DeriveInput) -> TokenStream {
} }
} }
fn selected_entries(&self) -> &HashSet<Entry> { fn selected_entries(&self) -> &FxHashSet<Entry> {
match self { match self {
#( #(
#enum_name::#variant_names(ref channel) => { #enum_name::#variant_names(ref channel) => {

View File

@ -21,6 +21,7 @@ tracing = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
color-eyre = { workspace = true } color-eyre = { workspace = true }
lazy_static = { workspace = true } lazy_static = { workspace = true }
rustc-hash = { workspace = true }
parking_lot = "0.12.3" parking_lot = "0.12.3"
devicons = "0.6.11" devicons = "0.6.11"

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, sync::Arc}; use rustc_hash::FxHashMap;
use std::sync::Arc;
use crate::previewers::Preview; use crate::previewers::Preview;
use television_utils::cache::RingSet; use television_utils::cache::RingSet;
@ -15,7 +16,7 @@ const DEFAULT_PREVIEW_CACHE_SIZE: usize = 100;
/// The cache is implemented as an LRU cache with a fixed size. /// The cache is implemented as an LRU cache with a fixed size.
#[derive(Debug)] #[derive(Debug)]
pub struct PreviewCache { pub struct PreviewCache {
entries: HashMap<String, Arc<Preview>>, entries: FxHashMap<String, Arc<Preview>>,
ring_set: RingSet<String>, ring_set: RingSet<String>,
} }
@ -23,7 +24,7 @@ impl PreviewCache {
/// Create a new preview cache with the given capacity. /// Create a new preview cache with the given capacity.
pub fn new(capacity: usize) -> Self { pub fn new(capacity: usize) -> Self {
PreviewCache { PreviewCache {
entries: HashMap::new(), entries: FxHashMap::default(),
ring_set: RingSet::with_capacity(capacity), ring_set: RingSet::with_capacity(capacity),
} }
} }

View File

@ -4,7 +4,7 @@ use crate::previewers::{Preview, PreviewContent};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::Mutex; use parking_lot::Mutex;
use regex::Regex; use regex::Regex;
use std::collections::HashSet; use rustc_hash::FxHashSet;
use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc; use std::sync::Arc;
use television_channels::entry::{Entry, PreviewCommand}; use television_channels::entry::{Entry, PreviewCommand};
@ -18,7 +18,7 @@ pub struct CommandPreviewer {
config: CommandPreviewerConfig, config: CommandPreviewerConfig,
concurrent_preview_tasks: Arc<AtomicU8>, concurrent_preview_tasks: Arc<AtomicU8>,
last_previewed: Arc<Mutex<Arc<Preview>>>, last_previewed: Arc<Mutex<Arc<Preview>>>,
in_flight_previews: Arc<Mutex<HashSet<String>>>, in_flight_previews: Arc<Mutex<FxHashSet<String>>>,
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -57,7 +57,7 @@ impl CommandPreviewer {
last_previewed: Arc::new(Mutex::new(Arc::new( last_previewed: Arc::new(Mutex::new(Arc::new(
Preview::default().stale(), Preview::default().stale(),
))), ))),
in_flight_previews: Arc::new(Mutex::new(HashSet::new())), in_flight_previews: Arc::new(Mutex::new(FxHashSet::default())),
} }
} }

View File

@ -1,4 +1,4 @@
use std::collections::HashMap; use rustc_hash::FxHashMap;
use std::sync::Arc; use std::sync::Arc;
use crate::previewers::{Preview, PreviewContent}; use crate::previewers::{Preview, PreviewContent};
@ -6,7 +6,7 @@ use television_channels::entry;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct EnvVarPreviewer { pub struct EnvVarPreviewer {
cache: HashMap<entry::Entry, Arc<Preview>>, cache: FxHashMap<entry::Entry, Arc<Preview>>,
_config: EnvVarPreviewerConfig, _config: EnvVarPreviewerConfig,
} }
@ -16,7 +16,7 @@ pub struct EnvVarPreviewerConfig {}
impl EnvVarPreviewer { impl EnvVarPreviewer {
pub fn new(config: Option<EnvVarPreviewerConfig>) -> Self { pub fn new(config: Option<EnvVarPreviewerConfig>) -> Self {
EnvVarPreviewer { EnvVarPreviewer {
cache: HashMap::new(), cache: FxHashMap::default(),
_config: config.unwrap_or_default(), _config: config.unwrap_or_default(),
} }
} }

View File

@ -1,5 +1,6 @@
use color_eyre::Result; use color_eyre::Result;
use parking_lot::Mutex; use parking_lot::Mutex;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet; use std::collections::HashSet;
use std::fs::File; use std::fs::File;
use std::io::{BufRead, BufReader, Seek}; use std::io::{BufRead, BufReader, Seek};
@ -28,7 +29,7 @@ pub struct FilePreviewer {
pub syntax_theme: Arc<Theme>, pub syntax_theme: Arc<Theme>,
concurrent_preview_tasks: Arc<AtomicU8>, concurrent_preview_tasks: Arc<AtomicU8>,
last_previewed: Arc<Mutex<Arc<Preview>>>, last_previewed: Arc<Mutex<Arc<Preview>>>,
in_flight_previews: Arc<Mutex<HashSet<String>>>, in_flight_previews: Arc<Mutex<FxHashSet<String>>>,
} }
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
@ -74,7 +75,9 @@ impl FilePreviewer {
last_previewed: Arc::new(Mutex::new(Arc::new( last_previewed: Arc::new(Mutex::new(Arc::new(
Preview::default().stale(), Preview::default().stale(),
))), ))),
in_flight_previews: Arc::new(Mutex::new(HashSet::new())), in_flight_previews: Arc::new(Mutex::new(HashSet::with_hasher(
FxBuildHasher,
))),
} }
} }
@ -137,7 +140,7 @@ pub fn try_preview(
syntax_theme: &Arc<Theme>, syntax_theme: &Arc<Theme>,
concurrent_tasks: &Arc<AtomicU8>, concurrent_tasks: &Arc<AtomicU8>,
last_previewed: &Arc<Mutex<Arc<Preview>>>, last_previewed: &Arc<Mutex<Arc<Preview>>>,
in_flight_previews: &Arc<Mutex<HashSet<String>>>, in_flight_previews: &Arc<Mutex<FxHashSet<String>>>,
) { ) {
debug!("Computing preview for {:?}", entry.name); debug!("Computing preview for {:?}", entry.name);
let path = PathBuf::from(&entry.name); let path = PathBuf::from(&entry.name);

View File

@ -21,6 +21,7 @@ ratatui = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
color-eyre = { workspace = true } color-eyre = { workspace = true }
syntect = { workspace = true } syntect = { workspace = true }
rustc-hash = { workspace = true }
[lints] [lints]
workspace = true workspace = true

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, sync::Arc}; use rustc_hash::FxHashMap;
use std::sync::Arc;
use ratatui::widgets::Paragraph; use ratatui::widgets::Paragraph;
use television_utils::cache::RingSet; use television_utils::cache::RingSet;
@ -7,14 +8,14 @@ const DEFAULT_RENDERED_PREVIEW_CACHE_SIZE: usize = 25;
#[derive(Debug)] #[derive(Debug)]
pub struct RenderedPreviewCache<'a> { pub struct RenderedPreviewCache<'a> {
previews: HashMap<String, Arc<Paragraph<'a>>>, previews: FxHashMap<String, Arc<Paragraph<'a>>>,
ring_set: RingSet<String>, ring_set: RingSet<String>,
} }
impl<'a> RenderedPreviewCache<'a> { impl<'a> RenderedPreviewCache<'a> {
pub fn new(capacity: usize) -> Self { pub fn new(capacity: usize) -> Self {
RenderedPreviewCache { RenderedPreviewCache {
previews: HashMap::new(), previews: FxHashMap::default(),
ring_set: RingSet::with_capacity(capacity), ring_set: RingSet::with_capacity(capacity),
} }
} }

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, fmt::Display}; use rustc_hash::FxHashMap;
use std::fmt::Display;
use crate::{colors::Colorscheme, mode::Mode}; use crate::{colors::Colorscheme, mode::Mode};
use ratatui::{ use ratatui::{
@ -10,11 +11,11 @@ use ratatui::{
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DisplayableKeybindings { pub struct DisplayableKeybindings {
bindings: HashMap<DisplayableAction, Vec<String>>, bindings: FxHashMap<DisplayableAction, Vec<String>>,
} }
impl DisplayableKeybindings { impl DisplayableKeybindings {
pub fn new(bindings: HashMap<DisplayableAction, Vec<String>>) -> Self { pub fn new(bindings: FxHashMap<DisplayableAction, Vec<String>>) -> Self {
Self { bindings } Self { bindings }
} }
} }
@ -52,7 +53,7 @@ impl Display for DisplayableAction {
} }
pub fn build_keybindings_table<'a>( pub fn build_keybindings_table<'a>(
keybindings: &'a HashMap<Mode, DisplayableKeybindings>, keybindings: &'a FxHashMap<Mode, DisplayableKeybindings>,
mode: Mode, mode: Mode,
colorscheme: &'a Colorscheme, colorscheme: &'a Colorscheme,
) -> Table<'a> { ) -> Table<'a> {

View File

@ -1,4 +1,4 @@
use std::collections::HashMap; use rustc_hash::FxHashMap;
use crate::colors::{Colorscheme, GeneralColorscheme}; use crate::colors::{Colorscheme, GeneralColorscheme};
use crate::logo::build_remote_logo_paragraph; use crate::logo::build_remote_logo_paragraph;
@ -25,7 +25,7 @@ pub fn draw_remote_control(
use_nerd_font_icons: bool, use_nerd_font_icons: bool,
picker_state: &mut ListState, picker_state: &mut ListState,
input_state: &mut Input, input_state: &mut Input,
icon_color_cache: &mut HashMap<String, Color>, icon_color_cache: &mut FxHashMap<String, Color>,
mode: &Mode, mode: &Mode,
colorscheme: &Colorscheme, colorscheme: &Colorscheme,
) -> Result<()> { ) -> Result<()> {
@ -65,7 +65,7 @@ fn draw_rc_channels(
entries: &[Entry], entries: &[Entry],
use_nerd_font_icons: bool, use_nerd_font_icons: bool,
picker_state: &mut ListState, picker_state: &mut ListState,
icon_color_cache: &mut HashMap<String, Color>, icon_color_cache: &mut FxHashMap<String, Color>,
colorscheme: &Colorscheme, colorscheme: &Colorscheme,
) { ) {
let rc_block = Block::default() let rc_block = Block::default()

View File

@ -8,7 +8,7 @@ use ratatui::widgets::{
Block, BorderType, Borders, List, ListDirection, ListState, Padding, Block, BorderType, Borders, List, ListDirection, ListState, Padding,
}; };
use ratatui::Frame; use ratatui::Frame;
use std::collections::{HashMap, HashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use std::str::FromStr; use std::str::FromStr;
use television_channels::entry::Entry; use television_channels::entry::Entry;
use television_utils::strings::{ use television_utils::strings::{
@ -23,10 +23,10 @@ const DESLECTED_SYMBOL: &str = " ";
pub fn build_results_list<'a, 'b>( pub fn build_results_list<'a, 'b>(
results_block: Block<'b>, results_block: Block<'b>,
entries: &'a [Entry], entries: &'a [Entry],
selected_entries: Option<&HashSet<Entry>>, selected_entries: Option<&FxHashSet<Entry>>,
list_direction: ListDirection, list_direction: ListDirection,
use_icons: bool, use_icons: bool,
icon_color_cache: &mut HashMap<String, Color>, icon_color_cache: &mut FxHashMap<String, Color>,
colorscheme: &ResultsColorscheme, colorscheme: &ResultsColorscheme,
) -> List<'a> ) -> List<'a>
where where
@ -156,11 +156,11 @@ pub fn draw_results_list(
f: &mut Frame, f: &mut Frame,
rect: Rect, rect: Rect,
entries: &[Entry], entries: &[Entry],
selected_entries: &HashSet<Entry>, selected_entries: &FxHashSet<Entry>,
relative_picker_state: &mut ListState, relative_picker_state: &mut ListState,
input_bar_position: InputPosition, input_bar_position: InputPosition,
use_nerd_font_icons: bool, use_nerd_font_icons: bool,
icon_color_cache: &mut HashMap<String, Color>, icon_color_cache: &mut FxHashMap<String, Color>,
colorscheme: &Colorscheme, colorscheme: &Colorscheme,
help_keybinding: &str, help_keybinding: &str,
preview_keybinding: &str, preview_keybinding: &str,

View File

@ -19,6 +19,7 @@ color-eyre = { workspace = true }
directories = { workspace = true } directories = { workspace = true }
syntect = { workspace = true } syntect = { workspace = true }
unicode-width = { workspace = true } unicode-width = { workspace = true }
rustc-hash = { workspace = true }
ignore = "0.4.23" ignore = "0.4.23"
bat = { version = "0.24.0", default-features = false, features = [ bat = { version = "0.24.0", default-features = false, features = [

View File

@ -1,3 +1,4 @@
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::{HashSet, VecDeque}; use std::collections::{HashSet, VecDeque};
use tracing::debug; use tracing::debug;
@ -43,7 +44,7 @@ use tracing::debug;
#[derive(Debug)] #[derive(Debug)]
pub struct RingSet<T> { pub struct RingSet<T> {
ring_buffer: VecDeque<T>, ring_buffer: VecDeque<T>,
known_keys: HashSet<T>, known_keys: FxHashSet<T>,
capacity: usize, capacity: usize,
} }
@ -55,7 +56,10 @@ where
pub fn with_capacity(capacity: usize) -> Self { pub fn with_capacity(capacity: usize) -> Self {
RingSet { RingSet {
ring_buffer: VecDeque::with_capacity(capacity), ring_buffer: VecDeque::with_capacity(capacity),
known_keys: HashSet::with_capacity(capacity), known_keys: HashSet::with_capacity_and_hasher(
capacity,
FxBuildHasher,
),
capacity, capacity,
} }
} }

View File

@ -1,8 +1,9 @@
use rustc_hash::FxHashSet;
use std::fmt::Debug; use std::fmt::Debug;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
use std::{collections::HashSet, path::PathBuf}; use std::path::PathBuf;
use ignore::{overrides::Override, types::TypesBuilder, WalkBuilder}; use ignore::{overrides::Override, types::TypesBuilder, WalkBuilder};
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -99,7 +100,7 @@ where
} }
lazy_static! { lazy_static! {
static ref KNOWN_TEXT_FILE_EXTENSIONS: HashSet<&'static str> = [ static ref KNOWN_TEXT_FILE_EXTENSIONS: FxHashSet<&'static str> = [
"ada", "ada",
"adb", "adb",
"ads", "ads",
@ -428,5 +429,7 @@ lazy_static! {
"zsh", "zsh",
"zshrc", "zshrc",
] ]
.into(); .iter()
.copied()
.collect();
} }

View File

@ -1,4 +1,4 @@
use std::collections::HashSet; use rustc_hash::FxHashSet;
use std::sync::Arc; use std::sync::Arc;
use color_eyre::Result; use color_eyre::Result;
@ -45,16 +45,16 @@ pub struct App {
/// The outcome of an action. /// The outcome of an action.
#[derive(Debug)] #[derive(Debug)]
pub enum ActionOutcome { pub enum ActionOutcome {
Entries(HashSet<Entry>), Entries(FxHashSet<Entry>),
Input(String), Input(String),
Passthrough(HashSet<Entry>, String), Passthrough(FxHashSet<Entry>, String),
None, None,
} }
/// The result of the application. /// The result of the application.
#[derive(Debug)] #[derive(Debug)]
pub struct AppOutput { pub struct AppOutput {
pub selected_entries: Option<HashSet<Entry>>, pub selected_entries: Option<FxHashSet<Entry>>,
pub passthrough: Option<String>, pub passthrough: Option<String>,
} }

View File

@ -1,4 +1,4 @@
use std::collections::HashMap; use rustc_hash::FxHashMap;
use color_eyre::Result; use color_eyre::Result;
use television_channels::cable::{CableChannelPrototype, CableChannels}; use television_channels::cable::{CableChannelPrototype, CableChannels};
@ -71,7 +71,7 @@ pub fn load_cable_channels() -> Result<CableChannels> {
debug!("Loaded cable channels: {:?}", user_defined_prototypes); debug!("Loaded cable channels: {:?}", user_defined_prototypes);
let mut cable_channels = HashMap::new(); let mut cable_channels = FxHashMap::default();
for prototype in user_defined_prototypes { for prototype in user_defined_prototypes {
cable_channels.insert(prototype.name.clone(), prototype); cable_channels.insert(prototype.name.clone(), prototype);
} }

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, path::Path}; use rustc_hash::FxHashMap;
use std::path::Path;
use clap::{Parser, Subcommand, ValueEnum}; use clap::{Parser, Subcommand, ValueEnum};
use color_eyre::{eyre::eyre, Result}; use color_eyre::{eyre::eyre, Result};
@ -231,7 +232,7 @@ pub fn list_channels() {
/// - it should be able to handle commands within delimiters (quotes, brackets, etc.) /// - it should be able to handle commands within delimiters (quotes, brackets, etc.)
pub fn guess_channel_from_prompt( pub fn guess_channel_from_prompt(
prompt: &str, prompt: &str,
command_mapping: &HashMap<String, String>, command_mapping: &FxHashMap<String, String>,
) -> Result<ParsedCliChannel> { ) -> Result<ParsedCliChannel> {
debug!("Guessing channel from prompt: {}", prompt); debug!("Guessing channel from prompt: {}", prompt);
// git checkout -qf // git checkout -qf

View File

@ -1,8 +1,8 @@
use crate::action::Action; use crate::action::Action;
use crate::event::{convert_raw_event_to_key, Key}; use crate::event::{convert_raw_event_to_key, Key};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
use std::fmt::Display; use std::fmt::Display;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use television_screen::mode::Mode; use television_screen::mode::Mode;
@ -56,10 +56,10 @@ impl<'de> Deserialize<'de> for KeyBindings {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let parsed_map = let parsed_map = FxHashMap::<
HashMap::<Mode, HashMap<Action, SerializedBinding>>::deserialize( Mode,
deserializer, FxHashMap<Action, SerializedBinding>,
)?; >::deserialize(deserializer)?;
let keybindings = parsed_map let keybindings = parsed_map
.into_iter() .into_iter()

View File

@ -1,6 +1,7 @@
use std::collections::HashMap;
use config::ValueKind; use config::ValueKind;
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap;
use television_previewers::previewers; use television_previewers::previewers;
use television_previewers::previewers::PreviewerConfig; use television_previewers::previewers::PreviewerConfig;

View File

@ -1,9 +1,11 @@
use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
use rustc_hash::FxHashMap;
use serde::Deserialize;
#[derive(Clone, Debug, Deserialize, Default)] #[derive(Clone, Debug, Deserialize, Default)]
pub struct ShellIntegrationConfig { pub struct ShellIntegrationConfig {
pub commands: HashMap<String, String>, pub commands: FxHashMap<String, String>,
} }
impl From<ShellIntegrationConfig> for config::ValueKind { impl From<ShellIntegrationConfig> for config::ValueKind {

View File

@ -1,16 +1,14 @@
use ratatui::prelude::{Color, Modifier, Style}; use ratatui::prelude::{Color, Modifier, Style};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::{ use std::ops::{Deref, DerefMut};
collections::HashMap,
ops::{Deref, DerefMut},
};
use television_screen::mode::Mode; use television_screen::mode::Mode;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Styles(pub HashMap<Mode, HashMap<String, Style>>); pub struct Styles(pub FxHashMap<Mode, FxHashMap<String, Style>>);
impl Deref for Styles { impl Deref for Styles {
type Target = HashMap<Mode, HashMap<String, Style>>; type Target = FxHashMap<Mode, FxHashMap<String, Style>>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
@ -28,7 +26,7 @@ impl<'de> Deserialize<'de> for Styles {
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let parsed_map = let parsed_map =
HashMap::<Mode, HashMap<String, String>>::deserialize( FxHashMap::<Mode, FxHashMap<String, String>>::deserialize(
deserializer, deserializer,
)?; )?;

View File

@ -1,10 +1,10 @@
use std::collections::HashMap; use rustc_hash::FxHashMap;
use lazy_static::lazy_static; use lazy_static::lazy_static;
lazy_static! { lazy_static! {
pub static ref BUILTIN_THEMES: HashMap<&'static str, &'static str> = { pub static ref BUILTIN_THEMES: FxHashMap<&'static str, &'static str> = {
let mut m = HashMap::new(); let mut m = FxHashMap::default();
m.insert("default", include_str!("../../../../themes/default.toml")); m.insert("default", include_str!("../../../../themes/default.toml"));
m.insert( m.insert(
"television", "television",

View File

@ -1,6 +1,7 @@
use std::collections::HashMap;
use config::ValueKind; use config::ValueKind;
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap;
use television_screen::layout::{InputPosition, PreviewTitlePosition}; use television_screen::layout::{InputPosition, PreviewTitlePosition};

View File

@ -1,4 +1,4 @@
use std::collections::HashMap; use rustc_hash::FxHashMap;
use std::ops::Deref; use std::ops::Deref;
use color_eyre::Result; use color_eyre::Result;
@ -9,10 +9,10 @@ use crate::config::{Binding, KeyBindings};
use crate::event::Key; use crate::event::Key;
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Keymap(pub HashMap<Mode, HashMap<Key, Action>>); pub struct Keymap(pub FxHashMap<Mode, FxHashMap<Key, Action>>);
impl Deref for Keymap { impl Deref for Keymap {
type Target = HashMap<Mode, HashMap<Key, Action>>; type Target = FxHashMap<Mode, FxHashMap<Key, Action>>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
@ -20,9 +20,9 @@ impl Deref for Keymap {
impl From<&KeyBindings> for Keymap { impl From<&KeyBindings> for Keymap {
fn from(keybindings: &KeyBindings) -> Self { fn from(keybindings: &KeyBindings) -> Self {
let mut keymap = HashMap::new(); let mut keymap = FxHashMap::default();
for (mode, bindings) in keybindings.iter() { for (mode, bindings) in keybindings.iter() {
let mut mode_keymap = HashMap::new(); let mut mode_keymap = FxHashMap::default();
for (action, binding) in bindings { for (action, binding) in bindings {
match binding { match binding {
Binding::SingleKey(key) => { Binding::SingleKey(key) => {

View File

@ -6,7 +6,8 @@ use crate::{cable::load_cable_channels, keymap::Keymap};
use color_eyre::Result; use color_eyre::Result;
use copypasta::{ClipboardContext, ClipboardProvider}; use copypasta::{ClipboardContext, ClipboardProvider};
use ratatui::{layout::Rect, style::Color, Frame}; use ratatui::{layout::Rect, style::Color, Frame};
use std::collections::{HashMap, HashSet}; use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
use std::collections::HashSet;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use television_channels::channels::{ use television_channels::channels::{
remote_control::{load_builtin_channels, RemoteControl}, remote_control::{load_builtin_channels, RemoteControl},
@ -46,7 +47,7 @@ pub struct Television {
pub preview_scroll: Option<u16>, pub preview_scroll: Option<u16>,
pub preview_pane_height: u16, pub preview_pane_height: u16,
current_preview_total_lines: u16, current_preview_total_lines: u16,
pub icon_color_cache: HashMap<String, Color>, pub icon_color_cache: FxHashMap<String, Color>,
pub rendered_preview_cache: Arc<Mutex<RenderedPreviewCache<'static>>>, pub rendered_preview_cache: Arc<Mutex<RenderedPreviewCache<'static>>>,
pub(crate) spinner: Spinner, pub(crate) spinner: Spinner,
pub(crate) spinner_state: SpinnerState, pub(crate) spinner_state: SpinnerState,
@ -102,7 +103,7 @@ impl Television {
preview_scroll: None, preview_scroll: None,
preview_pane_height: 0, preview_pane_height: 0,
current_preview_total_lines: 0, current_preview_total_lines: 0,
icon_color_cache: HashMap::new(), icon_color_cache: FxHashMap::default(),
rendered_preview_cache: Arc::new(Mutex::new( rendered_preview_cache: Arc::new(Mutex::new(
RenderedPreviewCache::default(), RenderedPreviewCache::default(),
)), )),
@ -169,12 +170,12 @@ impl Television {
pub fn get_selected_entries( pub fn get_selected_entries(
&mut self, &mut self,
mode: Option<Mode>, mode: Option<Mode>,
) -> Option<HashSet<Entry>> { ) -> Option<FxHashSet<Entry>> {
if self.channel.selected_entries().is_empty() if self.channel.selected_entries().is_empty()
|| matches!(mode, Some(Mode::RemoteControl)) || matches!(mode, Some(Mode::RemoteControl))
{ {
return self.get_selected_entry(mode).map(|e| { return self.get_selected_entry(mode).map(|e| {
let mut set = HashSet::new(); let mut set = HashSet::with_hasher(FxBuildHasher);
set.insert(e); set.insert(e);
set set
}); });
@ -615,10 +616,10 @@ impl Television {
} }
impl KeyBindings { impl KeyBindings {
pub fn to_displayable(&self) -> HashMap<Mode, DisplayableKeybindings> { pub fn to_displayable(&self) -> FxHashMap<Mode, DisplayableKeybindings> {
// channel mode keybindings // channel mode keybindings
let channel_bindings: HashMap<DisplayableAction, Vec<String>> = let channel_bindings: FxHashMap<DisplayableAction, Vec<String>> =
HashMap::from_iter(vec![ FxHashMap::from_iter(vec![
( (
DisplayableAction::ResultsNavigation, DisplayableAction::ResultsNavigation,
serialized_keys_for_actions( serialized_keys_for_actions(
@ -676,58 +677,56 @@ impl KeyBindings {
]); ]);
// remote control mode keybindings // remote control mode keybindings
let remote_control_bindings: HashMap<DisplayableAction, Vec<String>> = let remote_control_bindings: FxHashMap<
HashMap::from_iter(vec![ DisplayableAction,
( Vec<String>,
DisplayableAction::ResultsNavigation, > = FxHashMap::from_iter(vec![
serialized_keys_for_actions( (
self, DisplayableAction::ResultsNavigation,
&[Action::SelectPrevEntry, Action::SelectNextEntry], serialized_keys_for_actions(
), self,
&[Action::SelectPrevEntry, Action::SelectNextEntry],
), ),
( ),
DisplayableAction::SelectEntry, (
serialized_keys_for_actions( DisplayableAction::SelectEntry,
self, serialized_keys_for_actions(self, &[Action::ConfirmSelection]),
&[Action::ConfirmSelection], ),
), (
DisplayableAction::ToggleRemoteControl,
serialized_keys_for_actions(
self,
&[Action::ToggleRemoteControl],
), ),
( ),
DisplayableAction::ToggleRemoteControl, ]);
serialized_keys_for_actions(
self,
&[Action::ToggleRemoteControl],
),
),
]);
// send to channel mode keybindings // send to channel mode keybindings
let send_to_channel_bindings: HashMap<DisplayableAction, Vec<String>> = let send_to_channel_bindings: FxHashMap<
HashMap::from_iter(vec![ DisplayableAction,
( Vec<String>,
DisplayableAction::ResultsNavigation, > = FxHashMap::from_iter(vec![
serialized_keys_for_actions( (
self, DisplayableAction::ResultsNavigation,
&[Action::SelectPrevEntry, Action::SelectNextEntry], serialized_keys_for_actions(
), self,
&[Action::SelectPrevEntry, Action::SelectNextEntry],
), ),
( ),
DisplayableAction::SelectEntry, (
serialized_keys_for_actions( DisplayableAction::SelectEntry,
self, serialized_keys_for_actions(self, &[Action::ConfirmSelection]),
&[Action::ConfirmSelection], ),
), (
DisplayableAction::Cancel,
serialized_keys_for_actions(
self,
&[Action::ToggleSendToChannel],
), ),
( ),
DisplayableAction::Cancel, ]);
serialized_keys_for_actions(
self,
&[Action::ToggleSendToChannel],
),
),
]);
HashMap::from_iter(vec![ FxHashMap::from_iter(vec![
(Mode::Channel, DisplayableKeybindings::new(channel_bindings)), (Mode::Channel, DisplayableKeybindings::new(channel_bindings)),
( (
Mode::RemoteControl, Mode::RemoteControl,