diff options
| author | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-03-14 12:40:57 +0100 |
|---|---|---|
| committer | Rubén Beltrán del Río <jj@r.bdr.sh> | 2026-03-15 21:37:04 +0100 |
| commit | 68fc4436c2565ff31f1499d868ac71bc560121ee (patch) | |
| tree | a9558bc8772631ca6bed55b1e38f3266669a61b0 | |
| parent | 2cf84c3a5654a267b4628c443e205d1f8bef759a (diff) | |
Add contacts picker
| -rw-r--r-- | config/niri/config.kdl | 2 | ||||
| -rwxr-xr-x | scripts/contacts.sh | 57 |
2 files changed, 59 insertions, 0 deletions
diff --git a/config/niri/config.kdl b/config/niri/config.kdl index 6cf18fc..b7f4c38 100644 --- a/config/niri/config.kdl +++ b/config/niri/config.kdl @@ -415,6 +415,8 @@ binds { Ctrl+XF86MonBrightnessDown allow-when-locked=true { spawn "bash" "-c" "brightnessctl set 5%- -d 'kbd_backlight'| sed -En 's/.*\\(([0-9]+)%\\).*/\\1/p' > $XDG_RUNTIME_DIR/wob.sock"; } Ctrl+XF86MonBrightnessUp allow-when-locked=true { spawn "bash" "-c" "brightnessctl set +5% -d 'kbd_backlight' | sed -En 's/.*\\(([0-9]+)%\\).*/\\1/p' > $XDG_RUNTIME_DIR/wob.sock"; } + XF86Search hotkey-overlay-title="Contacts" { spawn "bash" "-c" "~/.dotfiles/scripts/contacts.sh"; } + Mod+V hotkey-overlay-title="Open Clipboard Manager" { spawn "bash" "-c" "cliphist list | bemenu --single-instance -i -l 10 -n -H 26 --hp 10 --fn 'InputSansCompressed Light 10' -p '>' --ff '#0f261F' --tf '#23C17C' --nf '#0f261F' --cf '#23C17C2' --af '#00140d' --hb '#23C17C' --hf '#0f261F' --hf '#DAE6E3' --nb '#DAE6E3' --tb '#DAE6E3' --fb '#DAE6E3' --cb '#DAE6E3' --ab '#DAE6E3' | cliphist decode | wl-copy"; } Mod+grave hotkey-overlay-title="Quick Terminal" { spawn "kitten" "quick-access-terminal"; } diff --git a/scripts/contacts.sh b/scripts/contacts.sh new file mode 100755 index 0000000..b13bdfb --- /dev/null +++ b/scripts/contacts.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +export BEMENU_OPTS='--single-instance -i -n -H 26 --hp 10 --fn "InputSansCompressed Light 10" -p ">" --ff "#0f261F" --tf "#23C17C" --nf "#0f261F" --cf "#23C17C2" --af "#00140d" --hb "#23C17C" --hf "#DAE6E3" --nb "#DAE6E3" --tb "#DAE6E3" --fb "#DAE6E3" --cb "#DAE6E3" --ab "#DAE6E3"' + +CACHE="$HOME/.cache/khard-contacts.tsv" +CACHE_MAX_AGE=30 + +if [[ ! -f "$CACHE" ]] || [[ -n "$(find "$CACHE" -mmin +"$CACHE_MAX_AGE" -print)" ]]; then + khard list --parsable --fields uid,name --search-in-source-files | tail -n +2 > "$CACHE.tmp" \ + && mv "$CACHE.tmp" "$CACHE" +fi + +declare -A contacts +while IFS=$'\t' read -r uid name; do + contacts["$name"]="$uid" +done < "$CACHE" + +name=$(printf '%s\n' "${!contacts[@]}" | sort | bemenu) +[[ -z "$name" ]] && exit 1 + +selection=$( + khard show --format=yaml "uid:${contacts[$name]}" --search-in-source-files \ + | python3 -c ' +import sys, yaml + +data = yaml.safe_load(sys.stdin) +fields = [ + "Formatted name", "First name", "Last name", + "Nickname", "Birthday", "Phone", "Email", "Address" +] + +def leaves(val): + if isinstance(val, dict): + for v in val.values(): + yield from leaves(v) + elif isinstance(val, list): + for v in val: + yield from leaves(v) + else: + if val is not None: + yield str(val) + +seen = set() +for key in fields: + if key in data: + for leaf in leaves(data[key]): + leaf = leaf.strip() + if leaf and leaf not in seen: + seen.add(leaf) + print(leaf) +' \ + | bemenu +) +[[ -z "$selection" ]] && exit 1 + +printf '%s' "$selection" | wl-copy +notify-send "Copied to clipboard" "$selection" |