#!/bin/bash shopt -s nullglob # We use this to make sure the cache files are sorted bytewise LC_COLLATE=C declare -A selections ordered_selections=() cache_file=/tmp/clipmenu.$USER/line_cache # We use tac since we want newest to oldest, and we append in clipmenud while IFS='|' read -r full_file first_line; do ordered_selections+=("$first_line") selections[$first_line]=$full_file done < <(tac "$cache_file") # It's okay to hardcode `-l 8` here as a sensible default without checking # whether `-l` is also in "$@", because the way that dmenu works allows a later # argument to override an earlier one. That is, if the user passes in `-l`, our # one will be ignored. chosen_line=$(printf '%s\n' "${ordered_selections[@]}" | uniq | dmenu -l 8 "$@") [[ $chosen_line ]] || exit 1 for selection in clipboard primary; do if type -p xsel >/dev/null 2>&1; then xsel -i --"$selection" < "${selections[$chosen_line]}" else xclip -sel "$selection" < "${selections[$chosen_line]}" fi done