mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 19:45:23 +00:00
fix(config): use the config default_channel
field as a fallback when no channel is specified
This commit is contained in:
parent
7bbf538898
commit
0b5276c74a
@ -12,7 +12,7 @@ use television::{
|
|||||||
action::Action,
|
action::Action,
|
||||||
channels::{
|
channels::{
|
||||||
entry::{into_ranges, Entry},
|
entry::{into_ranges, Entry},
|
||||||
prototypes::{Cable, ChannelPrototype},
|
prototypes::Cable,
|
||||||
},
|
},
|
||||||
config::{Config, ConfigEnv},
|
config::{Config, ConfigEnv},
|
||||||
screen::{colors::ResultsColorscheme, results::build_results_list},
|
screen::{colors::ResultsColorscheme, results::build_results_list},
|
||||||
@ -464,6 +464,8 @@ pub fn draw(c: &mut Criterion) {
|
|||||||
|
|
||||||
let rt = Runtime::new().unwrap();
|
let rt = Runtime::new().unwrap();
|
||||||
|
|
||||||
|
let cable = Cable::default();
|
||||||
|
|
||||||
c.bench_function("draw", |b| {
|
c.bench_function("draw", |b| {
|
||||||
b.to_async(&rt).iter_batched(
|
b.to_async(&rt).iter_batched(
|
||||||
// FIXME: this is kind of hacky
|
// FIXME: this is kind of hacky
|
||||||
@ -472,7 +474,7 @@ pub fn draw(c: &mut Criterion) {
|
|||||||
let backend = TestBackend::new(width, height);
|
let backend = TestBackend::new(width, height);
|
||||||
let terminal = Terminal::new(backend).unwrap();
|
let terminal = Terminal::new(backend).unwrap();
|
||||||
let (tx, _) = tokio::sync::mpsc::unbounded_channel();
|
let (tx, _) = tokio::sync::mpsc::unbounded_channel();
|
||||||
let channel_prototype = ChannelPrototype::default();
|
let channel_prototype = cable.get_channel("files");
|
||||||
// Wait for the channel to finish loading
|
// Wait for the channel to finish loading
|
||||||
let mut tv = Television::new(
|
let mut tv = Television::new(
|
||||||
tx,
|
tx,
|
||||||
|
@ -4,7 +4,10 @@ use std::{
|
|||||||
ops::Deref,
|
ops::Deref,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{cable::CableSpec, channels::preview::PreviewCommand};
|
use crate::{
|
||||||
|
cable::CableSpec, channels::preview::PreviewCommand,
|
||||||
|
cli::unknown_channel_exit,
|
||||||
|
};
|
||||||
|
|
||||||
/// A prototype for cable channels.
|
/// A prototype for cable channels.
|
||||||
///
|
///
|
||||||
@ -73,19 +76,19 @@ impl ChannelPrototype {
|
|||||||
preview_command: preview,
|
preview_command: preview,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_preview(self, preview_command: Option<PreviewCommand>) -> Self {
|
||||||
|
Self::new(
|
||||||
|
&self.name,
|
||||||
|
&self.source_command,
|
||||||
|
self.interactive,
|
||||||
|
preview_command,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULT_PROTOTYPE_NAME: &str = "files";
|
pub const DEFAULT_PROTOTYPE_NAME: &str = "files";
|
||||||
|
|
||||||
impl Default for ChannelPrototype {
|
|
||||||
fn default() -> Self {
|
|
||||||
Cable::default()
|
|
||||||
.get(DEFAULT_PROTOTYPE_NAME)
|
|
||||||
.cloned()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for ChannelPrototype {
|
impl Display for ChannelPrototype {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.name)
|
write!(f, "{}", self.name)
|
||||||
@ -109,12 +112,14 @@ impl Deref for Cable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Cable {
|
impl Cable {
|
||||||
pub fn default_channel(&self) -> ChannelPrototype {
|
pub fn get_channel(&self, name: &str) -> ChannelPrototype {
|
||||||
self.get(DEFAULT_PROTOTYPE_NAME)
|
self.get(name)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| unknown_channel_exit(name))
|
||||||
panic!("Default channel '{DEFAULT_PROTOTYPE_NAME}' not found")
|
}
|
||||||
})
|
|
||||||
|
pub fn has_channel(&self, name: &str) -> bool {
|
||||||
|
self.contains_key(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ pub mod args;
|
|||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PostProcessedCli {
|
pub struct PostProcessedCli {
|
||||||
pub channel: ChannelPrototype,
|
pub channel: Option<String>,
|
||||||
pub preview_command: Option<PreviewCommand>,
|
pub preview_command: Option<PreviewCommand>,
|
||||||
pub no_preview: bool,
|
pub no_preview: bool,
|
||||||
pub tick_rate: Option<f64>,
|
pub tick_rate: Option<f64>,
|
||||||
@ -40,7 +40,7 @@ pub struct PostProcessedCli {
|
|||||||
impl Default for PostProcessedCli {
|
impl Default for PostProcessedCli {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
channel: ChannelPrototype::default(),
|
channel: None,
|
||||||
preview_command: None,
|
preview_command: None,
|
||||||
no_preview: false,
|
no_preview: false,
|
||||||
tick_rate: None,
|
tick_rate: None,
|
||||||
@ -60,87 +60,59 @@ impl Default for PostProcessedCli {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Cli> for PostProcessedCli {
|
pub fn post_process(cli: Cli, cable: &Cable) -> PostProcessedCli {
|
||||||
fn from(cli: Cli) -> Self {
|
// Parse literal keybindings passed through the CLI
|
||||||
// parse literal keybindings passed through the CLI
|
let keybindings = cli.keybindings.as_ref().map(|kb| {
|
||||||
let keybindings: Option<KeyBindings> = cli.keybindings.map(|kb| {
|
parse_keybindings_literal(kb, CLI_KEYBINDINGS_DELIMITER)
|
||||||
parse_keybindings_literal(&kb, CLI_KEYBINDINGS_DELIMITER)
|
.unwrap_or_else(|e| cli_parsing_error_exit(&e.to_string()))
|
||||||
.map_err(|e| {
|
});
|
||||||
cli_parsing_error_exit(&e.to_string());
|
|
||||||
})
|
|
||||||
.unwrap()
|
|
||||||
});
|
|
||||||
|
|
||||||
// parse the preview command if provided
|
// Parse the preview command if provided
|
||||||
let preview_command = cli.preview.map(|preview| PreviewCommand {
|
let preview_command = cli.preview.as_ref().map(|preview| PreviewCommand {
|
||||||
command: preview,
|
command: preview.clone(),
|
||||||
delimiter: cli.delimiter.clone(),
|
delimiter: cli.delimiter.clone(),
|
||||||
offset_expr: cli.preview_offset.clone(),
|
offset_expr: cli.preview_offset.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut channel: ChannelPrototype;
|
// Determine channel and working_directory
|
||||||
let working_directory: Option<String>;
|
let (channel, working_directory) = match &cli.channel {
|
||||||
|
Some(c) if !cable.has_channel(c) => {
|
||||||
let cable = cable::load_cable().unwrap_or_default();
|
if cli.working_directory.is_none() && Path::new(c).exists() {
|
||||||
if cli.channel.is_none() {
|
(None, Some(c.clone()))
|
||||||
channel = cable.default_channel();
|
} else {
|
||||||
working_directory = cli.working_directory;
|
unknown_channel_exit(c);
|
||||||
} else {
|
|
||||||
let cli_channel = cli.channel.as_ref().unwrap().to_owned();
|
|
||||||
match parse_channel(&cli_channel, &cable) {
|
|
||||||
Ok(p) => {
|
|
||||||
channel = p;
|
|
||||||
working_directory = cli.working_directory;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
// if the path is provided as first argument and it exists, use it as the working
|
|
||||||
// directory and default to the files channel
|
|
||||||
if cli.working_directory.is_none()
|
|
||||||
&& Path::new(&cli_channel).exists()
|
|
||||||
{
|
|
||||||
channel = cable.default_channel();
|
|
||||||
working_directory = Some(cli.channel.unwrap().clone());
|
|
||||||
} else {
|
|
||||||
unknown_channel_exit(&cli.channel.unwrap());
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => (cli.channel.clone(), cli.working_directory.clone()),
|
||||||
|
};
|
||||||
|
|
||||||
// override the default previewer
|
PostProcessedCli {
|
||||||
if let Some(preview_cmd) = &preview_command {
|
channel,
|
||||||
channel.preview_command = Some(preview_cmd.clone());
|
preview_command,
|
||||||
}
|
no_preview: cli.no_preview,
|
||||||
|
tick_rate: cli.tick_rate,
|
||||||
Self {
|
frame_rate: cli.frame_rate,
|
||||||
channel,
|
input: cli.input,
|
||||||
preview_command,
|
custom_header: cli.custom_header,
|
||||||
no_preview: cli.no_preview,
|
command: cli.command,
|
||||||
tick_rate: cli.tick_rate,
|
working_directory,
|
||||||
frame_rate: cli.frame_rate,
|
autocomplete_prompt: cli.autocomplete_prompt,
|
||||||
input: cli.input,
|
keybindings,
|
||||||
custom_header: cli.custom_header,
|
exact: cli.exact,
|
||||||
command: cli.command,
|
select_1: cli.select_1,
|
||||||
working_directory,
|
no_remote: cli.no_remote,
|
||||||
autocomplete_prompt: cli.autocomplete_prompt,
|
no_help: cli.no_help,
|
||||||
keybindings,
|
ui_scale: cli.ui_scale,
|
||||||
exact: cli.exact,
|
|
||||||
select_1: cli.select_1,
|
|
||||||
no_remote: cli.no_remote,
|
|
||||||
no_help: cli.no_help,
|
|
||||||
ui_scale: cli.ui_scale,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cli_parsing_error_exit(message: &str) {
|
fn cli_parsing_error_exit(message: &str) -> ! {
|
||||||
eprintln!("Error parsing CLI arguments: {message}\n");
|
eprintln!("Error parsing CLI arguments: {message}\n");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unknown_channel_exit(channel: &str) {
|
pub fn unknown_channel_exit(channel: &str) -> ! {
|
||||||
eprintln!("Unknown channel: {channel}\n");
|
eprintln!("Channel not found: {channel}\n");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,20 +137,6 @@ fn parse_keybindings_literal(
|
|||||||
toml::from_str(&toml_definition).map_err(|e| anyhow!(e))
|
toml::from_str(&toml_definition).map_err(|e| anyhow!(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_channel(
|
|
||||||
channel: &str,
|
|
||||||
cable_channels: &Cable,
|
|
||||||
) -> Result<ChannelPrototype> {
|
|
||||||
// try to parse the channel as a cable channel
|
|
||||||
match cable_channels
|
|
||||||
.iter()
|
|
||||||
.find(|(k, _)| k.to_lowercase() == channel)
|
|
||||||
{
|
|
||||||
Some((_, v)) => Ok(v.clone()),
|
|
||||||
None => Err(anyhow!("The following channel wasn't found among cable channels: {channel}")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_channels() {
|
pub fn list_channels() {
|
||||||
for c in cable::load_cable().unwrap_or_default().keys() {
|
for c in cable::load_cable().unwrap_or_default().keys() {
|
||||||
println!("\t{c}");
|
println!("\t{c}");
|
||||||
@ -212,17 +170,17 @@ pub fn guess_channel_from_prompt(
|
|||||||
prompt: &str,
|
prompt: &str,
|
||||||
command_mapping: &FxHashMap<String, String>,
|
command_mapping: &FxHashMap<String, String>,
|
||||||
fallback_channel: &str,
|
fallback_channel: &str,
|
||||||
cable_channels: &Cable,
|
cable: &Cable,
|
||||||
) -> Result<ChannelPrototype> {
|
) -> ChannelPrototype {
|
||||||
debug!("Guessing channel from prompt: {}", prompt);
|
debug!("Guessing channel from prompt: {}", prompt);
|
||||||
// git checkout -qf
|
// git checkout -qf
|
||||||
// --- -------- --- <---------
|
// --- -------- --- <---------
|
||||||
let fallback = cable_channels
|
let fallback = cable
|
||||||
.get(fallback_channel)
|
.get(fallback_channel)
|
||||||
.expect("Fallback channel not found in cable channels")
|
.expect("Fallback channel not found in cable channels")
|
||||||
.clone();
|
.clone();
|
||||||
if prompt.trim().is_empty() {
|
if prompt.trim().is_empty() {
|
||||||
return Ok(fallback);
|
return fallback;
|
||||||
}
|
}
|
||||||
let rev_prompt_words = prompt.split_whitespace().rev();
|
let rev_prompt_words = prompt.split_whitespace().rev();
|
||||||
let mut stack = Vec::new();
|
let mut stack = Vec::new();
|
||||||
@ -236,7 +194,7 @@ pub fn guess_channel_from_prompt(
|
|||||||
for word in rev_prompt_words.clone() {
|
for word in rev_prompt_words.clone() {
|
||||||
// if the stack is empty, we have a match
|
// if the stack is empty, we have a match
|
||||||
if stack.is_empty() {
|
if stack.is_empty() {
|
||||||
return parse_channel(channel, cable_channels);
|
return cable.get_channel(channel);
|
||||||
}
|
}
|
||||||
// if the word matches the top of the stack, pop it
|
// if the word matches the top of the stack, pop it
|
||||||
if stack.last() == Some(&word) {
|
if stack.last() == Some(&word) {
|
||||||
@ -245,14 +203,14 @@ pub fn guess_channel_from_prompt(
|
|||||||
}
|
}
|
||||||
// if the stack is empty, we have a match
|
// if the stack is empty, we have a match
|
||||||
if stack.is_empty() {
|
if stack.is_empty() {
|
||||||
return parse_channel(channel, cable_channels);
|
return cable.get_channel(channel);
|
||||||
}
|
}
|
||||||
// reset the stack
|
// reset the stack
|
||||||
stack.clear();
|
stack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("No match found, falling back to default channel");
|
debug!("No match found, falling back to default channel");
|
||||||
Ok(fallback)
|
fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERSION_MESSAGE: &str = env!("CARGO_PKG_VERSION");
|
const VERSION_MESSAGE: &str = env!("CARGO_PKG_VERSION");
|
||||||
@ -304,18 +262,9 @@ mod tests {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let post_processed_cli: PostProcessedCli = cli.into();
|
let cable = cable::load_cable().unwrap_or_default();
|
||||||
|
let post_processed_cli = post_process(cli, &cable);
|
||||||
|
|
||||||
let expected = ChannelPrototype {
|
|
||||||
preview_command: Some(PreviewCommand {
|
|
||||||
command: "bat -n --color=always {}".to_string(),
|
|
||||||
delimiter: ":".to_string(),
|
|
||||||
offset_expr: None,
|
|
||||||
}),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(post_processed_cli.channel, expected,);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
post_processed_cli.preview_command,
|
post_processed_cli.preview_command,
|
||||||
Some(PreviewCommand {
|
Some(PreviewCommand {
|
||||||
@ -341,9 +290,9 @@ mod tests {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let post_processed_cli: PostProcessedCli = cli.into();
|
let cable = cable::load_cable().unwrap_or_default();
|
||||||
|
let post_processed_cli = post_process(cli, &cable);
|
||||||
|
|
||||||
assert_eq!(post_processed_cli.channel, ChannelPrototype::default(),);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
post_processed_cli.working_directory,
|
post_processed_cli.working_directory,
|
||||||
Some(".".to_string())
|
Some(".".to_string())
|
||||||
@ -364,7 +313,8 @@ mod tests {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let post_processed_cli: PostProcessedCli = cli.into();
|
let cable = cable::load_cable().unwrap_or_default();
|
||||||
|
let post_processed_cli = post_process(cli, &cable);
|
||||||
|
|
||||||
let mut expected = KeyBindings::default();
|
let mut expected = KeyBindings::default();
|
||||||
expected.insert(Action::Quit, Binding::SingleKey(Key::Esc));
|
expected.insert(Action::Quit, Binding::SingleKey(Key::Esc));
|
||||||
@ -402,8 +352,7 @@ mod tests {
|
|||||||
&command_mapping,
|
&command_mapping,
|
||||||
fallback,
|
fallback,
|
||||||
&channels,
|
&channels,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(channel.name, "files");
|
assert_eq!(channel.name, "files");
|
||||||
}
|
}
|
||||||
@ -420,8 +369,7 @@ mod tests {
|
|||||||
&command_mapping,
|
&command_mapping,
|
||||||
fallback,
|
fallback,
|
||||||
&channels,
|
&channels,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(channel.name, fallback);
|
assert_eq!(channel.name, fallback);
|
||||||
}
|
}
|
||||||
@ -438,8 +386,7 @@ mod tests {
|
|||||||
&command_mapping,
|
&command_mapping,
|
||||||
fallback,
|
fallback,
|
||||||
&channels,
|
&channels,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(channel.name, fallback);
|
assert_eq!(channel.name, fallback);
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,9 @@ use std::process::exit;
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use television::cable::load_cable;
|
||||||
|
use television::cli::post_process;
|
||||||
use television::{
|
use television::{
|
||||||
cable,
|
|
||||||
channels::prototypes::{Cable, ChannelPrototype},
|
channels::prototypes::{Cable, ChannelPrototype},
|
||||||
utils::clipboard::CLIPBOARD,
|
utils::clipboard::CLIPBOARD,
|
||||||
};
|
};
|
||||||
@ -35,15 +36,16 @@ async fn main() -> Result<()> {
|
|||||||
// process the CLI arguments
|
// process the CLI arguments
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
debug!("CLI: {:?}", cli);
|
debug!("CLI: {:?}", cli);
|
||||||
let args: PostProcessedCli = cli.into();
|
|
||||||
debug!("PostProcessedCli: {:?}", args);
|
|
||||||
|
|
||||||
// load the configuration file
|
// load the configuration file
|
||||||
debug!("Loading configuration...");
|
debug!("Loading configuration...");
|
||||||
let mut config = Config::new(&ConfigEnv::init()?)?;
|
let mut config = Config::new(&ConfigEnv::init()?)?;
|
||||||
|
|
||||||
debug!("Loading cable channels...");
|
debug!("Loading cable channels...");
|
||||||
let cable_channels = cable::load_cable().unwrap_or_default();
|
let cable = load_cable().unwrap_or_default();
|
||||||
|
|
||||||
|
let args = post_process(cli, &cable);
|
||||||
|
debug!("PostProcessedCli: {:?}", args);
|
||||||
|
|
||||||
// optionally handle subcommands
|
// optionally handle subcommands
|
||||||
debug!("Handling subcommands...");
|
debug!("Handling subcommands...");
|
||||||
@ -60,12 +62,8 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
// determine the channel to use based on the CLI arguments and configuration
|
// determine the channel to use based on the CLI arguments and configuration
|
||||||
debug!("Determining channel...");
|
debug!("Determining channel...");
|
||||||
let channel_prototype = determine_channel(
|
let channel_prototype =
|
||||||
args.clone(),
|
determine_channel(&args, &config, is_readable_stdin(), &cable);
|
||||||
&config,
|
|
||||||
is_readable_stdin(),
|
|
||||||
&cable_channels,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
CLIPBOARD.with(<_>::default);
|
CLIPBOARD.with(<_>::default);
|
||||||
|
|
||||||
@ -77,13 +75,8 @@ async fn main() -> Result<()> {
|
|||||||
args.no_help,
|
args.no_help,
|
||||||
config.application.tick_rate,
|
config.application.tick_rate,
|
||||||
);
|
);
|
||||||
let mut app = App::new(
|
let mut app =
|
||||||
&channel_prototype,
|
App::new(&channel_prototype, config, args.input, options, &cable);
|
||||||
config,
|
|
||||||
args.input,
|
|
||||||
options,
|
|
||||||
&cable_channels,
|
|
||||||
);
|
|
||||||
stdout().flush()?;
|
stdout().flush()?;
|
||||||
debug!("Running application...");
|
debug!("Running application...");
|
||||||
let output = app.run(stdout().is_terminal(), false).await?;
|
let output = app.run(stdout().is_terminal(), false).await?;
|
||||||
@ -156,27 +149,38 @@ pub fn handle_subcommands(command: &Command, config: &Config) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn determine_channel(
|
pub fn determine_channel(
|
||||||
args: PostProcessedCli,
|
args: &PostProcessedCli,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
readable_stdin: bool,
|
readable_stdin: bool,
|
||||||
cable_channels: &Cable,
|
cable: &Cable,
|
||||||
) -> Result<ChannelPrototype> {
|
) -> ChannelPrototype {
|
||||||
if readable_stdin {
|
if readable_stdin {
|
||||||
debug!("Using stdin channel");
|
debug!("Using stdin channel");
|
||||||
Ok(ChannelPrototype::stdin(args.preview_command))
|
ChannelPrototype::stdin(args.preview_command.clone())
|
||||||
} else if let Some(prompt) = args.autocomplete_prompt {
|
} else if let Some(prompt) = &args.autocomplete_prompt {
|
||||||
debug!("Using autocomplete prompt: {:?}", prompt);
|
debug!("Using autocomplete prompt: {:?}", prompt);
|
||||||
let channel_prototype = guess_channel_from_prompt(
|
let channel_prototype = guess_channel_from_prompt(
|
||||||
&prompt,
|
prompt,
|
||||||
&config.shell_integration.commands,
|
&config.shell_integration.commands,
|
||||||
&config.shell_integration.fallback_channel,
|
&config.shell_integration.fallback_channel,
|
||||||
cable_channels,
|
cable,
|
||||||
)?;
|
);
|
||||||
debug!("Using guessed channel: {:?}", channel_prototype);
|
debug!("Using guessed channel: {:?}", channel_prototype);
|
||||||
Ok(channel_prototype)
|
channel_prototype
|
||||||
} else {
|
} else {
|
||||||
debug!("Using {:?} channel", args.channel);
|
let channel = args
|
||||||
Ok(args.channel)
|
.channel
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&config.application.default_channel)
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let mut prototype = cable.get_channel(&channel);
|
||||||
|
// use cli preview command if any
|
||||||
|
if let Some(pc) = &args.preview_command {
|
||||||
|
prototype.preview_command = Some(pc.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
prototype
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +188,8 @@ pub fn determine_channel(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use television::{
|
use television::{
|
||||||
cable::load_cable, channels::prototypes::ChannelPrototype,
|
cable::load_cable,
|
||||||
|
channels::{preview::PreviewCommand, prototypes::ChannelPrototype},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -199,8 +204,7 @@ mod tests {
|
|||||||
let channels: Cable =
|
let channels: Cable =
|
||||||
cable_channels.unwrap_or_else(|| load_cable().unwrap_or_default());
|
cable_channels.unwrap_or_else(|| load_cable().unwrap_or_default());
|
||||||
let channel =
|
let channel =
|
||||||
determine_channel(args.clone(), config, readable_stdin, &channels)
|
determine_channel(args, config, readable_stdin, &channels);
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
channel.name, expected_channel.name,
|
channel.name, expected_channel.name,
|
||||||
@ -209,14 +213,10 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[test]
|
||||||
/// Test that the channel is stdin when stdin is readable
|
/// Test that the channel is stdin when stdin is readable
|
||||||
async fn test_determine_channel_readable_stdin() {
|
fn test_determine_channel_readable_stdin() {
|
||||||
let channel = ChannelPrototype::default();
|
let args = PostProcessedCli::default();
|
||||||
let args = PostProcessedCli {
|
|
||||||
channel,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
assert_is_correct_channel(
|
assert_is_correct_channel(
|
||||||
&args,
|
&args,
|
||||||
@ -227,8 +227,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[test]
|
||||||
async fn test_determine_channel_autocomplete_prompt() {
|
fn test_determine_channel_autocomplete_prompt() {
|
||||||
let autocomplete_prompt = Some("cd".to_string());
|
let autocomplete_prompt = Some("cd".to_string());
|
||||||
let expected_channel =
|
let expected_channel =
|
||||||
ChannelPrototype::new("dirs", "ls {}", false, None);
|
ChannelPrototype::new("dirs", "ls {}", false, None);
|
||||||
@ -261,9 +261,9 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[test]
|
||||||
async fn test_determine_channel_standard_case() {
|
fn test_determine_channel_standard_case() {
|
||||||
let channel = ChannelPrototype::new("dirs", "", false, None);
|
let channel = Some(String::from("dirs"));
|
||||||
let args = PostProcessedCli {
|
let args = PostProcessedCli {
|
||||||
channel,
|
channel,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -278,6 +278,50 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_determine_channel_config_fallback() {
|
||||||
|
let cable = Cable::default();
|
||||||
|
let args = PostProcessedCli {
|
||||||
|
channel: None,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let mut config = Config::default();
|
||||||
|
config.application.default_channel = String::from("dirs");
|
||||||
|
assert_is_correct_channel(
|
||||||
|
&args,
|
||||||
|
&config,
|
||||||
|
false,
|
||||||
|
&cable.get_channel("dirs"),
|
||||||
|
Some(cable),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_determine_channel_with_cli_preview() {
|
||||||
|
let cable = Cable::default();
|
||||||
|
|
||||||
|
let preview_command = PreviewCommand::new("echo hello", ",", None);
|
||||||
|
|
||||||
|
let args = PostProcessedCli {
|
||||||
|
channel: Some(String::from("dirs")),
|
||||||
|
preview_command: Some(preview_command),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let config = Config::default();
|
||||||
|
|
||||||
|
let expected_prototype = cable
|
||||||
|
.get_channel("dirs")
|
||||||
|
.set_preview(args.preview_command.clone());
|
||||||
|
|
||||||
|
assert_is_correct_channel(
|
||||||
|
&args,
|
||||||
|
&config,
|
||||||
|
false,
|
||||||
|
&expected_prototype,
|
||||||
|
Some(cable),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_apply_cli_overrides() {
|
fn test_apply_cli_overrides() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
|
@ -33,7 +33,7 @@ fn setup_app(
|
|||||||
.join("tests")
|
.join("tests")
|
||||||
.join("target_dir");
|
.join("target_dir");
|
||||||
std::env::set_current_dir(&target_dir).unwrap();
|
std::env::set_current_dir(&target_dir).unwrap();
|
||||||
ChannelPrototype::default()
|
Cable::default().get("files").unwrap().clone()
|
||||||
});
|
});
|
||||||
let mut config = default_config_from_file().unwrap();
|
let mut config = default_config_from_file().unwrap();
|
||||||
// this speeds up the tests
|
// this speeds up the tests
|
||||||
|
Loading…
x
Reference in New Issue
Block a user