#!/usr/bin/env bash shopt -s nullglob globstar prefix=${PASSWORD_STORE_DIR-~/.password-store} password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) notify() { # prints an integer which is the notification id # :param 1: the application name # :param 2: summary # sadly this is required until there is a direct way to call Notify python -c "import dbus; print(dbus.Bus().call_blocking( 'org.freedesktop.Notifications', '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', 'Notify', 'susssasa{sv}i', ('$1', # app_name 0, # replaces_id '', # app_icon '$2', # summary 'body', # body [], # actions {}, # hints 0 # expire_timeout )))" } notify_close() { # :param 1: close the notification with this id dbus-send --type=method_call --dest='org.freedesktop.Notifications' \ /org/freedesktop/Notifications org.freedesktop.Notifications.CloseNotification \ "uint32:$1" } dmenu_show() { # :param 1: Name of the password (`pass' path) echo "Done" pass show "$1" 2>&1 | \ sed -e 's/^\(pass\|password\):.*/\1: XXXX/' | # mask password \ sed -n -e '/^.\+$/p' # delete empty lines } write_clipboard() { # blocks until paste action happens xclip -i -verbose -l 1 2>/dev/null } password=$(printf '%s\n' "${password_files[@]}" | dmenu "$@") if [ -z "$password" ]; then exit fi while true; do choice=$(dmenu_show "$password" | dmenu -l 3 -p "Clipboard $pass") case "$choice" in login:*|user:*|username:*) id=$(notify "dmenu-pass" "Ready to paste username") pass show "$password" 2>&1 \ | sed -ne 's/^\(login\|user\|username\): \?\(.*\)/\2/p' \ | write_clipboard notify_close $id ;; pass:*|password:*) id=$(notify "dmenu-pass" "Ready to paste password") pass show "$password" 2>&1 \ | sed -ne 's/^\(pass\|password\): \?\(.*\)/\2/p' \ | write_clipboard notify_close $id ;; Done|"") break ;; *) echo $choice ;; esac done