Extend pass completion (#756)

This PR extends the existing completion for the pass command to include
all existing subcommands (as of pass v1.7.4). It also adds completions
for the pass-otp and pass-update extensions.
This commit is contained in:
Martin Wurm 2024-02-07 17:46:41 +01:00 committed by GitHub
parent c8c29728d8
commit dbf4586594
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 163 additions and 56 deletions

View File

@ -0,0 +1,41 @@
use ../../nu-complete "nu-complete pass-files"
# Prompt for and insert a new OTP key.
export extern "pass otp insert" [
name?: string@"nu-complete pass-files" # The name of the password entry to insert the OTP key into. If not provided, the URI label is used.
--force(-f) # Do not prompt before overwriting an existing URI.
--echo(-e) # Echo the input.
--secret(-s) # Prompt for the OTP secret, assuming SHA1 algorithm, 30-second period, and 6 OTP digits. If set, one of --issuer or --account is also required. If not set, prompt for a key URI.
--issuer(-i): string # The issuer of the OTP key.
--account(-a): string # The account the OTP key belongs to.
]
# Appends an OTP key URI to an existing password file.
export extern "pass otp append" [
name: string@"nu-complete pass-files" # The name of the password entry to insert the OTP key into.
--force(-f) # Do not prompt before overwriting an existing URI.
--echo(-e) # Echo the input.
--secret(-s) # Prompt for the OTP secret, assuming SHA1 algorithm, 30-second period, and 6 OTP digits. If set, one of --issuer or --account is also required. If not set, prompt for a key URI.
--issuer(-i): string # The issuer of the OTP key.
--account(-a): string # The account the OTP key belongs to.
]
# Display the key URI stored in the given password entry.
export extern "pass otp uri" [
name: string@"nu-complete pass-files" # The name of the password entry.
--clip(-c) # Put the URI on the clipboard.
--qrcode(-q) # Output the URI as a QR code.
]
# Test if the given URI is a valid OTP key URI.
export extern "pass otp validate" [
uri: string # The URI to validate.
]
# Generate an OTP code.
export extern "pass otp" [
name: string@"nu-complete pass-files" # The name of the password entry containing the OTP secret.
--clip(-c) # Put the OTP code on the clipboard and clear it after 45 seconds.
]
export alias "pass otp code" = pass otp

View File

@ -0,0 +1,17 @@
use ../../nu-complete "nu-complete pass-files"
# Interactively update a set of passwords.
export extern "pass update" [
...paths: string@"nu-complete pass-files" # The passwords and/or directories to update.
--clip(-c) # Write the password to the clipboard.
--no-symbols(-n) # Do not use any non-alphanumeric characters.
--length(-l): int = 25 # Provide a password length.
--provide(-p) # Let the user specify a password by hand.
--multiline(-m) # Update multiline passwords. If not set, only the first line of a password file is updated.
--include(-i): string # Only update the passwords that match a regex.
--exclude(-e): string # Do not update the passwords that match a regex.
--edit(-E) # Edit the passwords useing the default editor.
--force(-f) # Force update.
--version(-V) # Show version information.
--help(-h) # Print a help message.
]

View File

@ -0,0 +1,39 @@
def pass_completions_directory [] {
if ($env | columns | any { |it| $it == "PASSWORD_STORE_DIR" }) {
return $env.PASSWORD_STORE_DIR
} else {
return ("~/.password-store" | path expand)
}
}
export def "nu-complete pass-files" [] {
let dir = (pass_completions_directory)
ls ($dir | path join "**" | path join "*.gpg")
| get name
| each {|it| ( $it
| path relative-to $dir
| str replace ".gpg" ""
)
}
}
export def "nu-complete pass-directories" [] {
let dir = (pass_completions_directory)
ls ($dir | path join **)
| get name
| filter { |it| not (ls $it | is-empty) }
| each {|it| ( $it | path relative-to $dir) }
}
export def "nu-complete pass-gpg" [] {
^gpg --list-keys
| lines
| skip 2
| split list ''
| each { |entry|
{
value: ($entry.1 | str trim),
description: ($entry.2 | parse --regex '^uid\s*\[[\w\s]*\]\s*(.*?)\s*$' | get 0.capture0)
}
}
}

View File

@ -1,83 +1,93 @@
def pass_completions_directory [] {
if ($env | columns | any { |it| $it == "PASSWORD_STORE_DIR" }) {
return $env.PASSWORD_STORE_DIR
} else {
return ("~/.password-store" | path expand)
}
}
use nu-complete *
def "nu-complete pass-files" [] {
let dir = (pass_completions_directory)
ls ($dir | path join "**" | path join "*.gpg")
| get name
| each {|it| ( $it
| path relative-to $dir
| str replace ".gpg" ""
)
}
}
# Initialize new password storage or reencrypt existing passwords.
export extern "pass init" [
...gpg_ids: string@"nu-complete pass-gpg" # The ID(s) of the GPG public keys the passwords shall be encrypted with.
--path(-p): string@"nu-complete pass-directories" # Subfolder to selectively reencrypt.
]
def "nu-complete pass-directories" [] {
let dir = (pass_completions_directory)
ls ($dir | path join **)
| get name
| filter { |it| not (ls $it | is-empty) }
| each {|it| ( $it | path relative-to $dir) }
}
# Show folders in the password store
# List passwords.
export extern "pass ls" [
subfolder?: string@"nu-complete pass-directories"
subfolder?: string@"nu-complete pass-directories" # The subfolder to list.
]
# Show the value of a password
# List passwords that match pass-names.
export extern "pass find" [
...pass_names: string # List of terms to search for.
]
# Show the value of a password.
export extern "pass show" [
name: string@"nu-complete pass-files"
--clip(-c) # do not print the password but instead copy the first (or otherwise specified, example: -c2) line to the clipboard.
--qrcode(-q) # do not print the password but instead display a QR code.
name: string@"nu-complete pass-files" # The name of the password to show.
--clip(-c) # Do not print the password but instead copy the first (or otherwise specified, example: -c2) line to the clipboard.
--qrcode(-q) # Do not print the password but instead display a QR code.
]
# Add a new password
export extern "pass add" [
# Search for password files containing a given search string when decrypted.
export extern "pass grep" [
...grepoptions # Options that will be passed to ^grep.
search_string: string # The search string.
]
# Insert a new password
export extern "pass insert" [
name: string@"nu-complete pass-directories"
--echo(-e) # Enable keyboard echo
--multiline(-m) # Lines will be read until EOF or Ctrl+D is reached
--force(-f) # Omit prompt when trying to overwrite existing password
--echo(-e) # Enable keyboard echo.
--multiline(-m) # Lines will be read until EOF or Ctrl+D is reached.
--force(-f) # Omit prompt when trying to overwrite existing password.
]
# Edit an existing password
export alias "pass add" = pass insert
# Edit an existing password.
export extern "pass edit" [
name: string@"nu-complete pass-files"
name: string@"nu-complete pass-files" # The name of the password.
]
# Generate a new password
export extern "pass generate" [
name: string@"nu-complete pass-directories"
length?: number
--no-symbols(-n) # Do not use any non-alphanumeric characters in the generated password
--clip(-c) # Do not print the password but instead copy it to the clipboard using xclip or wl-clipboard
--in-place(-i) # Do not interactively prompt, and only replace the first line of the password file with the new generated password, keeping the remainder of the file intact
--force(-f) # Omit prompt when trying to overwrite existing password
name: string@"nu-complete pass-directories" # The name of the password.
length?: int = 25 # the length of the new password.
--no-symbols(-n) # Do not use any non-alphanumeric characters in the generated password.
--clip(-c) # Do not print the password but instead copy it to the clipboard using xclip or wl-clipboard.
--in-place(-i) # Do not interactively prompt, and only replace the first line of the password file with the new generated password, keeping the remainder of the file intact.
--force(-f) # Omit prompt when trying to overwrite existing password.
]
# Remove a password
# Remove a password or directory.
export extern "pass rm" [
name: string@"nu-complete pass-files"
--recursive(-r) # delete pass-name recursively if it is a directory
--force(-f) # Do not interactively prompt before removal
name: string@"nu-complete pass-files" # The name of the password or directory to remove.
--recursive(-r) # delete pass-name recursively if it is a directory.
--force(-f) # Do not interactively prompt before removal.
]
# Rename a password
# Rename or move a password or directory.
export extern "pass mv" [
oldname: string@"nu-complete pass-files"
newname: string@"nu-complete pass-directories"
--force(-f) # Omit prompt when trying to overwrite existing password
oldname: string@"nu-complete pass-files" # The password or directory to copy.
newname: string@"nu-complete pass-directories" # The path to copy the password or directory to.
--force(-f) # Omit prompt when trying to overwrite existing password.
]
# Copy a password
# Copy a password or directory.
export extern "pass cp" [
oldname: string@"nu-complete pass-files"
newname: string@"nu-complete pass-directories"
--force(-f) # Omit prompt when trying to overwrite existing password
oldname: string@"nu-complete pass-files" # The password or directory to copy.
newname: string@"nu-complete pass-directories" # The path to copy the password or directory to.
--force(-f) # Omit prompt when trying to overwrite existing password.
]
# If the password store is a git repository, execute a git command.
export extern "pass git" [
...git_command_args # The git command to run.
]
# Show help information.
export extern "pass help" []
# Show version information.
export extern "pass version" []
export extern "pass" [
path: string@"nu-complete pass-files" # The password to show or subfolder to list.
--clip(-c) # Do not print the password but instead copy the first (or otherwise specified, example: -c2) line to the clipboard.
--qrcode(-q) # Do not print the password but instead display a QR code.
]