1use clap::{CommandFactory, Parser, Subcommand};
2use clap_complete::{generate, Shell};
3
4const KEYBINDINGS_HELP: &str = "\
5Keybindings (inside an attached session):
6 Ctrl+a d Detach from the session (leave it running)
7 Ctrl+a k Kill the session
8 Ctrl+a Ctrl+a Send a literal Ctrl+a to the program";
9
10const TOP_LEVEL_HELP: &str = "\
11Shortcuts:
12 keep-running list running sessions
13 keep-running <name> attach to a session (prefix match works)
14
15Keybindings (inside an attached session):
16 Ctrl+a d Detach from the session (leave it running)
17 Ctrl+a k Kill the session
18 Ctrl+a Ctrl+a Send a literal Ctrl+a to the program";
19
20#[derive(Parser)]
21#[command(name = "keep-running")]
22#[command(about = "Human-friendly terminal session manager with dtach-style detach")]
23#[command(after_help = TOP_LEVEL_HELP)]
24#[command(after_long_help = TOP_LEVEL_HELP)]
25#[command(version)]
26pub struct Cli {
27 #[command(subcommand)]
28 pub command: Option<Commands>,
29
30 #[arg(value_name = "SESSION")]
32 pub session: Option<String>,
33}
34
35#[derive(Subcommand)]
36pub enum Commands {
37 #[command(trailing_var_arg = true)]
39 #[command(after_help = KEYBINDINGS_HELP)]
40 #[command(after_long_help = KEYBINDINGS_HELP)]
41 Run {
42 #[arg(short, long)]
44 name: Option<String>,
45
46 #[arg(required = true)]
48 command: Vec<String>,
49 },
50
51 Shell {
53 #[arg(short, long)]
55 name: Option<String>,
56 },
57
58 Attach {
60 session: String,
62 },
63
64 #[command(alias = "ls")]
66 List,
67
68 Kill {
70 session: String,
72 },
73
74 Start {
76 #[arg(short, long)]
78 name: Option<String>,
79
80 #[arg(required = true, trailing_var_arg = true)]
82 command: Vec<String>,
83 },
84
85 Completions {
87 #[arg(value_enum)]
89 shell: Shell,
90 },
91}
92
93pub fn parse() -> Cli {
94 Cli::parse()
95}
96
97pub fn print_completions(shell: Shell) {
98 let mut cmd = Cli::command();
99 generate(shell, &mut cmd, "keep-running", &mut std::io::stdout());
100}