Skip to content

Commit

Permalink
Merge pull request #58 from Biont/#50-purge-history
Browse files Browse the repository at this point in the history
Introduce function to purge invalid entries from history
  • Loading branch information
Biont authored May 19, 2022
2 parents f6efb1a + f8718f9 commit 93b99b2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ For example, if you wish to launch your programs with `swaymsg exec`, you can do
swaymsg exec "$(./sway-launcher-desktop.sh)"
```

### Setup a Terminal command
### Set up a Terminal command
Some of your desktop entries will probably be TUI programs that expect to be launched in a new terminal window. Those entries have the `Terminal=true` flag set and you need to tell the launcher which terminal emulator to use. Pass the `TERMINAL_COMMAND` environment variable with your terminal startup command to the script to use your preferred terminal emulator. The script will default to `$TERMINAL -e`

### Configure application autostart
Expand All @@ -62,6 +62,7 @@ The structure looks like this:
list_cmd=echo -e 'my-custom-entry\034my-provider\034 My custom provider'
preview_cmd=echo -e 'This is the preview of {1}'
launch_cmd=notify-send 'I am now launching {1}'
purge_cmd=command -v '{1}' || exit 43
```

The `list_cmd` generated the list of entries. For each entry, it has to print the following columns, separated by the `\034` field separator character:
Expand All @@ -74,6 +75,8 @@ The `preview_cmd` renders the contents of the `fzf` preview panel. You can use t

The `launch_cmd` is fired when the user has selected one of the provider's entries.

The `purge_cmd` is used as part of the `purge` function. It tests any entry of a provider. If the test exits with `43`, then the entry will be removed from the history file

Note: Pass the environment variable `PROVIDERS_FILE` to read custom providers from another file than the default `providers.conf`.
The path in `PROVIDERS_FILE` can either be absolute or relative to `${HOME}/.config/sway-launcher-desktop/`.

Expand All @@ -87,11 +90,13 @@ So you can simply mimick their behaviour by placing this in your config file:
list_cmd=/path/to/sway-launcher-desktop.sh list-entries
preview_cmd=/path/to/sway-launcher-desktop.sh describe-desktop "{1}"
launch_cmd=/path/to/sway-launcher-desktop.sh run-desktop '{1}' {2}
purge_cmd=test -f '{1}' || exit 43
[command]
list_cmd=/path/to/sway-launcher-desktop.sh list-commands
preview_cmd=/path/to/sway-launcher-desktop.sh describe-command "{1}"
launch_cmd=$TERMINAL_COMMAND {1}
purge_cmd=command -v '{1}' || exit 43
```

## Launcher history file
Expand All @@ -101,6 +106,12 @@ This history is stored in a file in `~/.cache/` (or `$XDG_CACHE_HOME`, if that e
You may change the file path and name by setting the environment variable `HIST_FILE` to the desired path.
Setting the variable to an empty value disables the history feature entirely.

### Housekeeping
After a while, this history might grow and contain some invalid entries due to removed/renamed programs etc.
You can use `./sway-launcher-desktop.sh purge` to identify broken entries and remove them.
Consider adding this command to a cronjob, startup script, or maybe even hook it into your package manager.


## Troubleshooting

Debug information is directed to file descriptor `3` and can be dumped using `./sway-launcher-desktop.sh 3>> ~/sway-launcher-desktop.log`
Expand Down
34 changes: 28 additions & 6 deletions sway-launcher-desktop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,31 @@ if [[ "${PROVIDERS_FILE#/}" == "${PROVIDERS_FILE}" ]]; then
fi

# Provider config entries are separated by the field separator \034 and have the following structure:
# list_cmd,preview_cmd,launch_cmd
# 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)_cmd/{st = index($0,"=");providers[provider][$1] = substr($0,st+1)}
/^(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"] "\x27\n"
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}"
PROVIDERS['command']="${0} list-commands${DEL}${0} describe-command \"{1}\"${DEL}${TERMINAL_COMMAND} {1}"
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
Expand Down Expand Up @@ -250,8 +251,29 @@ function list-autostart() {
${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)
describe | describe-desktop | describe-command | entries | list-entries | list-commands | list-autostart | generate-command | autostart | run-desktop | provide | purge)
"$@"
exit
;;
Expand Down
27 changes: 27 additions & 0 deletions tests/history-purge.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bats

setup() {
export TERMINAL_COMMAND='urxvt -e'
export XDG_DATA_HOME=./data/desktop-files/0
export SLD_DESKTOP_ROOT="$XDG_DATA_HOME/applications/"
export XDG_CACHE_HOME=$BATS_TEST_TMPDIR
export XDG_CONFIG_HOME=./data/autostart-folders/0
export XDG_CONFIG_DIRS=./data/autostart-folders/1
export SLD_HIST_FILE="$BATS_TEST_TMPDIR/sway-launcher-desktop.sh-history.txt"
touch "$SLD_HIST_FILE"

echo "1 ${SLD_DESKTOP_ROOT}firefox.desktopdesktop Firefox" >> "$SLD_HIST_FILE"
echo "1 ${SLD_DESKTOP_ROOT}cjsdalkcnjsaddesktop I wanna be purged" >> "$SLD_HIST_FILE"
echo "1 awkcommand awk" >> "$SLD_HIST_FILE"
echo "1 xksdkasjkslajdslakcommand I wanna be purged" >> "$SLD_HIST_FILE"
echo "1 xksdkasjkslajdslakcommand I wanna be purged too" >> "$SLD_HIST_FILE"
}

@test "Purge command removes invalid entries" {
run ../sway-launcher-desktop.sh purge
readarray HIST_LINES <"$SLD_HIST_FILE"
# cat "$SLD_HIST_FILE"
echo "$output"
[ "$status" -eq 0 ]
[[ ${#HIST_LINES[@]} == 2 ]]
}

0 comments on commit 93b99b2

Please sign in to comment.