use std::time::Duration;
use anyhow::Result;
use crate::cli::env_resolver::Source;
use crate::cli::route;
use crate::cli::trace::CommandTrace;
use crate::cli::type_cmd::target_matching;
use crate::session::backend::open_backend;
use crate::session::keys::{parse_chord, Chord};
use crate::session::with_scratch_recovery;
const KEY_TIMEOUT: Duration = Duration::from_secs(30);
pub async fn run(browser: Option<String>, key: String, target: Option<String>) -> Result<()> {
let mut trace = CommandTrace::new("key");
let result = run_inner(browser, &key, target, &mut trace).await;
trace.finish(result)?;
println!("pressed {key}");
Ok(())
}
async fn run_inner(
browser: Option<String>,
key: &str,
target: Option<String>,
trace: &mut CommandTrace,
) -> Result<()> {
let chord = parse_chord(key)?;
let r = route::preamble(browser, target.as_deref(), trace).await?;
let resolved = &r.resolved;
match (r.tab_name.clone(), target) {
(Some(name), None) => {
trace.route("named-tab").tab_name(&name);
let chord = chord.clone();
route::run_named_tab(
&r,
&name,
"named tabs (`<browser>/<name>`) require a registered browser; \
external endpoints can't carry tab names",
move |b, target_id| {
let chord: Chord = chord.clone();
async move { b.press_key_on_tab(&target_id, &chord, KEY_TIMEOUT).await }
},
)
.await
}
(None, None) => {
let browser_name = match &resolved.source {
Source::Registered { name } => name.clone(),
Source::External => anyhow::bail!(
"`key` needs a registered browser or an explicit `--target`; \
external endpoints have no tab to focus"
),
};
trace.route("scratch");
let backend = open_backend(&resolved.endpoint, resolved.engine).await?;
with_scratch_recovery(&backend, &r.registry, &browser_name, move |b, target_id| {
let chord: Chord = chord.clone();
async move { b.press_key_on_tab(&target_id, &chord, KEY_TIMEOUT).await }
})
.await
}
(None, Some(regex)) => {
trace.route("target-regex");
let backend = open_backend(&resolved.endpoint, resolved.engine).await?;
let target_id = target_matching(&backend, ®ex).await?;
let out = backend
.press_key_on_tab(&target_id, &chord, KEY_TIMEOUT)
.await;
backend.release().await;
out
}
_ => unreachable!("mutual exclusion checked in preamble"),
}
}