Skip to content

Commit

Permalink
work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpasmantier committed Sep 22, 2024
1 parent f38c8d9 commit d028163
Show file tree
Hide file tree
Showing 14 changed files with 390 additions and 235 deletions.
4 changes: 3 additions & 1 deletion .config/config.json5
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
"<ctrl-c>": "Quit", // Yet another way to quit
"<ctrl-z>": "Suspend", // Suspend the application
"<tab>": "GoToNextPane", // Move to the next pane
"<backtab>": "GoToPreviousPane", // Move to the previous pane
"<backtab>": "GoToPrevPane", // Move to the previous pane
"<ctrl-up>": "GoToPaneUp", // Move to the pane above
"<ctrl-down>": "GoToPaneDown", // Move to the pane below
"<ctrl-left>": "GoToPaneLeft", // Move to the pane to the left
"<ctrl-right>": "GoToPaneRight", // Move to the pane to the right
"<ctrl-j>": "SelectNextEntry", // Move to the next entry
"<ctrl-k>": "SelectPrevEntry", // Move to the previous entry
},
}
}
13 changes: 10 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ toml = "0.8.19"
tracing = "0.1.40"
tracing-error = "0.2.0"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
unicode-width = "0.2.0"

[build-dependencies]
anyhow = "1.0.86"
Expand Down
24 changes: 18 additions & 6 deletions src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,40 @@ use strum::Display;

#[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
pub enum Action {
KeyPress(char),
Tick,
// input actions
AddInputChar(char),
DeletePrevChar,
DeleteNextChar,
GoToPrevChar,
GoToNextChar,
GoToInputStart,
GoToInputEnd,
// rendering actions
Render,
Resize(u16, u16),
ClearScreen,
// results actions
SelectNextEntry,
SelectPreviousEntry,
SelectPrevEntry,
// navigation actions
GoToPaneUp,
GoToPaneDown,
GoToPaneLeft,
GoToPaneRight,
GoToNextPane,
GoToPreviousPane,
GoToPrevPane,
// preview actions
ScrollPreviewUp,
ScrollPreviewDown,
ScrollPreviewHalfPageUp,
ScrollPreviewHalfPageDown,
OpenEntry,
// application actions
Tick,
Suspend,
Resume,
Quit,
ClearScreen,
Error(String),
Help,
Error(String),
NoOp,
}
57 changes: 39 additions & 18 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use tracing::debug;

