| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
set -eu |
| 19 |
|
| 20 |
FIELD_CODES=' ?%[fFuUickdDnNvm]' |
| 21 |
|
| 22 |
dirs="/usr/share/applications |
| 23 |
${XDG_DATA_HOME:-$HOME/.local/share}/applications |
| 24 |
/var/lib/flatpak/exports/share/applications |
| 25 |
${XDG_DATA_HOME:-$HOME/.local/share}/flatpak/exports/share/applications" |
| 26 |
|
| 27 |
entries() { |
| 28 |
printf '%s\n' "$dirs" | while IFS= read -r dir; do |
| 29 |
[ -d "$dir" ] || continue |
| 30 |
find "$dir" -maxdepth 2 -name '*.desktop' 2>/dev/null |
| 31 |
done | while IFS= read -r file; do |
| 32 |
|
| 33 |
|
| 34 |
awk -v codes="$FIELD_CODES" ' |
| 35 |
/^\[Desktop Entry\]/ { group = 1; next } |
| 36 |
/^\[/ { group = 0 } |
| 37 |
!group { next } |
| 38 |
/^Name=/ && name == "" { name = substr($0, 6) } |
| 39 |
/^Exec=/ && cmd == "" { cmd = substr($0, 6) } |
| 40 |
/^Type=/ { type = substr($0, 6) } |
| 41 |
/^NoDisplay=[Tt]rue/ { hide = 1 } |
| 42 |
/^Hidden=[Tt]rue/ { hide = 1 } |
| 43 |
# Terminal=true means the entry is a TUI and has no window of its own. |
| 44 |
# On a TUI-first system this is not the rare case: helix, yazi and |
| 45 |
# gammastep all ship one. Launched without a terminal they exit |
| 46 |
# immediately with no output, which reads as the launcher being broken. |
| 47 |
/^Terminal=[Tt]rue/ { needs_term = 1 } |
| 48 |
END { |
| 49 |
if (hide || type != "Application" || name == "" || cmd == "") exit |
| 50 |
gsub(codes, "", cmd) |
| 51 |
printf "%s\t%d\t%s\n", name, needs_term, cmd |
| 52 |
} |
| 53 |
' "$file" |
| 54 |
done | sort -u -k1,1 -t "$(printf '\t')" |
| 55 |
} |
| 56 |
|
| 57 |
choice=$(entries | fzf \ |
| 58 |
--delimiter='\t' --with-nth=1 \ |
| 59 |
--prompt='run ' --pointer='>' --marker=' ' \ |
| 60 |
--layout=reverse --no-multi --height=100% --border=none --info=inline) || exit 0 |
| 61 |
|
| 62 |
[ -n "$choice" ] || exit 0 |
| 63 |
needs_term=$(printf '%s' "$choice" | cut -f2) |
| 64 |
cmd=$(printf '%s' "$choice" | cut -f3-) |
| 65 |
[ -n "$cmd" ] || exit 0 |
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
if [ "$needs_term" = "1" ]; then |
| 70 |
cmd="${TERMINAL:-shop} -e $cmd" |
| 71 |
fi |
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
if [ -n "${SWAYSOCK:-}" ] && command -v swaymsg >/dev/null 2>&1; then |
| 77 |
swaymsg exec "$cmd" >/dev/null |
| 78 |
else |
| 79 |
setsid sh -c "$cmd" >/dev/null 2>&1 & |
| 80 |
fi |
| 81 |
|