about summary refs log tree commit diff stats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--crates/yt/src/cli.rs46
1 files changed, 45 insertions, 1 deletions
diff --git a/crates/yt/src/cli.rs b/crates/yt/src/cli.rs
index 41fadf4..98bbb2d 100644
--- a/crates/yt/src/cli.rs
+++ b/crates/yt/src/cli.rs
@@ -10,20 +10,26 @@
 // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
 use std::{
+    ffi::OsStr,
     fmt::{self, Display, Formatter},
     path::PathBuf,
     str::FromStr,
+    thread,
 };
 
 use anyhow::Context;
 use bytes::Bytes;
 use chrono::NaiveDate;
 use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum};
+use clap_complete::{ArgValueCompleter, CompletionCandidate};
+use tokio::runtime::Runtime;
 use url::Url;
 
 use crate::{
+    app::App,
+    config::Config,
     select::selection_file::duration::MaybeDuration,
-    storage::video_database::extractor_hash::LazyExtractorHash,
+    storage::{subscriptions, video_database::extractor_hash::LazyExtractorHash},
 };
 
 #[derive(Parser, Debug)]
@@ -144,6 +150,7 @@ pub enum Command {
         total_number: Option<usize>,
 
         /// The subscriptions to update
+        #[arg(add = ArgValueCompleter::new(complete_subscription))]
         subscriptions: Vec<String>,
 
         /// Perform the updates in blocks.
@@ -217,6 +224,7 @@ pub enum SubscriptionCommand {
     /// Unsubscribe from an URL
     Remove {
         /// The human readable name of the subscription
+        #[arg(add = ArgValueCompleter::new(complete_subscription))]
         name: String,
     },
 
@@ -448,6 +456,42 @@ pub enum CacheCommand {
     },
 }
 
+fn complete_subscription(current: &OsStr) -> Vec<CompletionCandidate> {
+    let mut output = vec![];
+
+    let Some(current_prog) = current.to_str().map(ToOwned::to_owned) else {
+        return output;
+    };
+
+    let Ok(config) = Config::from_config_file(None, None, None) else {
+        return output;
+    };
+
+    let handle = thread::spawn(move || {
+        let Ok(rt) = Runtime::new() else {
+            return output;
+        };
+
+        let Ok(app) = rt.block_on(App::new(config, false)) else {
+            return output;
+        };
+
+        let Ok(all) = rt.block_on(subscriptions::get(&app)) else {
+            return output;
+        };
+
+        for sub in all.0.into_keys() {
+            if sub.starts_with(&current_prog) {
+                output.push(CompletionCandidate::new(sub));
+            }
+        }
+
+        output
+    });
+
+    handle.join().unwrap_or_default()
+}
+
 #[cfg(test)]
 mod test {
     use clap::CommandFactory;