#! /usr/bin/env bash # # i3-settree # Restore an i3 layout using a list of saved trees # Copyright (C) 2018 salt # # 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 "$@"