Repository: fujiapple852/trippy
Pull request #984 (2024-02-04 04:33:38)

Snapshot-shared-folder
Replace the snapshots manually managed over to insta for management
using the tool

We can choose to put the snapshot files anywhere we want so where the files are is not an issue. Only issue we need to contend with is white space and what appears to be screen with issues between local and CI.

fujiapple852: What shall we do with this PR @c-git ?
c-git: Sure, I don't recall what we'd decided. I'll have to try to lookup the chat.
c-git: By any chance do you recall?
c-git: Documenting the next planned steps

- [ ] Rebase branch to onto main
- [ ] Clear out old work done on this
- [ ] Remove the current baseline files and replace them with snapshots (hopefully they will be similar as we'll also be removing the whitespace so it will look like a file rename and not a delete and add).
- [ ] Test and document update process (where should it be documented?)
c-git: Closed by rebase, will reopen once I have a commit I want. Just trying to finalize what to do in my head. Trying to read the current code to get context.
c-git: I can merge it at the end instead of modify the same files multiple times but for now wanted to start from closer to the target structure.
c-git: Ok done. Didn't document how to accept the new snapshots when the time comes but I don't know where would be a good place to do that, contributors guide?

I included a string version of the input before removing white space you'll let me know if it makes sense.

Patch:
diff --git a/.gitignore b/.gitignore
index b38a673..f0f57f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 /target
 .idea
 .DS_Store
-.vscode/launch.json
\ No newline at end of file
+.vscode/launch.json
+*.snap.new
diff --git a/Cargo.lock b/Cargo.lock
index 18cb787..037a06c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -342,6 +342,18 @@ dependencies = [
  "static_assertions",
 ]
 
+[[package]]
+name = "console"
+version = "0.15.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
+dependencies = [
+ "encode_unicode",
+ "lazy_static",
+ "libc",
+ "windows-sys 0.52.0",
+]
+
 [[package]]
 name = "core-foundation-sys"
 version = "0.8.6"
@@ -542,6 +554,12 @@ version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
 
+[[package]]
+name = "encode_unicode"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
+
 [[package]]
 name = "encoding_rs"
 version = "0.8.34"
@@ -877,6 +895,19 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "insta"
+version = "1.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5"
+dependencies = [
+ "console",
+ "lazy_static",
+ "linked-hash-map",
+ "serde",
+ "similar",
+]
+
 [[package]]
 name = "ipconfig"
 version = "0.3.2"
@@ -1568,6 +1599,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "similar"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640"
+
 [[package]]
 name = "slab"
 version = "0.4.9"
@@ -1963,6 +2000,7 @@ dependencies = [
  "etcetera",
  "humantime",
  "indexmap 2.2.6",
+ "insta",
  "itertools",
  "maxminddb",
  "parking_lot",
diff --git a/crates/trippy/Cargo.toml b/crates/trippy/Cargo.toml
index 8b9f530..effd98b 100644
--- a/crates/trippy/Cargo.toml
+++ b/crates/trippy/Cargo.toml
@@ -53,6 +53,7 @@ clap_mangen = "0.2.20"
 [dev-dependencies]
 test-case.workspace = true
 serde_yaml.workspace = true
+insta = { version = "1.39.0", features = ["serde"] }
 pretty_assertions = "1.4.0"
 
 [package.metadata.generate-rpm]
diff --git a/crates/trippy/src/backend/trace.rs b/crates/trippy/src/backend/trace.rs
index 4858379..f106a3e 100644
--- a/crates/trippy/src/backend/trace.rs
+++ b/crates/trippy/src/backend/trace.rs
@@ -629,7 +629,7 @@ mod tests {
 
     macro_rules! file {
         ($path:expr) => {{
-            let yaml = include_str!(concat!("../../test_resources/backend/", $path));
+            let yaml = include_str!(concat!("../../tests/resources/backend/", $path));
             serde_yaml::from_str(yaml).unwrap()
         }};
     }
diff --git a/crates/trippy/src/config.rs b/crates/trippy/src/config.rs
index 563e28b..29649f1 100644
--- a/crates/trippy/src/config.rs
+++ b/crates/trippy/src/config.rs
@@ -1096,6 +1096,7 @@ fn validate_bindings(bindings: &TuiBindings) -> anyhow::Result<()> {
 #[cfg(test)]
 mod tests {
     use super::*;
+    use crate::tests::{insta, remove_whitespace};
     use crossterm::event::KeyCode;
     use std::net::{Ipv4Addr, Ipv6Addr};
     use std::str::FromStr;
@@ -1129,12 +1130,16 @@ mod tests {
         pretty_assertions::assert_eq!(expected, config);
     }
 
-    #[test_case("trip", Err(anyhow!(include_str!("../test_resources/config/usage_short.txt"))); "show default help")]
-    #[test_case("trip -h", Err(anyhow!(include_str!("../test_resources/config/usage_short.txt"))); "show short help")]
-    #[test_case("trip --help", Err(anyhow!(include_str!("../test_resources/config/usage_long.txt"))); "show long help")]
+    #[test_case("trip"; "show default help")]
+    #[test_case("trip -h"; "show short help")]
+    #[test_case("trip --help"; "show long help")]
+    fn test_help(cmd: &str) {
+        compare_snapshot(cmd, parse_config(cmd));
+    }
+
     #[test_case("trip --version", Err(anyhow!(format!("trip {}", clap::crate_version!()))); "show version")]
     #[test_case("trip -V", Err(anyhow!(format!("trip {}", clap::crate_version!()))); "show version short")]
-    fn test_help(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
+    fn test_version_help(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
         compare(parse_config(cmd), expected);
     }
 
@@ -1682,6 +1687,20 @@ mod tests {
         }
     }
 
+    fn compare_snapshot<T>(name: &str, actual: anyhow::Result<T>)
+    where
+        T: std::fmt::Debug,
+    {
+        insta(name, || match actual {
+            Ok(act) => {
+                insta::assert_debug_snapshot!(act);
+            }
+            Err(err) => {
+                insta::assert_snapshot!(remove_whitespace(err.to_string()));
+            }
+        });
+    }
+
     fn cfg() -> TrippyConfigBuilder {
         TrippyConfigBuilder::new(vec![String::from("example.com")])
     }
@@ -1705,11 +1724,6 @@ mod tests {
         )?)
     }
 
-    fn remove_whitespace(mut s: String) -> String {
-        s.retain(|c| !c.is_whitespace());
-        s
-    }
-
     pub struct TrippyConfigBuilder {
         config: TrippyConfig,
     }
diff --git a/crates/trippy/src/main.rs b/crates/trippy/src/main.rs
index c211336..38a53be 100644
--- a/crates/trippy/src/main.rs
+++ b/crates/trippy/src/main.rs
@@ -485,21 +485,29 @@ mod tests {
     use super::*;
     use test_case::test_case;
 
-    #[test_case(include_str!("../test_resources/tui/tui_theme_items.txt"), &tui_theme_items(); "tui theme items match")]
-    #[test_case(include_str!("../test_resources/tui/tui_binding_commands.txt"), &tui_binding_commands(); "tui binding commands match")]
-    #[test_case(include_str!("../test_resources/config/completions_bash.txt"), &shell_completions(Shell::Bash).unwrap(); "generate bash shell completions")]
-    #[test_case(include_str!("../test_resources/config/completions_elvish.txt"), &shell_completions(Shell::Elvish).unwrap(); "generate elvish shell completions")]
-    #[test_case(include_str!("../test_resources/config/completions_fish.txt"), &shell_completions(Shell::Fish).unwrap(); "generate fish shell completions")]
-    #[test_case(include_str!("../test_resources/config/completions_powershell.txt"), &shell_completions(Shell::PowerShell).unwrap(); "generate powershell shell completions")]
-    #[test_case(include_str!("../test_resources/config/completions_zsh.txt"), &shell_completions(Shell::Zsh).unwrap(); "generate zsh shell completions")]
-    #[test_case(include_str!("../test_resources/config/trip.1"), &man_page().unwrap(); "generate man page")]
-    fn test_output(expected: &str, actual: &str) {
-        if remove_whitespace(actual.to_string()) != remove_whitespace(expected.to_string()) {
-            pretty_assertions::assert_eq!(actual, expected);
-        }
+    #[test_case(&tui_theme_items(), "tui theme items match"; "tui theme items match")]
+    #[test_case(&tui_binding_commands(), "tui binding commands match"; "tui binding commands match")]
+    #[test_case(&shell_completions(Shell::Bash).unwrap(), "generate bash shell completions"; "generate bash shell completions")]
+    #[test_case(&shell_completions(Shell::Elvish).unwrap(), "generate elvish shell completions"; "generate elvish shell completions")]
+    #[test_case(&shell_completions(Shell::Fish).unwrap(), "generate fish shell completions"; "generate fish shell completions")]
+    #[test_case(&shell_completions(Shell::PowerShell).unwrap(), "generate powershell shell completions"; "generate powershell shell completions")]
+    #[test_case(&shell_completions(Shell::Zsh).unwrap(), "generate zsh shell completions"; "generate zsh shell completions")]
+    #[test_case(&man_page().unwrap(), "generate man page"; "generate man page")]
+    fn test_output(actual: &str, name: &str) {
+        insta(name, || {
+            insta::assert_snapshot!(remove_whitespace(actual.to_string()));
+        });
+    }
+
+    pub fn insta<F: FnOnce()>(name: &str, f: F) {
+        let mut settings = insta::Settings::new();
+        settings.set_snapshot_suffix(name.replace(' ', "_"));
+        settings.set_snapshot_path("../tests/resources/snapshots");
+        settings.set_omit_expression(true);
+        settings.bind(f);
     }
 
-    fn remove_whitespace(mut s: String) -> String {
+    pub fn remove_whitespace(mut s: String) -> String {
         s.retain(|c| !c.is_whitespace());
         s
     }


Test patch:
diff --git a/crates/trippy/test_resources/config/completions_bash.txt b/crates/trippy/test_resources/config/completions_bash.txt
deleted file mode 100644
index 8d433d9..0000000
--- a/crates/trippy/test_resources/config/completions_bash.txt
+++ /dev/null
@@ -1,335 +0,0 @@
-_trip() {
-    local i cur prev opts cmd
-    COMPREPLY=()
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    prev="${COMP_WORDS[COMP_CWORD-1]}"
-    cmd=""
-    opts=""
-
-    for i in ${COMP_WORDS[@]}
-    do
-        case "${cmd},${i}" in
-            ",$1")
-                cmd="trip"
-                ;;
-            *)
-                ;;
-        esac
-    done
-
-    case "${cmd}" in
-        trip)
-            opts="-c -m -u -p -F -4 -6 -P -S -A -I -i -T -g -R -U -f -t -Q -e -r -y -z -a -M -s -C -G -v -h -V --config-file --mode --unprivileged --protocol --udp --tcp --icmp --addr-family --ipv4 --ipv6 --target-port --source-port --source-address --interface --min-round-duration --max-round-duration --grace-duration --initial-sequence --multipath-strategy --max-inflight --first-ttl --max-ttl --packet-size --payload-pattern --tos --icmp-extensions --read-timeout --dns-resolve-method --dns-resolve-all --dns-timeout --dns-lookup-as-info --tui-address-mode --tui-as-mode --tui-custom-columns --tui-icmp-extension-mode --tui-geoip-mode --tui-max-addrs --tui-max-samples --tui-max-flows --tui-preserve-screen --tui-refresh-rate --tui-privacy-max-ttl --tui-theme-colors --print-tui-theme-items --tui-key-bindings --print-tui-binding-commands --report-cycles --geoip-mmdb-file --generate --generate-man --print-config-template --log-format --log-filter --log-span-events --verbose --help --version [TARGETS]..."
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                --config-file)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                -c)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --mode)
-                    COMPREPLY=($(compgen -W "tui stream pretty markdown csv json dot flows silent" -- "${cur}"))
-                    return 0
-                    ;;
-                -m)
-                    COMPREPLY=($(compgen -W "tui stream pretty markdown csv json dot flows silent" -- "${cur}"))
-                    return 0
-                    ;;
-                --protocol)
-                    COMPREPLY=($(compgen -W "icmp udp tcp" -- "${cur}"))
-                    return 0
-                    ;;
-                -p)
-                    COMPREPLY=($(compgen -W "icmp udp tcp" -- "${cur}"))
-                    return 0
-                    ;;
-                --addr-family)
-                    COMPREPLY=($(compgen -W "ipv4 ipv6 ipv6-then-ipv4 ipv4-then-ipv6" -- "${cur}"))
-                    return 0
-                    ;;
-                -F)
-                    COMPREPLY=($(compgen -W "ipv4 ipv6 ipv6-then-ipv4 ipv4-then-ipv6" -- "${cur}"))
-                    return 0
-                    ;;
-                --target-port)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -P)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --source-port)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -S)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --source-address)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -A)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --interface)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -I)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --min-round-duration)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -i)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --max-round-duration)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -T)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --grace-duration)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -g)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --initial-sequence)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --multipath-strategy)
-                    COMPREPLY=($(compgen -W "classic paris dublin" -- "${cur}"))
-                    return 0
-                    ;;
-                -R)
-                    COMPREPLY=($(compgen -W "classic paris dublin" -- "${cur}"))
-                    return 0
-                    ;;
-                --max-inflight)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -U)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --first-ttl)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -f)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --max-ttl)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -t)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --packet-size)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --payload-pattern)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tos)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -Q)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --read-timeout)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --dns-resolve-method)
-                    COMPREPLY=($(compgen -W "system resolv google cloudflare" -- "${cur}"))
-                    return 0
-                    ;;
-                -r)
-                    COMPREPLY=($(compgen -W "system resolv google cloudflare" -- "${cur}"))
-                    return 0
-                    ;;
-                --dns-timeout)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-address-mode)
-                    COMPREPLY=($(compgen -W "ip host both" -- "${cur}"))
-                    return 0
-                    ;;
-                -a)
-                    COMPREPLY=($(compgen -W "ip host both" -- "${cur}"))
-                    return 0
-                    ;;
-                --tui-as-mode)
-                    COMPREPLY=($(compgen -W "asn prefix country-code registry allocated name" -- "${cur}"))
-                    return 0
-                    ;;
-                --tui-custom-columns)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-icmp-extension-mode)
-                    COMPREPLY=($(compgen -W "off mpls full all" -- "${cur}"))
-                    return 0
-                    ;;
-                --tui-geoip-mode)
-                    COMPREPLY=($(compgen -W "off short long location" -- "${cur}"))
-                    return 0
-                    ;;
-                --tui-max-addrs)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -M)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-max-samples)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -s)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-max-flows)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-refresh-rate)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-privacy-max-ttl)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-theme-colors)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --tui-key-bindings)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --report-cycles)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                -C)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --geoip-mmdb-file)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                -G)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --generate)
-                    COMPREPLY=($(compgen -W "bash elvish fish powershell zsh" -- "${cur}"))
-                    return 0
-                    ;;
-                --log-format)
-                    COMPREPLY=($(compgen -W "compact pretty json chrome" -- "${cur}"))
-                    return 0
-                    ;;
-                --log-filter)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --log-span-events)
-                    COMPREPLY=($(compgen -W "off active full" -- "${cur}"))
-                    return 0
-                    ;;
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
-    esac
-}
-
-if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
-    complete -F _trip -o nosort -o bashdefault -o default trip
-else
-    complete -F _trip -o bashdefault -o default trip
-fi
-
diff --git a/crates/trippy/test_resources/config/completions_elvish.txt b/crates/trippy/test_resources/config/completions_elvish.txt
deleted file mode 100644
index cbf3358..0000000
--- a/crates/trippy/test_resources/config/completions_elvish.txt
+++ /dev/null
@@ -1,113 +0,0 @@
-
-use builtin;
-use str;
-
-set edit:completion:arg-completer[trip] = {|@words|
-    fn spaces {|n|
-        builtin:repeat $n ' ' | str:join ''
-    }
-    fn cand {|text desc|
-        edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
-    }
-    var command = 'trip'
-    for word $words[1..-1] {
-        if (str:has-prefix $word '-') {
-            break
-        }
-        set command = $command';'$word
-    }
-    var completions = [
-        &'trip'= {
-            cand -c 'Config file'
-            cand --config-file 'Config file'
-            cand -m 'Output mode [default: tui]'
-            cand --mode 'Output mode [default: tui]'
-            cand -p 'Tracing protocol [default: icmp]'
-            cand --protocol 'Tracing protocol [default: icmp]'
-            cand -F 'The address family [default: Ipv4thenIpv6]'
-            cand --addr-family 'The address family [default: Ipv4thenIpv6]'
-            cand -P 'The target port (TCP & UDP only) [default: 80]'
-            cand --target-port 'The target port (TCP & UDP only) [default: 80]'
-            cand -S 'The source port (TCP & UDP only) [default: auto]'
-            cand --source-port 'The source port (TCP & UDP only) [default: auto]'
-            cand -A 'The source IP address [default: auto]'
-            cand --source-address 'The source IP address [default: auto]'
-            cand -I 'The network interface [default: auto]'
-            cand --interface 'The network interface [default: auto]'
-            cand -i 'The minimum duration of every round [default: 1s]'
-            cand --min-round-duration 'The minimum duration of every round [default: 1s]'
-            cand -T 'The maximum duration of every round [default: 1s]'
-            cand --max-round-duration 'The maximum duration of every round [default: 1s]'
-            cand -g 'The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]'
-            cand --grace-duration 'The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]'
-            cand --initial-sequence 'The initial sequence number [default: 33000]'
-            cand -R 'The Equal-cost Multi-Path routing strategy (UDP only) [default: classic]'
-            cand --multipath-strategy 'The Equal-cost Multi-Path routing strategy (UDP only) [default: classic]'
-            cand -U 'The maximum number of in-flight ICMP echo requests [default: 24]'
-            cand --max-inflight 'The maximum number of in-flight ICMP echo requests [default: 24]'
-            cand -f 'The TTL to start from [default: 1]'
-            cand --first-ttl 'The TTL to start from [default: 1]'
-            cand -t 'The maximum number of TTL hops [default: 64]'
-            cand --max-ttl 'The maximum number of TTL hops [default: 64]'
-            cand --packet-size 'The size of IP packet to send (IP header + ICMP header + payload) [default: 84]'
-            cand --payload-pattern 'The repeating pattern in the payload of the ICMP packet [default: 0]'
-            cand -Q 'The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]'
-            cand --tos 'The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]'
-            cand --read-timeout 'The socket read timeout [default: 10ms]'
-            cand -r 'How to perform DNS queries [default: system]'
-            cand --dns-resolve-method 'How to perform DNS queries [default: system]'
-            cand --dns-timeout 'The maximum time to wait to perform DNS queries [default: 5s]'
-            cand -a 'How to render addresses [default: host]'
-            cand --tui-address-mode 'How to render addresses [default: host]'
-            cand --tui-as-mode 'How to render AS information [default: asn]'
-            cand --tui-custom-columns 'Custom columns to be displayed in the TUI hops table [default: holsravbwdt]'
-            cand --tui-icmp-extension-mode 'How to render ICMP extensions [default: off]'
-            cand --tui-geoip-mode 'How to render GeoIp information [default: short]'
-            cand -M 'The maximum number of addresses to show per hop [default: auto]'
-            cand --tui-max-addrs 'The maximum number of addresses to show per hop [default: auto]'
-            cand -s 'The maximum number of samples to record per hop [default: 256]'
-            cand --tui-max-samples 'The maximum number of samples to record per hop [default: 256]'
-            cand --tui-max-flows 'The maximum number of flows to show [default: 64]'
-            cand --tui-refresh-rate 'The Tui refresh rate [default: 100ms]'
-            cand --tui-privacy-max-ttl 'The maximum ttl of hops which will be masked for privacy [default: 0]'
-            cand --tui-theme-colors 'The TUI theme colors [item=color,item=color,..]'
-            cand --tui-key-bindings 'The TUI key bindings [command=key,command=key,..]'
-            cand -C 'The number of report cycles to run [default: 10]'
-            cand --report-cycles 'The number of report cycles to run [default: 10]'
-            cand -G 'The supported MaxMind or IPinfo GeoIp mmdb file'
-            cand --geoip-mmdb-file 'The supported MaxMind or IPinfo GeoIp mmdb file'
-            cand --generate 'Generate shell completion'
-            cand --log-format 'The debug log format [default: pretty]'
-            cand --log-filter 'The debug log filter [default: trippy=debug]'
-            cand --log-span-events 'The debug log format [default: off]'
-            cand -u 'Trace without requiring elevated privileges on supported platforms [default: false]'
-            cand --unprivileged 'Trace without requiring elevated privileges on supported platforms [default: false]'
-            cand --udp 'Trace using the UDP protocol'
-            cand --tcp 'Trace using the TCP protocol'
-            cand --icmp 'Trace using the ICMP protocol'
-            cand -4 'Use IPv4 only'
-            cand --ipv4 'Use IPv4 only'
-            cand -6 'Use IPv6 only'
-            cand --ipv6 'Use IPv6 only'
-            cand -e 'Parse ICMP extensions'
-            cand --icmp-extensions 'Parse ICMP extensions'
-            cand -y 'Trace to all IPs resolved from DNS lookup [default: false]'
-            cand --dns-resolve-all 'Trace to all IPs resolved from DNS lookup [default: false]'
-            cand -z 'Lookup autonomous system (AS) information during DNS queries [default: false]'
-            cand --dns-lookup-as-info 'Lookup autonomous system (AS) information during DNS queries [default: false]'
-            cand --tui-preserve-screen 'Preserve the screen on exit [default: false]'
-            cand --print-tui-theme-items 'Print all TUI theme items and exit'
-            cand --print-tui-binding-commands 'Print all TUI commands that can be bound and exit'
-            cand --generate-man 'Generate ROFF man page'
-            cand --print-config-template 'Print a template toml config file and exit'
-            cand -v 'Enable verbose debug logging'
-            cand --verbose 'Enable verbose debug logging'
-            cand -h 'Print help (see more with ''--help'')'
-            cand --help 'Print help (see more with ''--help'')'
-            cand -V 'Print version'
-            cand --version 'Print version'
-        }
-    ]
-    $completions[$command]
-}
-
diff --git a/crates/trippy/test_resources/config/completions_fish.txt b/crates/trippy/test_resources/config/completions_fish.txt
deleted file mode 100644
index 99b1e8a..0000000
--- a/crates/trippy/test_resources/config/completions_fish.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-complete -c trip -s c -l config-file -d 'Config file' -r -F
-complete -c trip -s m -l mode -d 'Output mode [default: tui]' -r -f -a "{tui	'Display interactive TUI',stream	'Display a continuous stream of tracing data',pretty	'Generate a pretty text table report for N cycles',markdown	'Generate a Markdown text table report for N cycles',csv	'Generate a CSV report for N cycles',json	'Generate a JSON report for N cycles',dot	'Generate a Graphviz DOT file for N cycles',flows	'Display all flows for N cycles',silent	'Do not generate any tracing output for N cycles'}"
-complete -c trip -s p -l protocol -d 'Tracing protocol [default: icmp]' -r -f -a "{icmp	'Internet Control Message Protocol',udp	'User Datagram Protocol',tcp	'Transmission Control Protocol'}"
-complete -c trip -s F -l addr-family -d 'The address family [default: Ipv4thenIpv6]' -r -f -a "{ipv4	'Ipv4 only',ipv6	'Ipv6 only',ipv6-then-ipv4	'Ipv6 with a fallback to Ipv4',ipv4-then-ipv6	'Ipv4 with a fallback to Ipv6'}"
-complete -c trip -s P -l target-port -d 'The target port (TCP & UDP only) [default: 80]' -r
-complete -c trip -s S -l source-port -d 'The source port (TCP & UDP only) [default: auto]' -r
-complete -c trip -s A -l source-address -d 'The source IP address [default: auto]' -r
-complete -c trip -s I -l interface -d 'The network interface [default: auto]' -r
-complete -c trip -s i -l min-round-duration -d 'The minimum duration of every round [default: 1s]' -r
-complete -c trip -s T -l max-round-duration -d 'The maximum duration of every round [default: 1s]' -r
-complete -c trip -s g -l grace-duration -d 'The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]' -r
-complete -c trip -l initial-sequence -d 'The initial sequence number [default: 33000]' -r
-complete -c trip -s R -l multipath-strategy -d 'The Equal-cost Multi-Path routing strategy (UDP only) [default: classic]' -r -f -a "{classic	'The src or dest port is used to store the sequence number',paris	'The UDP `checksum` field is used to store the sequence number',dublin	'The IP `identifier` field is used to store the sequence number'}"
-complete -c trip -s U -l max-inflight -d 'The maximum number of in-flight ICMP echo requests [default: 24]' -r
-complete -c trip -s f -l first-ttl -d 'The TTL to start from [default: 1]' -r
-complete -c trip -s t -l max-ttl -d 'The maximum number of TTL hops [default: 64]' -r
-complete -c trip -l packet-size -d 'The size of IP packet to send (IP header + ICMP header + payload) [default: 84]' -r
-complete -c trip -l payload-pattern -d 'The repeating pattern in the payload of the ICMP packet [default: 0]' -r
-complete -c trip -s Q -l tos -d 'The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]' -r
-complete -c trip -l read-timeout -d 'The socket read timeout [default: 10ms]' -r
-complete -c trip -s r -l dns-resolve-method -d 'How to perform DNS queries [default: system]' -r -f -a "{system	'Resolve using the OS resolver',resolv	'Resolve using the `/etc/resolv.conf` DNS configuration',google	'Resolve using the Google `8.8.8.8` DNS service',cloudflare	'Resolve using the Cloudflare `1.1.1.1` DNS service'}"
-complete -c trip -l dns-timeout -d 'The maximum time to wait to perform DNS queries [default: 5s]' -r
-complete -c trip -s a -l tui-address-mode -d 'How to render addresses [default: host]' -r -f -a "{ip	'Show IP address only',host	'Show reverse-lookup DNS hostname only',both	'Show both IP address and reverse-lookup DNS hostname'}"
-complete -c trip -l tui-as-mode -d 'How to render AS information [default: asn]' -r -f -a "{asn	'Show the ASN',prefix	'Display the AS prefix',country-code	'Display the country code',registry	'Display the registry name',allocated	'Display the allocated date',name	'Display the AS name'}"
-complete -c trip -l tui-custom-columns -d 'Custom columns to be displayed in the TUI hops table [default: holsravbwdt]' -r
-complete -c trip -l tui-icmp-extension-mode -d 'How to render ICMP extensions [default: off]' -r -f -a "{off	'Do not show `icmp` extensions',mpls	'Show MPLS label(s) only',full	'Show full `icmp` extension data for all known extensions',all	'Show full `icmp` extension data for all classes'}"
-complete -c trip -l tui-geoip-mode -d 'How to render GeoIp information [default: short]' -r -f -a "{off	'Do not display GeoIp data',short	'Show short format',long	'Show long format',location	'Show latitude and Longitude format'}"
-complete -c trip -s M -l tui-max-addrs -d 'The maximum number of addresses to show per hop [default: auto]' -r
-complete -c trip -s s -l tui-max-samples -d 'The maximum number of samples to record per hop [default: 256]' -r
-complete -c trip -l tui-max-flows -d 'The maximum number of flows to show [default: 64]' -r
-complete -c trip -l tui-refresh-rate -d 'The Tui refresh rate [default: 100ms]' -r
-complete -c trip -l tui-privacy-max-ttl -d 'The maximum ttl of hops which will be masked for privacy [default: 0]' -r
-complete -c trip -l tui-theme-colors -d 'The TUI theme colors [item=color,item=color,..]' -r
-complete -c trip -l tui-key-bindings -d 'The TUI key bindings [command=key,command=key,..]' -r
-complete -c trip -s C -l report-cycles -d 'The number of report cycles to run [default: 10]' -r
-complete -c trip -s G -l geoip-mmdb-file -d 'The supported MaxMind or IPinfo GeoIp mmdb file' -r -F
-complete -c trip -l generate -d 'Generate shell completion' -r -f -a "{bash	'',elvish	'',fish	'',powershell	'',zsh	''}"
-complete -c trip -l log-format -d 'The debug log format [default: pretty]' -r -f -a "{compact	'Display log data in a compact format',pretty	'Display log data in a pretty format',json	'Display log data in a json format',chrome	'Display log data in Chrome trace format'}"
-complete -c trip -l log-filter -d 'The debug log filter [default: trippy=debug]' -r
-complete -c trip -l log-span-events -d 'The debug log format [default: off]' -r -f -a "{off	'Do not display event spans',active	'Display enter and exit event spans',full	'Display all event spans'}"
-complete -c trip -s u -l unprivileged -d 'Trace without requiring elevated privileges on supported platforms [default: false]'
-complete -c trip -l udp -d 'Trace using the UDP protocol'
-complete -c trip -l tcp -d 'Trace using the TCP protocol'
-complete -c trip -l icmp -d 'Trace using the ICMP protocol'
-complete -c trip -s 4 -l ipv4 -d 'Use IPv4 only'
-complete -c trip -s 6 -l ipv6 -d 'Use IPv6 only'
-complete -c trip -s e -l icmp-extensions -d 'Parse ICMP extensions'
-complete -c trip -s y -l dns-resolve-all -d 'Trace to all IPs resolved from DNS lookup [default: false]'
-complete -c trip -s z -l dns-lookup-as-info -d 'Lookup autonomous system (AS) information during DNS queries [default: false]'
-complete -c trip -l tui-preserve-screen -d 'Preserve the screen on exit [default: false]'
-complete -c trip -l print-tui-theme-items -d 'Print all TUI theme items and exit'
-complete -c trip -l print-tui-binding-commands -d 'Print all TUI commands that can be bound and exit'
-complete -c trip -l generate-man -d 'Generate ROFF man page'
-complete -c trip -l print-config-template -d 'Print a template toml config file and exit'
-complete -c trip -s v -l verbose -d 'Enable verbose debug logging'
-complete -c trip -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c trip -s V -l version -d 'Print version'
-
diff --git a/crates/trippy/test_resources/config/completions_powershell.txt b/crates/trippy/test_resources/config/completions_powershell.txt
deleted file mode 100644
index fef90d9..0000000
--- a/crates/trippy/test_resources/config/completions_powershell.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-
-using namespace System.Management.Automation
-using namespace System.Management.Automation.Language
-
-Register-ArgumentCompleter -Native -CommandName 'trip' -ScriptBlock {
-    param($wordToComplete, $commandAst, $cursorPosition)
-
-    $commandElements = $commandAst.CommandElements
-    $command = @(
-        'trip'
-        for ($i = 1; $i -lt $commandElements.Count; $i++) {
-            $element = $commandElements[$i]
-            if ($element -isnot [StringConstantExpressionAst] -or
-                $element.StringConstantType -ne [StringConstantType]::BareWord -or
-                $element.Value.StartsWith('-') -or
-                $element.Value -eq $wordToComplete) {
-                break
-        }
-        $element.Value
-    }) -join ';'
-
-    $completions = @(switch ($command) {
-        'trip' {
-            [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Config file')
-            [CompletionResult]::new('--config-file', 'config-file', [CompletionResultType]::ParameterName, 'Config file')
-            [CompletionResult]::new('-m', 'm', [CompletionResultType]::ParameterName, 'Output mode [default: tui]')
-            [CompletionResult]::new('--mode', 'mode', [CompletionResultType]::ParameterName, 'Output mode [default: tui]')
-            [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Tracing protocol [default: icmp]')
-            [CompletionResult]::new('--protocol', 'protocol', [CompletionResultType]::ParameterName, 'Tracing protocol [default: icmp]')
-            [CompletionResult]::new('-F', 'F ', [CompletionResultType]::ParameterName, 'The address family [default: Ipv4thenIpv6]')
-            [CompletionResult]::new('--addr-family', 'addr-family', [CompletionResultType]::ParameterName, 'The address family [default: Ipv4thenIpv6]')
-            [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'The target port (TCP & UDP only) [default: 80]')
-            [CompletionResult]::new('--target-port', 'target-port', [CompletionResultType]::ParameterName, 'The target port (TCP & UDP only) [default: 80]')
-            [CompletionResult]::new('-S', 'S ', [CompletionResultType]::ParameterName, 'The source port (TCP & UDP only) [default: auto]')
-            [CompletionResult]::new('--source-port', 'source-port', [CompletionResultType]::ParameterName, 'The source port (TCP & UDP only) [default: auto]')
-            [CompletionResult]::new('-A', 'A ', [CompletionResultType]::ParameterName, 'The source IP address [default: auto]')
-            [CompletionResult]::new('--source-address', 'source-address', [CompletionResultType]::ParameterName, 'The source IP address [default: auto]')
-            [CompletionResult]::new('-I', 'I ', [CompletionResultType]::ParameterName, 'The network interface [default: auto]')
-            [CompletionResult]::new('--interface', 'interface', [CompletionResultType]::ParameterName, 'The network interface [default: auto]')
-            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'The minimum duration of every round [default: 1s]')
-            [CompletionResult]::new('--min-round-duration', 'min-round-duration', [CompletionResultType]::ParameterName, 'The minimum duration of every round [default: 1s]')
-            [CompletionResult]::new('-T', 'T ', [CompletionResultType]::ParameterName, 'The maximum duration of every round [default: 1s]')
-            [CompletionResult]::new('--max-round-duration', 'max-round-duration', [CompletionResultType]::ParameterName, 'The maximum duration of every round [default: 1s]')
-            [CompletionResult]::new('-g', 'g', [CompletionResultType]::ParameterName, 'The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]')
-            [CompletionResult]::new('--grace-duration', 'grace-duration', [CompletionResultType]::ParameterName, 'The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]')
-            [CompletionResult]::new('--initial-sequence', 'initial-sequence', [CompletionResultType]::ParameterName, 'The initial sequence number [default: 33000]')
-            [CompletionResult]::new('-R', 'R ', [CompletionResultType]::ParameterName, 'The Equal-cost Multi-Path routing strategy (UDP only) [default: classic]')
-            [CompletionResult]::new('--multipath-strategy', 'multipath-strategy', [CompletionResultType]::ParameterName, 'The Equal-cost Multi-Path routing strategy (UDP only) [default: classic]')
-            [CompletionResult]::new('-U', 'U ', [CompletionResultType]::ParameterName, 'The maximum number of in-flight ICMP echo requests [default: 24]')
-            [CompletionResult]::new('--max-inflight', 'max-inflight', [CompletionResultType]::ParameterName, 'The maximum number of in-flight ICMP echo requests [default: 24]')
-            [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'The TTL to start from [default: 1]')
-            [CompletionResult]::new('--first-ttl', 'first-ttl', [CompletionResultType]::ParameterName, 'The TTL to start from [default: 1]')
-            [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'The maximum number of TTL hops [default: 64]')
-            [CompletionResult]::new('--max-ttl', 'max-ttl', [CompletionResultType]::ParameterName, 'The maximum number of TTL hops [default: 64]')
-            [CompletionResult]::new('--packet-size', 'packet-size', [CompletionResultType]::ParameterName, 'The size of IP packet to send (IP header + ICMP header + payload) [default: 84]')
-            [CompletionResult]::new('--payload-pattern', 'payload-pattern', [CompletionResultType]::ParameterName, 'The repeating pattern in the payload of the ICMP packet [default: 0]')
-            [CompletionResult]::new('-Q', 'Q ', [CompletionResultType]::ParameterName, 'The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]')
-            [CompletionResult]::new('--tos', 'tos', [CompletionResultType]::ParameterName, 'The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]')
-            [CompletionResult]::new('--read-timeout', 'read-timeout', [CompletionResultType]::ParameterName, 'The socket read timeout [default: 10ms]')
-            [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'How to perform DNS queries [default: system]')
-            [CompletionResult]::new('--dns-resolve-method', 'dns-resolve-method', [CompletionResultType]::ParameterName, 'How to perform DNS queries [default: system]')
-            [CompletionResult]::new('--dns-timeout', 'dns-timeout', [CompletionResultType]::ParameterName, 'The maximum time to wait to perform DNS queries [default: 5s]')
-            [CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, 'How to render addresses [default: host]')
-            [CompletionResult]::new('--tui-address-mode', 'tui-address-mode', [CompletionResultType]::ParameterName, 'How to render addresses [default: host]')
-            [CompletionResult]::new('--tui-as-mode', 'tui-as-mode', [CompletionResultType]::ParameterName, 'How to render AS information [default: asn]')
-            [CompletionResult]::new('--tui-custom-columns', 'tui-custom-columns', [CompletionResultType]::ParameterName, 'Custom columns to be displayed in the TUI hops table [default: holsravbwdt]')
-            [CompletionResult]::new('--tui-icmp-extension-mode', 'tui-icmp-extension-mode', [CompletionResultType]::ParameterName, 'How to render ICMP extensions [default: off]')
-            [CompletionResult]::new('--tui-geoip-mode', 'tui-geoip-mode', [CompletionResultType]::ParameterName, 'How to render GeoIp information [default: short]')
-            [CompletionResult]::new('-M', 'M ', [CompletionResultType]::ParameterName, 'The maximum number of addresses to show per hop [default: auto]')
-            [CompletionResult]::new('--tui-max-addrs', 'tui-max-addrs', [CompletionResultType]::ParameterName, 'The maximum number of addresses to show per hop [default: auto]')
-            [CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'The maximum number of samples to record per hop [default: 256]')
-            [CompletionResult]::new('--tui-max-samples', 'tui-max-samples', [CompletionResultType]::ParameterName, 'The maximum number of samples to record per hop [default: 256]')
-            [CompletionResult]::new('--tui-max-flows', 'tui-max-flows', [CompletionResultType]::ParameterName, 'The maximum number of flows to show [default: 64]')
-            [CompletionResult]::new('--tui-refresh-rate', 'tui-refresh-rate', [CompletionResultType]::ParameterName, 'The Tui refresh rate [default: 100ms]')
-            [CompletionResult]::new('--tui-privacy-max-ttl', 'tui-privacy-max-ttl', [CompletionResultType]::ParameterName, 'The maximum ttl of hops which will be masked for privacy [default: 0]')
-            [CompletionResult]::new('--tui-theme-colors', 'tui-theme-colors', [CompletionResultType]::ParameterName, 'The TUI theme colors [item=color,item=color,..]')
-            [CompletionResult]::new('--tui-key-bindings', 'tui-key-bindings', [CompletionResultType]::ParameterName, 'The TUI key bindings [command=key,command=key,..]')
-            [CompletionResult]::new('-C', 'C ', [CompletionResultType]::ParameterName, 'The number of report cycles to run [default: 10]')
-            [CompletionResult]::new('--report-cycles', 'report-cycles', [CompletionResultType]::ParameterName, 'The number of report cycles to run [default: 10]')
-            [CompletionResult]::new('-G', 'G ', [CompletionResultType]::ParameterName, 'The supported MaxMind or IPinfo GeoIp mmdb file')
-            [CompletionResult]::new('--geoip-mmdb-file', 'geoip-mmdb-file', [CompletionResultType]::ParameterName, 'The supported MaxMind or IPinfo GeoIp mmdb file')
-            [CompletionResult]::new('--generate', 'generate', [CompletionResultType]::ParameterName, 'Generate shell completion')
-            [CompletionResult]::new('--log-format', 'log-format', [CompletionResultType]::ParameterName, 'The debug log format [default: pretty]')
-            [CompletionResult]::new('--log-filter', 'log-filter', [CompletionResultType]::ParameterName, 'The debug log filter [default: trippy=debug]')
-            [CompletionResult]::new('--log-span-events', 'log-span-events', [CompletionResultType]::ParameterName, 'The debug log format [default: off]')
-            [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'Trace without requiring elevated privileges on supported platforms [default: false]')
-            [CompletionResult]::new('--unprivileged', 'unprivileged', [CompletionResultType]::ParameterName, 'Trace without requiring elevated privileges on supported platforms [default: false]')
-            [CompletionResult]::new('--udp', 'udp', [CompletionResultType]::ParameterName, 'Trace using the UDP protocol')
-            [CompletionResult]::new('--tcp', 'tcp', [CompletionResultType]::ParameterName, 'Trace using the TCP protocol')
-            [CompletionResult]::new('--icmp', 'icmp', [CompletionResultType]::ParameterName, 'Trace using the ICMP protocol')
-            [CompletionResult]::new('-4', '4', [CompletionResultType]::ParameterName, 'Use IPv4 only')
-            [CompletionResult]::new('--ipv4', 'ipv4', [CompletionResultType]::ParameterName, 'Use IPv4 only')
-            [CompletionResult]::new('-6', '6', [CompletionResultType]::ParameterName, 'Use IPv6 only')
-            [CompletionResult]::new('--ipv6', 'ipv6', [CompletionResultType]::ParameterName, 'Use IPv6 only')
-            [CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'Parse ICMP extensions')
-            [CompletionResult]::new('--icmp-extensions', 'icmp-extensions', [CompletionResultType]::ParameterName, 'Parse ICMP extensions')
-            [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Trace to all IPs resolved from DNS lookup [default: false]')
-            [CompletionResult]::new('--dns-resolve-all', 'dns-resolve-all', [CompletionResultType]::ParameterName, 'Trace to all IPs resolved from DNS lookup [default: false]')
-            [CompletionResult]::new('-z', 'z', [CompletionResultType]::ParameterName, 'Lookup autonomous system (AS) information during DNS queries [default: false]')
-            [CompletionResult]::new('--dns-lookup-as-info', 'dns-lookup-as-info', [CompletionResultType]::ParameterName, 'Lookup autonomous system (AS) information during DNS queries [default: false]')
-            [CompletionResult]::new('--tui-preserve-screen', 'tui-preserve-screen', [CompletionResultType]::ParameterName, 'Preserve the screen on exit [default: false]')
-            [CompletionResult]::new('--print-tui-theme-items', 'print-tui-theme-items', [CompletionResultType]::ParameterName, 'Print all TUI theme items and exit')
-            [CompletionResult]::new('--print-tui-binding-commands', 'print-tui-binding-commands', [CompletionResultType]::ParameterName, 'Print all TUI commands that can be bound and exit')
-            [CompletionResult]::new('--generate-man', 'generate-man', [CompletionResultType]::ParameterName, 'Generate ROFF man page')
-            [CompletionResult]::new('--print-config-template', 'print-config-template', [CompletionResultType]::ParameterName, 'Print a template toml config file and exit')
-            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Enable verbose debug logging')
-            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Enable verbose debug logging')
-            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
-            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
-            [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version')
-            [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version')
-            break
-        }
-    })
-
-    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
-        Sort-Object -Property ListItemText
-}
-
diff --git a/crates/trippy/test_resources/config/completions_zsh.txt b/crates/trippy/test_resources/config/completions_zsh.txt
deleted file mode 100644
index 56fe8b1..0000000
--- a/crates/trippy/test_resources/config/completions_zsh.txt
+++ /dev/null
@@ -1,177 +0,0 @@
-#compdef trip
-
-autoload -U is-at-least
-
-_trip() {
-    typeset -A opt_args
-    typeset -a _arguments_options
-    local ret=1
-
-    if is-at-least 5.2; then
-        _arguments_options=(-s -S -C)
-    else
-        _arguments_options=(-s -C)
-    fi
-
-    local context curcontext="$curcontext" state line
-    _arguments "${_arguments_options[@]}" \
-'-c+[Config file]:CONFIG_FILE:_files' \
-'--config-file=[Config file]:CONFIG_FILE:_files' \
-'-m+[Output mode \[default\: tui\]]:MODE:((tui\:"Display interactive TUI"
-stream\:"Display a continuous stream of tracing data"
-pretty\:"Generate a pretty text table report for N cycles"
-markdown\:"Generate a Markdown text table report for N cycles"
-csv\:"Generate a CSV report for N cycles"
-json\:"Generate a JSON report for N cycles"
-dot\:"Generate a Graphviz DOT file for N cycles"
-flows\:"Display all flows for N cycles"
-silent\:"Do not generate any tracing output for N cycles"))' \
-'--mode=[Output mode \[default\: tui\]]:MODE:((tui\:"Display interactive TUI"
-stream\:"Display a continuous stream of tracing data"
-pretty\:"Generate a pretty text table report for N cycles"
-markdown\:"Generate a Markdown text table report for N cycles"
-csv\:"Generate a CSV report for N cycles"
-json\:"Generate a JSON report for N cycles"
-dot\:"Generate a Graphviz DOT file for N cycles"
-flows\:"Display all flows for N cycles"
-silent\:"Do not generate any tracing output for N cycles"))' \
-'-p+[Tracing protocol \[default\: icmp\]]:PROTOCOL:((icmp\:"Internet Control Message Protocol"
-udp\:"User Datagram Protocol"
-tcp\:"Transmission Control Protocol"))' \
-'--protocol=[Tracing protocol \[default\: icmp\]]:PROTOCOL:((icmp\:"Internet Control Message Protocol"
-udp\:"User Datagram Protocol"
-tcp\:"Transmission Control Protocol"))' \
-'-F+[The address family \[default\: Ipv4thenIpv6\]]:ADDR_FAMILY:((ipv4\:"Ipv4 only"
-ipv6\:"Ipv6 only"
-ipv6-then-ipv4\:"Ipv6 with a fallback to Ipv4"
-ipv4-then-ipv6\:"Ipv4 with a fallback to Ipv6"))' \
-'--addr-family=[The address family \[default\: Ipv4thenIpv6\]]:ADDR_FAMILY:((ipv4\:"Ipv4 only"
-ipv6\:"Ipv6 only"
-ipv6-then-ipv4\:"Ipv6 with a fallback to Ipv4"
-ipv4-then-ipv6\:"Ipv4 with a fallback to Ipv6"))' \
-'-P+[The target port (TCP & UDP only) \[default\: 80\]]:TARGET_PORT: ' \
-'--target-port=[The target port (TCP & UDP only) \[default\: 80\]]:TARGET_PORT: ' \
-'-S+[The source port (TCP & UDP only) \[default\: auto\]]:SOURCE_PORT: ' \
-'--source-port=[The source port (TCP & UDP only) \[default\: auto\]]:SOURCE_PORT: ' \
-'(-I --interface)-A+[The source IP address \[default\: auto\]]:SOURCE_ADDRESS: ' \
-'(-I --interface)--source-address=[The source IP address \[default\: auto\]]:SOURCE_ADDRESS: ' \
-'-I+[The network interface \[default\: auto\]]:INTERFACE: ' \
-'--interface=[The network interface \[default\: auto\]]:INTERFACE: ' \
-'-i+[The minimum duration of every round \[default\: 1s\]]:MIN_ROUND_DURATION: ' \
-'--min-round-duration=[The minimum duration of every round \[default\: 1s\]]:MIN_ROUND_DURATION: ' \
-'-T+[The maximum duration of every round \[default\: 1s\]]:MAX_ROUND_DURATION: ' \
-'--max-round-duration=[The maximum duration of every round \[default\: 1s\]]:MAX_ROUND_DURATION: ' \
-'-g+[The period of time to wait for additional ICMP responses after the target has responded \[default\: 100ms\]]:GRACE_DURATION: ' \
-'--grace-duration=[The period of time to wait for additional ICMP responses after the target has responded \[default\: 100ms\]]:GRACE_DURATION: ' \
-'--initial-sequence=[The initial sequence number \[default\: 33000\]]:INITIAL_SEQUENCE: ' \
-'-R+[The Equal-cost Multi-Path routing strategy (UDP only) \[default\: classic\]]:MULTIPATH_STRATEGY:((classic\:"The src or dest port is used to store the sequence number"
-paris\:"The UDP \`checksum\` field is used to store the sequence number"
-dublin\:"The IP \`identifier\` field is used to store the sequence number"))' \
-'--multipath-strategy=[The Equal-cost Multi-Path routing strategy (UDP only) \[default\: classic\]]:MULTIPATH_STRATEGY:((classic\:"The src or dest port is used to store the sequence number"
-paris\:"The UDP \`checksum\` field is used to store the sequence number"
-dublin\:"The IP \`identifier\` field is used to store the sequence number"))' \
-'-U+[The maximum number of in-flight ICMP echo requests \[default\: 24\]]:MAX_INFLIGHT: ' \
-'--max-inflight=[The maximum number of in-flight ICMP echo requests \[default\: 24\]]:MAX_INFLIGHT: ' \
-'-f+[The TTL to start from \[default\: 1\]]:FIRST_TTL: ' \
-'--first-ttl=[The TTL to start from \[default\: 1\]]:FIRST_TTL: ' \
-'-t+[The maximum number of TTL hops \[default\: 64\]]:MAX_TTL: ' \
-'--max-ttl=[The maximum number of TTL hops \[default\: 64\]]:MAX_TTL: ' \
-'--packet-size=[The size of IP packet to send (IP header + ICMP header + payload) \[default\: 84\]]:PACKET_SIZE: ' \
-'--payload-pattern=[The repeating pattern in the payload of the ICMP packet \[default\: 0\]]:PAYLOAD_PATTERN: ' \
-'-Q+[The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) \[default\: 0\]]:TOS: ' \
-'--tos=[The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) \[default\: 0\]]:TOS: ' \
-'--read-timeout=[The socket read timeout \[default\: 10ms\]]:READ_TIMEOUT: ' \
-'-r+[How to perform DNS queries \[default\: system\]]:DNS_RESOLVE_METHOD:((system\:"Resolve using the OS resolver"
-resolv\:"Resolve using the \`/etc/resolv.conf\` DNS configuration"
-google\:"Resolve using the Google \`8.8.8.8\` DNS service"
-cloudflare\:"Resolve using the Cloudflare \`1.1.1.1\` DNS service"))' \
-'--dns-resolve-method=[How to perform DNS queries \[default\: system\]]:DNS_RESOLVE_METHOD:((system\:"Resolve using the OS resolver"
-resolv\:"Resolve using the \`/etc/resolv.conf\` DNS configuration"
-google\:"Resolve using the Google \`8.8.8.8\` DNS service"
-cloudflare\:"Resolve using the Cloudflare \`1.1.1.1\` DNS service"))' \
-'--dns-timeout=[The maximum time to wait to perform DNS queries \[default\: 5s\]]:DNS_TIMEOUT: ' \
-'-a+[How to render addresses \[default\: host\]]:TUI_ADDRESS_MODE:((ip\:"Show IP address only"
-host\:"Show reverse-lookup DNS hostname only"
-both\:"Show both IP address and reverse-lookup DNS hostname"))' \
-'--tui-address-mode=[How to render addresses \[default\: host\]]:TUI_ADDRESS_MODE:((ip\:"Show IP address only"
-host\:"Show reverse-lookup DNS hostname only"
-both\:"Show both IP address and reverse-lookup DNS hostname"))' \
-'--tui-as-mode=[How to render AS information \[default\: asn\]]:TUI_AS_MODE:((asn\:"Show the ASN"
-prefix\:"Display the AS prefix"
-country-code\:"Display the country code"
-registry\:"Display the registry name"
-allocated\:"Display the allocated date"
-name\:"Display the AS name"))' \
-'--tui-custom-columns=[Custom columns to be displayed in the TUI hops table \[default\: holsravbwdt\]]:TUI_CUSTOM_COLUMNS: ' \
-'--tui-icmp-extension-mode=[How to render ICMP extensions \[default\: off\]]:TUI_ICMP_EXTENSION_MODE:((off\:"Do not show \`icmp\` extensions"
-mpls\:"Show MPLS label(s) only"
-full\:"Show full \`icmp\` extension data for all known extensions"
-all\:"Show full \`icmp\` extension data for all classes"))' \
-'--tui-geoip-mode=[How to render GeoIp information \[default\: short\]]:TUI_GEOIP_MODE:((off\:"Do not display GeoIp data"
-short\:"Show short format"
-long\:"Show long format"
-location\:"Show latitude and Longitude format"))' \
-'-M+[The maximum number of addresses to show per hop \[default\: auto\]]:TUI_MAX_ADDRS: ' \
-'--tui-max-addrs=[The maximum number of addresses to show per hop \[default\: auto\]]:TUI_MAX_ADDRS: ' \
-'-s+[The maximum number of samples to record per hop \[default\: 256\]]:TUI_MAX_SAMPLES: ' \
-'--tui-max-samples=[The maximum number of samples to record per hop \[default\: 256\]]:TUI_MAX_SAMPLES: ' \
-'--tui-max-flows=[The maximum number of flows to show \[default\: 64\]]:TUI_MAX_FLOWS: ' \
-'--tui-refresh-rate=[The Tui refresh rate \[default\: 100ms\]]:TUI_REFRESH_RATE: ' \
-'--tui-privacy-max-ttl=[The maximum ttl of hops which will be masked for privacy \[default\: 0\]]:TUI_PRIVACY_MAX_TTL: ' \
-'*--tui-theme-colors=[The TUI theme colors \[item=color,item=color,..\]]:TUI_THEME_COLORS: ' \
-'*--tui-key-bindings=[The TUI key bindings \[command=key,command=key,..\]]:TUI_KEY_BINDINGS: ' \
-'-C+[The number of report cycles to run \[default\: 10\]]:REPORT_CYCLES: ' \
-'--report-cycles=[The number of report cycles to run \[default\: 10\]]:REPORT_CYCLES: ' \
-'-G+[The supported MaxMind or IPinfo GeoIp mmdb file]:GEOIP_MMDB_FILE:_files' \
-'--geoip-mmdb-file=[The supported MaxMind or IPinfo GeoIp mmdb file]:GEOIP_MMDB_FILE:_files' \
-'--generate=[Generate shell completion]:GENERATE:(bash elvish fish powershell zsh)' \
-'--log-format=[The debug log format \[default\: pretty\]]:LOG_FORMAT:((compact\:"Display log data in a compact format"
-pretty\:"Display log data in a pretty format"
-json\:"Display log data in a json format"
-chrome\:"Display log data in Chrome trace format"))' \
-'--log-filter=[The debug log filter \[default\: trippy=debug\]]:LOG_FILTER: ' \
-'--log-span-events=[The debug log format \[default\: off\]]:LOG_SPAN_EVENTS:((off\:"Do not display event spans"
-active\:"Display enter and exit event spans"
-full\:"Display all event spans"))' \
-'-u[Trace without requiring elevated privileges on supported platforms \[default\: false\]]' \
-'--unprivileged[Trace without requiring elevated privileges on supported platforms \[default\: false\]]' \
-'(-p --protocol --tcp --icmp)--udp[Trace using the UDP protocol]' \
-'(-p --protocol --udp --icmp)--tcp[Trace using the TCP protocol]' \
-'(-p --protocol --udp --tcp)--icmp[Trace using the ICMP protocol]' \
-'(-6 --ipv6 -F --addr-family)-4[Use IPv4 only]' \
-'(-6 --ipv6 -F --addr-family)--ipv4[Use IPv4 only]' \
-'(-4 --ipv4 -F --addr-family)-6[Use IPv6 only]' \
-'(-4 --ipv4 -F --addr-family)--ipv6[Use IPv6 only]' \
-'-e[Parse ICMP extensions]' \
-'--icmp-extensions[Parse ICMP extensions]' \
-'-y[Trace to all IPs resolved from DNS lookup \[default\: false\]]' \
-'--dns-resolve-all[Trace to all IPs resolved from DNS lookup \[default\: false\]]' \
-'-z[Lookup autonomous system (AS) information during DNS queries \[default\: false\]]' \
-'--dns-lookup-as-info[Lookup autonomous system (AS) information during DNS queries \[default\: false\]]' \
-'--tui-preserve-screen[Preserve the screen on exit \[default\: false\]]' \
-'--print-tui-theme-items[Print all TUI theme items and exit]' \
-'--print-tui-binding-commands[Print all TUI commands that can be bound and exit]' \
-'--generate-man[Generate ROFF man page]' \
-'--print-config-template[Print a template toml config file and exit]' \
-'-v[Enable verbose debug logging]' \
-'--verbose[Enable verbose debug logging]' \
-'-h[Print help (see more with '\''--help'\'')]' \
-'--help[Print help (see more with '\''--help'\'')]' \
-'-V[Print version]' \
-'--version[Print version]' \
-'*::targets -- A space delimited list of hostnames and IPs to trace:' \
-&& ret=0
-}
-
-(( $+functions[_trip_commands] )) ||
-_trip_commands() {
-    local commands; commands=()
-    _describe -t commands 'trip commands' commands "$@"
-}
-
-if [ "$funcstack[1]" = "_trip" ]; then
-    _trip "$@"
-else
-    compdef _trip trip
-fi
-
diff --git a/crates/trippy/test_resources/config/trip.1 b/crates/trippy/test_resources/config/trip.1
deleted file mode 100644
index 5d9c0a7..0000000
--- a/crates/trippy/test_resources/config/trip.1
+++ /dev/null
@@ -1,353 +0,0 @@
-.ie \n(.g .ds Aq \(aq
-.el .ds Aq '
-.TH trip 1  "trip 0.11.0-dev" 
-.SH NAME
-trip \- A network diagnostic tool
-.SH SYNOPSIS
-\fBtrip\fR [\fB\-c\fR|\fB\-\-config\-file\fR] [\fB\-m\fR|\fB\-\-mode\fR] [\fB\-u\fR|\fB\-\-unprivileged\fR] [\fB\-p\fR|\fB\-\-protocol\fR] [\fB\-\-udp\fR] [\fB\-\-tcp\fR] [\fB\-\-icmp\fR] [\fB\-F\fR|\fB\-\-addr\-family\fR] [\fB\-4\fR|\fB\-\-ipv4\fR] [\fB\-6\fR|\fB\-\-ipv6\fR] [\fB\-P\fR|\fB\-\-target\-port\fR] [\fB\-S\fR|\fB\-\-source\-port\fR] [\fB\-A\fR|\fB\-\-source\-address\fR] [\fB\-I\fR|\fB\-\-interface\fR] [\fB\-i\fR|\fB\-\-min\-round\-duration\fR] [\fB\-T\fR|\fB\-\-max\-round\-duration\fR] [\fB\-g\fR|\fB\-\-grace\-duration\fR] [\fB\-\-initial\-sequence\fR] [\fB\-R\fR|\fB\-\-multipath\-strategy\fR] [\fB\-U\fR|\fB\-\-max\-inflight\fR] [\fB\-f\fR|\fB\-\-first\-ttl\fR] [\fB\-t\fR|\fB\-\-max\-ttl\fR] [\fB\-\-packet\-size\fR] [\fB\-\-payload\-pattern\fR] [\fB\-Q\fR|\fB\-\-tos\fR] [\fB\-e\fR|\fB\-\-icmp\-extensions\fR] [\fB\-\-read\-timeout\fR] [\fB\-r\fR|\fB\-\-dns\-resolve\-method\fR] [\fB\-y\fR|\fB\-\-dns\-resolve\-all\fR] [\fB\-\-dns\-timeout\fR] [\fB\-z\fR|\fB\-\-dns\-lookup\-as\-info\fR] [\fB\-a\fR|\fB\-\-tui\-address\-mode\fR] [\fB\-\-tui\-as\-mode\fR] [\fB\-\-tui\-custom\-columns\fR] [\fB\-\-tui\-icmp\-extension\-mode\fR] [\fB\-\-tui\-geoip\-mode\fR] [\fB\-M\fR|\fB\-\-tui\-max\-addrs\fR] [\fB\-s\fR|\fB\-\-tui\-max\-samples\fR] [\fB\-\-tui\-max\-flows\fR] [\fB\-\-tui\-preserve\-screen\fR] [\fB\-\-tui\-refresh\-rate\fR] [\fB\-\-tui\-privacy\-max\-ttl\fR] [\fB\-\-tui\-theme\-colors\fR] [\fB\-\-print\-tui\-theme\-items\fR] [\fB\-\-tui\-key\-bindings\fR] [\fB\-\-print\-tui\-binding\-commands\fR] [\fB\-C\fR|\fB\-\-report\-cycles\fR] [\fB\-G\fR|\fB\-\-geoip\-mmdb\-file\fR] [\fB\-\-generate\fR] [\fB\-\-generate\-man\fR] [\fB\-\-print\-config\-template\fR] [\fB\-\-log\-format\fR] [\fB\-\-log\-filter\fR] [\fB\-\-log\-span\-events\fR] [\fB\-v\fR|\fB\-\-verbose\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fITARGETS\fR] 
-.SH DESCRIPTION
-A network diagnostic tool
-.SH OPTIONS
-.TP
-\fB\-c\fR, \fB\-\-config\-file\fR=\fICONFIG_FILE\fR
-Config file
-.TP
-\fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR
-Output mode [default: tui]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-tui: Display interactive TUI
-.IP \(bu 2
-stream: Display a continuous stream of tracing data
-.IP \(bu 2
-pretty: Generate a pretty text table report for N cycles
-.IP \(bu 2
-markdown: Generate a Markdown text table report for N cycles
-.IP \(bu 2
-csv: Generate a CSV report for N cycles
-.IP \(bu 2
-json: Generate a JSON report for N cycles
-.IP \(bu 2
-dot: Generate a Graphviz DOT file for N cycles
-.IP \(bu 2
-flows: Display all flows for N cycles
-.IP \(bu 2
-silent: Do not generate any tracing output for N cycles
-.RE
-.TP
-\fB\-u\fR, \fB\-\-unprivileged\fR
-Trace without requiring elevated privileges on supported platforms [default: false]
-.TP
-\fB\-p\fR, \fB\-\-protocol\fR=\fIPROTOCOL\fR
-Tracing protocol [default: icmp]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-icmp: Internet Control Message Protocol
-.IP \(bu 2
-udp: User Datagram Protocol
-.IP \(bu 2
-tcp: Transmission Control Protocol
-.RE
-.TP
-\fB\-\-udp\fR
-Trace using the UDP protocol
-.TP
-\fB\-\-tcp\fR
-Trace using the TCP protocol
-.TP
-\fB\-\-icmp\fR
-Trace using the ICMP protocol
-.TP
-\fB\-F\fR, \fB\-\-addr\-family\fR=\fIADDR_FAMILY\fR
-The address family [default: Ipv4thenIpv6]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-ipv4: Ipv4 only
-.IP \(bu 2
-ipv6: Ipv6 only
-.IP \(bu 2
-ipv6\-then\-ipv4: Ipv6 with a fallback to Ipv4
-.IP \(bu 2
-ipv4\-then\-ipv6: Ipv4 with a fallback to Ipv6
-.RE
-.TP
-\fB\-4\fR, \fB\-\-ipv4\fR
-Use IPv4 only
-.TP
-\fB\-6\fR, \fB\-\-ipv6\fR
-Use IPv6 only
-.TP
-\fB\-P\fR, \fB\-\-target\-port\fR=\fITARGET_PORT\fR
-The target port (TCP & UDP only) [default: 80]
-.TP
-\fB\-S\fR, \fB\-\-source\-port\fR=\fISOURCE_PORT\fR
-The source port (TCP & UDP only) [default: auto]
-.TP
-\fB\-A\fR, \fB\-\-source\-address\fR=\fISOURCE_ADDRESS\fR
-The source IP address [default: auto]
-.TP
-\fB\-I\fR, \fB\-\-interface\fR=\fIINTERFACE\fR
-The network interface [default: auto]
-.TP
-\fB\-i\fR, \fB\-\-min\-round\-duration\fR=\fIMIN_ROUND_DURATION\fR
-The minimum duration of every round [default: 1s]
-.TP
-\fB\-T\fR, \fB\-\-max\-round\-duration\fR=\fIMAX_ROUND_DURATION\fR
-The maximum duration of every round [default: 1s]
-.TP
-\fB\-g\fR, \fB\-\-grace\-duration\fR=\fIGRACE_DURATION\fR
-The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]
-.TP
-\fB\-\-initial\-sequence\fR=\fIINITIAL_SEQUENCE\fR
-The initial sequence number [default: 33000]
-.TP
-\fB\-R\fR, \fB\-\-multipath\-strategy\fR=\fIMULTIPATH_STRATEGY\fR
-The Equal\-cost Multi\-Path routing strategy (UDP only) [default: classic]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-classic: The src or dest port is used to store the sequence number
-.IP \(bu 2
-paris: The UDP `checksum` field is used to store the sequence number
-.IP \(bu 2
-dublin: The IP `identifier` field is used to store the sequence number
-.RE
-.TP
-\fB\-U\fR, \fB\-\-max\-inflight\fR=\fIMAX_INFLIGHT\fR
-The maximum number of in\-flight ICMP echo requests [default: 24]
-.TP
-\fB\-f\fR, \fB\-\-first\-ttl\fR=\fIFIRST_TTL\fR
-The TTL to start from [default: 1]
-.TP
-\fB\-t\fR, \fB\-\-max\-ttl\fR=\fIMAX_TTL\fR
-The maximum number of TTL hops [default: 64]
-.TP
-\fB\-\-packet\-size\fR=\fIPACKET_SIZE\fR
-The size of IP packet to send (IP header + ICMP header + payload) [default: 84]
-.TP
-\fB\-\-payload\-pattern\fR=\fIPAYLOAD_PATTERN\fR
-The repeating pattern in the payload of the ICMP packet [default: 0]
-.TP
-\fB\-Q\fR, \fB\-\-tos\fR=\fITOS\fR
-The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]
-.TP
-\fB\-e\fR, \fB\-\-icmp\-extensions\fR
-Parse ICMP extensions
-.TP
-\fB\-\-read\-timeout\fR=\fIREAD_TIMEOUT\fR
-The socket read timeout [default: 10ms]
-.TP
-\fB\-r\fR, \fB\-\-dns\-resolve\-method\fR=\fIDNS_RESOLVE_METHOD\fR
-How to perform DNS queries [default: system]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-system: Resolve using the OS resolver
-.IP \(bu 2
-resolv: Resolve using the `/etc/resolv.conf` DNS configuration
-.IP \(bu 2
-google: Resolve using the Google `8.8.8.8` DNS service
-.IP \(bu 2
-cloudflare: Resolve using the Cloudflare `1.1.1.1` DNS service
-.RE
-.TP
-\fB\-y\fR, \fB\-\-dns\-resolve\-all\fR
-Trace to all IPs resolved from DNS lookup [default: false]
-.TP
-\fB\-\-dns\-timeout\fR=\fIDNS_TIMEOUT\fR
-The maximum time to wait to perform DNS queries [default: 5s]
-.TP
-\fB\-z\fR, \fB\-\-dns\-lookup\-as\-info\fR
-Lookup autonomous system (AS) information during DNS queries [default: false]
-.TP
-\fB\-a\fR, \fB\-\-tui\-address\-mode\fR=\fITUI_ADDRESS_MODE\fR
-How to render addresses [default: host]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-ip: Show IP address only
-.IP \(bu 2
-host: Show reverse\-lookup DNS hostname only
-.IP \(bu 2
-both: Show both IP address and reverse\-lookup DNS hostname
-.RE
-.TP
-\fB\-\-tui\-as\-mode\fR=\fITUI_AS_MODE\fR
-How to render AS information [default: asn]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-asn: Show the ASN
-.IP \(bu 2
-prefix: Display the AS prefix
-.IP \(bu 2
-country\-code: Display the country code
-.IP \(bu 2
-registry: Display the registry name
-.IP \(bu 2
-allocated: Display the allocated date
-.IP \(bu 2
-name: Display the AS name
-.RE
-.TP
-\fB\-\-tui\-custom\-columns\fR=\fITUI_CUSTOM_COLUMNS\fR
-Custom columns to be displayed in the TUI hops table [default: holsravbwdt]
-.TP
-\fB\-\-tui\-icmp\-extension\-mode\fR=\fITUI_ICMP_EXTENSION_MODE\fR
-How to render ICMP extensions [default: off]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-off: Do not show `icmp` extensions
-.IP \(bu 2
-mpls: Show MPLS label(s) only
-.IP \(bu 2
-full: Show full `icmp` extension data for all known extensions
-.IP \(bu 2
-all: Show full `icmp` extension data for all classes
-.RE
-.TP
-\fB\-\-tui\-geoip\-mode\fR=\fITUI_GEOIP_MODE\fR
-How to render GeoIp information [default: short]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-off: Do not display GeoIp data
-.IP \(bu 2
-short: Show short format
-.IP \(bu 2
-long: Show long format
-.IP \(bu 2
-location: Show latitude and Longitude format
-.RE
-.TP
-\fB\-M\fR, \fB\-\-tui\-max\-addrs\fR=\fITUI_MAX_ADDRS\fR
-The maximum number of addresses to show per hop [default: auto]
-.TP
-\fB\-s\fR, \fB\-\-tui\-max\-samples\fR=\fITUI_MAX_SAMPLES\fR
-The maximum number of samples to record per hop [default: 256]
-.TP
-\fB\-\-tui\-max\-flows\fR=\fITUI_MAX_FLOWS\fR
-The maximum number of flows to show [default: 64]
-.TP
-\fB\-\-tui\-preserve\-screen\fR
-Preserve the screen on exit [default: false]
-.TP
-\fB\-\-tui\-refresh\-rate\fR=\fITUI_REFRESH_RATE\fR
-The Tui refresh rate [default: 100ms]
-.TP
-\fB\-\-tui\-privacy\-max\-ttl\fR=\fITUI_PRIVACY_MAX_TTL\fR
-The maximum ttl of hops which will be masked for privacy [default: 0]
-.TP
-\fB\-\-tui\-theme\-colors\fR=\fITUI_THEME_COLORS\fR
-The TUI theme colors [item=color,item=color,..]
-.TP
-\fB\-\-print\-tui\-theme\-items\fR
-Print all TUI theme items and exit
-.TP
-\fB\-\-tui\-key\-bindings\fR=\fITUI_KEY_BINDINGS\fR
-The TUI key bindings [command=key,command=key,..]
-.TP
-\fB\-\-print\-tui\-binding\-commands\fR
-Print all TUI commands that can be bound and exit
-.TP
-\fB\-C\fR, \fB\-\-report\-cycles\fR=\fIREPORT_CYCLES\fR
-The number of report cycles to run [default: 10]
-.TP
-\fB\-G\fR, \fB\-\-geoip\-mmdb\-file\fR=\fIGEOIP_MMDB_FILE\fR
-The supported MaxMind or IPinfo GeoIp mmdb file
-.TP
-\fB\-\-generate\fR=\fIGENERATE\fR
-Generate shell completion
-.br
-
-.br
-[\fIpossible values: \fRbash, elvish, fish, powershell, zsh]
-.TP
-\fB\-\-generate\-man\fR
-Generate ROFF man page
-.TP
-\fB\-\-print\-config\-template\fR
-Print a template toml config file and exit
-.TP
-\fB\-\-log\-format\fR=\fILOG_FORMAT\fR
-The debug log format [default: pretty]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-compact: Display log data in a compact format
-.IP \(bu 2
-pretty: Display log data in a pretty format
-.IP \(bu 2
-json: Display log data in a json format
-.IP \(bu 2
-chrome: Display log data in Chrome trace format
-.RE
-.TP
-\fB\-\-log\-filter\fR=\fILOG_FILTER\fR
-The debug log filter [default: trippy=debug]
-.TP
-\fB\-\-log\-span\-events\fR=\fILOG_SPAN_EVENTS\fR
-The debug log format [default: off]
-.br
-
-.br
-\fIPossible values:\fR
-.RS 14
-.IP \(bu 2
-off: Do not display event spans
-.IP \(bu 2
-active: Display enter and exit event spans
-.IP \(bu 2
-full: Display all event spans
-.RE
-.TP
-\fB\-v\fR, \fB\-\-verbose\fR
-Enable verbose debug logging
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-Print help (see a summary with \*(Aq\-h\*(Aq)
-.TP
-\fB\-V\fR, \fB\-\-version\fR
-Print version
-.TP
-[\fITARGETS\fR]
-A space delimited list of hostnames and IPs to trace
-.SH VERSION
-v0.11.0\-dev
-.SH AUTHORS
-FujiApple <fujiapple852@gmail.com>
-
diff --git a/crates/trippy/test_resources/config/usage_long.txt b/crates/trippy/test_resources/config/usage_long.txt
deleted file mode 100644
index 00b18d2..0000000
--- a/crates/trippy/test_resources/config/usage_long.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-A network diagnostic tool
-
-Usage: trip [OPTIONS] [TARGETS]...
-
-Arguments:
-  [TARGETS]...
-          A space delimited list of hostnames and IPs to trace
-
-Options:
-  -c, --config-file <CONFIG_FILE>
-          Config file
-
-  -m, --mode <MODE>
-          Output mode [default: tui]
-
-          Possible values:
-          - tui:      Display interactive TUI
-          - stream:   Display a continuous stream of tracing data
-          - pretty:   Generate a pretty text table report for N cycles
-          - markdown: Generate a Markdown text table report for N cycles
-          - csv:      Generate a CSV report for N cycles
-          - json:     Generate a JSON report for N cycles
-          - dot:      Generate a Graphviz DOT file for N cycles
-          - flows:    Display all flows for N cycles
-          - silent:   Do not generate any tracing output for N cycles
-
-  -u, --unprivileged
-          Trace without requiring elevated privileges on supported platforms [default: false]
-
-  -p, --protocol <PROTOCOL>
-          Tracing protocol [default: icmp]
-
-          Possible values:
-          - icmp: Internet Control Message Protocol
-          - udp:  User Datagram Protocol
-          - tcp:  Transmission Control Protocol
-
-      --udp
-          Trace using the UDP protocol
-
-      --tcp
-          Trace using the TCP protocol
-
-      --icmp
-          Trace using the ICMP protocol
-
-  -F, --addr-family <ADDR_FAMILY>
-          The address family [default: Ipv4thenIpv6]
-
-          Possible values:
-          - ipv4:           Ipv4 only
-          - ipv6:           Ipv6 only
-          - ipv6-then-ipv4: Ipv6 with a fallback to Ipv4
-          - ipv4-then-ipv6: Ipv4 with a fallback to Ipv6
-
-  -4, --ipv4
-          Use IPv4 only
-
-  -6, --ipv6
-          Use IPv6 only
-
-  -P, --target-port <TARGET_PORT>
-          The target port (TCP & UDP only) [default: 80]
-
-  -S, --source-port <SOURCE_PORT>
-          The source port (TCP & UDP only) [default: auto]
-
-  -A, --source-address <SOURCE_ADDRESS>
-          The source IP address [default: auto]
-
-  -I, --interface <INTERFACE>
-          The network interface [default: auto]
-
-  -i, --min-round-duration <MIN_ROUND_DURATION>
-          The minimum duration of every round [default: 1s]
-
-  -T, --max-round-duration <MAX_ROUND_DURATION>
-          The maximum duration of every round [default: 1s]
-
-  -g, --grace-duration <GRACE_DURATION>
-          The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]
-
-      --initial-sequence <INITIAL_SEQUENCE>
-          The initial sequence number [default: 33000]
-
-  -R, --multipath-strategy <MULTIPATH_STRATEGY>
-          The Equal-cost Multi-Path routing strategy (UDP only) [default: classic]
-
-          Possible values:
-          - classic: The src or dest port is used to store the sequence number
-          - paris:   The UDP `checksum` field is used to store the sequence number
-          - dublin:  The IP `identifier` field is used to store the sequence number
-
-  -U, --max-inflight <MAX_INFLIGHT>
-          The maximum number of in-flight ICMP echo requests [default: 24]
-
-  -f, --first-ttl <FIRST_TTL>
-          The TTL to start from [default: 1]
-
-  -t, --max-ttl <MAX_TTL>
-          The maximum number of TTL hops [default: 64]
-
-      --packet-size <PACKET_SIZE>
-          The size of IP packet to send (IP header + ICMP header + payload) [default: 84]
-
-      --payload-pattern <PAYLOAD_PATTERN>
-          The repeating pattern in the payload of the ICMP packet [default: 0]
-
-  -Q, --tos <TOS>
-          The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]
-
-  -e, --icmp-extensions
-          Parse ICMP extensions
-
-      --read-timeout <READ_TIMEOUT>
-          The socket read timeout [default: 10ms]
-
-  -r, --dns-resolve-method <DNS_RESOLVE_METHOD>
-          How to perform DNS queries [default: system]
-
-          Possible values:
-          - system:     Resolve using the OS resolver
-          - resolv:     Resolve using the `/etc/resolv.conf` DNS configuration
-          - google:     Resolve using the Google `8.8.8.8` DNS service
-          - cloudflare: Resolve using the Cloudflare `1.1.1.1` DNS service
-
-  -y, --dns-resolve-all
-          Trace to all IPs resolved from DNS lookup [default: false]
-
-      --dns-timeout <DNS_TIMEOUT>
-          The maximum time to wait to perform DNS queries [default: 5s]
-
-  -z, --dns-lookup-as-info
-          Lookup autonomous system (AS) information during DNS queries [default: false]
-
-  -a, --tui-address-mode <TUI_ADDRESS_MODE>
-          How to render addresses [default: host]
-
-          Possible values:
-          - ip:   Show IP address only
-          - host: Show reverse-lookup DNS hostname only
-          - both: Show both IP address and reverse-lookup DNS hostname
-
-      --tui-as-mode <TUI_AS_MODE>
-          How to render AS information [default: asn]
-
-          Possible values:
-          - asn:          Show the ASN
-          - prefix:       Display the AS prefix
-          - country-code: Display the country code
-          - registry:     Display the registry name
-          - allocated:    Display the allocated date
-          - name:         Display the AS name
-
-      --tui-custom-columns <TUI_CUSTOM_COLUMNS>
-          Custom columns to be displayed in the TUI hops table [default: holsravbwdt]
-
-      --tui-icmp-extension-mode <TUI_ICMP_EXTENSION_MODE>
-          How to render ICMP extensions [default: off]
-
-          Possible values:
-          - off:  Do not show `icmp` extensions
-          - mpls: Show MPLS label(s) only
-          - full: Show full `icmp` extension data for all known extensions
-          - all:  Show full `icmp` extension data for all classes
-
-      --tui-geoip-mode <TUI_GEOIP_MODE>
-          How to render GeoIp information [default: short]
-
-          Possible values:
-          - off:      Do not display GeoIp data
-          - short:    Show short format
-          - long:     Show long format
-          - location: Show latitude and Longitude format
-
-  -M, --tui-max-addrs <TUI_MAX_ADDRS>
-          The maximum number of addresses to show per hop [default: auto]
-
-  -s, --tui-max-samples <TUI_MAX_SAMPLES>
-          The maximum number of samples to record per hop [default: 256]
-
-      --tui-max-flows <TUI_MAX_FLOWS>
-          The maximum number of flows to show [default: 64]
-
-      --tui-preserve-screen
-          Preserve the screen on exit [default: false]
-
-      --tui-refresh-rate <TUI_REFRESH_RATE>
-          The Tui refresh rate [default: 100ms]
-
-      --tui-privacy-max-ttl <TUI_PRIVACY_MAX_TTL>
-          The maximum ttl of hops which will be masked for privacy [default: 0]
-
-      --tui-theme-colors <TUI_THEME_COLORS>
-          The TUI theme colors [item=color,item=color,..]
-
-      --print-tui-theme-items
-          Print all TUI theme items and exit
-
-      --tui-key-bindings <TUI_KEY_BINDINGS>
-          The TUI key bindings [command=key,command=key,..]
-
-      --print-tui-binding-commands
-          Print all TUI commands that can be bound and exit
-
-  -C, --report-cycles <REPORT_CYCLES>
-          The number of report cycles to run [default: 10]
-
-  -G, --geoip-mmdb-file <GEOIP_MMDB_FILE>
-          The supported MaxMind or IPinfo GeoIp mmdb file
-
-      --generate <GENERATE>
-          Generate shell completion
-          
-          [possible values: bash, elvish, fish, powershell, zsh]
-
-      --generate-man
-          Generate ROFF man page
-
-      --print-config-template
-          Print a template toml config file and exit
-
-      --log-format <LOG_FORMAT>
-          The debug log format [default: pretty]
-
-          Possible values:
-          - compact: Display log data in a compact format
-          - pretty:  Display log data in a pretty format
-          - json:    Display log data in a json format
-          - chrome:  Display log data in Chrome trace format
-
-      --log-filter <LOG_FILTER>
-          The debug log filter [default: trippy=debug]
-
-      --log-span-events <LOG_SPAN_EVENTS>
-          The debug log format [default: off]
-
-          Possible values:
-          - off:    Do not display event spans
-          - active: Display enter and exit event spans
-          - full:   Display all event spans
-
-  -v, --verbose
-          Enable verbose debug logging
-
-  -h, --help
-          Print help (see a summary with '-h')
-
-  -V, --version
-          Print version
diff --git a/crates/trippy/test_resources/config/usage_short.txt b/crates/trippy/test_resources/config/usage_short.txt
deleted file mode 100644
index eb7f3fe..0000000
--- a/crates/trippy/test_resources/config/usage_short.txt
+++ /dev/null
@@ -1,124 +0,0 @@
-A network diagnostic tool
-
-Usage: trip [OPTIONS] [TARGETS]...
-
-Arguments:
-  [TARGETS]...  A space delimited list of hostnames and IPs to trace
-
-Options:
-  -c, --config-file <CONFIG_FILE>
-          Config file
-  -m, --mode <MODE>
-          Output mode [default: tui] [possible values: tui, stream, pretty, markdown, csv, json, dot, flows, silent]
-  -u, --unprivileged
-          Trace without requiring elevated privileges on supported platforms [default: false]
-  -p, --protocol <PROTOCOL>
-          Tracing protocol [default: icmp] [possible values: icmp, udp, tcp]
-      --udp
-          Trace using the UDP protocol
-      --tcp
-          Trace using the TCP protocol
-      --icmp
-          Trace using the ICMP protocol
-  -F, --addr-family <ADDR_FAMILY>
-          The address family [default: Ipv4thenIpv6] [possible values: ipv4, ipv6, ipv6-then-ipv4, ipv4-then-ipv6]
-  -4, --ipv4
-          Use IPv4 only
-  -6, --ipv6
-          Use IPv6 only
-  -P, --target-port <TARGET_PORT>
-          The target port (TCP & UDP only) [default: 80]
-  -S, --source-port <SOURCE_PORT>
-          The source port (TCP & UDP only) [default: auto]
-  -A, --source-address <SOURCE_ADDRESS>
-          The source IP address [default: auto]
-  -I, --interface <INTERFACE>
-          The network interface [default: auto]
-  -i, --min-round-duration <MIN_ROUND_DURATION>
-          The minimum duration of every round [default: 1s]
-  -T, --max-round-duration <MAX_ROUND_DURATION>
-          The maximum duration of every round [default: 1s]
-  -g, --grace-duration <GRACE_DURATION>
-          The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]
-      --initial-sequence <INITIAL_SEQUENCE>
-          The initial sequence number [default: 33000]
-  -R, --multipath-strategy <MULTIPATH_STRATEGY>
-          The Equal-cost Multi-Path routing strategy (UDP only) [default: classic] [possible values: classic, paris,
-          dublin]
-  -U, --max-inflight <MAX_INFLIGHT>
-          The maximum number of in-flight ICMP echo requests [default: 24]
-  -f, --first-ttl <FIRST_TTL>
-          The TTL to start from [default: 1]
-  -t, --max-ttl <MAX_TTL>
-          The maximum number of TTL hops [default: 64]
-      --packet-size <PACKET_SIZE>
-          The size of IP packet to send (IP header + ICMP header + payload) [default: 84]
-      --payload-pattern <PAYLOAD_PATTERN>
-          The repeating pattern in the payload of the ICMP packet [default: 0]
-  -Q, --tos <TOS>
-          The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]
-  -e, --icmp-extensions
-          Parse ICMP extensions
-      --read-timeout <READ_TIMEOUT>
-          The socket read timeout [default: 10ms]
-  -r, --dns-resolve-method <DNS_RESOLVE_METHOD>
-          How to perform DNS queries [default: system] [possible values: system, resolv, google, cloudflare]
-  -y, --dns-resolve-all
-          Trace to all IPs resolved from DNS lookup [default: false]
-      --dns-timeout <DNS_TIMEOUT>
-          The maximum time to wait to perform DNS queries [default: 5s]
-  -z, --dns-lookup-as-info
-          Lookup autonomous system (AS) information during DNS queries [default: false]
-  -a, --tui-address-mode <TUI_ADDRESS_MODE>
-          How to render addresses [default: host] [possible values: ip, host, both]
-      --tui-as-mode <TUI_AS_MODE>
-          How to render AS information [default: asn] [possible values: asn, prefix, country-code, registry, allocated,
-          name]
-      --tui-custom-columns <TUI_CUSTOM_COLUMNS>
-          Custom columns to be displayed in the TUI hops table [default: holsravbwdt]
-      --tui-icmp-extension-mode <TUI_ICMP_EXTENSION_MODE>
-          How to render ICMP extensions [default: off] [possible values: off, mpls, full, all]
-      --tui-geoip-mode <TUI_GEOIP_MODE>
-          How to render GeoIp information [default: short] [possible values: off, short, long, location]
-  -M, --tui-max-addrs <TUI_MAX_ADDRS>
-          The maximum number of addresses to show per hop [default: auto]
-  -s, --tui-max-samples <TUI_MAX_SAMPLES>
-          The maximum number of samples to record per hop [default: 256]
-      --tui-max-flows <TUI_MAX_FLOWS>
-          The maximum number of flows to show [default: 64]
-      --tui-preserve-screen
-          Preserve the screen on exit [default: false]
-      --tui-refresh-rate <TUI_REFRESH_RATE>
-          The Tui refresh rate [default: 100ms]
-      --tui-privacy-max-ttl <TUI_PRIVACY_MAX_TTL>
-          The maximum ttl of hops which will be masked for privacy [default: 0]
-      --tui-theme-colors <TUI_THEME_COLORS>
-          The TUI theme colors [item=color,item=color,..]
-      --print-tui-theme-items
-          Print all TUI theme items and exit
-      --tui-key-bindings <TUI_KEY_BINDINGS>
-          The TUI key bindings [command=key,command=key,..]
-      --print-tui-binding-commands
-          Print all TUI commands that can be bound and exit
-  -C, --report-cycles <REPORT_CYCLES>
-          The number of report cycles to run [default: 10]
-  -G, --geoip-mmdb-file <GEOIP_MMDB_FILE>
-          The supported MaxMind or IPinfo GeoIp mmdb file
-      --generate <GENERATE>
-          Generate shell completion [possible values: bash, elvish, fish, powershell, zsh]
-      --generate-man
-          Generate ROFF man page
-      --print-config-template
-          Print a template toml config file and exit
-      --log-format <LOG_FORMAT>
-          The debug log format [default: pretty] [possible values: compact, pretty, json, chrome]
-      --log-filter <LOG_FILTER>
-          The debug log filter [default: trippy=debug]
-      --log-span-events <LOG_SPAN_EVENTS>
-          The debug log format [default: off] [possible values: off, active, full]
-  -v, --verbose
-          Enable verbose debug logging
-  -h, --help
-          Print help (see more with '--help')
-  -V, --version
-          Print version
diff --git a/crates/trippy/test_resources/tui/tui_binding_commands.txt b/crates/trippy/test_resources/tui/tui_binding_commands.txt
deleted file mode 100644
index 97d00a8..0000000
--- a/crates/trippy/test_resources/tui/tui_binding_commands.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-TUI binding commands: toggle-help, toggle-help-alt, toggle-settings, next-hop, previous-hop, next-trace, previous-trace, next-hop-address, previous-hop-address, address-mode-ip, address-mode-host, address-mode-both, toggle-freeze, toggle-chart, toggle-map, toggle-flows, toggle-privacy, expand-hosts, expand-hosts-max, contract-hosts, contract-hosts-min, chart-zoom-in, chart-zoom-out, clear-trace-data, clear-dns-cache, clear-selection, toggle-as-info, toggle-hop-details, quit
diff --git a/crates/trippy/test_resources/tui/tui_theme_items.txt b/crates/trippy/test_resources/tui/tui_theme_items.txt
deleted file mode 100644
index 2462205..0000000
--- a/crates/trippy/test_resources/tui/tui_theme_items.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-TUI theme color items: bg-color, border-color, text-color, tab-text-color, hops-table-header-bg-color, hops-table-header-text-color, hops-table-row-active-text-color, hops-table-row-inactive-text-color, hops-chart-selected-color, hops-chart-unselected-color, hops-chart-axis-color, frequency-chart-bar-color, frequency-chart-text-color, flows-chart-bar-selected-color, flows-chart-bar-unselected-color, flows-chart-text-current-color, flows-chart-text-non-current-color, samples-chart-color, help-dialog-bg-color, help-dialog-text-color, settings-tab-text-color, settings-dialog-bg-color, settings-table-header-text-color, settings-table-header-bg-color, settings-table-row-text-color, map-world-color, map-radius-color, map-selected-color, map-info-panel-border-color, map-info-panel-bg-color, map-info-panel-text-color
diff --git a/crates/trippy/test_resources/backend/ipv4_3probes_3hops_completed.yaml b/crates/trippy/tests/resources/backend/ipv4_3probes_3hops_completed.yaml
similarity index 100%
rename from crates/trippy/test_resources/backend/ipv4_3probes_3hops_completed.yaml
rename to crates/trippy/tests/resources/backend/ipv4_3probes_3hops_completed.yaml
diff --git a/crates/trippy/test_resources/backend/ipv4_3probes_3hops_mixed_multi.yaml b/crates/trippy/tests/resources/backend/ipv4_3probes_3hops_mixed_multi.yaml
similarity index 100%
rename from crates/trippy/test_resources/backend/ipv4_3probes_3hops_mixed_multi.yaml
rename to crates/trippy/tests/resources/backend/ipv4_3probes_3hops_mixed_multi.yaml
diff --git a/crates/trippy/test_resources/backend/ipv4_4probes_0latency.yaml b/crates/trippy/tests/resources/backend/ipv4_4probes_0latency.yaml
similarity index 100%
rename from crates/trippy/test_resources/backend/ipv4_4probes_0latency.yaml
rename to crates/trippy/tests/resources/backend/ipv4_4probes_0latency.yaml
diff --git a/crates/trippy/test_resources/backend/ipv4_4probes_all_status.yaml b/crates/trippy/tests/resources/backend/ipv4_4probes_all_status.yaml
similarity index 100%
rename from crates/trippy/test_resources/backend/ipv4_4probes_all_status.yaml
rename to crates/trippy/tests/resources/backend/ipv4_4probes_all_status.yaml
diff --git a/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip.snap b/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip.snap
new file mode 100644
index 0000000..e77710a
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/config.rs
+---
+AnetworkdiagnostictoolUsage:trip[OPTIONS][TARGETS]...Arguments:[TARGETS]...AspacedelimitedlistofhostnamesandIPstotraceOptions:-c,--config-file<CONFIG_FILE>Configfile-m,--mode<MODE>Outputmode[default:tui][possiblevalues:tui,stream,pretty,markdown,csv,json,dot,flows,silent]-u,--unprivilegedTracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]-p,--protocol<PROTOCOL>Tracingprotocol[default:icmp][possiblevalues:icmp,udp,tcp]--udpTraceusingtheUDPprotocol--tcpTraceusingtheTCPprotocol--icmpTraceusingtheICMPprotocol-F,--addr-family<ADDR_FAMILY>Theaddressfamily[default:Ipv4thenIpv6][possiblevalues:ipv4,ipv6,ipv6-then-ipv4,ipv4-then-ipv6]-4,--ipv4UseIPv4only-6,--ipv6UseIPv6only-P,--target-port<TARGET_PORT>Thetargetport(TCP&UDPonly)[default:80]-S,--source-port<SOURCE_PORT>Thesourceport(TCP&UDPonly)[default:auto]-A,--source-address<SOURCE_ADDRESS>ThesourceIPaddress[default:auto]-I,--interface<INTERFACE>Thenetworkinterface[default:auto]-i,--min-round-duration<MIN_ROUND_DURATION>Theminimumdurationofeveryround[default:1s]-T,--max-round-duration<MAX_ROUND_DURATION>Themaximumdurationofeveryround[default:1s]-g,--grace-duration<GRACE_DURATION>TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]--initial-sequence<INITIAL_SEQUENCE>Theinitialsequencenumber[default:33000]-R,--multipath-strategy<MULTIPATH_STRATEGY>TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic][possiblevalues:classic,paris,dublin]-U,--max-inflight<MAX_INFLIGHT>Themaximumnumberofin-flightICMPechorequests[default:24]-f,--first-ttl<FIRST_TTL>TheTTLtostartfrom[default:1]-t,--max-ttl<MAX_TTL>ThemaximumnumberofTTLhops[default:64]--packet-size<PACKET_SIZE>ThesizeofIPpackettosend(IPheader+ICMPheader+payload)[default:84]--payload-pattern<PAYLOAD_PATTERN>TherepeatingpatterninthepayloadoftheICMPpacket[default:0]-Q,--tos<TOS>TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]-e,--icmp-extensionsParseICMPextensions--read-timeout<READ_TIMEOUT>Thesocketreadtimeout[default:10ms]-r,--dns-resolve-method<DNS_RESOLVE_METHOD>HowtoperformDNSqueries[default:system][possiblevalues:system,resolv,google,cloudflare]-y,--dns-resolve-allTracetoallIPsresolvedfromDNSlookup[default:false]--dns-timeout<DNS_TIMEOUT>ThemaximumtimetowaittoperformDNSqueries[default:5s]-z,--dns-lookup-as-infoLookupautonomoussystem(AS)informationduringDNSqueries[default:false]-a,--tui-address-mode<TUI_ADDRESS_MODE>Howtorenderaddresses[default:host][possiblevalues:ip,host,both]--tui-as-mode<TUI_AS_MODE>HowtorenderASinformation[default:asn][possiblevalues:asn,prefix,country-code,registry,allocated,name]--tui-custom-columns<TUI_CUSTOM_COLUMNS>CustomcolumnstobedisplayedintheTUIhopstable[default:holsravbwdt]--tui-icmp-extension-mode<TUI_ICMP_EXTENSION_MODE>HowtorenderICMPextensions[default:off][possiblevalues:off,mpls,full,all]--tui-geoip-mode<TUI_GEOIP_MODE>HowtorenderGeoIpinformation[default:short][possiblevalues:off,short,long,location]-M,--tui-max-addrs<TUI_MAX_ADDRS>Themaximumnumberofaddressestoshowperhop[default:auto]-s,--tui-max-samples<TUI_MAX_SAMPLES>Themaximumnumberofsamplestorecordperhop[default:256]--tui-max-flows<TUI_MAX_FLOWS>Themaximumnumberofflowstoshow[default:64]--tui-preserve-screenPreservethescreenonexit[default:false]--tui-refresh-rate<TUI_REFRESH_RATE>TheTuirefreshrate[default:100ms]--tui-privacy-max-ttl<TUI_PRIVACY_MAX_TTL>Themaximumttlofhopswhichwillbemaskedforprivacy[default:0]--tui-theme-colors<TUI_THEME_COLORS>TheTUIthemecolors[item=color,item=color,..]--print-tui-theme-itemsPrintallTUIthemeitemsandexit--tui-key-bindings<TUI_KEY_BINDINGS>TheTUIkeybindings[command=key,command=key,..]--print-tui-binding-commandsPrintallTUIcommandsthatcanbeboundandexit-C,--report-cycles<REPORT_CYCLES>Thenumberofreportcyclestorun[default:10]-G,--geoip-mmdb-file<GEOIP_MMDB_FILE>ThesupportedMaxMindorIPinfoGeoIpmmdbfile--generate<GENERATE>Generateshellcompletion[possiblevalues:bash,elvish,fish,powershell,zsh]--generate-manGenerateROFFmanpage--print-config-templatePrintatemplatetomlconfigfileandexit--log-format<LOG_FORMAT>Thedebuglogformat[default:pretty][possiblevalues:compact,pretty,json,chrome]--log-filter<LOG_FILTER>Thedebuglogfilter[default:trippy=debug]--log-span-events<LOG_SPAN_EVENTS>Thedebuglogformat[default:off][possiblevalues:off,active,full]-v,--verboseEnableverbosedebuglogging-h,--helpPrinthelp(seemorewith'--help')-V,--versionPrintversion
diff --git a/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip_--help.snap b/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip_--help.snap
new file mode 100644
index 0000000..b78681d
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip_--help.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/config.rs
+---
+AnetworkdiagnostictoolUsage:trip[OPTIONS][TARGETS]...Arguments:[TARGETS]...AspacedelimitedlistofhostnamesandIPstotraceOptions:-c,--config-file<CONFIG_FILE>Configfile-m,--mode<MODE>Outputmode[default:tui]Possiblevalues:-tui:DisplayinteractiveTUI-stream:Displayacontinuousstreamoftracingdata-pretty:GenerateaprettytexttablereportforNcycles-markdown:GenerateaMarkdowntexttablereportforNcycles-csv:GenerateaCSVreportforNcycles-json:GenerateaJSONreportforNcycles-dot:GenerateaGraphvizDOTfileforNcycles-flows:DisplayallflowsforNcycles-silent:DonotgenerateanytracingoutputforNcycles-u,--unprivilegedTracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]-p,--protocol<PROTOCOL>Tracingprotocol[default:icmp]Possiblevalues:-icmp:InternetControlMessageProtocol-udp:UserDatagramProtocol-tcp:TransmissionControlProtocol--udpTraceusingtheUDPprotocol--tcpTraceusingtheTCPprotocol--icmpTraceusingtheICMPprotocol-F,--addr-family<ADDR_FAMILY>Theaddressfamily[default:Ipv4thenIpv6]Possiblevalues:-ipv4:Ipv4only-ipv6:Ipv6only-ipv6-then-ipv4:Ipv6withafallbacktoIpv4-ipv4-then-ipv6:Ipv4withafallbacktoIpv6-4,--ipv4UseIPv4only-6,--ipv6UseIPv6only-P,--target-port<TARGET_PORT>Thetargetport(TCP&UDPonly)[default:80]-S,--source-port<SOURCE_PORT>Thesourceport(TCP&UDPonly)[default:auto]-A,--source-address<SOURCE_ADDRESS>ThesourceIPaddress[default:auto]-I,--interface<INTERFACE>Thenetworkinterface[default:auto]-i,--min-round-duration<MIN_ROUND_DURATION>Theminimumdurationofeveryround[default:1s]-T,--max-round-duration<MAX_ROUND_DURATION>Themaximumdurationofeveryround[default:1s]-g,--grace-duration<GRACE_DURATION>TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]--initial-sequence<INITIAL_SEQUENCE>Theinitialsequencenumber[default:33000]-R,--multipath-strategy<MULTIPATH_STRATEGY>TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic]Possiblevalues:-classic:Thesrcordestportisusedtostorethesequencenumber-paris:TheUDP`checksum`fieldisusedtostorethesequencenumber-dublin:TheIP`identifier`fieldisusedtostorethesequencenumber-U,--max-inflight<MAX_INFLIGHT>Themaximumnumberofin-flightICMPechorequests[default:24]-f,--first-ttl<FIRST_TTL>TheTTLtostartfrom[default:1]-t,--max-ttl<MAX_TTL>ThemaximumnumberofTTLhops[default:64]--packet-size<PACKET_SIZE>ThesizeofIPpackettosend(IPheader+ICMPheader+payload)[default:84]--payload-pattern<PAYLOAD_PATTERN>TherepeatingpatterninthepayloadoftheICMPpacket[default:0]-Q,--tos<TOS>TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]-e,--icmp-extensionsParseICMPextensions--read-timeout<READ_TIMEOUT>Thesocketreadtimeout[default:10ms]-r,--dns-resolve-method<DNS_RESOLVE_METHOD>HowtoperformDNSqueries[default:system]Possiblevalues:-system:ResolveusingtheOSresolver-resolv:Resolveusingthe`/etc/resolv.conf`DNSconfiguration-google:ResolveusingtheGoogle`8.8.8.8`DNSservice-cloudflare:ResolveusingtheCloudflare`1.1.1.1`DNSservice-y,--dns-resolve-allTracetoallIPsresolvedfromDNSlookup[default:false]--dns-timeout<DNS_TIMEOUT>ThemaximumtimetowaittoperformDNSqueries[default:5s]-z,--dns-lookup-as-infoLookupautonomoussystem(AS)informationduringDNSqueries[default:false]-a,--tui-address-mode<TUI_ADDRESS_MODE>Howtorenderaddresses[default:host]Possiblevalues:-ip:ShowIPaddressonly-host:Showreverse-lookupDNShostnameonly-both:ShowbothIPaddressandreverse-lookupDNShostname--tui-as-mode<TUI_AS_MODE>HowtorenderASinformation[default:asn]Possiblevalues:-asn:ShowtheASN-prefix:DisplaytheASprefix-country-code:Displaythecountrycode-registry:Displaytheregistryname-allocated:Displaytheallocateddate-name:DisplaytheASname--tui-custom-columns<TUI_CUSTOM_COLUMNS>CustomcolumnstobedisplayedintheTUIhopstable[default:holsravbwdt]--tui-icmp-extension-mode<TUI_ICMP_EXTENSION_MODE>HowtorenderICMPextensions[default:off]Possiblevalues:-off:Donotshow`icmp`extensions-mpls:ShowMPLSlabel(s)only-full:Showfull`icmp`extensiondataforallknownextensions-all:Showfull`icmp`extensiondataforallclasses--tui-geoip-mode<TUI_GEOIP_MODE>HowtorenderGeoIpinformation[default:short]Possiblevalues:-off:DonotdisplayGeoIpdata-short:Showshortformat-long:Showlongformat-location:ShowlatitudeandLongitudeformat-M,--tui-max-addrs<TUI_MAX_ADDRS>Themaximumnumberofaddressestoshowperhop[default:auto]-s,--tui-max-samples<TUI_MAX_SAMPLES>Themaximumnumberofsamplestorecordperhop[default:256]--tui-max-flows<TUI_MAX_FLOWS>Themaximumnumberofflowstoshow[default:64]--tui-preserve-screenPreservethescreenonexit[default:false]--tui-refresh-rate<TUI_REFRESH_RATE>TheTuirefreshrate[default:100ms]--tui-privacy-max-ttl<TUI_PRIVACY_MAX_TTL>Themaximumttlofhopswhichwillbemaskedforprivacy[default:0]--tui-theme-colors<TUI_THEME_COLORS>TheTUIthemecolors[item=color,item=color,..]--print-tui-theme-itemsPrintallTUIthemeitemsandexit--tui-key-bindings<TUI_KEY_BINDINGS>TheTUIkeybindings[command=key,command=key,..]--print-tui-binding-commandsPrintallTUIcommandsthatcanbeboundandexit-C,--report-cycles<REPORT_CYCLES>Thenumberofreportcyclestorun[default:10]-G,--geoip-mmdb-file<GEOIP_MMDB_FILE>ThesupportedMaxMindorIPinfoGeoIpmmdbfile--generate<GENERATE>Generateshellcompletion[possiblevalues:bash,elvish,fish,powershell,zsh]--generate-manGenerateROFFmanpage--print-config-templatePrintatemplatetomlconfigfileandexit--log-format<LOG_FORMAT>Thedebuglogformat[default:pretty]Possiblevalues:-compact:Displaylogdatainacompactformat-pretty:Displaylogdatainaprettyformat-json:Displaylogdatainajsonformat-chrome:DisplaylogdatainChrometraceformat--log-filter<LOG_FILTER>Thedebuglogfilter[default:trippy=debug]--log-span-events<LOG_SPAN_EVENTS>Thedebuglogformat[default:off]Possiblevalues:-off:Donotdisplayeventspans-active:Displayenterandexiteventspans-full:Displayalleventspans-v,--verboseEnableverbosedebuglogging-h,--helpPrinthelp(seeasummarywith'-h')-V,--versionPrintversion
diff --git a/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip_-h.snap b/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip_-h.snap
new file mode 100644
index 0000000..e77710a
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__config__tests__compare_snapshot@trip_-h.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/config.rs
+---
+AnetworkdiagnostictoolUsage:trip[OPTIONS][TARGETS]...Arguments:[TARGETS]...AspacedelimitedlistofhostnamesandIPstotraceOptions:-c,--config-file<CONFIG_FILE>Configfile-m,--mode<MODE>Outputmode[default:tui][possiblevalues:tui,stream,pretty,markdown,csv,json,dot,flows,silent]-u,--unprivilegedTracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]-p,--protocol<PROTOCOL>Tracingprotocol[default:icmp][possiblevalues:icmp,udp,tcp]--udpTraceusingtheUDPprotocol--tcpTraceusingtheTCPprotocol--icmpTraceusingtheICMPprotocol-F,--addr-family<ADDR_FAMILY>Theaddressfamily[default:Ipv4thenIpv6][possiblevalues:ipv4,ipv6,ipv6-then-ipv4,ipv4-then-ipv6]-4,--ipv4UseIPv4only-6,--ipv6UseIPv6only-P,--target-port<TARGET_PORT>Thetargetport(TCP&UDPonly)[default:80]-S,--source-port<SOURCE_PORT>Thesourceport(TCP&UDPonly)[default:auto]-A,--source-address<SOURCE_ADDRESS>ThesourceIPaddress[default:auto]-I,--interface<INTERFACE>Thenetworkinterface[default:auto]-i,--min-round-duration<MIN_ROUND_DURATION>Theminimumdurationofeveryround[default:1s]-T,--max-round-duration<MAX_ROUND_DURATION>Themaximumdurationofeveryround[default:1s]-g,--grace-duration<GRACE_DURATION>TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]--initial-sequence<INITIAL_SEQUENCE>Theinitialsequencenumber[default:33000]-R,--multipath-strategy<MULTIPATH_STRATEGY>TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic][possiblevalues:classic,paris,dublin]-U,--max-inflight<MAX_INFLIGHT>Themaximumnumberofin-flightICMPechorequests[default:24]-f,--first-ttl<FIRST_TTL>TheTTLtostartfrom[default:1]-t,--max-ttl<MAX_TTL>ThemaximumnumberofTTLhops[default:64]--packet-size<PACKET_SIZE>ThesizeofIPpackettosend(IPheader+ICMPheader+payload)[default:84]--payload-pattern<PAYLOAD_PATTERN>TherepeatingpatterninthepayloadoftheICMPpacket[default:0]-Q,--tos<TOS>TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]-e,--icmp-extensionsParseICMPextensions--read-timeout<READ_TIMEOUT>Thesocketreadtimeout[default:10ms]-r,--dns-resolve-method<DNS_RESOLVE_METHOD>HowtoperformDNSqueries[default:system][possiblevalues:system,resolv,google,cloudflare]-y,--dns-resolve-allTracetoallIPsresolvedfromDNSlookup[default:false]--dns-timeout<DNS_TIMEOUT>ThemaximumtimetowaittoperformDNSqueries[default:5s]-z,--dns-lookup-as-infoLookupautonomoussystem(AS)informationduringDNSqueries[default:false]-a,--tui-address-mode<TUI_ADDRESS_MODE>Howtorenderaddresses[default:host][possiblevalues:ip,host,both]--tui-as-mode<TUI_AS_MODE>HowtorenderASinformation[default:asn][possiblevalues:asn,prefix,country-code,registry,allocated,name]--tui-custom-columns<TUI_CUSTOM_COLUMNS>CustomcolumnstobedisplayedintheTUIhopstable[default:holsravbwdt]--tui-icmp-extension-mode<TUI_ICMP_EXTENSION_MODE>HowtorenderICMPextensions[default:off][possiblevalues:off,mpls,full,all]--tui-geoip-mode<TUI_GEOIP_MODE>HowtorenderGeoIpinformation[default:short][possiblevalues:off,short,long,location]-M,--tui-max-addrs<TUI_MAX_ADDRS>Themaximumnumberofaddressestoshowperhop[default:auto]-s,--tui-max-samples<TUI_MAX_SAMPLES>Themaximumnumberofsamplestorecordperhop[default:256]--tui-max-flows<TUI_MAX_FLOWS>Themaximumnumberofflowstoshow[default:64]--tui-preserve-screenPreservethescreenonexit[default:false]--tui-refresh-rate<TUI_REFRESH_RATE>TheTuirefreshrate[default:100ms]--tui-privacy-max-ttl<TUI_PRIVACY_MAX_TTL>Themaximumttlofhopswhichwillbemaskedforprivacy[default:0]--tui-theme-colors<TUI_THEME_COLORS>TheTUIthemecolors[item=color,item=color,..]--print-tui-theme-itemsPrintallTUIthemeitemsandexit--tui-key-bindings<TUI_KEY_BINDINGS>TheTUIkeybindings[command=key,command=key,..]--print-tui-binding-commandsPrintallTUIcommandsthatcanbeboundandexit-C,--report-cycles<REPORT_CYCLES>Thenumberofreportcyclestorun[default:10]-G,--geoip-mmdb-file<GEOIP_MMDB_FILE>ThesupportedMaxMindorIPinfoGeoIpmmdbfile--generate<GENERATE>Generateshellcompletion[possiblevalues:bash,elvish,fish,powershell,zsh]--generate-manGenerateROFFmanpage--print-config-templatePrintatemplatetomlconfigfileandexit--log-format<LOG_FORMAT>Thedebuglogformat[default:pretty][possiblevalues:compact,pretty,json,chrome]--log-filter<LOG_FILTER>Thedebuglogfilter[default:trippy=debug]--log-span-events<LOG_SPAN_EVENTS>Thedebuglogformat[default:off][possiblevalues:off,active,full]-v,--verboseEnableverbosedebuglogging-h,--helpPrinthelp(seemorewith'--help')-V,--versionPrintversion
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_bash_shell_completions.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_bash_shell_completions.snap
new file mode 100644
index 0000000..37a2bf8
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_bash_shell_completions.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+_trip(){localicurprevoptscmdCOMPREPLY=()cur="${COMP_WORDS[COMP_CWORD]}"prev="${COMP_WORDS[COMP_CWORD-1]}"cmd=""opts=""foriin${COMP_WORDS[@]}docase"${cmd},${i}"in",$1")cmd="trip";;*);;esacdonecase"${cmd}"intrip)opts="-c-m-u-p-F-4-6-P-S-A-I-i-T-g-R-U-f-t-Q-e-r-y-z-a-M-s-C-G-v-h-V--config-file--mode--unprivileged--protocol--udp--tcp--icmp--addr-family--ipv4--ipv6--target-port--source-port--source-address--interface--min-round-duration--max-round-duration--grace-duration--initial-sequence--multipath-strategy--max-inflight--first-ttl--max-ttl--packet-size--payload-pattern--tos--icmp-extensions--read-timeout--dns-resolve-method--dns-resolve-all--dns-timeout--dns-lookup-as-info--tui-address-mode--tui-as-mode--tui-custom-columns--tui-icmp-extension-mode--tui-geoip-mode--tui-max-addrs--tui-max-samples--tui-max-flows--tui-preserve-screen--tui-refresh-rate--tui-privacy-max-ttl--tui-theme-colors--print-tui-theme-items--tui-key-bindings--print-tui-binding-commands--report-cycles--geoip-mmdb-file--generate--generate-man--print-config-template--log-format--log-filter--log-span-events--verbose--help--version[TARGETS]..."if[[${cur}==-*||${COMP_CWORD}-eq1]];thenCOMPREPLY=($(compgen-W"${opts}"--"${cur}"))return0ficase"${prev}"in--config-file)localoldifsif[-n"${IFS+x}"];thenoldifs="$IFS"fiIFS=$'\n'COMPREPLY=($(compgen-f"${cur}"))if[-n"${oldifs+x}"];thenIFS="$oldifs"fiif[["${BASH_VERSINFO[0]}"-ge4]];thencompopt-ofilenamesfireturn0;;-c)localoldifsif[-n"${IFS+x}"];thenoldifs="$IFS"fiIFS=$'\n'COMPREPLY=($(compgen-f"${cur}"))if[-n"${oldifs+x}"];thenIFS="$oldifs"fiif[["${BASH_VERSINFO[0]}"-ge4]];thencompopt-ofilenamesfireturn0;;--mode)COMPREPLY=($(compgen-W"tuistreamprettymarkdowncsvjsondotflowssilent"--"${cur}"))return0;;-m)COMPREPLY=($(compgen-W"tuistreamprettymarkdowncsvjsondotflowssilent"--"${cur}"))return0;;--protocol)COMPREPLY=($(compgen-W"icmpudptcp"--"${cur}"))return0;;-p)COMPREPLY=($(compgen-W"icmpudptcp"--"${cur}"))return0;;--addr-family)COMPREPLY=($(compgen-W"ipv4ipv6ipv6-then-ipv4ipv4-then-ipv6"--"${cur}"))return0;;-F)COMPREPLY=($(compgen-W"ipv4ipv6ipv6-then-ipv4ipv4-then-ipv6"--"${cur}"))return0;;--target-port)COMPREPLY=($(compgen-f"${cur}"))return0;;-P)COMPREPLY=($(compgen-f"${cur}"))return0;;--source-port)COMPREPLY=($(compgen-f"${cur}"))return0;;-S)COMPREPLY=($(compgen-f"${cur}"))return0;;--source-address)COMPREPLY=($(compgen-f"${cur}"))return0;;-A)COMPREPLY=($(compgen-f"${cur}"))return0;;--interface)COMPREPLY=($(compgen-f"${cur}"))return0;;-I)COMPREPLY=($(compgen-f"${cur}"))return0;;--min-round-duration)COMPREPLY=($(compgen-f"${cur}"))return0;;-i)COMPREPLY=($(compgen-f"${cur}"))return0;;--max-round-duration)COMPREPLY=($(compgen-f"${cur}"))return0;;-T)COMPREPLY=($(compgen-f"${cur}"))return0;;--grace-duration)COMPREPLY=($(compgen-f"${cur}"))return0;;-g)COMPREPLY=($(compgen-f"${cur}"))return0;;--initial-sequence)COMPREPLY=($(compgen-f"${cur}"))return0;;--multipath-strategy)COMPREPLY=($(compgen-W"classicparisdublin"--"${cur}"))return0;;-R)COMPREPLY=($(compgen-W"classicparisdublin"--"${cur}"))return0;;--max-inflight)COMPREPLY=($(compgen-f"${cur}"))return0;;-U)COMPREPLY=($(compgen-f"${cur}"))return0;;--first-ttl)COMPREPLY=($(compgen-f"${cur}"))return0;;-f)COMPREPLY=($(compgen-f"${cur}"))return0;;--max-ttl)COMPREPLY=($(compgen-f"${cur}"))return0;;-t)COMPREPLY=($(compgen-f"${cur}"))return0;;--packet-size)COMPREPLY=($(compgen-f"${cur}"))return0;;--payload-pattern)COMPREPLY=($(compgen-f"${cur}"))return0;;--tos)COMPREPLY=($(compgen-f"${cur}"))return0;;-Q)COMPREPLY=($(compgen-f"${cur}"))return0;;--read-timeout)COMPREPLY=($(compgen-f"${cur}"))return0;;--dns-resolve-method)COMPREPLY=($(compgen-W"systemresolvgooglecloudflare"--"${cur}"))return0;;-r)COMPREPLY=($(compgen-W"systemresolvgooglecloudflare"--"${cur}"))return0;;--dns-timeout)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-address-mode)COMPREPLY=($(compgen-W"iphostboth"--"${cur}"))return0;;-a)COMPREPLY=($(compgen-W"iphostboth"--"${cur}"))return0;;--tui-as-mode)COMPREPLY=($(compgen-W"asnprefixcountry-coderegistryallocatedname"--"${cur}"))return0;;--tui-custom-columns)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-icmp-extension-mode)COMPREPLY=($(compgen-W"offmplsfullall"--"${cur}"))return0;;--tui-geoip-mode)COMPREPLY=($(compgen-W"offshortlonglocation"--"${cur}"))return0;;--tui-max-addrs)COMPREPLY=($(compgen-f"${cur}"))return0;;-M)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-max-samples)COMPREPLY=($(compgen-f"${cur}"))return0;;-s)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-max-flows)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-refresh-rate)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-privacy-max-ttl)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-theme-colors)COMPREPLY=($(compgen-f"${cur}"))return0;;--tui-key-bindings)COMPREPLY=($(compgen-f"${cur}"))return0;;--report-cycles)COMPREPLY=($(compgen-f"${cur}"))return0;;-C)COMPREPLY=($(compgen-f"${cur}"))return0;;--geoip-mmdb-file)localoldifsif[-n"${IFS+x}"];thenoldifs="$IFS"fiIFS=$'\n'COMPREPLY=($(compgen-f"${cur}"))if[-n"${oldifs+x}"];thenIFS="$oldifs"fiif[["${BASH_VERSINFO[0]}"-ge4]];thencompopt-ofilenamesfireturn0;;-G)localoldifsif[-n"${IFS+x}"];thenoldifs="$IFS"fiIFS=$'\n'COMPREPLY=($(compgen-f"${cur}"))if[-n"${oldifs+x}"];thenIFS="$oldifs"fiif[["${BASH_VERSINFO[0]}"-ge4]];thencompopt-ofilenamesfireturn0;;--generate)COMPREPLY=($(compgen-W"bashelvishfishpowershellzsh"--"${cur}"))return0;;--log-format)COMPREPLY=($(compgen-W"compactprettyjsonchrome"--"${cur}"))return0;;--log-filter)COMPREPLY=($(compgen-f"${cur}"))return0;;--log-span-events)COMPREPLY=($(compgen-W"offactivefull"--"${cur}"))return0;;*)COMPREPLY=();;esacCOMPREPLY=($(compgen-W"${opts}"--"${cur}"))return0;;esac}if[["${BASH_VERSINFO[0]}"-eq4&&"${BASH_VERSINFO[1]}"-ge4||"${BASH_VERSINFO[0]}"-gt4]];thencomplete-F_trip-onosort-obashdefault-odefaulttripelsecomplete-F_trip-obashdefault-odefaulttripfi
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_elvish_shell_completions.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_elvish_shell_completions.snap
new file mode 100644
index 0000000..ee1c58a
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_elvish_shell_completions.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+usebuiltin;usestr;setedit:completion:arg-completer[trip]={|@words|fnspaces{|n|builtin:repeat$n''|str:join''}fncand{|textdesc|edit:complex-candidate$text&display=$text''(spaces(-14(wcswidth$text)))$desc}varcommand='trip'forword$words[1..-1]{if(str:has-prefix$word'-'){break}setcommand=$command';'$word}varcompletions=[&'trip'={cand-c'Configfile'cand--config-file'Configfile'cand-m'Outputmode[default:tui]'cand--mode'Outputmode[default:tui]'cand-p'Tracingprotocol[default:icmp]'cand--protocol'Tracingprotocol[default:icmp]'cand-F'Theaddressfamily[default:Ipv4thenIpv6]'cand--addr-family'Theaddressfamily[default:Ipv4thenIpv6]'cand-P'Thetargetport(TCP&UDPonly)[default:80]'cand--target-port'Thetargetport(TCP&UDPonly)[default:80]'cand-S'Thesourceport(TCP&UDPonly)[default:auto]'cand--source-port'Thesourceport(TCP&UDPonly)[default:auto]'cand-A'ThesourceIPaddress[default:auto]'cand--source-address'ThesourceIPaddress[default:auto]'cand-I'Thenetworkinterface[default:auto]'cand--interface'Thenetworkinterface[default:auto]'cand-i'Theminimumdurationofeveryround[default:1s]'cand--min-round-duration'Theminimumdurationofeveryround[default:1s]'cand-T'Themaximumdurationofeveryround[default:1s]'cand--max-round-duration'Themaximumdurationofeveryround[default:1s]'cand-g'TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]'cand--grace-duration'TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]'cand--initial-sequence'Theinitialsequencenumber[default:33000]'cand-R'TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic]'cand--multipath-strategy'TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic]'cand-U'Themaximumnumberofin-flightICMPechorequests[default:24]'cand--max-inflight'Themaximumnumberofin-flightICMPechorequests[default:24]'cand-f'TheTTLtostartfrom[default:1]'cand--first-ttl'TheTTLtostartfrom[default:1]'cand-t'ThemaximumnumberofTTLhops[default:64]'cand--max-ttl'ThemaximumnumberofTTLhops[default:64]'cand--packet-size'ThesizeofIPpackettosend(IPheader+ICMPheader+payload)[default:84]'cand--payload-pattern'TherepeatingpatterninthepayloadoftheICMPpacket[default:0]'cand-Q'TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]'cand--tos'TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]'cand--read-timeout'Thesocketreadtimeout[default:10ms]'cand-r'HowtoperformDNSqueries[default:system]'cand--dns-resolve-method'HowtoperformDNSqueries[default:system]'cand--dns-timeout'ThemaximumtimetowaittoperformDNSqueries[default:5s]'cand-a'Howtorenderaddresses[default:host]'cand--tui-address-mode'Howtorenderaddresses[default:host]'cand--tui-as-mode'HowtorenderASinformation[default:asn]'cand--tui-custom-columns'CustomcolumnstobedisplayedintheTUIhopstable[default:holsravbwdt]'cand--tui-icmp-extension-mode'HowtorenderICMPextensions[default:off]'cand--tui-geoip-mode'HowtorenderGeoIpinformation[default:short]'cand-M'Themaximumnumberofaddressestoshowperhop[default:auto]'cand--tui-max-addrs'Themaximumnumberofaddressestoshowperhop[default:auto]'cand-s'Themaximumnumberofsamplestorecordperhop[default:256]'cand--tui-max-samples'Themaximumnumberofsamplestorecordperhop[default:256]'cand--tui-max-flows'Themaximumnumberofflowstoshow[default:64]'cand--tui-refresh-rate'TheTuirefreshrate[default:100ms]'cand--tui-privacy-max-ttl'Themaximumttlofhopswhichwillbemaskedforprivacy[default:0]'cand--tui-theme-colors'TheTUIthemecolors[item=color,item=color,..]'cand--tui-key-bindings'TheTUIkeybindings[command=key,command=key,..]'cand-C'Thenumberofreportcyclestorun[default:10]'cand--report-cycles'Thenumberofreportcyclestorun[default:10]'cand-G'ThesupportedMaxMindorIPinfoGeoIpmmdbfile'cand--geoip-mmdb-file'ThesupportedMaxMindorIPinfoGeoIpmmdbfile'cand--generate'Generateshellcompletion'cand--log-format'Thedebuglogformat[default:pretty]'cand--log-filter'Thedebuglogfilter[default:trippy=debug]'cand--log-span-events'Thedebuglogformat[default:off]'cand-u'Tracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]'cand--unprivileged'Tracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]'cand--udp'TraceusingtheUDPprotocol'cand--tcp'TraceusingtheTCPprotocol'cand--icmp'TraceusingtheICMPprotocol'cand-4'UseIPv4only'cand--ipv4'UseIPv4only'cand-6'UseIPv6only'cand--ipv6'UseIPv6only'cand-e'ParseICMPextensions'cand--icmp-extensions'ParseICMPextensions'cand-y'TracetoallIPsresolvedfromDNSlookup[default:false]'cand--dns-resolve-all'TracetoallIPsresolvedfromDNSlookup[default:false]'cand-z'Lookupautonomoussystem(AS)informationduringDNSqueries[default:false]'cand--dns-lookup-as-info'Lookupautonomoussystem(AS)informationduringDNSqueries[default:false]'cand--tui-preserve-screen'Preservethescreenonexit[default:false]'cand--print-tui-theme-items'PrintallTUIthemeitemsandexit'cand--print-tui-binding-commands'PrintallTUIcommandsthatcanbeboundandexit'cand--generate-man'GenerateROFFmanpage'cand--print-config-template'Printatemplatetomlconfigfileandexit'cand-v'Enableverbosedebuglogging'cand--verbose'Enableverbosedebuglogging'cand-h'Printhelp(seemorewith''--help'')'cand--help'Printhelp(seemorewith''--help'')'cand-V'Printversion'cand--version'Printversion'}]$completions[$command]}
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_fish_shell_completions.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_fish_shell_completions.snap
new file mode 100644
index 0000000..a90be83
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_fish_shell_completions.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+complete-ctrip-sc-lconfig-file-d'Configfile'-r-Fcomplete-ctrip-sm-lmode-d'Outputmode[default:tui]'-r-f-a"{tui'DisplayinteractiveTUI',stream'Displayacontinuousstreamoftracingdata',pretty'GenerateaprettytexttablereportforNcycles',markdown'GenerateaMarkdowntexttablereportforNcycles',csv'GenerateaCSVreportforNcycles',json'GenerateaJSONreportforNcycles',dot'GenerateaGraphvizDOTfileforNcycles',flows'DisplayallflowsforNcycles',silent'DonotgenerateanytracingoutputforNcycles'}"complete-ctrip-sp-lprotocol-d'Tracingprotocol[default:icmp]'-r-f-a"{icmp'InternetControlMessageProtocol',udp'UserDatagramProtocol',tcp'TransmissionControlProtocol'}"complete-ctrip-sF-laddr-family-d'Theaddressfamily[default:Ipv4thenIpv6]'-r-f-a"{ipv4'Ipv4only',ipv6'Ipv6only',ipv6-then-ipv4'Ipv6withafallbacktoIpv4',ipv4-then-ipv6'Ipv4withafallbacktoIpv6'}"complete-ctrip-sP-ltarget-port-d'Thetargetport(TCP&UDPonly)[default:80]'-rcomplete-ctrip-sS-lsource-port-d'Thesourceport(TCP&UDPonly)[default:auto]'-rcomplete-ctrip-sA-lsource-address-d'ThesourceIPaddress[default:auto]'-rcomplete-ctrip-sI-linterface-d'Thenetworkinterface[default:auto]'-rcomplete-ctrip-si-lmin-round-duration-d'Theminimumdurationofeveryround[default:1s]'-rcomplete-ctrip-sT-lmax-round-duration-d'Themaximumdurationofeveryround[default:1s]'-rcomplete-ctrip-sg-lgrace-duration-d'TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]'-rcomplete-ctrip-linitial-sequence-d'Theinitialsequencenumber[default:33000]'-rcomplete-ctrip-sR-lmultipath-strategy-d'TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic]'-r-f-a"{classic'Thesrcordestportisusedtostorethesequencenumber',paris'TheUDP`checksum`fieldisusedtostorethesequencenumber',dublin'TheIP`identifier`fieldisusedtostorethesequencenumber'}"complete-ctrip-sU-lmax-inflight-d'Themaximumnumberofin-flightICMPechorequests[default:24]'-rcomplete-ctrip-sf-lfirst-ttl-d'TheTTLtostartfrom[default:1]'-rcomplete-ctrip-st-lmax-ttl-d'ThemaximumnumberofTTLhops[default:64]'-rcomplete-ctrip-lpacket-size-d'ThesizeofIPpackettosend(IPheader+ICMPheader+payload)[default:84]'-rcomplete-ctrip-lpayload-pattern-d'TherepeatingpatterninthepayloadoftheICMPpacket[default:0]'-rcomplete-ctrip-sQ-ltos-d'TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]'-rcomplete-ctrip-lread-timeout-d'Thesocketreadtimeout[default:10ms]'-rcomplete-ctrip-sr-ldns-resolve-method-d'HowtoperformDNSqueries[default:system]'-r-f-a"{system'ResolveusingtheOSresolver',resolv'Resolveusingthe`/etc/resolv.conf`DNSconfiguration',google'ResolveusingtheGoogle`8.8.8.8`DNSservice',cloudflare'ResolveusingtheCloudflare`1.1.1.1`DNSservice'}"complete-ctrip-ldns-timeout-d'ThemaximumtimetowaittoperformDNSqueries[default:5s]'-rcomplete-ctrip-sa-ltui-address-mode-d'Howtorenderaddresses[default:host]'-r-f-a"{ip'ShowIPaddressonly',host'Showreverse-lookupDNShostnameonly',both'ShowbothIPaddressandreverse-lookupDNShostname'}"complete-ctrip-ltui-as-mode-d'HowtorenderASinformation[default:asn]'-r-f-a"{asn'ShowtheASN',prefix'DisplaytheASprefix',country-code'Displaythecountrycode',registry'Displaytheregistryname',allocated'Displaytheallocateddate',name'DisplaytheASname'}"complete-ctrip-ltui-custom-columns-d'CustomcolumnstobedisplayedintheTUIhopstable[default:holsravbwdt]'-rcomplete-ctrip-ltui-icmp-extension-mode-d'HowtorenderICMPextensions[default:off]'-r-f-a"{off'Donotshow`icmp`extensions',mpls'ShowMPLSlabel(s)only',full'Showfull`icmp`extensiondataforallknownextensions',all'Showfull`icmp`extensiondataforallclasses'}"complete-ctrip-ltui-geoip-mode-d'HowtorenderGeoIpinformation[default:short]'-r-f-a"{off'DonotdisplayGeoIpdata',short'Showshortformat',long'Showlongformat',location'ShowlatitudeandLongitudeformat'}"complete-ctrip-sM-ltui-max-addrs-d'Themaximumnumberofaddressestoshowperhop[default:auto]'-rcomplete-ctrip-ss-ltui-max-samples-d'Themaximumnumberofsamplestorecordperhop[default:256]'-rcomplete-ctrip-ltui-max-flows-d'Themaximumnumberofflowstoshow[default:64]'-rcomplete-ctrip-ltui-refresh-rate-d'TheTuirefreshrate[default:100ms]'-rcomplete-ctrip-ltui-privacy-max-ttl-d'Themaximumttlofhopswhichwillbemaskedforprivacy[default:0]'-rcomplete-ctrip-ltui-theme-colors-d'TheTUIthemecolors[item=color,item=color,..]'-rcomplete-ctrip-ltui-key-bindings-d'TheTUIkeybindings[command=key,command=key,..]'-rcomplete-ctrip-sC-lreport-cycles-d'Thenumberofreportcyclestorun[default:10]'-rcomplete-ctrip-sG-lgeoip-mmdb-file-d'ThesupportedMaxMindorIPinfoGeoIpmmdbfile'-r-Fcomplete-ctrip-lgenerate-d'Generateshellcompletion'-r-f-a"{bash'',elvish'',fish'',powershell'',zsh''}"complete-ctrip-llog-format-d'Thedebuglogformat[default:pretty]'-r-f-a"{compact'Displaylogdatainacompactformat',pretty'Displaylogdatainaprettyformat',json'Displaylogdatainajsonformat',chrome'DisplaylogdatainChrometraceformat'}"complete-ctrip-llog-filter-d'Thedebuglogfilter[default:trippy=debug]'-rcomplete-ctrip-llog-span-events-d'Thedebuglogformat[default:off]'-r-f-a"{off'Donotdisplayeventspans',active'Displayenterandexiteventspans',full'Displayalleventspans'}"complete-ctrip-su-lunprivileged-d'Tracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]'complete-ctrip-ludp-d'TraceusingtheUDPprotocol'complete-ctrip-ltcp-d'TraceusingtheTCPprotocol'complete-ctrip-licmp-d'TraceusingtheICMPprotocol'complete-ctrip-s4-lipv4-d'UseIPv4only'complete-ctrip-s6-lipv6-d'UseIPv6only'complete-ctrip-se-licmp-extensions-d'ParseICMPextensions'complete-ctrip-sy-ldns-resolve-all-d'TracetoallIPsresolvedfromDNSlookup[default:false]'complete-ctrip-sz-ldns-lookup-as-info-d'Lookupautonomoussystem(AS)informationduringDNSqueries[default:false]'complete-ctrip-ltui-preserve-screen-d'Preservethescreenonexit[default:false]'complete-ctrip-lprint-tui-theme-items-d'PrintallTUIthemeitemsandexit'complete-ctrip-lprint-tui-binding-commands-d'PrintallTUIcommandsthatcanbeboundandexit'complete-ctrip-lgenerate-man-d'GenerateROFFmanpage'complete-ctrip-lprint-config-template-d'Printatemplatetomlconfigfileandexit'complete-ctrip-sv-lverbose-d'Enableverbosedebuglogging'complete-ctrip-sh-lhelp-d'Printhelp(seemorewith\'--help\')'complete-ctrip-sV-lversion-d'Printversion'
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_man_page.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_man_page.snap
new file mode 100644
index 0000000..e991386
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_man_page.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+.ie\n(.g.dsAq\(aq.el.dsAq'.THtrip1"trip0.11.0-dev".SHNAMEtrip\-Anetworkdiagnostictool.SHSYNOPSIS\fBtrip\fR[\fB\-c\fR|\fB\-\-config\-file\fR][\fB\-m\fR|\fB\-\-mode\fR][\fB\-u\fR|\fB\-\-unprivileged\fR][\fB\-p\fR|\fB\-\-protocol\fR][\fB\-\-udp\fR][\fB\-\-tcp\fR][\fB\-\-icmp\fR][\fB\-F\fR|\fB\-\-addr\-family\fR][\fB\-4\fR|\fB\-\-ipv4\fR][\fB\-6\fR|\fB\-\-ipv6\fR][\fB\-P\fR|\fB\-\-target\-port\fR][\fB\-S\fR|\fB\-\-source\-port\fR][\fB\-A\fR|\fB\-\-source\-address\fR][\fB\-I\fR|\fB\-\-interface\fR][\fB\-i\fR|\fB\-\-min\-round\-duration\fR][\fB\-T\fR|\fB\-\-max\-round\-duration\fR][\fB\-g\fR|\fB\-\-grace\-duration\fR][\fB\-\-initial\-sequence\fR][\fB\-R\fR|\fB\-\-multipath\-strategy\fR][\fB\-U\fR|\fB\-\-max\-inflight\fR][\fB\-f\fR|\fB\-\-first\-ttl\fR][\fB\-t\fR|\fB\-\-max\-ttl\fR][\fB\-\-packet\-size\fR][\fB\-\-payload\-pattern\fR][\fB\-Q\fR|\fB\-\-tos\fR][\fB\-e\fR|\fB\-\-icmp\-extensions\fR][\fB\-\-read\-timeout\fR][\fB\-r\fR|\fB\-\-dns\-resolve\-method\fR][\fB\-y\fR|\fB\-\-dns\-resolve\-all\fR][\fB\-\-dns\-timeout\fR][\fB\-z\fR|\fB\-\-dns\-lookup\-as\-info\fR][\fB\-a\fR|\fB\-\-tui\-address\-mode\fR][\fB\-\-tui\-as\-mode\fR][\fB\-\-tui\-custom\-columns\fR][\fB\-\-tui\-icmp\-extension\-mode\fR][\fB\-\-tui\-geoip\-mode\fR][\fB\-M\fR|\fB\-\-tui\-max\-addrs\fR][\fB\-s\fR|\fB\-\-tui\-max\-samples\fR][\fB\-\-tui\-max\-flows\fR][\fB\-\-tui\-preserve\-screen\fR][\fB\-\-tui\-refresh\-rate\fR][\fB\-\-tui\-privacy\-max\-ttl\fR][\fB\-\-tui\-theme\-colors\fR][\fB\-\-print\-tui\-theme\-items\fR][\fB\-\-tui\-key\-bindings\fR][\fB\-\-print\-tui\-binding\-commands\fR][\fB\-C\fR|\fB\-\-report\-cycles\fR][\fB\-G\fR|\fB\-\-geoip\-mmdb\-file\fR][\fB\-\-generate\fR][\fB\-\-generate\-man\fR][\fB\-\-print\-config\-template\fR][\fB\-\-log\-format\fR][\fB\-\-log\-filter\fR][\fB\-\-log\-span\-events\fR][\fB\-v\fR|\fB\-\-verbose\fR][\fB\-h\fR|\fB\-\-help\fR][\fB\-V\fR|\fB\-\-version\fR][\fITARGETS\fR].SHDESCRIPTIONAnetworkdiagnostictool.SHOPTIONS.TP\fB\-c\fR,\fB\-\-config\-file\fR=\fICONFIG_FILE\fRConfigfile.TP\fB\-m\fR,\fB\-\-mode\fR=\fIMODE\fROutputmode[default:tui].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2tui:DisplayinteractiveTUI.IP\(bu2stream:Displayacontinuousstreamoftracingdata.IP\(bu2pretty:GenerateaprettytexttablereportforNcycles.IP\(bu2markdown:GenerateaMarkdowntexttablereportforNcycles.IP\(bu2csv:GenerateaCSVreportforNcycles.IP\(bu2json:GenerateaJSONreportforNcycles.IP\(bu2dot:GenerateaGraphvizDOTfileforNcycles.IP\(bu2flows:DisplayallflowsforNcycles.IP\(bu2silent:DonotgenerateanytracingoutputforNcycles.RE.TP\fB\-u\fR,\fB\-\-unprivileged\fRTracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false].TP\fB\-p\fR,\fB\-\-protocol\fR=\fIPROTOCOL\fRTracingprotocol[default:icmp].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2icmp:InternetControlMessageProtocol.IP\(bu2udp:UserDatagramProtocol.IP\(bu2tcp:TransmissionControlProtocol.RE.TP\fB\-\-udp\fRTraceusingtheUDPprotocol.TP\fB\-\-tcp\fRTraceusingtheTCPprotocol.TP\fB\-\-icmp\fRTraceusingtheICMPprotocol.TP\fB\-F\fR,\fB\-\-addr\-family\fR=\fIADDR_FAMILY\fRTheaddressfamily[default:Ipv4thenIpv6].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2ipv4:Ipv4only.IP\(bu2ipv6:Ipv6only.IP\(bu2ipv6\-then\-ipv4:Ipv6withafallbacktoIpv4.IP\(bu2ipv4\-then\-ipv6:Ipv4withafallbacktoIpv6.RE.TP\fB\-4\fR,\fB\-\-ipv4\fRUseIPv4only.TP\fB\-6\fR,\fB\-\-ipv6\fRUseIPv6only.TP\fB\-P\fR,\fB\-\-target\-port\fR=\fITARGET_PORT\fRThetargetport(TCP&UDPonly)[default:80].TP\fB\-S\fR,\fB\-\-source\-port\fR=\fISOURCE_PORT\fRThesourceport(TCP&UDPonly)[default:auto].TP\fB\-A\fR,\fB\-\-source\-address\fR=\fISOURCE_ADDRESS\fRThesourceIPaddress[default:auto].TP\fB\-I\fR,\fB\-\-interface\fR=\fIINTERFACE\fRThenetworkinterface[default:auto].TP\fB\-i\fR,\fB\-\-min\-round\-duration\fR=\fIMIN_ROUND_DURATION\fRTheminimumdurationofeveryround[default:1s].TP\fB\-T\fR,\fB\-\-max\-round\-duration\fR=\fIMAX_ROUND_DURATION\fRThemaximumdurationofeveryround[default:1s].TP\fB\-g\fR,\fB\-\-grace\-duration\fR=\fIGRACE_DURATION\fRTheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms].TP\fB\-\-initial\-sequence\fR=\fIINITIAL_SEQUENCE\fRTheinitialsequencenumber[default:33000].TP\fB\-R\fR,\fB\-\-multipath\-strategy\fR=\fIMULTIPATH_STRATEGY\fRTheEqual\-costMulti\-Pathroutingstrategy(UDPonly)[default:classic].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2classic:Thesrcordestportisusedtostorethesequencenumber.IP\(bu2paris:TheUDP`checksum`fieldisusedtostorethesequencenumber.IP\(bu2dublin:TheIP`identifier`fieldisusedtostorethesequencenumber.RE.TP\fB\-U\fR,\fB\-\-max\-inflight\fR=\fIMAX_INFLIGHT\fRThemaximumnumberofin\-flightICMPechorequests[default:24].TP\fB\-f\fR,\fB\-\-first\-ttl\fR=\fIFIRST_TTL\fRTheTTLtostartfrom[default:1].TP\fB\-t\fR,\fB\-\-max\-ttl\fR=\fIMAX_TTL\fRThemaximumnumberofTTLhops[default:64].TP\fB\-\-packet\-size\fR=\fIPACKET_SIZE\fRThesizeofIPpackettosend(IPheader+ICMPheader+payload)[default:84].TP\fB\-\-payload\-pattern\fR=\fIPAYLOAD_PATTERN\fRTherepeatingpatterninthepayloadoftheICMPpacket[default:0].TP\fB\-Q\fR,\fB\-\-tos\fR=\fITOS\fRTheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0].TP\fB\-e\fR,\fB\-\-icmp\-extensions\fRParseICMPextensions.TP\fB\-\-read\-timeout\fR=\fIREAD_TIMEOUT\fRThesocketreadtimeout[default:10ms].TP\fB\-r\fR,\fB\-\-dns\-resolve\-method\fR=\fIDNS_RESOLVE_METHOD\fRHowtoperformDNSqueries[default:system].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2system:ResolveusingtheOSresolver.IP\(bu2resolv:Resolveusingthe`/etc/resolv.conf`DNSconfiguration.IP\(bu2google:ResolveusingtheGoogle`8.8.8.8`DNSservice.IP\(bu2cloudflare:ResolveusingtheCloudflare`1.1.1.1`DNSservice.RE.TP\fB\-y\fR,\fB\-\-dns\-resolve\-all\fRTracetoallIPsresolvedfromDNSlookup[default:false].TP\fB\-\-dns\-timeout\fR=\fIDNS_TIMEOUT\fRThemaximumtimetowaittoperformDNSqueries[default:5s].TP\fB\-z\fR,\fB\-\-dns\-lookup\-as\-info\fRLookupautonomoussystem(AS)informationduringDNSqueries[default:false].TP\fB\-a\fR,\fB\-\-tui\-address\-mode\fR=\fITUI_ADDRESS_MODE\fRHowtorenderaddresses[default:host].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2ip:ShowIPaddressonly.IP\(bu2host:Showreverse\-lookupDNShostnameonly.IP\(bu2both:ShowbothIPaddressandreverse\-lookupDNShostname.RE.TP\fB\-\-tui\-as\-mode\fR=\fITUI_AS_MODE\fRHowtorenderASinformation[default:asn].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2asn:ShowtheASN.IP\(bu2prefix:DisplaytheASprefix.IP\(bu2country\-code:Displaythecountrycode.IP\(bu2registry:Displaytheregistryname.IP\(bu2allocated:Displaytheallocateddate.IP\(bu2name:DisplaytheASname.RE.TP\fB\-\-tui\-custom\-columns\fR=\fITUI_CUSTOM_COLUMNS\fRCustomcolumnstobedisplayedintheTUIhopstable[default:holsravbwdt].TP\fB\-\-tui\-icmp\-extension\-mode\fR=\fITUI_ICMP_EXTENSION_MODE\fRHowtorenderICMPextensions[default:off].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2off:Donotshow`icmp`extensions.IP\(bu2mpls:ShowMPLSlabel(s)only.IP\(bu2full:Showfull`icmp`extensiondataforallknownextensions.IP\(bu2all:Showfull`icmp`extensiondataforallclasses.RE.TP\fB\-\-tui\-geoip\-mode\fR=\fITUI_GEOIP_MODE\fRHowtorenderGeoIpinformation[default:short].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2off:DonotdisplayGeoIpdata.IP\(bu2short:Showshortformat.IP\(bu2long:Showlongformat.IP\(bu2location:ShowlatitudeandLongitudeformat.RE.TP\fB\-M\fR,\fB\-\-tui\-max\-addrs\fR=\fITUI_MAX_ADDRS\fRThemaximumnumberofaddressestoshowperhop[default:auto].TP\fB\-s\fR,\fB\-\-tui\-max\-samples\fR=\fITUI_MAX_SAMPLES\fRThemaximumnumberofsamplestorecordperhop[default:256].TP\fB\-\-tui\-max\-flows\fR=\fITUI_MAX_FLOWS\fRThemaximumnumberofflowstoshow[default:64].TP\fB\-\-tui\-preserve\-screen\fRPreservethescreenonexit[default:false].TP\fB\-\-tui\-refresh\-rate\fR=\fITUI_REFRESH_RATE\fRTheTuirefreshrate[default:100ms].TP\fB\-\-tui\-privacy\-max\-ttl\fR=\fITUI_PRIVACY_MAX_TTL\fRThemaximumttlofhopswhichwillbemaskedforprivacy[default:0].TP\fB\-\-tui\-theme\-colors\fR=\fITUI_THEME_COLORS\fRTheTUIthemecolors[item=color,item=color,..].TP\fB\-\-print\-tui\-theme\-items\fRPrintallTUIthemeitemsandexit.TP\fB\-\-tui\-key\-bindings\fR=\fITUI_KEY_BINDINGS\fRTheTUIkeybindings[command=key,command=key,..].TP\fB\-\-print\-tui\-binding\-commands\fRPrintallTUIcommandsthatcanbeboundandexit.TP\fB\-C\fR,\fB\-\-report\-cycles\fR=\fIREPORT_CYCLES\fRThenumberofreportcyclestorun[default:10].TP\fB\-G\fR,\fB\-\-geoip\-mmdb\-file\fR=\fIGEOIP_MMDB_FILE\fRThesupportedMaxMindorIPinfoGeoIpmmdbfile.TP\fB\-\-generate\fR=\fIGENERATE\fRGenerateshellcompletion.br.br[\fIpossiblevalues:\fRbash,elvish,fish,powershell,zsh].TP\fB\-\-generate\-man\fRGenerateROFFmanpage.TP\fB\-\-print\-config\-template\fRPrintatemplatetomlconfigfileandexit.TP\fB\-\-log\-format\fR=\fILOG_FORMAT\fRThedebuglogformat[default:pretty].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2compact:Displaylogdatainacompactformat.IP\(bu2pretty:Displaylogdatainaprettyformat.IP\(bu2json:Displaylogdatainajsonformat.IP\(bu2chrome:DisplaylogdatainChrometraceformat.RE.TP\fB\-\-log\-filter\fR=\fILOG_FILTER\fRThedebuglogfilter[default:trippy=debug].TP\fB\-\-log\-span\-events\fR=\fILOG_SPAN_EVENTS\fRThedebuglogformat[default:off].br.br\fIPossiblevalues:\fR.RS14.IP\(bu2off:Donotdisplayeventspans.IP\(bu2active:Displayenterandexiteventspans.IP\(bu2full:Displayalleventspans.RE.TP\fB\-v\fR,\fB\-\-verbose\fREnableverbosedebuglogging.TP\fB\-h\fR,\fB\-\-help\fRPrinthelp(seeasummarywith\*(Aq\-h\*(Aq).TP\fB\-V\fR,\fB\-\-version\fRPrintversion.TP[\fITARGETS\fR]AspacedelimitedlistofhostnamesandIPstotrace.SHVERSIONv0.11.0\-dev.SHAUTHORSFujiApple<fujiapple852@gmail.com>
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_powershell_shell_completions.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_powershell_shell_completions.snap
new file mode 100644
index 0000000..612daa3
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_powershell_shell_completions.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+usingnamespaceSystem.Management.AutomationusingnamespaceSystem.Management.Automation.LanguageRegister-ArgumentCompleter-Native-CommandName'trip'-ScriptBlock{param($wordToComplete,$commandAst,$cursorPosition)$commandElements=$commandAst.CommandElements$command=@('trip'for($i=1;$i-lt$commandElements.Count;$i++){$element=$commandElements[$i]if($element-isnot[StringConstantExpressionAst]-or$element.StringConstantType-ne[StringConstantType]::BareWord-or$element.Value.StartsWith('-')-or$element.Value-eq$wordToComplete){break}$element.Value})-join';'$completions=@(switch($command){'trip'{[CompletionResult]::new('-c','c',[CompletionResultType]::ParameterName,'Configfile')[CompletionResult]::new('--config-file','config-file',[CompletionResultType]::ParameterName,'Configfile')[CompletionResult]::new('-m','m',[CompletionResultType]::ParameterName,'Outputmode[default:tui]')[CompletionResult]::new('--mode','mode',[CompletionResultType]::ParameterName,'Outputmode[default:tui]')[CompletionResult]::new('-p','p',[CompletionResultType]::ParameterName,'Tracingprotocol[default:icmp]')[CompletionResult]::new('--protocol','protocol',[CompletionResultType]::ParameterName,'Tracingprotocol[default:icmp]')[CompletionResult]::new('-F','F',[CompletionResultType]::ParameterName,'Theaddressfamily[default:Ipv4thenIpv6]')[CompletionResult]::new('--addr-family','addr-family',[CompletionResultType]::ParameterName,'Theaddressfamily[default:Ipv4thenIpv6]')[CompletionResult]::new('-P','P',[CompletionResultType]::ParameterName,'Thetargetport(TCP&UDPonly)[default:80]')[CompletionResult]::new('--target-port','target-port',[CompletionResultType]::ParameterName,'Thetargetport(TCP&UDPonly)[default:80]')[CompletionResult]::new('-S','S',[CompletionResultType]::ParameterName,'Thesourceport(TCP&UDPonly)[default:auto]')[CompletionResult]::new('--source-port','source-port',[CompletionResultType]::ParameterName,'Thesourceport(TCP&UDPonly)[default:auto]')[CompletionResult]::new('-A','A',[CompletionResultType]::ParameterName,'ThesourceIPaddress[default:auto]')[CompletionResult]::new('--source-address','source-address',[CompletionResultType]::ParameterName,'ThesourceIPaddress[default:auto]')[CompletionResult]::new('-I','I',[CompletionResultType]::ParameterName,'Thenetworkinterface[default:auto]')[CompletionResult]::new('--interface','interface',[CompletionResultType]::ParameterName,'Thenetworkinterface[default:auto]')[CompletionResult]::new('-i','i',[CompletionResultType]::ParameterName,'Theminimumdurationofeveryround[default:1s]')[CompletionResult]::new('--min-round-duration','min-round-duration',[CompletionResultType]::ParameterName,'Theminimumdurationofeveryround[default:1s]')[CompletionResult]::new('-T','T',[CompletionResultType]::ParameterName,'Themaximumdurationofeveryround[default:1s]')[CompletionResult]::new('--max-round-duration','max-round-duration',[CompletionResultType]::ParameterName,'Themaximumdurationofeveryround[default:1s]')[CompletionResult]::new('-g','g',[CompletionResultType]::ParameterName,'TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]')[CompletionResult]::new('--grace-duration','grace-duration',[CompletionResultType]::ParameterName,'TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded[default:100ms]')[CompletionResult]::new('--initial-sequence','initial-sequence',[CompletionResultType]::ParameterName,'Theinitialsequencenumber[default:33000]')[CompletionResult]::new('-R','R',[CompletionResultType]::ParameterName,'TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic]')[CompletionResult]::new('--multipath-strategy','multipath-strategy',[CompletionResultType]::ParameterName,'TheEqual-costMulti-Pathroutingstrategy(UDPonly)[default:classic]')[CompletionResult]::new('-U','U',[CompletionResultType]::ParameterName,'Themaximumnumberofin-flightICMPechorequests[default:24]')[CompletionResult]::new('--max-inflight','max-inflight',[CompletionResultType]::ParameterName,'Themaximumnumberofin-flightICMPechorequests[default:24]')[CompletionResult]::new('-f','f',[CompletionResultType]::ParameterName,'TheTTLtostartfrom[default:1]')[CompletionResult]::new('--first-ttl','first-ttl',[CompletionResultType]::ParameterName,'TheTTLtostartfrom[default:1]')[CompletionResult]::new('-t','t',[CompletionResultType]::ParameterName,'ThemaximumnumberofTTLhops[default:64]')[CompletionResult]::new('--max-ttl','max-ttl',[CompletionResultType]::ParameterName,'ThemaximumnumberofTTLhops[default:64]')[CompletionResult]::new('--packet-size','packet-size',[CompletionResultType]::ParameterName,'ThesizeofIPpackettosend(IPheader+ICMPheader+payload)[default:84]')[CompletionResult]::new('--payload-pattern','payload-pattern',[CompletionResultType]::ParameterName,'TherepeatingpatterninthepayloadoftheICMPpacket[default:0]')[CompletionResult]::new('-Q','Q',[CompletionResultType]::ParameterName,'TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]')[CompletionResult]::new('--tos','tos',[CompletionResultType]::ParameterName,'TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)[default:0]')[CompletionResult]::new('--read-timeout','read-timeout',[CompletionResultType]::ParameterName,'Thesocketreadtimeout[default:10ms]')[CompletionResult]::new('-r','r',[CompletionResultType]::ParameterName,'HowtoperformDNSqueries[default:system]')[CompletionResult]::new('--dns-resolve-method','dns-resolve-method',[CompletionResultType]::ParameterName,'HowtoperformDNSqueries[default:system]')[CompletionResult]::new('--dns-timeout','dns-timeout',[CompletionResultType]::ParameterName,'ThemaximumtimetowaittoperformDNSqueries[default:5s]')[CompletionResult]::new('-a','a',[CompletionResultType]::ParameterName,'Howtorenderaddresses[default:host]')[CompletionResult]::new('--tui-address-mode','tui-address-mode',[CompletionResultType]::ParameterName,'Howtorenderaddresses[default:host]')[CompletionResult]::new('--tui-as-mode','tui-as-mode',[CompletionResultType]::ParameterName,'HowtorenderASinformation[default:asn]')[CompletionResult]::new('--tui-custom-columns','tui-custom-columns',[CompletionResultType]::ParameterName,'CustomcolumnstobedisplayedintheTUIhopstable[default:holsravbwdt]')[CompletionResult]::new('--tui-icmp-extension-mode','tui-icmp-extension-mode',[CompletionResultType]::ParameterName,'HowtorenderICMPextensions[default:off]')[CompletionResult]::new('--tui-geoip-mode','tui-geoip-mode',[CompletionResultType]::ParameterName,'HowtorenderGeoIpinformation[default:short]')[CompletionResult]::new('-M','M',[CompletionResultType]::ParameterName,'Themaximumnumberofaddressestoshowperhop[default:auto]')[CompletionResult]::new('--tui-max-addrs','tui-max-addrs',[CompletionResultType]::ParameterName,'Themaximumnumberofaddressestoshowperhop[default:auto]')[CompletionResult]::new('-s','s',[CompletionResultType]::ParameterName,'Themaximumnumberofsamplestorecordperhop[default:256]')[CompletionResult]::new('--tui-max-samples','tui-max-samples',[CompletionResultType]::ParameterName,'Themaximumnumberofsamplestorecordperhop[default:256]')[CompletionResult]::new('--tui-max-flows','tui-max-flows',[CompletionResultType]::ParameterName,'Themaximumnumberofflowstoshow[default:64]')[CompletionResult]::new('--tui-refresh-rate','tui-refresh-rate',[CompletionResultType]::ParameterName,'TheTuirefreshrate[default:100ms]')[CompletionResult]::new('--tui-privacy-max-ttl','tui-privacy-max-ttl',[CompletionResultType]::ParameterName,'Themaximumttlofhopswhichwillbemaskedforprivacy[default:0]')[CompletionResult]::new('--tui-theme-colors','tui-theme-colors',[CompletionResultType]::ParameterName,'TheTUIthemecolors[item=color,item=color,..]')[CompletionResult]::new('--tui-key-bindings','tui-key-bindings',[CompletionResultType]::ParameterName,'TheTUIkeybindings[command=key,command=key,..]')[CompletionResult]::new('-C','C',[CompletionResultType]::ParameterName,'Thenumberofreportcyclestorun[default:10]')[CompletionResult]::new('--report-cycles','report-cycles',[CompletionResultType]::ParameterName,'Thenumberofreportcyclestorun[default:10]')[CompletionResult]::new('-G','G',[CompletionResultType]::ParameterName,'ThesupportedMaxMindorIPinfoGeoIpmmdbfile')[CompletionResult]::new('--geoip-mmdb-file','geoip-mmdb-file',[CompletionResultType]::ParameterName,'ThesupportedMaxMindorIPinfoGeoIpmmdbfile')[CompletionResult]::new('--generate','generate',[CompletionResultType]::ParameterName,'Generateshellcompletion')[CompletionResult]::new('--log-format','log-format',[CompletionResultType]::ParameterName,'Thedebuglogformat[default:pretty]')[CompletionResult]::new('--log-filter','log-filter',[CompletionResultType]::ParameterName,'Thedebuglogfilter[default:trippy=debug]')[CompletionResult]::new('--log-span-events','log-span-events',[CompletionResultType]::ParameterName,'Thedebuglogformat[default:off]')[CompletionResult]::new('-u','u',[CompletionResultType]::ParameterName,'Tracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]')[CompletionResult]::new('--unprivileged','unprivileged',[CompletionResultType]::ParameterName,'Tracewithoutrequiringelevatedprivilegesonsupportedplatforms[default:false]')[CompletionResult]::new('--udp','udp',[CompletionResultType]::ParameterName,'TraceusingtheUDPprotocol')[CompletionResult]::new('--tcp','tcp',[CompletionResultType]::ParameterName,'TraceusingtheTCPprotocol')[CompletionResult]::new('--icmp','icmp',[CompletionResultType]::ParameterName,'TraceusingtheICMPprotocol')[CompletionResult]::new('-4','4',[CompletionResultType]::ParameterName,'UseIPv4only')[CompletionResult]::new('--ipv4','ipv4',[CompletionResultType]::ParameterName,'UseIPv4only')[CompletionResult]::new('-6','6',[CompletionResultType]::ParameterName,'UseIPv6only')[CompletionResult]::new('--ipv6','ipv6',[CompletionResultType]::ParameterName,'UseIPv6only')[CompletionResult]::new('-e','e',[CompletionResultType]::ParameterName,'ParseICMPextensions')[CompletionResult]::new('--icmp-extensions','icmp-extensions',[CompletionResultType]::ParameterName,'ParseICMPextensions')[CompletionResult]::new('-y','y',[CompletionResultType]::ParameterName,'TracetoallIPsresolvedfromDNSlookup[default:false]')[CompletionResult]::new('--dns-resolve-all','dns-resolve-all',[CompletionResultType]::ParameterName,'TracetoallIPsresolvedfromDNSlookup[default:false]')[CompletionResult]::new('-z','z',[CompletionResultType]::ParameterName,'Lookupautonomoussystem(AS)informationduringDNSqueries[default:false]')[CompletionResult]::new('--dns-lookup-as-info','dns-lookup-as-info',[CompletionResultType]::ParameterName,'Lookupautonomoussystem(AS)informationduringDNSqueries[default:false]')[CompletionResult]::new('--tui-preserve-screen','tui-preserve-screen',[CompletionResultType]::ParameterName,'Preservethescreenonexit[default:false]')[CompletionResult]::new('--print-tui-theme-items','print-tui-theme-items',[CompletionResultType]::ParameterName,'PrintallTUIthemeitemsandexit')[CompletionResult]::new('--print-tui-binding-commands','print-tui-binding-commands',[CompletionResultType]::ParameterName,'PrintallTUIcommandsthatcanbeboundandexit')[CompletionResult]::new('--generate-man','generate-man',[CompletionResultType]::ParameterName,'GenerateROFFmanpage')[CompletionResult]::new('--print-config-template','print-config-template',[CompletionResultType]::ParameterName,'Printatemplatetomlconfigfileandexit')[CompletionResult]::new('-v','v',[CompletionResultType]::ParameterName,'Enableverbosedebuglogging')[CompletionResult]::new('--verbose','verbose',[CompletionResultType]::ParameterName,'Enableverbosedebuglogging')[CompletionResult]::new('-h','h',[CompletionResultType]::ParameterName,'Printhelp(seemorewith''--help'')')[CompletionResult]::new('--help','help',[CompletionResultType]::ParameterName,'Printhelp(seemorewith''--help'')')[CompletionResult]::new('-V','V',[CompletionResultType]::ParameterName,'Printversion')[CompletionResult]::new('--version','version',[CompletionResultType]::ParameterName,'Printversion')break}})$completions.Where{$_.CompletionText-like"$wordToComplete*"}|Sort-Object-PropertyListItemText}
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_zsh_shell_completions.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_zsh_shell_completions.snap
new file mode 100644
index 0000000..e3b0b48
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@generate_zsh_shell_completions.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+#compdeftripautoload-Uis-at-least_trip(){typeset-Aopt_argstypeset-a_arguments_optionslocalret=1ifis-at-least5.2;then_arguments_options=(-s-S-C)else_arguments_options=(-s-C)filocalcontextcurcontext="$curcontext"stateline_arguments"${_arguments_options[@]}"\'-c+[Configfile]:CONFIG_FILE:_files'\'--config-file=[Configfile]:CONFIG_FILE:_files'\'-m+[Outputmode\[default\:tui\]]:MODE:((tui\:"DisplayinteractiveTUI"stream\:"Displayacontinuousstreamoftracingdata"pretty\:"GenerateaprettytexttablereportforNcycles"markdown\:"GenerateaMarkdowntexttablereportforNcycles"csv\:"GenerateaCSVreportforNcycles"json\:"GenerateaJSONreportforNcycles"dot\:"GenerateaGraphvizDOTfileforNcycles"flows\:"DisplayallflowsforNcycles"silent\:"DonotgenerateanytracingoutputforNcycles"))'\'--mode=[Outputmode\[default\:tui\]]:MODE:((tui\:"DisplayinteractiveTUI"stream\:"Displayacontinuousstreamoftracingdata"pretty\:"GenerateaprettytexttablereportforNcycles"markdown\:"GenerateaMarkdowntexttablereportforNcycles"csv\:"GenerateaCSVreportforNcycles"json\:"GenerateaJSONreportforNcycles"dot\:"GenerateaGraphvizDOTfileforNcycles"flows\:"DisplayallflowsforNcycles"silent\:"DonotgenerateanytracingoutputforNcycles"))'\'-p+[Tracingprotocol\[default\:icmp\]]:PROTOCOL:((icmp\:"InternetControlMessageProtocol"udp\:"UserDatagramProtocol"tcp\:"TransmissionControlProtocol"))'\'--protocol=[Tracingprotocol\[default\:icmp\]]:PROTOCOL:((icmp\:"InternetControlMessageProtocol"udp\:"UserDatagramProtocol"tcp\:"TransmissionControlProtocol"))'\'-F+[Theaddressfamily\[default\:Ipv4thenIpv6\]]:ADDR_FAMILY:((ipv4\:"Ipv4only"ipv6\:"Ipv6only"ipv6-then-ipv4\:"Ipv6withafallbacktoIpv4"ipv4-then-ipv6\:"Ipv4withafallbacktoIpv6"))'\'--addr-family=[Theaddressfamily\[default\:Ipv4thenIpv6\]]:ADDR_FAMILY:((ipv4\:"Ipv4only"ipv6\:"Ipv6only"ipv6-then-ipv4\:"Ipv6withafallbacktoIpv4"ipv4-then-ipv6\:"Ipv4withafallbacktoIpv6"))'\'-P+[Thetargetport(TCP&UDPonly)\[default\:80\]]:TARGET_PORT:'\'--target-port=[Thetargetport(TCP&UDPonly)\[default\:80\]]:TARGET_PORT:'\'-S+[Thesourceport(TCP&UDPonly)\[default\:auto\]]:SOURCE_PORT:'\'--source-port=[Thesourceport(TCP&UDPonly)\[default\:auto\]]:SOURCE_PORT:'\'(-I--interface)-A+[ThesourceIPaddress\[default\:auto\]]:SOURCE_ADDRESS:'\'(-I--interface)--source-address=[ThesourceIPaddress\[default\:auto\]]:SOURCE_ADDRESS:'\'-I+[Thenetworkinterface\[default\:auto\]]:INTERFACE:'\'--interface=[Thenetworkinterface\[default\:auto\]]:INTERFACE:'\'-i+[Theminimumdurationofeveryround\[default\:1s\]]:MIN_ROUND_DURATION:'\'--min-round-duration=[Theminimumdurationofeveryround\[default\:1s\]]:MIN_ROUND_DURATION:'\'-T+[Themaximumdurationofeveryround\[default\:1s\]]:MAX_ROUND_DURATION:'\'--max-round-duration=[Themaximumdurationofeveryround\[default\:1s\]]:MAX_ROUND_DURATION:'\'-g+[TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded\[default\:100ms\]]:GRACE_DURATION:'\'--grace-duration=[TheperiodoftimetowaitforadditionalICMPresponsesafterthetargethasresponded\[default\:100ms\]]:GRACE_DURATION:'\'--initial-sequence=[Theinitialsequencenumber\[default\:33000\]]:INITIAL_SEQUENCE:'\'-R+[TheEqual-costMulti-Pathroutingstrategy(UDPonly)\[default\:classic\]]:MULTIPATH_STRATEGY:((classic\:"Thesrcordestportisusedtostorethesequencenumber"paris\:"TheUDP\`checksum\`fieldisusedtostorethesequencenumber"dublin\:"TheIP\`identifier\`fieldisusedtostorethesequencenumber"))'\'--multipath-strategy=[TheEqual-costMulti-Pathroutingstrategy(UDPonly)\[default\:classic\]]:MULTIPATH_STRATEGY:((classic\:"Thesrcordestportisusedtostorethesequencenumber"paris\:"TheUDP\`checksum\`fieldisusedtostorethesequencenumber"dublin\:"TheIP\`identifier\`fieldisusedtostorethesequencenumber"))'\'-U+[Themaximumnumberofin-flightICMPechorequests\[default\:24\]]:MAX_INFLIGHT:'\'--max-inflight=[Themaximumnumberofin-flightICMPechorequests\[default\:24\]]:MAX_INFLIGHT:'\'-f+[TheTTLtostartfrom\[default\:1\]]:FIRST_TTL:'\'--first-ttl=[TheTTLtostartfrom\[default\:1\]]:FIRST_TTL:'\'-t+[ThemaximumnumberofTTLhops\[default\:64\]]:MAX_TTL:'\'--max-ttl=[ThemaximumnumberofTTLhops\[default\:64\]]:MAX_TTL:'\'--packet-size=[ThesizeofIPpackettosend(IPheader+ICMPheader+payload)\[default\:84\]]:PACKET_SIZE:'\'--payload-pattern=[TherepeatingpatterninthepayloadoftheICMPpacket\[default\:0\]]:PAYLOAD_PATTERN:'\'-Q+[TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)\[default\:0\]]:TOS:'\'--tos=[TheTOS(i.e.DSCP+ECN)IPheadervalue(TCPandUDPonly)\[default\:0\]]:TOS:'\'--read-timeout=[Thesocketreadtimeout\[default\:10ms\]]:READ_TIMEOUT:'\'-r+[HowtoperformDNSqueries\[default\:system\]]:DNS_RESOLVE_METHOD:((system\:"ResolveusingtheOSresolver"resolv\:"Resolveusingthe\`/etc/resolv.conf\`DNSconfiguration"google\:"ResolveusingtheGoogle\`8.8.8.8\`DNSservice"cloudflare\:"ResolveusingtheCloudflare\`1.1.1.1\`DNSservice"))'\'--dns-resolve-method=[HowtoperformDNSqueries\[default\:system\]]:DNS_RESOLVE_METHOD:((system\:"ResolveusingtheOSresolver"resolv\:"Resolveusingthe\`/etc/resolv.conf\`DNSconfiguration"google\:"ResolveusingtheGoogle\`8.8.8.8\`DNSservice"cloudflare\:"ResolveusingtheCloudflare\`1.1.1.1\`DNSservice"))'\'--dns-timeout=[ThemaximumtimetowaittoperformDNSqueries\[default\:5s\]]:DNS_TIMEOUT:'\'-a+[Howtorenderaddresses\[default\:host\]]:TUI_ADDRESS_MODE:((ip\:"ShowIPaddressonly"host\:"Showreverse-lookupDNShostnameonly"both\:"ShowbothIPaddressandreverse-lookupDNShostname"))'\'--tui-address-mode=[Howtorenderaddresses\[default\:host\]]:TUI_ADDRESS_MODE:((ip\:"ShowIPaddressonly"host\:"Showreverse-lookupDNShostnameonly"both\:"ShowbothIPaddressandreverse-lookupDNShostname"))'\'--tui-as-mode=[HowtorenderASinformation\[default\:asn\]]:TUI_AS_MODE:((asn\:"ShowtheASN"prefix\:"DisplaytheASprefix"country-code\:"Displaythecountrycode"registry\:"Displaytheregistryname"allocated\:"Displaytheallocateddate"name\:"DisplaytheASname"))'\'--tui-custom-columns=[CustomcolumnstobedisplayedintheTUIhopstable\[default\:holsravbwdt\]]:TUI_CUSTOM_COLUMNS:'\'--tui-icmp-extension-mode=[HowtorenderICMPextensions\[default\:off\]]:TUI_ICMP_EXTENSION_MODE:((off\:"Donotshow\`icmp\`extensions"mpls\:"ShowMPLSlabel(s)only"full\:"Showfull\`icmp\`extensiondataforallknownextensions"all\:"Showfull\`icmp\`extensiondataforallclasses"))'\'--tui-geoip-mode=[HowtorenderGeoIpinformation\[default\:short\]]:TUI_GEOIP_MODE:((off\:"DonotdisplayGeoIpdata"short\:"Showshortformat"long\:"Showlongformat"location\:"ShowlatitudeandLongitudeformat"))'\'-M+[Themaximumnumberofaddressestoshowperhop\[default\:auto\]]:TUI_MAX_ADDRS:'\'--tui-max-addrs=[Themaximumnumberofaddressestoshowperhop\[default\:auto\]]:TUI_MAX_ADDRS:'\'-s+[Themaximumnumberofsamplestorecordperhop\[default\:256\]]:TUI_MAX_SAMPLES:'\'--tui-max-samples=[Themaximumnumberofsamplestorecordperhop\[default\:256\]]:TUI_MAX_SAMPLES:'\'--tui-max-flows=[Themaximumnumberofflowstoshow\[default\:64\]]:TUI_MAX_FLOWS:'\'--tui-refresh-rate=[TheTuirefreshrate\[default\:100ms\]]:TUI_REFRESH_RATE:'\'--tui-privacy-max-ttl=[Themaximumttlofhopswhichwillbemaskedforprivacy\[default\:0\]]:TUI_PRIVACY_MAX_TTL:'\'*--tui-theme-colors=[TheTUIthemecolors\[item=color,item=color,..\]]:TUI_THEME_COLORS:'\'*--tui-key-bindings=[TheTUIkeybindings\[command=key,command=key,..\]]:TUI_KEY_BINDINGS:'\'-C+[Thenumberofreportcyclestorun\[default\:10\]]:REPORT_CYCLES:'\'--report-cycles=[Thenumberofreportcyclestorun\[default\:10\]]:REPORT_CYCLES:'\'-G+[ThesupportedMaxMindorIPinfoGeoIpmmdbfile]:GEOIP_MMDB_FILE:_files'\'--geoip-mmdb-file=[ThesupportedMaxMindorIPinfoGeoIpmmdbfile]:GEOIP_MMDB_FILE:_files'\'--generate=[Generateshellcompletion]:GENERATE:(bashelvishfishpowershellzsh)'\'--log-format=[Thedebuglogformat\[default\:pretty\]]:LOG_FORMAT:((compact\:"Displaylogdatainacompactformat"pretty\:"Displaylogdatainaprettyformat"json\:"Displaylogdatainajsonformat"chrome\:"DisplaylogdatainChrometraceformat"))'\'--log-filter=[Thedebuglogfilter\[default\:trippy=debug\]]:LOG_FILTER:'\'--log-span-events=[Thedebuglogformat\[default\:off\]]:LOG_SPAN_EVENTS:((off\:"Donotdisplayeventspans"active\:"Displayenterandexiteventspans"full\:"Displayalleventspans"))'\'-u[Tracewithoutrequiringelevatedprivilegesonsupportedplatforms\[default\:false\]]'\'--unprivileged[Tracewithoutrequiringelevatedprivilegesonsupportedplatforms\[default\:false\]]'\'(-p--protocol--tcp--icmp)--udp[TraceusingtheUDPprotocol]'\'(-p--protocol--udp--icmp)--tcp[TraceusingtheTCPprotocol]'\'(-p--protocol--udp--tcp)--icmp[TraceusingtheICMPprotocol]'\'(-6--ipv6-F--addr-family)-4[UseIPv4only]'\'(-6--ipv6-F--addr-family)--ipv4[UseIPv4only]'\'(-4--ipv4-F--addr-family)-6[UseIPv6only]'\'(-4--ipv4-F--addr-family)--ipv6[UseIPv6only]'\'-e[ParseICMPextensions]'\'--icmp-extensions[ParseICMPextensions]'\'-y[TracetoallIPsresolvedfromDNSlookup\[default\:false\]]'\'--dns-resolve-all[TracetoallIPsresolvedfromDNSlookup\[default\:false\]]'\'-z[Lookupautonomoussystem(AS)informationduringDNSqueries\[default\:false\]]'\'--dns-lookup-as-info[Lookupautonomoussystem(AS)informationduringDNSqueries\[default\:false\]]'\'--tui-preserve-screen[Preservethescreenonexit\[default\:false\]]'\'--print-tui-theme-items[PrintallTUIthemeitemsandexit]'\'--print-tui-binding-commands[PrintallTUIcommandsthatcanbeboundandexit]'\'--generate-man[GenerateROFFmanpage]'\'--print-config-template[Printatemplatetomlconfigfileandexit]'\'-v[Enableverbosedebuglogging]'\'--verbose[Enableverbosedebuglogging]'\'-h[Printhelp(seemorewith'\''--help'\'')]'\'--help[Printhelp(seemorewith'\''--help'\'')]'\'-V[Printversion]'\'--version[Printversion]'\'*::targets--AspacedelimitedlistofhostnamesandIPstotrace:'\&&ret=0}(($+functions[_trip_commands]))||_trip_commands(){localcommands;commands=()_describe-tcommands'tripcommands'commands"$@"}if["$funcstack[1]"="_trip"];then_trip"$@"elsecompdef_triptripfi
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@tui_binding_commands_match.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@tui_binding_commands_match.snap
new file mode 100644
index 0000000..32323c0
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@tui_binding_commands_match.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+TUIbindingcommands:toggle-help,toggle-help-alt,toggle-settings,next-hop,previous-hop,next-trace,previous-trace,next-hop-address,previous-hop-address,address-mode-ip,address-mode-host,address-mode-both,toggle-freeze,toggle-chart,toggle-map,toggle-flows,toggle-privacy,expand-hosts,expand-hosts-max,contract-hosts,contract-hosts-min,chart-zoom-in,chart-zoom-out,clear-trace-data,clear-dns-cache,clear-selection,toggle-as-info,toggle-hop-details,quit
diff --git a/crates/trippy/tests/resources/snapshots/trip__tests__output@tui_theme_items_match.snap b/crates/trippy/tests/resources/snapshots/trip__tests__output@tui_theme_items_match.snap
new file mode 100644
index 0000000..cffa2d4
--- /dev/null
+++ b/crates/trippy/tests/resources/snapshots/trip__tests__output@tui_theme_items_match.snap
@@ -0,0 +1,4 @@
+---
+source: crates/trippy/src/main.rs
+---
+TUIthemecoloritems:bg-color,border-color,text-color,tab-text-color,hops-table-header-bg-color,hops-table-header-text-color,hops-table-row-active-text-color,hops-table-row-inactive-text-color,hops-chart-selected-color,hops-chart-unselected-color,hops-chart-axis-color,frequency-chart-bar-color,frequency-chart-text-color,flows-chart-bar-selected-color,flows-chart-bar-unselected-color,flows-chart-text-current-color,flows-chart-text-non-current-color,samples-chart-color,help-dialog-bg-color,help-dialog-text-color,settings-tab-text-color,settings-dialog-bg-color,settings-table-header-text-color,settings-table-header-bg-color,settings-table-row-text-color,map-world-color,map-radius-color,map-selected-color,map-info-panel-border-color,map-info-panel-bg-color,map-info-panel-text-color