Skip to content

Commit

Permalink
massive progress
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpasmantier committed Oct 12, 2024
1 parent b178bd1 commit 05f5f2c
Show file tree
Hide file tree
Showing 112 changed files with 1,968 additions and 673 deletions.
495 changes: 264 additions & 231 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@ categories = [
]


[[bin]]
bench = false
path = "crates/television/main.rs"
name = "tv"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace]
members = [
"crates/television_derive",
]

[dependencies]
television-derive = { path = "crates/television_derive" }
better-panic = "0.3.0"
clap = { version = "4.4.5", features = [
"derive",
Expand All @@ -30,7 +40,7 @@ clap = { version = "4.4.5", features = [
] }
color-eyre = "0.6.3"
config = "0.14.0"
crossterm = { version = "0.28.1", features = ["serde", "event-stream"] }
crossterm = { version = "0.28.1", features = ["serde"] }
derive_deref = "1.1.1"
devicons = "0.5.4"
directories = "5.0.1"
Expand All @@ -39,6 +49,7 @@ fuzzy-matcher = "0.3.7"
human-panic = "2.0.1"
ignore = "0.4.23"
image = "0.25.2"
impl-enum = "0.3.1"
infer = "0.16.0"
json5 = "0.4.1"
lazy_static = "1.5.0"
Expand Down Expand Up @@ -81,3 +92,5 @@ overflow-checks = false
lto = "thin"
panic = "abort"

[target.'cfg(target_os = "macos")'.dependencies]
crossterm = { version = "0.28.1", features = ["serde", "use-dev-tty"] }
5 changes: 3 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
- [x] preview navigation
- [ ] add a way to open the selected file in the default editor
- [x] maybe filter out image types etc. for now
- [ ] return selected entry on exit
- [ ] piping custom entries from stdin (e.g. `ls | tv`, what bout choosing previewers in that case? Some AUTO mode?)
- [x] return selected entry on exit
- [x] piping output to another command
- [x] piping custom entries from stdin (e.g. `ls | tv`, what bout choosing previewers in that case? Some AUTO mode?)

## bugs
- [x] sanitize input (tabs, \0, etc) (see https://github.com/autobib/nucleo-picker/blob/d51dec9efd523e88842c6eda87a19c0a492f4f36/src/lib.rs#L212-L227)
Expand Down
File renamed without changes.
51 changes: 39 additions & 12 deletions src/app.rs → crates/television/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use tracing::{debug, info};

use crate::{
action::Action,
cli::UnitTvChannel,
cli::CliTvChannel,
components::{television::Television, Component, Entry},
config::Config,
event::{Event, EventLoop, Key},
Expand All @@ -82,7 +82,9 @@ pub struct App {
render_tx: mpsc::UnboundedSender<RenderingTask>,
}

#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(
Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize,
)]
pub enum Mode {
#[default]
Help,
Expand All @@ -92,7 +94,11 @@ pub enum Mode {
}

impl App {
pub fn new(channel: UnitTvChannel, tick_rate: f64, frame_rate: f64) -> Result<Self> {
pub fn new(
channel: CliTvChannel,
tick_rate: f64,
frame_rate: f64,
) -> Result<Self> {
let (action_tx, action_rx) = mpsc::unbounded_channel();
let (render_tx, _) = mpsc::unbounded_channel();
let (_, event_rx) = mpsc::unbounded_channel();
Expand All @@ -115,7 +121,7 @@ impl App {
})
}

pub async fn run(&mut self) -> Result<Option<Entry>> {
pub async fn run(&mut self, is_output_tty: bool) -> Result<Option<Entry>> {
info!("Starting backend event loop");
let event_loop = EventLoop::new(self.tick_rate, true);
self.event_rx = event_loop.rx;
Expand All @@ -129,14 +135,15 @@ impl App {
let config_r = self.config.clone();
let television_r = self.television.clone();
let frame_rate = self.frame_rate;
tokio::spawn(async move {
let rendering_task = tokio::spawn(async move {
render(
render_rx,
//render_tx,
action_tx_r,
config_r,
television_r,
frame_rate,
is_output_tty,
)
.await
});
Expand All @@ -156,6 +163,10 @@ impl App {
if self.should_quit {
// send a termination signal to the event loop
self.event_abort_tx.send(())?;

// wait for the rendering task to finish
rendering_task.await??;

return Ok(maybe_selected);
}
}
Expand All @@ -174,8 +185,12 @@ impl App {
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::Home | Key::Ctrl('a') => {
return Action::GoToInputStart
}
Key::End | Key::Ctrl('e') => {
return Action::GoToInputEnd
}
Key::Char(c) => return Action::AddInputChar(c),
_ => {}
}
Expand Down Expand Up @@ -221,14 +236,26 @@ impl App {
Action::SelectEntry => {
self.should_quit = true;
self.render_tx.send(RenderingTask::Quit)?;
return Ok(self.television.lock().await.get_selected_entry());
return Ok(self
.television
.lock()
.await
.get_selected_entry());
}
Action::ClearScreen => {
self.render_tx.send(RenderingTask::ClearScreen)?
}
Action::Resize(w, h) => {
self.render_tx.send(RenderingTask::Resize(w, h))?
}
Action::Render => {
self.render_tx.send(RenderingTask::Render)?
}
Action::ClearScreen => self.render_tx.send(RenderingTask::ClearScreen)?,
Action::Resize(w, h) => self.render_tx.send(RenderingTask::Resize(w, h))?,
Action::Render => self.render_tx.send(RenderingTask::Render)?,
_ => {}
}
if let Some(action) = self.television.lock().await.update(action.clone()).await? {
if let Some(action) =
self.television.lock().await.update(action.clone()).await?
{
self.action_tx.send(action)?;
};
}
Expand Down
10 changes: 6 additions & 4 deletions src/cli.rs → crates/television/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ use clap::{Parser, ValueEnum};
use crate::config::{get_config_dir, get_data_dir};

#[derive(Clone, ValueEnum, Debug, Default, Copy)]
pub enum UnitTvChannel {
#[default]
pub enum CliTvChannel {
Env,
#[default]
Files,
Grep,
Stdin,
Alias,
}

#[derive(Parser, Debug)]
#[command(author, version = version(), about)]
pub struct Cli {
/// Which channel shall we watch?
#[arg(value_enum)]
pub channel: UnitTvChannel,
#[arg(value_enum, default_value = "files")]
pub channel: CliTvChannel,

/// Tick rate, i.e. number of ticks per second
#[arg(short, long, value_name = "FLOAT", default_value_t = 50.0)]
Expand Down
5 changes: 4 additions & 1 deletion src/components.rs → crates/television/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ pub trait Component: Send {
/// # Returns
///
/// * `Result<()>` - An Ok result or an error.
fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> Result<()> {
fn register_action_handler(
&mut self,
tx: UnboundedSender<Action>,
) -> Result<()> {
let _ = tx; // to appease clippy
Ok(())
}
Expand Down
41 changes: 41 additions & 0 deletions crates/television/components/channels.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::cli::CliTvChannel;
use crate::components::finders::Entry;
use crate::components::finders::{
AliasFinder, EnvVarFinder, FileFinder, GrepFinder, StdinFinder,
};

use super::finders::Finder;

#[derive(television_derive::Channel, television_derive::FromCliChannel)]
pub enum TvChannel {
Env(EnvChannel),
Files(FilesChannel),
Grep(GrepChannel),
Stdin(StdinChannel),
Alias(AliasChannel),
}

#[derive(television_derive::ConcreteChannel)]
pub struct EnvChannel {
pub finder: EnvVarFinder,
}

#[derive(television_derive::ConcreteChannel)]
pub struct FilesChannel {
pub finder: FileFinder,
}

#[derive(television_derive::ConcreteChannel)]
pub struct GrepChannel {
pub finder: GrepFinder,
}

#[derive(television_derive::ConcreteChannel)]
pub struct StdinChannel {
pub finder: StdinFinder,
}

#[derive(television_derive::ConcreteChannel)]
pub struct AliasChannel {
pub finder: AliasFinder,
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use devicons::FileIcon;

mod alias;
mod env;
mod files;
mod grep;
mod stdin;

// finder types
pub use alias::AliasFinder;
pub use env::EnvVarFinder;
pub use files::FileFinder;
pub use grep::GrepFinder;
pub use stdin::StdinFinder;

use super::previewers::PreviewType;

Expand All @@ -31,10 +35,10 @@ impl Entry {
pub fn stdout_repr(&self) -> String {
let mut repr = self.name.clone();
if let Some(line_number) = self.line_number {
repr.push_str(&format!(":{}", line_number));
repr.push_str(&format!(":{line_number}"));
}
if let Some(preview) = &self.preview {
repr.push_str(&format!("\n{}", preview));
repr.push_str(&format!("\n{preview}"));
}
repr
}
Expand All @@ -59,7 +63,11 @@ pub const ENTRY_PLACEHOLDER: Entry = Entry {
pub trait Finder {
fn find(&mut self, pattern: &str);

fn results(&mut self, num_entries: u32, offset: u32) -> impl Iterator<Item = Entry>;
fn results(
&mut self,
num_entries: u32,
offset: u32,
) -> impl Iterator<Item = Entry>;

fn get_result(&self, index: u32) -> Option<Entry>;

Expand Down
Loading

0 comments on commit 05f5f2c

Please sign in to comment.