use crate::{
action::Action,
cli::TvChannel,
cli::UnitTvChannel,
components::{television::Television, Component},
config::Config,
event::{Event, EventLoop, Key},
Expand All @@ -70,7 +70,9 @@ pub struct App {
// via the cli?
tick_rate: f64,
frame_rate: f64,
components: Arc<Mutex<Vec<Box<dyn Component>>>>,
//components: Arc<Mutex<Vec<Box<dyn Component>>>>,
television: Arc<Mutex<Television>>,
active_component: usize,
should_quit: bool,
should_suspend: bool,
mode: Mode,
Expand All @@ -91,16 +93,17 @@ pub enum Mode {
}

impl App {
pub fn new(channel: TvChannel, tick_rate: f64, frame_rate: f64) -> Result<Self> {
pub fn new(channel: UnitTvChannel, tick_rate: f64, frame_rate: f64) -> Result<Self> {
let (action_tx, action_rx) = mpsc::unbounded_channel();
let (render_tx, _) = mpsc::unbounded_channel();
let event_loop = EventLoop::new(tick_rate, true);
let television = Television::new(channel);
let television = Arc::new(Mutex::new(Television::new(channel)));

Ok(Self {
tick_rate,
frame_rate,
components: Arc::new(Mutex::new(vec![Box::new(television)])),
television,
active_component: 0,
should_quit: false,
should_suspend: false,
config: Config::new()?,
Expand All @@ -121,7 +124,7 @@ impl App {
self.render_tx = render_tx.clone();
let action_tx_r = self.action_tx.clone();
let config_r = self.config.clone();
let components_r = self.components.clone();
let television_r = self.television.clone();
let frame_rate = self.frame_rate;
tokio::spawn(async move {
render(
Expand All @@ -130,7 +133,7 @@ impl App {
//render_tx,
action_tx_r,
config_r,
components_r,
television_r,
frame_rate,
)
.await
Expand All @@ -157,12 +160,32 @@ impl App {

fn convert_event_to_action(&self, event: Event<Key>) -> Action {
match event {
Event::Input(keycode) => self
.config
.keybindings
.get(&self.mode)
.and_then(|keymap| keymap.get(&keycode).cloned())
.unwrap_or(Action::NoOp),
Event::Input(keycode) => {
// if the current component is the television
// and the mode is input, we want to handle
if self.television.lock().unwrap().is_input_focused() {
match keycode {
Key::Backspace => return Action::DeletePrevChar,
Key::Delete => return Action::DeleteNextChar,
Key::Left => return Action::GoToPrevChar,
Key::Right => return Action::GoToNextChar,
Key::Home | Key::Ctrl('a') => return Action::GoToInputStart,
Key::End | Key::Ctrl('e') => return Action::GoToInputEnd,
Key::Char(c) => return Action::AddInputChar(c),
_ => {}
}
}
return self
.config
.keybindings
.get(&self.mode)
.and_then(|keymap| keymap.get(&keycode).cloned())
.unwrap_or(if let Key::Char(c) = keycode {
Action::AddInputChar(c)
} else {
Action::NoOp
});
}
Event::Tick => Action::Tick,
Event::Resize(x, y) => Action::Resize(x, y),
Event::FocusGained => Action::Resume,
Expand Down Expand Up @@ -195,11 +218,9 @@ impl App {
Action::Render => self.render_tx.send(RenderingTask::Render)?,
_ => {}
}
for component in self.components.lock().unwrap().iter_mut() {
if let Some(action) = component.update(action.clone())? {
self.action_tx.send(action)?
};
}
if let Some(action) = self.television.lock().unwrap().update(action.clone())? {
self.action_tx.send(action)?
};
}
Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use clap::{Parser, ValueEnum};
use crate::config::{get_config_dir, get_data_dir};

#[derive(Clone, ValueEnum, Debug, Default)]
pub enum TvChannel {
pub enum UnitTvChannel {
#[default]
ENV,
OTHER,
Expand All @@ -14,10 +14,10 @@ pub enum TvChannel {
pub struct Cli {
/// Which channel shall we watch?
#[arg(value_enum)]
pub channel: TvChannel,
pub channel: UnitTvChannel,

/// Tick rate, i.e. number of ticks per second
#[arg(short, long, value_name = "FLOAT", default_value_t = 20.0)]
#[arg(short, long, value_name = "FLOAT", default_value_t = 50.0)]
pub tick_rate: f64,

/// Frame rate, i.e. number of frames per second
Expand Down
2 changes: 1 addition & 1 deletion src/components/finders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ pub struct Entry {
/// # Methods
/// - `find`: Find entries based on a pattern.
pub trait Finder {
fn find(&self, pattern: &str) -> impl Iterator<Item = Entry>;
fn find(&mut self, pattern: &str) -> impl Iterator<Item = Entry>;
}
81 changes: 45 additions & 36 deletions src/components/finders/env.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{env::vars, path::Path};
use std::{cmp::max, collections::HashMap, env::vars, path::Path};

use fuzzy_matcher::skim::SkimMatcherV2;
use rust_devicons::{icon_for_file, File, FileIcon};
Expand All @@ -14,6 +14,7 @@ pub struct EnvVarFinder {
env_vars: Vec<EnvVar>,
matcher: SkimMatcherV2,
file_icon: FileIcon,
cache: HashMap<String, Vec<Entry>>,
}

impl EnvVarFinder {
Expand All @@ -27,54 +28,62 @@ impl EnvVarFinder {
env_vars,
matcher: SkimMatcherV2::default(),
file_icon,
cache: HashMap::new(),
}
}
}

impl Finder for EnvVarFinder {
fn find(&self, pattern: &str) -> impl Iterator<Item = Entry> {
let mut results = Vec::new();
for env_var in &self.env_vars {
if pattern.is_empty() {
results.push(Entry {
name: env_var.name.clone(),
preview: Some(env_var.value.clone()),
score: 0,
name_match_ranges: None,
preview_match_ranges: None,
icon: Some(self.file_icon.clone()),
line_number: None,
});
} else {
let mut total_score = 0;
let preview_match_ranges = if let Some((score, indices)) =
self.matcher.fuzzy(&env_var.value, pattern, true)
{
total_score += score;
Some(indices.iter().map(|i| (*i, *i + 1)).collect())
} else {
None
};
let name_match_ranges = if let Some((score, indices)) =
self.matcher.fuzzy(&env_var.name, pattern, true)
{
total_score += score;
Some(indices.iter().map(|i| (*i, *i + 1)).collect())
} else {
None
};
if preview_match_ranges.is_some() || name_match_ranges.is_some() {
fn find(&mut self, pattern: &str) -> impl Iterator<Item = Entry> {
let mut results: Vec<Entry> = Vec::new();
// try to get from cache
if let Some(entries) = self.cache.get(pattern) {
results.extend(entries.iter().cloned());
} else {
for env_var in &self.env_vars {
if pattern.is_empty() {
results.push(Entry {
name: env_var.name.clone(),
preview: Some(env_var.value.clone()),
score: total_score,
name_match_ranges,
preview_match_ranges,
score: 0,
name_match_ranges: None,
preview_match_ranges: None,
icon: Some(self.file_icon.clone()),
line_number: None,
});
} else {
let mut final_score = 0;
let preview_match_ranges = if let Some((score, indices)) =
self.matcher.fuzzy(&env_var.value, pattern, true)
{
final_score = max(final_score, score);
Some(indices.iter().map(|i| (*i, *i + 1)).collect())
} else {
None
};
let name_match_ranges = if let Some((score, indices)) =
self.matcher.fuzzy(&env_var.name, pattern, true)
{
final_score = max(final_score, score);
Some(indices.iter().map(|i| (*i, *i + 1)).collect())
} else {
None
};
if preview_match_ranges.is_some() || name_match_ranges.is_some() {
results.push(Entry {
name: env_var.name.clone(),
preview: Some(env_var.value.clone()),
score: final_score,
name_match_ranges,
preview_match_ranges,
icon: Some(self.file_icon.clone()),
line_number: None,
});
}
}
}
// cache the results
self.cache.insert(pattern.to_string(), results.clone());
}
results.into_iter()
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/input/backend.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::event::Key;

use super::{Input, InputRequest, StateChanged};
use ratatui::crossterm::event::{
Event as CrosstermEvent, KeyCode, KeyEvent, KeyEventKind, KeyModifiers,
Expand Down
Loading

0 comments on commit d028163

Please sign in to comment.