bin/i3-settree

150 lines
3.2 KiB
Bash
Executable File

#! /usr/bin/env bash
#
# i3-settree
# Restore an i3 layout using a list of saved trees
# Copyright (C) 2018 salt <salt@lap-th-e560-0>
#
# Distributed under terms of the MIT license.
#
# Pedantry
# shellcheck disable=1117
# Globals
name="$(basename -- "$0")"
treespath="${XDG_CONFIG_DIR:-$HOME/.config}/i3/trees"
# Helpers
log() {
[ -z "$1" ] && return 1
printf "%s: %s\n" \
"$name" \
"$1"
return 0
}
prepare_input() {
options="Save"
for file in "$treespath"/*; do
if ! [ -r "$file" ]; then
# Cannot read the file; skip it
continue
fi
if ! [[ "$file" = *".json" ]]; then
# File is not a json structure; skip it
continue
fi
if [[ "$file" = "$treespath/$name-layout-"* ]]; then
# File is an unmodified saved tree; skip it
continue
fi
if [ "$(basename -s ".json" -- "$file")" = "Save" ]; then
# File conflicts with reserved word "Save"; skip it
continue
fi
if ! [ -f "$file" ]; then
# Glob failed and no files exist; error
return 1
fi
options="$options
$(basename -s ".json" -- "$file")"
done
printf "%s" \
"$options"
return 0
}
# Steps
step_validate_deps() {
# Ensure we have all the programs we need to do this
for dep in mkdir date rofi i3-msg notify-send; do
if ! command -v "$dep" > /dev/null 2>&1; then
log "Could not validate dependency \"$dep\""
return 1
fi
done
return 0
}
step_validate_files() {
# Ensure we actually have tree files to set
if ! [ -d "$treespath" ]; then
mkdir -p "$treespath" > /dev/null 2>&1
if [ -d "$treespath" ]; then
log "Trees path was created: $treespath"
log "Put your modified i3-save-tree trees there"
return 1
else
log "Failed to create trees path: $treespath"
log "Are permissions set correctly? Is the filesystem mounted read-write?"
return 1
fi
fi
return 0
}
step_get_input() {
# Get the user input, store it in $choice
choice="$(rofi -dmenu -p "i3 tree" <<< "$(prepare_input)")"
choicefile="$treespath/$choice.json"
if [ -z "$choice" ]; then
log "User cancelled the operation"
return 1
else
log "Choice: $choice"
log "Choicefile: $choicefile"
fi
}
step_act() {
# Do the do
case "$choice" in
Save)
file="$treespath/$name-layout-$(date +%s%N).json"
if command -v kdialog > /dev/null 2>&1; then
# Handle with kdialog
newpath="$(kdialog --getsavefilename "$file" "i3 Layout Trees (*.json)")"
# Shellcheck you're a dumb
# We need that output, man
#shellcheck disable=2181
if ! [ $? -eq 0 ]; then
log "User canceled the save operation"
return 61
else
file="$newpath"
fi
else
# Basic handling
if [ -f "$file" ]; then
log "Not clobbering existing layout file: $file"
return 60
fi
fi
i3-save-tree > "$file"
notify-send \
-u normal \
-a "$name" \
-t 3000 \
-i dialog-information \
"Saved Layout" \
"Saved current i3 tree to:\n$file"
;;
*)
i3-msg "append_layout $choicefile" > /dev/null 2>&1
if [ -r "$choicefile.rc" ]; then
log "Running $choicefile.rc"
"$choicefile".rc
fi
return $!
;;
esac
}
# Main
main() {
step_validate_deps || return 50
step_validate_files || return 51
step_get_input || return 52
step_act
return $!
}
main "$@"