diff --git a/bin/launcher.sh b/bin/launcher.sh index 64c1efd..45e7d63 100755 --- a/bin/launcher.sh +++ b/bin/launcher.sh @@ -1,66 +1,36 @@ -#!/bin/sh +#!/bin/bash # terminal application launcher for sway, using fzf -# original command: -# Based on: https://github.com/swaywm/sway/issues/1367 -# bindsym $altkey+space exec termite --name=launcher -e \ -# "bash -c 'compgen -c | sort -u | fzf --no-extended --print-query | \ -# tail -n1 | xargs -r swaymsg -t command exec'" +# inspired by https://github.com/Biont/sway-launcher-desktop +set -o pipefail +shopt -s nullglob globstar HIST_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/sway-launcher-history.txt" -FZF_OPTIONS="--layout=reverse --no-extended --print-query --no-sort" +export FZF_DEFAULT_OPTS="--layout=reverse --no-extended --print-query --no-sort" -# Get shell command list -# This may include the occasional non-executable file -# command_list=$({ IFS=:; ls -H $PATH; } | grep -v '/.*' | sort -u) -command_list=$(\ - find $(echo $PATH | tr ':' ' ') -type f -executable -printf "\n%f" | \ - sort -u) -# read existing command history -if [ -f "$HIST_FILE" ]; then - command_history=$(cat "$HIST_FILE") +[ ! -f "$HIST_FILE" ] && touch {"$HIST_FILE" +# Create fifo for populate fzf in async mode +FZFPIPE=$(mktemp -u) +mkfifo "$FZFPIPE" +trap 'rm "$FZFPIPE"' EXIT INT + +#retrieve history and pipe it into our fifo +readarray HIST_LINES <"$HIST_FILE" +(printf '%s' "${HIST_LINES[@]#* }" >>"$FZFPIPE") & + +# Get command, if empty exit +command=$(fzf <"$FZFPIPE" | tail -n1 || exit 1) +[[ "$command" == "" ]] && exit 0 + +# Update history +index=$(printf '%s' "${HIST_LINES[@]}" | grep -n -Pe "^[0-9]+ ${command}$" | awk -F ':' '{print $1-1}') +if [ -n "$index" ]; then + occurences=${HIST_LINES[$index]%% *} + occurences=$((occurences + 1)) + HIST_LINES[$index]="${occurences} ${command}"$'\n' else - command_history="" + HIST_LINES+=("1 $command"$'\n') fi -# search command list -command_str=$(printf "%s\n" "${command_history}" "${command_list}" | \ - sed -E 's/^[0-9]+ (.+)$/\1/' | \ - fzf $FZF_OPTIONS | \ - tail -n1) || exit 1 - -if [ "$command_str" = "" ]; then - exit 1 -fi -# echo "Command: $command_str" - -# using \E flag from https://github.com/junegunn/fzfperl regex -test "${command_str#*\\E}" != "$command_str" && echo "command can't contain '\E'" -test "${command_str#*\\E}" != "$command_str" && exit 1 - -# get full line from history (with count number) -hist_line=$(echo "$command_history" | grep -Pe "^[0-9]+ \Q$command_str\E$") -# echo "Hist Line: $hist_line" - -if [ "$hist_line" = "" ]; then - hist_count=1 -else - # Increment usage count - hist_count=$(echo "$hist_line" | sed -E 's/^([0-9]+) .+$/\1/') - hist_count=$((hist_count + 1)) - # delete line, to add updated later - # echo "Hist Before: $command_history" - command_history=$(echo "$command_history" | \ - grep --invert-match -Pe "^[0-9]+ \Q$command_str\E$") - # echo "Hist After: $command_history" -fi - -# update history -update_line="${hist_count} ${command_str}" -printf "%s\n" "${update_line}" "${command_history}" | \ - sort --numeric-sort --reverse > "$HIST_FILE" -# echo "$update_line" - -# execute command -echo "$command_str" -swaymsg -t command exec "$command_str" - +printf '%s' "${HIST_LINES[@]}" | sort --numeric-sort --reverse > "$HIST_FILE" +swaymsg -t command exec "$command" +exit 0