150 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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 "$@"
 | |
| 
 |