summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-11-01 23:12:20 +0200
committerPaul Buetow <paul@buetow.org>2025-11-01 23:12:20 +0200
commitc87e2837112c064da8528d38727dd7cad7acaa32 (patch)
tree51612e1a43e6f6f73ea168d74285b5dfc4b74a53
parent28ccc70feeab8aef7bcafaea75e288e6e58c2034 (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.md80
-rw-r--r--completions/ge.fish53
-rw-r--r--completions/geheim.fish33
-rwxr-xr-xgeheim.rb34
-rwxr-xr-xinstall-fish.sh23
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)"
diff --git a/geheim.rb b/geheim.rb
index 2a1d1d2..d095d06 100755
--- a/geheim.rb
+++ b/geheim.rb
@@ -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."