diff --git a/README.md b/README.md
index 557fa54..d799c99 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,18 @@ let decoded = decode(encoded);
 assert_eq!(decoded, "i love cats");
 ```
 
+Or to encode binary in cat2text's expanded base16 alphabet:
+
+```rust
+use cat2text::{anybase::bytes::encode, core::bytes::char_length};
+
+let bytes = &[243, 10];
+let base = 16;
+let char_length = char_length(base);
+
+assert_eq!("mrow~ mrow meow purrrr", encode(bytes, base, char_length));
+```
+
 You can use the library to encode anything up to base 16 - for details, see the [docs](https://docs.rs/cat2text/latest/cat2text/)
 
 ## Binary usage
@@ -92,12 +104,3 @@ For example, `cat2text encode 'i love cats'` to encode `i love cats` in text mod
 ### Shell completions
 
 To generate shell completions, you can run `cat2text generate-$(basename $SHELL)-completions | source` on *nix systems using bash, zsh, or fish.
-
-## Limitations
-
-This currently only supports lowercase text in the latin alphabet, and byte arrays.
-
-## TODO
-
-- Add error handling
-- Optimize code
diff --git a/src/anybase.rs b/src/anybase.rs
index b57d33c..9fb9d79 100644
--- a/src/anybase.rs
+++ b/src/anybase.rs
@@ -19,7 +19,8 @@ pub fn encode(text: impl AsRef<str>, base: u32, char_length: u32) -> String {
     shortened_alphabet.truncate(base as usize);
 
     // makes it lowercase and split by spaces
-    let words: Vec<String> = text.as_ref()
+    let words: Vec<String> = text
+        .as_ref()
         .to_ascii_lowercase()
         .split(" ")
         .map(|item| return item.to_string())
@@ -61,7 +62,11 @@ pub fn encode(text: impl AsRef<str>, base: u32, char_length: u32) -> String {
 /// assert_eq!("i love cats", decode(text, base, char_length));
 /// ```
 pub fn decode(text: impl AsRef<str>, base: u32, char_length: u32) -> String {
-    let catspeak_words: Vec<String> = text.as_ref().split("; ").map(|item| item.to_string()).collect();
+    let catspeak_words: Vec<String> = text
+        .as_ref()
+        .split("; ")
+        .map(|item| item.to_string())
+        .collect();
     let mut output: String = String::new();
     let mut shortened_alphabet = core::alphabet();
     shortened_alphabet.truncate(base as usize);
diff --git a/src/cli.rs b/src/cli.rs
index bf6779f..75e83c8 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -1,7 +1,7 @@
 // this is a separate feature for *optional* dependencies to ensure clap doesn't get compiled if you're just using the library
 use cat2text::{self, anybase, core};
 use clap::{CommandFactory, Parser, Subcommand};
-use clap_complete::aot::{generate, Bash, Fish, PowerShell, Zsh};
+use clap_complete::aot::{generate, Bash, Elvish, Fish, PowerShell, Zsh};
 use std::{io::stdout, time::Instant};
 
 #[derive(Parser)]
@@ -13,14 +13,13 @@ pub(crate) struct Cli {
 
 #[derive(Subcommand, Debug)]
 pub(crate) enum Commands {
-    ///Generate bash completions
-    GenerateBashCompletions,
-    ///Generate zsh completions
-    GenerateZshCompletions,
-    ///Generate fish completions
-    GenerateFishCompletions,
-    ///Generate PowerShell completions,
-    GeneratePowershellCompletions,
+    ///Generate shell completions
+    GenCompletion {
+        #[command(subcommand)]
+        shell: ShellCommands,
+        #[arg(short, long, default_value = "cat2text")]
+        binary_name: String,
+    },
     ///Encodes text/data to mrow~
     ///
     ///The default is base 4 text encoding, to match the original program, but it can encode either text or binary data in up to base 16 meows :3
@@ -63,33 +62,23 @@ pub(crate) fn run() {
     let cli = Cli::parse();
 
     match cli.command {
-        Commands::GenerateBashCompletions => {
-            generate(
-                Bash,
-                &mut Cli::command(),
-                clap::crate_name!(),
-                &mut stdout(),
-            );
-        }
-        Commands::GenerateZshCompletions => {
-            generate(Zsh, &mut Cli::command(), clap::crate_name!(), &mut stdout());
-        }
-        Commands::GenerateFishCompletions => {
-            generate(
-                Fish,
-                &mut Cli::command(),
-                clap::crate_name!(),
-                &mut stdout(),
-            );
-        }
-        Commands::GeneratePowershellCompletions => {
-            generate(
-                PowerShell,
-                &mut Cli::command(),
-                clap::crate_name!(),
-                &mut stdout(),
-            );
-        }
+        Commands::GenCompletion { shell, binary_name } => match shell {
+            ShellCommands::Bash => {
+                generate(Bash, &mut Cli::command(), binary_name, &mut stdout());
+            }
+            ShellCommands::Zsh => {
+                generate(Zsh, &mut Cli::command(), binary_name, &mut stdout());
+            }
+            ShellCommands::Fish => {
+                generate(Fish, &mut Cli::command(), binary_name, &mut stdout());
+            }
+            ShellCommands::Elvish => {
+                generate(Elvish, &mut Cli::command(), binary_name, &mut stdout());
+            }
+            ShellCommands::Powershell => {
+                generate(PowerShell, &mut Cli::command(), binary_name, &mut stdout());
+            }
+        },
         Commands::Encode { base, text, bytes } => {
             println!("{}", encode(base, text, bytes))
         }
@@ -160,3 +149,12 @@ fn decode(base: u8, text: String, bytes: bool) -> String {
         }
     }
 }
+
+#[derive(Subcommand, Debug)]
+pub enum ShellCommands {
+    Bash,
+    Zsh,
+    Fish,
+    Elvish,
+    Powershell,
+}
diff --git a/src/core.rs b/src/core.rs
index 153062c..ed4715e 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -70,7 +70,11 @@ pub fn cat_to_num(text: Vec<String>, alphabet: Vec<String>, char_length: u32) ->
 pub(crate) fn split_every_x(text: impl AsRef<str>, x: u32) -> Vec<String> {
     let x = x as usize;
     let delim = " ";
-    let tmp: Vec<String> = text.as_ref().split(delim).map(|item| item.to_string()).collect();
+    let tmp: Vec<String> = text
+        .as_ref()
+        .split(delim)
+        .map(|item| item.to_string())
+        .collect();
     let mut output: Vec<String> = Vec::new();
     for i in 0..tmp.len() {
         if i % x == 0 {