1use clap::ValueEnum;
2use std::{fmt::Display, str};
3
4use crate::client;
5use crate::error::Result;
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
8pub enum Shell {
9 Bash,
10 Fish,
11 }
14
15impl Shell {
16 pub fn generate_completion_str(&self) -> Result<String> {
17 match self {
18 Shell::Bash => bash_completion(),
19 Shell::Fish => fish_completion(),
20 }
21 }
22
23 pub fn iter() -> impl Iterator<Item = String> {
24 [Shell::Bash, Shell::Fish] .iter()
26 .map(|s| s.to_string().to_lowercase())
27 }
28}
29
30impl Display for Shell {
31 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
32 let s = match self {
33 Shell::Bash => "Bash",
34 Shell::Fish => "Fish",
35 };
36 write!(f, "{}", s)
37 }
38}
39
40pub fn bash_completion() -> Result<String> {
41 client::list_templates().map(|all_templates| {
42 BASH_COMPLETION_TEMPLATE.replace("{all_templates}", &all_templates.join(" "))
43 })
44}
45
46pub fn fish_completion() -> Result<String> {
47 client::list_templates().map(|all_templates| {
48 let all_shells = Shell::iter().collect::<Vec<String>>();
49 FISH_COMPLETION_TEMPLATE
50 .replace("{all_templates}", &all_templates.join(" "))
51 .replace("{all_shells}", &all_shells.join(" "))
52 })
53}
54
55const BASH_COMPLETION_TEMPLATE: &str = "\
56#!/usr/bin/env bash
57complete -W \"{all_templates}\" gi
58";
59
60const FISH_COMPLETION_TEMPLATE: &str = "\
61complete -c gi -f
62complete -c gi -a '{all_templates}'
63complete -c gi -s h -l help -d 'Print a short help text and exit'
64complete -c gi -s v -l version -d 'Print a short version string and exit'
65complete -c gi -l no-pager -d 'Do not pipe output into a pager'
66complete -c gi -l completion -a '{all_shells}' -d 'Generate shell completion file'
67";