diff options
| author | Paul Buetow <paul@buetow.org> | 2025-11-01 23:12:20 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-11-01 23:12:20 +0200 |
| commit | c87e2837112c064da8528d38727dd7cad7acaa32 (patch) | |
| tree | 51612e1a43e6f6f73ea168d74285b5dfc4b74a53 | |
| parent | 28ccc70feeab8aef7bcafaea75e288e6e58c2034 (diff) | |
Add fish shell integration with dynamic command completion (v0.2.0)v0.2.0
Amp-Thread-ID: https://ampcode.com/threads/T-9aec59d6-cd27-4607-ac11-baac5f2ca758
Co-authored-by: Amp <amp@ampcode.com>
| -rw-r--r-- | FISH_INTEGRATION.md | 80 | ||||
| -rw-r--r-- | completions/ge.fish | 53 | ||||
| -rw-r--r-- | completions/geheim.fish | 33 | ||||
| -rwxr-xr-x | geheim.rb | 34 | ||||
| -rwxr-xr-x | install-fish.sh | 23 |
5 files changed, 222 insertions, 1 deletions
diff --git a/FISH_INTEGRATION.md b/FISH_INTEGRATION.md new file mode 100644 index 0000000..6c9b964 --- /dev/null +++ b/FISH_INTEGRATION.md @@ -0,0 +1,80 @@ +# Fish Shell Integration for Geheim + +## Installation + +### Automatic Installation + +```bash +cd /home/paul/git/geheim +./install-fish.sh +``` + +### Manual Installation + +1. Copy the completion file for `geheim`: +```bash +cp completions/geheim.fish ~/.config/fish/completions/ +``` + +2. Copy the wrapper function for `ge`: +```bash +cp completions/ge.fish ~/.config/fish/functions/ +``` + +3. Reload fish shell: +```bash +exec fish +``` + +## Usage + +### `geheim` command + +The `geheim` command now has full tab completion: +- Tab complete all subcommands (ls, search, cat, paste, etc.) +- Tab complete file paths for `import` +- Tab complete the `force` flag for import + +### `ge` wrapper + +The `ge` wrapper provides shortcuts: + +```bash +# Interactive mode (no arguments) +ge + +# Search shortcut (if not a known command, treats as search) +ge mypassword +# Same as: geheim search mypassword + +# Explicit commands still work +ge cat mypassword +ge import file.txt backup/ +ge import file.txt backup/ force +``` + +### Dynamic Entry Completion + +For better security, entry completion only works when the `PIN` environment variable is set: + +```bash +# Set PIN for session (entries will autocomplete) +set -x PIN yourpin + +# Use geheim with autocomplete +ge <TAB> + +# Unset PIN when done +set -e PIN +``` + +Without `PIN` set, commands will still autocomplete, but entry names won't (to avoid prompting for PIN during tab completion). + +## Features + +- ✓ Dynamic command completion (fetched from `geheim commands`) +- ✓ Smart search fallback in `ge` wrapper +- ✓ Entry name completion (when PIN is set) +- ✓ File path completion for import/export +- ✓ Force flag completion +- ✓ No hardcoded command lists (stays in sync with geheim updates) diff --git a/completions/ge.fish b/completions/ge.fish new file mode 100644 index 0000000..8a1206a --- /dev/null +++ b/completions/ge.fish @@ -0,0 +1,53 @@ +# Fish wrapper and completion for ge (geheim shortcut) +# Install to ~/.config/fish/functions/ge.fish + +function ge --description 'Geheim wrapper with shortcuts' + # If no arguments, run interactive mode + if test (count $argv) -eq 0 + geheim shell + return $status + end + + set -l cmd $argv[1] + + # Check if first argument is a known command + if contains $cmd (geheim commands 2>/dev/null) + # It's a command, pass through to geheim + geheim $argv + else + # Not a command, treat as search term + geheim search $argv + end +end + +# Dynamically load commands from geheim +function __fish_ge_commands + geheim commands 2>/dev/null +end + +# Get list of entries for completion +function __fish_ge_entries + # Only run if PIN is set to avoid interactive prompt + if set -q PIN + geheim ls 2>/dev/null | string replace -r ';.*$' '' | string trim + end +end + +# Complete subcommands or search terms +complete -c ge -f -n "__fish_use_subcommand" -a "(__fish_ge_commands)" +complete -c ge -f -n "__fish_use_subcommand" -a "(__fish_ge_entries)" + +# Complete search terms for commands that need them +complete -c ge -f -n "__fish_seen_subcommand_from search cat paste export pathexport open edit rm" -a "(__fish_ge_entries)" + +# Complete file paths for import +complete -c ge -n "__fish_seen_subcommand_from import" -F + +# Complete directory paths for import destination +complete -c ge -n "__fish_seen_subcommand_from import; and __fish_is_nth_token 3" -F -a "(__fish_complete_directories)" + +# Force flag for import +complete -c ge -n "__fish_seen_subcommand_from import; and __fish_is_nth_token 4" -f -a "force" + +# Complete directory paths for import_r +complete -c ge -n "__fish_seen_subcommand_from import_r" -F -a "(__fish_complete_directories)" diff --git a/completions/geheim.fish b/completions/geheim.fish new file mode 100644 index 0000000..c36ad03 --- /dev/null +++ b/completions/geheim.fish @@ -0,0 +1,33 @@ +# Fish completion for geheim +# Install to ~/.config/fish/completions/geheim.fish + +# Dynamically load commands from geheim +function __fish_geheim_commands + geheim commands 2>/dev/null +end + +# Get list of entries for completion +function __fish_geheim_entries + # Only run if PIN is set to avoid interactive prompt + if set -q PIN + geheim ls 2>/dev/null | string replace -r ';.*$' '' | string trim + end +end + +# Complete subcommands +complete -c geheim -f -n "__fish_use_subcommand" -a "(__fish_geheim_commands)" + +# Complete search terms for commands that need them +complete -c geheim -f -n "__fish_seen_subcommand_from search cat paste export pathexport open edit rm" -a "(__fish_geheim_entries)" + +# Complete file paths for import +complete -c geheim -n "__fish_seen_subcommand_from import" -F + +# Complete directory paths for import destination +complete -c geheim -n "__fish_seen_subcommand_from import; and __fish_is_nth_token 3" -F -a "(__fish_complete_directories)" + +# Force flag for import +complete -c geheim -n "__fish_seen_subcommand_from import; and __fish_is_nth_token 4" -f -a "force" + +# Complete directory paths for import_r +complete -c geheim -n "__fish_seen_subcommand_from import_r" -F -a "(__fish_complete_directories)" @@ -8,7 +8,7 @@ require 'io/console' require 'openssl' require 'json' -VERSION = 'v0.1.0' +VERSION = 'v0.2.0' # Configuration class Config @@ -577,6 +577,35 @@ class CLI @interactive = interactive end + def commands + puts 'ls' + puts 'search' + puts 'cat' + puts 'paste' + puts 'get' + puts 'add' + puts 'export' + puts 'pathexport' + puts 'open' + puts 'edit' + puts 'import' + puts 'import_r' + puts 'rm' + puts 'sync' + puts 'status' + puts 'commit' + puts 'reset' + puts 'fullcommit' + puts 'shred' + puts 'version' + puts 'commands' + puts 'help' + puts 'shell' + puts 'exit' + puts 'last' + 0 + end + def help log <<-HELP ls @@ -592,6 +621,7 @@ class CLI sync|status|commit|reset|fullcommit shred version + commands help shell HELP @@ -663,6 +693,8 @@ class CLI when 'version' log "geheim #{VERSION}" 0 + when 'commands' + commands when 'last' puts last_result last_result diff --git a/install-fish.sh b/install-fish.sh new file mode 100755 index 0000000..73d4d3e --- /dev/null +++ b/install-fish.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -e + +echo "Installing geheim fish shell integration..." + +# Create directories if they don't exist +mkdir -p ~/.config/fish/completions +mkdir -p ~/.config/fish/functions + +# Copy completion files +echo "Installing geheim completion..." +cp completions/geheim.fish ~/.config/fish/completions/ + +echo "Installing ge wrapper function..." +cp completions/ge.fish ~/.config/fish/functions/ + +echo "" +echo "✓ Fish integration installed successfully!" +echo "" +echo "Reload your fish shell with: exec fish" +echo "" +echo "See FISH_INTEGRATION.md for usage instructions." |
