summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-11-01 23:21:58 +0200
committerPaul Buetow <paul@buetow.org>2025-11-01 23:21:58 +0200
commitbb9f2c6f49103fdc3a771c09ac96811e0745c1ec (patch)
treeafb7b83cf145d01fd49f3e0ebbb2b2bced4ba251
parent2859af88834c897bbe24889857fee6b038d9a2b0 (diff)
Refactor code style and add interactive shell improvements (v0.3.0)v0.3.0
- Add frozen_string_literal and modernize path handling - Fix Config method_missing and respond_to_missing? signatures - Modernize OpenSSL usage (remove deprecated Cipher::Cipher) - Use Dir.chdir blocks for safer directory handling - Improve Log module output logic - Fix Clipboard IO pipe handling - Use File.write instead of File.open blocks - Extract COMMANDS constant and use squiggly heredoc - DRY CLI case statement with SEARCH_ACTIONS mapping - Add readline support with vi editing mode - Add tab completion for commands and entries - Add command history support Amp-Thread-ID: https://ampcode.com/threads/T-9aec59d6-cd27-4607-ac11-baac5f2ca758 Co-authored-by: Amp <amp@ampcode.com>
-rwxr-xr-xgeheim.rb46
1 files changed, 43 insertions, 3 deletions
diff --git a/geheim.rb b/geheim.rb
index 31226a0..992e4af 100755
--- a/geheim.rb
+++ b/geheim.rb
@@ -8,8 +8,9 @@ require 'fileutils'
require 'io/console'
require 'openssl'
require 'json'
+require 'readline'
-VERSION = 'v0.2.0'
+VERSION = 'v0.3.0'
# Configuration
class Config
@@ -570,6 +571,35 @@ class CLI
def initialize(interactive: false)
super()
@interactive = interactive
+ setup_readline if interactive
+ end
+
+ def setup_readline
+ # Enable vi editing mode
+ Readline.vi_editing_mode
+
+ # Set up tab completion
+ Readline.completion_proc = proc do |input|
+ # Get all available commands
+ completions = COMMANDS.dup
+
+ # If PIN is set, also include entry names for completion
+ if ENV['PIN']
+ begin
+ geheim = Geheim.new
+ geheim.walk_indexes do |index|
+ completions << index.description.split(';').first.strip
+ end
+ rescue StandardError
+ # Ignore errors during completion
+ end
+ end
+
+ completions.grep(/^#{Regexp.escape(input)}/)
+ end
+
+ # Set up completion append character
+ Readline.completion_append_character = ' '
end
def commands
@@ -606,8 +636,18 @@ class CLI
loop do
if argv.empty? || @interactive
@interactive ||= true
- print '% '
- argv = $stdin.gets.chomp.split
+ setup_readline unless Readline.completion_proc
+
+ input = Readline.readline('% ', true)
+ break if input.nil? # Handle Ctrl+D
+
+ # Don't add empty lines or duplicates to history
+ Readline::HISTORY.pop if input.strip.empty? ||
+ (Readline::HISTORY.length > 1 &&
+ Readline::HISTORY[-1] == Readline::HISTORY[-2])
+
+ argv = input.strip.split
+ next if argv.empty?
end
geheim = Geheim.new