This commit implements additional options to passmenu for typing
additional information:

--name only types the basename of the entry (usually a username).

--both types username <TAB> password

--delay SECONDS sleeps for a configurable amount of seconds before
typing the requested data.

Signed-off-by: Maximilian Eschenbacher <[email protected]>
---
 contrib/dmenu/README.md | 20 +++++++++++++++++---
 contrib/dmenu/passmenu  | 38 ++++++++++++++++++++++++++++++++------
 2 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/contrib/dmenu/README.md b/contrib/dmenu/README.md
index 9d54fb4..022e794 100644
--- a/contrib/dmenu/README.md
+++ b/contrib/dmenu/README.md
@@ -1,12 +1,26 @@
 `passmenu` is a [dmenu][]-based interface to [pass][], the standard Unix
 password manager. This design allows you to quickly copy a password to the
 clipboard without having to open up a terminal window if you don't already have
-one open. If `--type` is specified, the password is typed using [xdotool][]
-instead of copied to the clipboard.
+one open.
+
+If `--type` is specified, the password is typed using [xdotool][] instead of
+copied to the clipboard. Adding to `--type`, if `--name` is specified, only the
+user name (basename) will be typed. The `--both` option types user name TAB
+password. An optional `--delay SECONDS` causes the typing to start after
+`SECONDS`.
 
 # Usage
 
-    passmenu [--type] [dmenu arguments...]
+    passmenu [--type [--both|--name] [--delay SECONDS]] [dmenu arguments...]
+
+# Example usage for the i3 window manager
+
+    bindsym $mod+p exec ~/bin/passmenu --type
+    bindsym $mod+o exec ~/bin/passmenu --type --both
+    bindsym $mod+i exec ~/bin/passmenu --type --name
+    bindsym $mod+shift+p exec ~/bin/passmenu --type --delay 5
+    bindsym $mod+shift+o exec ~/bin/passmenu --type --both --delay 5
+    bindsym $mod+shift+i exec ~/bin/passmenu --type --name --delay 5
 
 [dmenu]: http://tools.suckless.org/dmenu/
 [xdotool]: http://www.semicomplete.com/projects/xdotool/
diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu
index 83268bc..c5ccf90 100755
--- a/contrib/dmenu/passmenu
+++ b/contrib/dmenu/passmenu
@@ -3,23 +3,49 @@
 shopt -s nullglob globstar
 
 typeit=0
-if [[ $1 == "--type" ]]; then
-       typeit=1
-       shift
-fi
+typeboth=0
+typename=0
+delay=0
+
+while true; do case $1 in
+       --type) typeit=1; shift ;;
+       --both) typeboth=1; shift ;;
+       --name) typename=1; shift ;;
+       --delay) shift; delay=$1; shift ;;
+       *) break ;;
+esac done
 
 prefix=${PASSWORD_STORE_DIR-~/.password-store}
 password_files=( "$prefix"/**/*.gpg )
 password_files=( "${password_files[@]#"$prefix"/}" )
 password_files=( "${password_files[@]%.gpg}" )
 
-password=$(printf '%s\n' "${password_files[@]}" | dmenu "$@")
+password=$(printf '%s\n' "${password_files[@]}" | dmenu -i "$@")
+loginname=$(basename "$password")
 
 [[ -n $password ]] || exit
 
 if [[ $typeit -eq 0 ]]; then
+       # this is the easy case
        pass show -c "$password" 2>/dev/null
-else
+       exit
+fi
+
+if [[ $typeit -eq 1 ]] && [[ $delay -gt 0 ]]; then
+       # with a startup delay, decrypt the password once at startup to 
increase our
+       # chances that we will not be asked for a decryption passphrase in a few
+       # seconds
+       pass show "$password" 1>/dev/null 2>/dev/null
+       sleep "$delay"
+fi
+
+if [[ $typeboth -eq 1 ]] || [ $typename -eq 1 ]; then
+       echo -n "$loginname" | xdotool type --clearmodifiers --file -
+fi
+if [[ $typeboth -eq 1 ]]; then
+       xdotool key --clearmodifiers Tab
+fi
+if [[ $typeboth -eq 1 ]] || [[ $typename -eq 0 ]]; then
        pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } |
                xdotool type --clearmodifiers --file -
 fi
-- 
2.30.0

Reply via email to