aboutsummaryrefslogtreecommitdiff
path: root/.config/otter-launcher/sway-launcher-desktop.sh
diff options
context:
space:
mode:
authordacctal <donotcontactmevia@email.invalid>2026-07-10 10:49:55 +0000
committerdacctal <donotcontactmevia@email.invalid>2026-07-10 10:49:55 +0000
commit9ea4e05127e7aaf79a58f98076288b25973e949f (patch)
tree38e526e572e48a4c9e9cf08d6d1a6dabacb893c9 /.config/otter-launcher/sway-launcher-desktop.sh
parentdd03d22b6605aa26ceb9d2fbaf9b24c4ceb0e0fb (diff)
backup
Diffstat (limited to '.config/otter-launcher/sway-launcher-desktop.sh')
-rwxr-xr-x.config/otter-launcher/sway-launcher-desktop.sh390
1 files changed, 0 insertions, 390 deletions
diff --git a/.config/otter-launcher/sway-launcher-desktop.sh b/.config/otter-launcher/sway-launcher-desktop.sh
deleted file mode 100755
index 0153175..0000000
--- a/.config/otter-launcher/sway-launcher-desktop.sh
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/usr/bin/env bash
-# terminal application launcher for sway, using fzf
-# Based on: https://gitlab.com/FlyingWombat/my-scripts/blob/master/sway-launcher
-# https://gist.github.com/Biont/40ef59652acf3673520c7a03c9f22d2a
-shopt -s nullglob globstar
-set -o pipefail
-if ! { exec 0>&3; } 1>/dev/null 2>&1; then
- exec 3>/dev/null # If file descriptor 3 is unused in parent shell, output to /dev/null
-fi
-# shellcheck disable=SC2154
-trap 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
-IFS=$'\n\t'
-DEL=$'\34'
-
-FZF_COMMAND="${FZF_COMMAND:=fzf}"
-TERMINAL_COMMAND="${TERMINAL_COMMAND:="$TERMINAL -e"}"
-GLYPH_COMMAND="${GLYPH_COMMAND- }"
-GLYPH_DESKTOP="${GLYPH_DESKTOP- }"
-CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/sway-launcher-desktop"
-PROVIDERS_FILE="${PROVIDERS_FILE:=providers.conf}"
-if [[ "${PROVIDERS_FILE#/}" == "${PROVIDERS_FILE}" ]]; then
- # $PROVIDERS_FILE is a relative path, prepend $CONFIG_DIR
- PROVIDERS_FILE="${CONFIG_DIR}/${PROVIDERS_FILE}"
-fi
-if [[ ! -v PREVIEW_WINDOW ]]; then
- PREVIEW_WINDOW=up:2:noborder
-fi
-
-# Provider config entries are separated by the field separator \034 and have the following structure:
-# list_cmd,preview_cmd,launch_cmd,purge_cmd
-declare -A PROVIDERS
-if [ -f "${PROVIDERS_FILE}" ]; then
- eval "$(awk -F= '
- BEGINFILE{ provider=""; }
- /^\[.*\]/{sub("^\\[", "");sub("\\]$", "");provider=$0}
- /^(launch|list|preview|purge)_cmd/{st = index($0,"=");providers[provider][$1] = substr($0,st+1)}
- ENDFILE{
- for (key in providers){
- if(!("list_cmd" in providers[key])){continue;}
- if(!("launch_cmd" in providers[key])){continue;}
- if(!("preview_cmd" in providers[key])){continue;}
- if(!("purge_cmd" in providers[key])){providers[key]["purge_cmd"] = "exit 0";}
- for (entry in providers[key]){
- gsub(/[\x27,\047]/,"\x27\"\x27\"\x27", providers[key][entry])
- }
- print "PROVIDERS[\x27" key "\x27]=\x27" providers[key]["list_cmd"] "\034" providers[key]["preview_cmd"] "\034" providers[key]["launch_cmd"] "\034" providers[key]["purge_cmd"] "\x27\n"
- }
- }' "${PROVIDERS_FILE}")"
- if [[ ! -v HIST_FILE ]]; then
- HIST_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/${0##*/}-${PROVIDERS_FILE##*/}-history.txt"
- fi
-else
- PROVIDERS['desktop']="${0} list-entries${DEL}${0} describe-desktop \"{1}\"${DEL}${0} run-desktop '{1}' {2}${DEL}test -f '{1}' || exit 43"
- PROVIDERS['command']="${0} list-commands${DEL}${0} describe-command \"{1}\"${DEL}${TERMINAL_COMMAND} {1}${DEL}command -v '{1}' || exit 43"
- if [[ ! -v HIST_FILE ]]; then
- HIST_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/${0##*/}-history.txt"
- fi
-fi
-PROVIDERS['user']="exit${DEL}exit${DEL}{1}" # Fallback provider that simply executes the exact command if there were no matches
-
-if [[ -n "${HIST_FILE}" ]]; then
- mkdir -p "${HIST_FILE%/*}" && touch "$HIST_FILE"
- readarray HIST_LINES <"$HIST_FILE"
-fi
-
-function describe() {
- # shellcheck disable=SC2086
- readarray -d ${DEL} -t PROVIDER_ARGS <<<${PROVIDERS[${1}]}
- # shellcheck disable=SC2086
- [ -n "${PROVIDER_ARGS[1]}" ] && eval "${PROVIDER_ARGS[1]//\{1\}/${2}}"
-}
-function describe-desktop() {
- description=$(sed -ne '/^Comment=/{s/^Comment=//;p;q}' "$1")
- echo -e "\033[33m$(sed -ne '/^Name=/{s/^Name=//;p;q}' "$1")\033[0m"
- echo "${description:-No description}"
-}
-function describe-command() {
- readarray arr < <(whatis -l "$1" 2>/dev/null)
- description="${arr[0]}"
- description="${description#* - }"
- echo -e "\033[33m${1}\033[0m"
- echo "${description:-No description}"
-}
-
-function provide() {
- # shellcheck disable=SC2086
- readarray -d ${DEL} -t PROVIDER_ARGS <<<${PROVIDERS[$1]}
- eval "${PROVIDER_ARGS[0]}"
-}
-#function list-commands() {
-# IFS=: read -ra path <<<"$PATH"
-# for dir in "${path[@]}"; do
-# printf '%s\n' "$dir/"* |
-# awk -F / -v pre="$GLYPH_COMMAND" '{print $NF "\034command\034\033[31m" pre "\033[0m" $NF;}'
-# done | sort -u
-#}
-function list-commands() {
- # Add your path
- CUSTOM_BIN_DIR="$HOME/.local/share/uspm/bin/"
-
- # Og PATH directories
- IFS=: read -ra path <<<"$PATH"
-
- # directory
- if [[ -d "$CUSTOM_BIN_DIR" ]]; then
- path+=("$CUSTOM_BIN_DIR")
- fi
-
- for dir in "${path[@]}"; do
- printf '%s\n' "$dir/"* |
- awk -F / -v pre="$GLYPH_COMMAND" '{print $NF "\034command\034\033[31m" pre "\033[0m" $NF;}'
- done | sort -u
-}
-function list-entries() {
- # Get locations of desktop application folders according to spec
- # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
- IFS=':' read -ra DIRS <<<"${XDG_DATA_HOME-${HOME}/.local/share}:${XDG_DATA_DIRS-/usr/local/share:/usr/share}"
- for i in "${!DIRS[@]}"; do
- if [[ ! -d "${DIRS[i]}" ]]; then
- unset -v 'DIRS[$i]'
- else
- DIRS[$i]="${DIRS[i]}/applications/**/*.desktop"
- fi
- done
-
- # shellcheck disable=SC2068
- entries ${DIRS[@]} | sort -k2
-}
-function entries() {
- # shellcheck disable=SC2068
- awk -v pre="$GLYPH_DESKTOP" -F= '
- function desktopFileID(filename){
- sub("^.*applications/", "", filename);
- sub("/", "-", filename);
- return filename
- }
- BEGINFILE{
- application=0;
- hidden=0;
- block="";
- a=0
-
- id=desktopFileID(FILENAME)
- if(id in fileIds){
- nextfile;
- }else{
- fileIds[id]=0
- }
- }
- /^\[Desktop Entry\]/{block="entry"}
- /^Type=Application/{application=1}
- /^\[Desktop Action/{
- sub("^\\[Desktop Action ", "");
- sub("\\]$", "");
- block="action";
- a++;
- actions[a,"key"]=$0
- }
- /^\[X-/{
- sub("^\\[X-", "");
- sub("\\]$", "");
- block="action";
- a++;
- actions[a,"key"]=$0
- }
- /^Name=/{ (block=="action")? actions[a,"name"]=$2 : name=$2 }
- /^NoDisplay=true/{ (block=="action")? actions[a,"hidden"]=1 : hidden=1 }
- ENDFILE{
- if (application){
- if (!hidden)
- print FILENAME "\034desktop\034\033[33m" pre name "\033[0m";
- if (a>0)
- for (i=1; i<=a; i++)
- if (!actions[i, "hidden"])
- print FILENAME "\034desktop\034\033[33m" pre name "\033[0m (" actions[i, "name"] ")\034" actions[i, "key"]
- }
- }' \
- $@ </dev/null
- # the empty stdin is needed in case no *.desktop files
-}
-function run-desktop() {
- CMD="$("${0}" generate-command "$@" 2>&3)"
- echo "Generated Launch command from .desktop file: ${CMD}" >&3
- eval "${CMD}"
-}
-function generate-command() {
- # Define the search pattern that specifies the block to search for within the .desktop file
- PATTERN="^\\\\[Desktop Entry\\\\]"
- if [[ -n $2 ]]; then
- PATTERN="^\\\\[Desktop Action ${2}\\\\]"
- fi
- echo "Searching for pattern: ${PATTERN}" >&3
- # 1. We see a line starting [Desktop, but we're already searching: deactivate search again
- # 2. We see the specified pattern: start search
- # 3. We see an Exec= line during search: remove field codes and set variable
- # 3. We see a Path= line during search: set variable
- # 4. Finally, build command line
- awk -v pattern="${PATTERN}" -v terminal_cmd="${TERMINAL_COMMAND}" -F= '
- BEGIN{a=0;exec=0;path=0}
- /^\[Desktop/{
- if(a){ a=0 }
- }
- $0 ~ pattern{ a=1 }
- /^Terminal=/{
- sub("^Terminal=", "");
- if ($0 == "true") { terminal=1 }
- }
- /^Exec=/{
- if(a && !exec){
- sub("^Exec=", "");
- gsub(" ?%[cDdFfikmNnUuv]", "");
- exec=$0;
- }
- }
- /^Path=/{
- if(a && !path){ path=$2 }
- }
- END{
- if(path){ printf "cd " path " && " }
- printf "exec "
- if (terminal){ printf terminal_cmd " " }
- print exec
- }' "$1"
-}
-
-function shouldAutostart() {
- local condition="$(cat $1 | grep "AutostartCondition" | cut -d'=' -f2)"
- local filename="${XDG_CONFIG_HOME-${HOME}/.config}/${condition#* }"
- case $condition in
- if-exists*)
- [[ -e $filename ]]
- ;;
- unless-exists*)
- [[ ! -e $filename ]]
- ;;
- *)
- return 0
- ;;
- esac
-}
-
-function autostart() {
- for application in $(list-autostart); do
- if shouldAutostart "$application"; then
- (exec setsid /bin/sh -c "$(run-desktop "${application}")" &>/dev/null &)
- fi
- done
-}
-
-function list-autostart() {
- # Get locations of desktop application folders according to spec
- # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
- IFS=':' read -ra DIRS <<<"${XDG_CONFIG_HOME-${HOME}/.config}:${XDG_CONFIG_DIRS-/etc/xdg}"
- for i in "${!DIRS[@]}"; do
- if [[ ! -d "${DIRS[i]}" ]]; then
- unset -v 'DIRS[$i]'
- else
- DIRS[$i]="${DIRS[i]}/autostart/*.desktop"
- fi
- done
-
- # shellcheck disable=SC2068
- awk -v pre="$GLYPH_DESKTOP" -F= '
- function desktopFileID(filename){
- sub("^.*autostart/", "", filename);
- sub("/", "-", filename);
- return filename
- }
- BEGINFILE{
- application=0;
- block="";
- disabled=0;
- a=0
-
- id=desktopFileID(FILENAME)
- if(id in fileIds){
- nextfile;
- }else{
- fileIds[id]=0
- }
- }
- /^\[Desktop Entry\]/{block="entry"}
- /^Type=Application/{application=1}
- /^Name=/{ iname=$2 }
- /^Hidden=true/{disabled=1}
- ENDFILE{
- if (application && !disabled){
- print FILENAME;
- }
- }' \
- ${DIRS[@]} </dev/null
-}
-
-purge() {
- # shellcheck disable=SC2188
- >"${HIST_FILE}"
- declare -A PURGE_CMDS
- for PROVIDER_NAME in "${!PROVIDERS[@]}"; do
- readarray -td ${DEL} PROVIDER_ARGS <<<${PROVIDERS[${PROVIDER_NAME}]}
- PURGE_CMD=${PROVIDER_ARGS[3]}
- [ -z "${PURGE_CMD}" ] && PURGE_CMD='test -f "{1}" || exit 43'
- PURGE_CMDS[$PROVIDER_NAME]="${PURGE_CMD%$'\n'}"
- done
- for HIST_LINE in "${HIST_LINES[@]#*' '}"; do
- readarray -td $'\034' HIST_ENTRY <<<${HIST_LINE}
- ENTRY=${HIST_ENTRY[1]}
- readarray -td ' ' FILTER <<<${PURGE_CMDS[$ENTRY]//\{1\}/${HIST_ENTRY[0]}}
- (eval "${FILTER[@]}" 1>/dev/null) # Run filter command discarding output. We only want the exit status
- if [[ $? -ne 43 ]]; then
- echo "1 ${HIST_LINE[@]%$'\n'}" >>"${HIST_FILE}"
- fi
- done
-}
-
-case "$1" in
-describe | describe-desktop | describe-command | entries | list-entries | list-commands | list-autostart | generate-command | autostart | run-desktop | provide | purge)
- "$@"
- exit
- ;;
-esac
-echo "Starting launcher instance with the following providers:" "${!PROVIDERS[@]}" >&3
-
-FZFPIPE=$(mktemp -u)
-mkfifo "$FZFPIPE"
-trap 'rm "$FZFPIPE"' EXIT INT
-
-# Append Launcher History, removing usage count
-(printf '%s' "${HIST_LINES[@]#* }" >>"$FZFPIPE") &
-
-# Iterate over providers and run their list-command
-for PROVIDER_NAME in "${!PROVIDERS[@]}"; do
- (bash -c "${0} provide ${PROVIDER_NAME}" >>"$FZFPIPE") &
-done
-
-readarray -t COMMAND_STR <<<$(
- ${FZF_COMMAND} --ansi +s -x -d '\034' --nth ..3 --with-nth 3 \
- --print-query \
- --preview "$0 describe {2} {1}" \
- --preview-window="${PREVIEW_WINDOW}" \
- --no-multi --cycle \
- --prompt="${GLYPH_PROMPT-# }" \
- --header='' --no-info --margin='1,2' \
- --color='16,gutter:-1' \
- <"$FZFPIPE"
-) || exit 1
-# Get the last line of the fzf output. If there were no matches, it contains the query which we'll treat as a custom command
-# If there were matches, it contains the selected item
-COMMAND_STR=$(printf '%s\n' "${COMMAND_STR[@]: -1}")
-# We still need to format the query to conform to our fallback provider.
-# We check for the presence of field separator character to determine if we're dealing with a custom command
-if [[ $COMMAND_STR != *$'\034'* ]]; then
- COMMAND_STR="${COMMAND_STR}"$'\034user\034'"${COMMAND_STR}"$'\034'
- SKIP_HIST=1 # I chose not to include custom commands in the history. If this is a bad idea, open an issue please
-fi
-
-[ -z "$COMMAND_STR" ] && exit 1
-
-if [[ -n "${HIST_FILE}" && ! "$SKIP_HIST" ]]; then
- # update history
- for i in "${!HIST_LINES[@]}"; do
- if [[ "${HIST_LINES[i]}" == *" $COMMAND_STR"$'\n' ]]; then
- HIST_COUNT=${HIST_LINES[i]%% *}
- HIST_LINES[$i]="$((HIST_COUNT + 1)) $COMMAND_STR"$'\n'
- match=1
- break
- fi
- done
- if ! ((match)); then
- HIST_LINES+=("1 $COMMAND_STR"$'\n')
- fi
-
- printf '%s' "${HIST_LINES[@]}" | sort -nr >"$HIST_FILE"
-fi
-
-# shellcheck disable=SC2086
-readarray -d $'\034' -t PARAMS <<<${COMMAND_STR}
-# shellcheck disable=SC2086
-readarray -d ${DEL} -t PROVIDER_ARGS <<<${PROVIDERS[${PARAMS[1]}]}
-# Substitute {1}, {2} etc with the correct values
-COMMAND=${PROVIDER_ARGS[2]//\{1\}/${PARAMS[0]}}
-COMMAND=${COMMAND//\{2\}/${PARAMS[3]}}
-COMMAND=${COMMAND%%[[:space:]]}
-
-if [ -t 1 ]; then
- echo "Launching command: ${COMMAND}" >&3
- setsid /bin/sh -c "${COMMAND}" >&/dev/null </dev/null &
- sleep 0.01
-else
- echo "${COMMAND}"
-fi