mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 19:45:23 +00:00
wip: checkpoint
This commit is contained in:
parent
59bba56ab1
commit
1bf67b537f
@ -8,12 +8,12 @@ use ratatui::prelude::{Line, Style};
|
||||
use ratatui::style::Color;
|
||||
use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding};
|
||||
use ratatui::Terminal;
|
||||
use television::channels::cable::prototypes::CableChannelPrototypes;
|
||||
use television::{
|
||||
action::Action,
|
||||
channels::{
|
||||
cable::prototypes::CableChannelPrototype,
|
||||
entry::{into_ranges, Entry},
|
||||
preview::PreviewType,
|
||||
OnAir, TelevisionChannel,
|
||||
},
|
||||
config::{Config, ConfigEnv},
|
||||
@ -37,7 +37,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#7e8e91",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/README.md".to_string(),
|
||||
@ -49,7 +48,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#dddddd",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/re.pyi".to_string(),
|
||||
@ -61,7 +59,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/io.pyi".to_string(),
|
||||
@ -73,7 +70,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/gc.pyi".to_string(),
|
||||
@ -85,7 +81,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/uu.pyi".to_string(),
|
||||
@ -97,7 +92,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/nt.pyi".to_string(),
|
||||
@ -109,7 +103,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/dis.pyi".to_string(),
|
||||
@ -121,7 +114,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/imp.pyi".to_string(),
|
||||
@ -133,7 +125,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/bdb.pyi".to_string(),
|
||||
@ -145,7 +136,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/abc.pyi".to_string(),
|
||||
@ -157,7 +147,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/cgi.pyi".to_string(),
|
||||
@ -169,7 +158,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/bz2.pyi".to_string(),
|
||||
@ -181,7 +169,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/grp.pyi".to_string(),
|
||||
@ -193,7 +180,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/ast.pyi".to_string(),
|
||||
@ -205,7 +191,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/csv.pyi".to_string(),
|
||||
@ -217,7 +202,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/pdb.pyi".to_string(),
|
||||
@ -229,7 +213,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/pwd.pyi".to_string(),
|
||||
@ -241,7 +224,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/ssl.pyi".to_string(),
|
||||
@ -253,7 +235,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/tty.pyi".to_string(),
|
||||
@ -265,7 +246,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/nis.pyi".to_string(),
|
||||
@ -277,7 +257,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/pty.pyi".to_string(),
|
||||
@ -289,7 +268,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/cmd.pyi".to_string(),
|
||||
@ -301,7 +279,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/tests/utils.py".to_string(),
|
||||
@ -313,7 +290,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/pyproject.toml".to_string(),
|
||||
@ -325,7 +301,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#9c4221",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/MAINTAINERS.md".to_string(),
|
||||
@ -337,7 +312,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#dddddd",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/enum.pyi".to_string(),
|
||||
@ -349,7 +323,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/hmac.pyi".to_string(),
|
||||
@ -361,7 +334,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/uuid.pyi".to_string(),
|
||||
@ -373,7 +345,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/glob.pyi".to_string(),
|
||||
@ -385,7 +356,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/_ast.pyi".to_string(),
|
||||
@ -397,7 +367,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/_csv.pyi".to_string(),
|
||||
@ -409,7 +378,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/code.pyi".to_string(),
|
||||
@ -421,7 +389,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/spwd.pyi".to_string(),
|
||||
@ -433,7 +400,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/_msi.pyi".to_string(),
|
||||
@ -445,7 +411,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
},
|
||||
Entry {
|
||||
name: "typeshed/stdlib/time.pyi".to_string(),
|
||||
@ -456,7 +421,6 @@ pub fn draw_results_list(c: &mut Criterion) {
|
||||
color: "#ffbc03",
|
||||
}),
|
||||
line_number: None,
|
||||
preview_type: PreviewType::Files,
|
||||
name_match_ranges: Some(into_ranges(&[0, 1, 2, 3])),
|
||||
value_match_ranges: None,
|
||||
},
|
||||
@ -514,7 +478,14 @@ pub fn draw(c: &mut Criterion) {
|
||||
channel.find("television");
|
||||
// Wait for the channel to finish loading
|
||||
let mut tv = Television::new(
|
||||
tx, channel, config, None, false, false, false,
|
||||
tx,
|
||||
channel,
|
||||
config,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
CableChannelPrototypes::default(),
|
||||
);
|
||||
for _ in 0..5 {
|
||||
// tick the matcher
|
||||
|
@ -4,6 +4,7 @@ use anyhow::Result;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
use crate::channels::cable::prototypes::CableChannelPrototypes;
|
||||
use crate::channels::{entry::Entry, OnAir, TelevisionChannel};
|
||||
use crate::config::{default_tick_rate, Config};
|
||||
use crate::keymap::Keymap;
|
||||
@ -96,6 +97,8 @@ pub struct App {
|
||||
/// Render task handle
|
||||
render_task: Option<tokio::task::JoinHandle<Result<()>>>,
|
||||
options: AppOptions,
|
||||
/// The cable channels that are available.
|
||||
cable_channels: CableChannelPrototypes,
|
||||
}
|
||||
|
||||
/// The outcome of an action.
|
||||
@ -139,6 +142,7 @@ impl App {
|
||||
config: Config,
|
||||
input: Option<String>,
|
||||
options: AppOptions,
|
||||
cable_channels: CableChannelPrototypes,
|
||||
) -> Self {
|
||||
let (action_tx, action_rx) = mpsc::unbounded_channel();
|
||||
let (render_tx, render_rx) = mpsc::unbounded_channel();
|
||||
@ -156,6 +160,7 @@ impl App {
|
||||
options.no_remote,
|
||||
options.no_help,
|
||||
options.exact,
|
||||
CableChannelPrototypes(cable_channels.clone()),
|
||||
);
|
||||
|
||||
Self {
|
||||
@ -173,6 +178,7 @@ impl App {
|
||||
ui_state_tx,
|
||||
render_task: None,
|
||||
options,
|
||||
cable_channels,
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +204,7 @@ impl App {
|
||||
// Event loop
|
||||
if !headless {
|
||||
debug!("Starting backend event loop");
|
||||
let event_loop = EventLoop::new(self.options.tick_rate, true);
|
||||
let event_loop = EventLoop::new(self.options.tick_rate);
|
||||
self.event_rx = event_loop.rx;
|
||||
self.event_abort_tx = event_loop.abort_tx;
|
||||
}
|
||||
@ -437,15 +443,18 @@ impl App {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::channels::stdin::Channel as StdinChannel;
|
||||
use crate::channels::cable::Channel as CableChannel;
|
||||
|
||||
#[test]
|
||||
fn test_maybe_select_1() {
|
||||
let mut app = App::new(
|
||||
TelevisionChannel::Stdin(StdinChannel::new(None)),
|
||||
TelevisionChannel::Cable(CableChannel::new(
|
||||
"random", "cat", false, None,
|
||||
)),
|
||||
Config::default(),
|
||||
None,
|
||||
AppOptions::default(),
|
||||
CableChannelPrototypes::default(),
|
||||
);
|
||||
app.television
|
||||
.results_picker
|
||||
|
@ -6,7 +6,9 @@ use anyhow::Result;
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::{
|
||||
channels::cable::prototypes::{CableChannelPrototype, CableChannels},
|
||||
channels::cable::prototypes::{
|
||||
CableChannelPrototype, CableChannelPrototypes,
|
||||
},
|
||||
config::get_config_dir,
|
||||
};
|
||||
|
||||
@ -40,7 +42,7 @@ const DEFAULT_CABLE_CHANNELS: &str =
|
||||
/// ├── my_channels.toml
|
||||
/// └── windows_channels.toml
|
||||
/// ```
|
||||
pub fn load_cable_channels() -> Result<CableChannels> {
|
||||
pub fn load_cable_channels() -> Result<CableChannelPrototypes> {
|
||||
let config_dir = get_config_dir();
|
||||
|
||||
// list all files in the config directory
|
||||
@ -95,7 +97,7 @@ pub fn load_cable_channels() -> Result<CableChannels> {
|
||||
{
|
||||
cable_channels.insert(prototype.name.clone(), prototype);
|
||||
}
|
||||
Ok(CableChannels(cable_channels))
|
||||
Ok(CableChannelPrototypes(cable_channels))
|
||||
}
|
||||
|
||||
fn is_cable_file_format<P>(p: P) -> bool
|
||||
|
@ -18,7 +18,7 @@ pub struct Channel {
|
||||
pub name: String,
|
||||
matcher: Matcher<String>,
|
||||
entries_command: String,
|
||||
preview_command: Option<PreviewCommand>,
|
||||
pub preview_command: Option<PreviewCommand>,
|
||||
selected_entries: FxHashSet<Entry>,
|
||||
crawl_handle: tokio::task::JoinHandle<()>,
|
||||
}
|
||||
@ -29,7 +29,7 @@ impl Default for Channel {
|
||||
"files",
|
||||
"find . -type f",
|
||||
false,
|
||||
Some(PreviewCommand::new("cat {}", ":")),
|
||||
Some(PreviewCommand::new("cat {}", ":", None)),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -46,6 +46,7 @@ impl From<CableChannelPrototype> for Channel {
|
||||
&prototype
|
||||
.preview_delimiter
|
||||
.unwrap_or(DEFAULT_DELIMITER.to_string()),
|
||||
prototype.preview_offset,
|
||||
)),
|
||||
None => None,
|
||||
},
|
||||
|
@ -106,9 +106,11 @@ impl Display for CableChannelPrototype {
|
||||
/// in a way that facilitates answering questions like "what's the prototype
|
||||
/// for `files`?" or "does this channel exist?".
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct CableChannels(pub FxHashMap<String, CableChannelPrototype>);
|
||||
pub struct CableChannelPrototypes(
|
||||
pub FxHashMap<String, CableChannelPrototype>,
|
||||
);
|
||||
|
||||
impl Deref for CableChannels {
|
||||
impl Deref for CableChannelPrototypes {
|
||||
type Target = FxHashMap<String, CableChannelPrototype>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
@ -127,18 +129,18 @@ const DEFAULT_CABLE_CHANNELS_FILE: &str =
|
||||
const DEFAULT_CABLE_CHANNELS_FILE: &str =
|
||||
include_str!("../../cable/windows-channels.toml");
|
||||
|
||||
impl Default for CableChannels {
|
||||
impl Default for CableChannelPrototypes {
|
||||
/// Fallback to the default cable channels specification (the template file
|
||||
/// included in the repo).
|
||||
fn default() -> Self {
|
||||
let pts = toml::from_str::<SerializedChannelPrototypes>(
|
||||
let s = toml::from_str::<SerializedChannelPrototypes>(
|
||||
DEFAULT_CABLE_CHANNELS_FILE,
|
||||
)
|
||||
.expect("Unable to parse default cable channels");
|
||||
let mut channels = FxHashMap::default();
|
||||
for prototype in pts.prototypes {
|
||||
channels.insert(prototype.name.clone(), prototype);
|
||||
let mut prototypes = FxHashMap::default();
|
||||
for prototype in s.prototypes {
|
||||
prototypes.insert(prototype.name.clone(), prototype);
|
||||
}
|
||||
CableChannels(channels)
|
||||
CableChannelPrototypes(prototypes)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ pub mod cable;
|
||||
pub mod entry;
|
||||
pub mod preview;
|
||||
pub mod remote_control;
|
||||
pub mod stdin;
|
||||
// pub mod stdin;
|
||||
|
||||
/// The interface that all television channels must implement.
|
||||
///
|
||||
@ -118,7 +118,7 @@ pub enum TelevisionChannel {
|
||||
/// The standard input channel.
|
||||
///
|
||||
/// This channel allows to search through whatever is passed through stdin.
|
||||
Stdin(stdin::Channel),
|
||||
// Stdin(stdin::Channel),
|
||||
/// The remote control channel.
|
||||
///
|
||||
/// This channel allows to switch between different channels.
|
||||
@ -142,7 +142,7 @@ impl TelevisionChannel {
|
||||
pub fn name(&self) -> String {
|
||||
match self {
|
||||
TelevisionChannel::Cable(channel) => channel.name.clone(),
|
||||
TelevisionChannel::Stdin(_) => String::from("Stdin"),
|
||||
// TelevisionChannel::Stdin(_) => String::from("Stdin"),
|
||||
TelevisionChannel::RemoteControl(_) => String::from("Remote"),
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use lazy_regex::{regex, Lazy, Regex};
|
||||
|
||||
use super::entry::Entry;
|
||||
use crate::channels::cable::prototypes::CableChannelPrototype;
|
||||
use lazy_regex::{regex, Lazy, Regex};
|
||||
|
||||
static CMD_RE: &Lazy<Regex> = regex!(r"\{(\d+)\}");
|
||||
|
||||
@ -10,13 +10,19 @@ static CMD_RE: &Lazy<Regex> = regex!(r"\{(\d+)\}");
|
||||
pub struct PreviewCommand {
|
||||
pub command: String,
|
||||
pub delimiter: String,
|
||||
pub offset_expr: Option<String>,
|
||||
}
|
||||
|
||||
impl PreviewCommand {
|
||||
pub fn new(command: &str, delimiter: &str) -> Self {
|
||||
pub fn new(
|
||||
command: &str,
|
||||
delimiter: &str,
|
||||
offset_expr: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
command: command.to_string(),
|
||||
delimiter: delimiter.to_string(),
|
||||
offset_expr,
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +35,7 @@ impl PreviewCommand {
|
||||
/// let command = PreviewCommand {
|
||||
/// command: "something {} {2} {0}".to_string(),
|
||||
/// delimiter: ":".to_string(),
|
||||
/// offset_expr: None,
|
||||
/// };
|
||||
/// let entry = Entry::new("a:given:entry:to:preview".to_string());
|
||||
///
|
||||
@ -55,6 +62,29 @@ impl PreviewCommand {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&CableChannelPrototype> for PreviewCommand {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: &CableChannelPrototype) -> Result<Self, Self::Error> {
|
||||
let command = value
|
||||
.preview_command
|
||||
.as_ref()
|
||||
.expect("Preview command is not set.");
|
||||
|
||||
let delimiter = value
|
||||
.preview_delimiter
|
||||
.as_ref()
|
||||
.expect("Preview delimiter is not set");
|
||||
|
||||
let offset_expr = value.preview_offset.clone();
|
||||
|
||||
// FIXME: handle offset here (side note: we don't want to reparse the offset
|
||||
// expression for each entry, so maybe just parse it once and try to store it
|
||||
// as some sort of function we can call later on
|
||||
Ok(PreviewCommand::new(command, delimiter, offset_expr))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PreviewCommand {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
@ -71,6 +101,7 @@ mod tests {
|
||||
let command = PreviewCommand {
|
||||
command: "something {} {2} {0}".to_string(),
|
||||
delimiter: ":".to_string(),
|
||||
offset_expr: None,
|
||||
};
|
||||
let entry = Entry::new("an:entry:to:preview".to_string());
|
||||
let formatted_command = command.format_with(&entry);
|
||||
@ -86,6 +117,7 @@ mod tests {
|
||||
let command = PreviewCommand {
|
||||
command: "something".to_string(),
|
||||
delimiter: ":".to_string(),
|
||||
offset_expr: None,
|
||||
};
|
||||
let entry = Entry::new("an:entry:to:preview".to_string());
|
||||
let formatted_command = command.format_with(&entry);
|
||||
@ -98,6 +130,7 @@ mod tests {
|
||||
let command = PreviewCommand {
|
||||
command: "something {}".to_string(),
|
||||
delimiter: ":".to_string(),
|
||||
offset_expr: None,
|
||||
};
|
||||
let entry = Entry::new("an:entry:to:preview".to_string());
|
||||
let formatted_command = command.format_with(&entry);
|
||||
@ -110,6 +143,7 @@ mod tests {
|
||||
let command = PreviewCommand {
|
||||
command: "something {0} -t {2}".to_string(),
|
||||
delimiter: ":".to_string(),
|
||||
offset_expr: None,
|
||||
};
|
||||
let entry = Entry::new("an:entry:to:preview".to_string());
|
||||
let formatted_command = command.format_with(&entry);
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::channels::cable::prototypes::CableChannels;
|
||||
use crate::channels::cable::prototypes::CableChannelPrototypes;
|
||||
use crate::channels::entry::Entry;
|
||||
use crate::channels::{OnAir, TelevisionChannel};
|
||||
use crate::matcher::{config::Config, Matcher};
|
||||
@ -12,19 +12,19 @@ use super::cable;
|
||||
|
||||
pub struct RemoteControl {
|
||||
matcher: Matcher<String>,
|
||||
cable_channels: Option<CableChannels>,
|
||||
cable_channels: Option<CableChannelPrototypes>,
|
||||
selected_entries: FxHashSet<Entry>,
|
||||
}
|
||||
|
||||
const NUM_THREADS: usize = 1;
|
||||
|
||||
impl RemoteControl {
|
||||
pub fn new(cable_channels: Option<CableChannels>) -> Self {
|
||||
pub fn new(cable_channels: Option<CableChannelPrototypes>) -> Self {
|
||||
let matcher = Matcher::new(Config::default().n_threads(NUM_THREADS));
|
||||
let injector = matcher.injector();
|
||||
for c in cable_channels
|
||||
.as_ref()
|
||||
.unwrap_or(&CableChannels::default())
|
||||
.unwrap_or(&CableChannelPrototypes::default())
|
||||
.keys()
|
||||
{
|
||||
let () = injector.push(c.clone(), |e, cols| {
|
||||
|
@ -13,7 +13,7 @@ use crate::matcher::{config::Config, injector::Injector, Matcher};
|
||||
|
||||
pub struct Channel {
|
||||
matcher: Matcher<String>,
|
||||
preview_command: Option<PreviewCommand>,
|
||||
pub preview_command: Option<PreviewCommand>,
|
||||
selected_entries: FxHashSet<Entry>,
|
||||
instream_handle: std::thread::JoinHandle<()>,
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use anyhow::{anyhow, Result};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::channels::cable::prototypes::{
|
||||
CableChannelPrototype, CableChannels,
|
||||
CableChannelPrototype, CableChannelPrototypes,
|
||||
};
|
||||
use crate::channels::preview::PreviewCommand;
|
||||
use crate::cli::args::{Cli, Command};
|
||||
@ -76,6 +76,8 @@ impl From<Cli> for PostProcessedCli {
|
||||
let preview_command = cli.preview.map(|preview| PreviewCommand {
|
||||
command: preview,
|
||||
delimiter: cli.delimiter.clone(),
|
||||
// TODO: add the --preview-offset option to the CLI
|
||||
offset_expr: None,
|
||||
});
|
||||
|
||||
let channel: CableChannelPrototype;
|
||||
@ -170,7 +172,7 @@ fn parse_keybindings_literal(
|
||||
|
||||
pub fn parse_channel(
|
||||
channel: &str,
|
||||
cable_channels: &CableChannels,
|
||||
cable_channels: &CableChannelPrototypes,
|
||||
) -> Result<CableChannelPrototype> {
|
||||
// try to parse the channel as a cable channel
|
||||
match cable_channels
|
||||
@ -215,7 +217,7 @@ pub fn guess_channel_from_prompt(
|
||||
prompt: &str,
|
||||
command_mapping: &FxHashMap<String, String>,
|
||||
fallback_channel: &str,
|
||||
cable_channels: &CableChannels,
|
||||
cable_channels: &CableChannelPrototypes,
|
||||
) -> Result<CableChannelPrototype> {
|
||||
debug!("Guessing channel from prompt: {}", prompt);
|
||||
// git checkout -qf
|
||||
@ -317,7 +319,8 @@ mod tests {
|
||||
post_processed_cli.preview_command,
|
||||
Some(PreviewCommand {
|
||||
command: "bat -n --color=always {}".to_string(),
|
||||
delimiter: ":".to_string()
|
||||
delimiter: ":".to_string(),
|
||||
offset_expr: None,
|
||||
})
|
||||
);
|
||||
assert_eq!(post_processed_cli.tick_rate, None);
|
||||
@ -377,7 +380,7 @@ mod tests {
|
||||
|
||||
/// Returns a tuple containing a command mapping and a fallback channel.
|
||||
fn guess_channel_from_prompt_setup<'a>(
|
||||
) -> (FxHashMap<String, String>, &'a str, CableChannels) {
|
||||
) -> (FxHashMap<String, String>, &'a str, CableChannelPrototypes) {
|
||||
let mut command_mapping = FxHashMap::default();
|
||||
command_mapping.insert("vim".to_string(), "files".to_string());
|
||||
command_mapping.insert("export".to_string(), "env".to_string());
|
||||
|
@ -115,9 +115,7 @@ impl Display for Key {
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub struct EventLoop {
|
||||
pub rx: mpsc::UnboundedReceiver<Event<Key>>,
|
||||
//tx: mpsc::UnboundedSender<Event<Key>>,
|
||||
pub abort_tx: mpsc::UnboundedSender<()>,
|
||||
//tick_rate: std::time::Duration,
|
||||
}
|
||||
|
||||
struct PollFuture {
|
||||
@ -162,8 +160,7 @@ fn flush_existing_events() {
|
||||
}
|
||||
|
||||
impl EventLoop {
|
||||
// FIXME: this init parameter doesn't seem to be used anymore
|
||||
pub fn new(tick_rate: f64, init: bool) -> Self {
|
||||
pub fn new(tick_rate: f64) -> Self {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
let tick_interval = Duration::from_secs_f64(1.0 / tick_rate);
|
||||
|
||||
@ -171,8 +168,6 @@ impl EventLoop {
|
||||
|
||||
flush_existing_events();
|
||||
|
||||
if init {
|
||||
//let mut reader = crossterm::event::EventStream::new();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
let delay = tokio::time::sleep(tick_interval);
|
||||
@ -219,7 +214,6 @@ impl EventLoop {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
//tx,
|
||||
|
@ -7,7 +7,9 @@ use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use crossterm::terminal::enable_raw_mode;
|
||||
use television::cable;
|
||||
use television::channels::cable::prototypes::CableChannels;
|
||||
use television::channels::cable::prototypes::{
|
||||
CableChannelPrototype, CableChannelPrototypes,
|
||||
};
|
||||
use television::utils::clipboard::CLIPBOARD;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
@ -81,7 +83,8 @@ async fn main() -> Result<()> {
|
||||
args.no_help,
|
||||
config.application.tick_rate,
|
||||
);
|
||||
let mut app = App::new(channel, config, args.input, options);
|
||||
let mut app =
|
||||
App::new(channel, config, args.input, options, cable_channels);
|
||||
stdout().flush()?;
|
||||
debug!("Running application...");
|
||||
let output = app.run(stdout().is_terminal(), false).await?;
|
||||
@ -157,8 +160,8 @@ pub fn determine_channel(
|
||||
args: PostProcessedCli,
|
||||
config: &Config,
|
||||
readable_stdin: bool,
|
||||
cable_channels: &CableChannels,
|
||||
) -> Result<TelevisionChannel> {
|
||||
cable_channels: &CableChannelPrototypes,
|
||||
) -> Result<CableChannelPrototype> {
|
||||
if readable_stdin {
|
||||
debug!("Using stdin channel");
|
||||
Ok(TelevisionChannel::Stdin(StdinChannel::new(
|
||||
@ -197,9 +200,9 @@ mod tests {
|
||||
config: &Config,
|
||||
readable_stdin: bool,
|
||||
expected_channel: &TelevisionChannel,
|
||||
cable_channels: Option<CableChannels>,
|
||||
cable_channels: Option<CableChannelPrototypes>,
|
||||
) {
|
||||
let channels: CableChannels = cable_channels
|
||||
let channels: CableChannelPrototypes = cable_channels
|
||||
.unwrap_or_else(|| load_cable_channels().unwrap_or_default());
|
||||
let channel =
|
||||
determine_channel(args.clone(), config, readable_stdin, &channels)
|
||||
|
@ -1,21 +1,29 @@
|
||||
use crate::action::Action;
|
||||
use crate::cable::load_cable_channels;
|
||||
use crate::channels::entry::{Entry, ENTRY_PLACEHOLDER};
|
||||
use crate::channels::{
|
||||
remote_control::RemoteControl, OnAir, TelevisionChannel,
|
||||
use crate::{
|
||||
action::Action,
|
||||
cable::load_cable_channels,
|
||||
channels::{
|
||||
cable::{prototypes::CableChannelPrototypes, Channel as CableChannel},
|
||||
entry::{Entry, ENTRY_PLACEHOLDER},
|
||||
remote_control::RemoteControl,
|
||||
// stdin::Channel as StdinChannel,
|
||||
OnAir,
|
||||
TelevisionChannel,
|
||||
},
|
||||
config::{Config, Theme},
|
||||
draw::{ChannelState, Ctx, TvState},
|
||||
input::convert_action_to_input_request,
|
||||
picker::Picker,
|
||||
preview::{previewer::Previewer, Preview, PreviewState},
|
||||
render::UiState,
|
||||
screen::{
|
||||
colors::Colorscheme,
|
||||
layout::InputPosition,
|
||||
spinner::{Spinner, SpinnerState},
|
||||
},
|
||||
utils::{
|
||||
clipboard::CLIPBOARD, metadata::AppMetadata, strings::EMPTY_STRING,
|
||||
},
|
||||
};
|
||||
use crate::config::{Config, Theme};
|
||||
use crate::draw::{ChannelState, Ctx, TvState};
|
||||
use crate::input::convert_action_to_input_request;
|
||||
use crate::picker::Picker;
|
||||
use crate::preview::{previewer::Previewer, Preview, PreviewState};
|
||||
use crate::render::UiState;
|
||||
use crate::screen::colors::Colorscheme;
|
||||
use crate::screen::layout::InputPosition;
|
||||
use crate::screen::spinner::{Spinner, SpinnerState};
|
||||
use crate::utils::clipboard::CLIPBOARD;
|
||||
use crate::utils::metadata::AppMetadata;
|
||||
use crate::utils::strings::EMPTY_STRING;
|
||||
use anyhow::Result;
|
||||
use rustc_hash::{FxBuildHasher, FxHashSet};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -45,7 +53,7 @@ pub struct Television {
|
||||
pub matching_mode: MatchingMode,
|
||||
pub results_picker: Picker,
|
||||
pub rc_picker: Picker,
|
||||
pub previewer: Previewer,
|
||||
pub previewer: Option<Previewer>,
|
||||
pub preview_state: PreviewState,
|
||||
pub spinner: Spinner,
|
||||
pub spinner_state: SpinnerState,
|
||||
@ -66,14 +74,24 @@ impl Television {
|
||||
no_remote: bool,
|
||||
no_help: bool,
|
||||
exact: bool,
|
||||
cable_channels: CableChannelPrototypes,
|
||||
) -> Self {
|
||||
let mut results_picker = Picker::new(input.clone());
|
||||
if config.ui.input_bar_position == InputPosition::Bottom {
|
||||
results_picker = results_picker.inverted();
|
||||
}
|
||||
// FIXME: fix this
|
||||
let previewer = Previewer::new();
|
||||
let cable_channels = load_cable_channels().unwrap_or_default();
|
||||
|
||||
let previewer = match &channel {
|
||||
// TelevisionChannel::Stdin(StdinChannel {
|
||||
// preview_command: command,
|
||||
// ..
|
||||
// }) |
|
||||
TelevisionChannel::Cable(CableChannel {
|
||||
preview_command: command,
|
||||
..
|
||||
}) => command.clone().map(Previewer::new),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let app_metadata = AppMetadata::new(
|
||||
env!("CARGO_PKG_VERSION").to_string(),
|
||||
@ -369,10 +387,14 @@ impl Television {
|
||||
&mut self,
|
||||
selected_entry: &Entry,
|
||||
) -> Result<()> {
|
||||
if self.config.ui.show_preview_panel && self.channel.supports_preview()
|
||||
if self.config.ui.show_preview_panel
|
||||
&& self.channel.supports_preview()
|
||||
&& self.previewer.is_some()
|
||||
{
|
||||
// preview content
|
||||
if let Some(preview) = self.previewer.preview(selected_entry) {
|
||||
if let Some(preview) =
|
||||
self.previewer.as_mut().unwrap().preview(selected_entry)
|
||||
{
|
||||
// only update if the preview content has changed
|
||||
if self.preview_state.preview.title != preview.title {
|
||||
self.preview_state.update(
|
||||
|
Loading…
x
Reference in New Issue
Block a user