One of the oldest and unresolved issue I often run into with Operating Systems
in general, is saving and restoring the state of my work.
But what does "saving" mean exactly?
It's not about restoring windows and programs it is about the ability to to
defining dynamic workflows that can be parameterized easily. To be able to open
group of windows and programs at will, to me, these group of windows often
mount to a project. That's right, a group of windows and their states is a
project.
Achieving decent workspace state management through shell scripting
First thing to think about is the usage, it is often overlooked but it's the
most important thing, it should be easy to achieve saving and restoring.
Something like workspace.sh [project] [feature] for example.
A clear distinction between projects features should be made though.
The project is in this case would represent the framework, the basis : the i3 la
yout, the setup scripts and the programs/scripts themselves. The feature could b
e a specific branch in a git repository for example, or it could be as simple as
a parameter that you give to your programs/scripts.
Use case
One might want to start working on a project called foo, on very this
project there is need to work simultaneously on 3 different features.
One terminal that cd into the project directly, the shell session should be able
to source scripts for initiatilization purposes that could be something like a
Python venv for example.
Scripting
Prerequisites
- i3wm
- i3-resurrect
- dmenu
Goals
- Prompt the user for the project it wants to work on.
- Run the main.sh script for the selected project
The script might prompt the user for additional information such as the
feature name etc..
workspace.sh
#!/usr/bin/env sh
projects_path="$HOME/.i3/i3-resurrect/projects"
project_name=$(ls "$projects_path" | dmenu -p project -i | xargs)
if [[ "$project_name" == "" ]]; then
echo "Invalid project"
exit 1
fi
project_path="$projects_path/$project_name"
temp_folder="$(mktemp -d)"
workspace_number=$(i3-msg -t get_workspaces | jq '.[] | select(.focused==true)
.name' | cut -d"\"" -f2)
$project_path/main.sh "$project_path" "$temp_folder" "$workspace_number" && pipx
run i3-resurrect restore -d "$temp_folder" -p current
rm -rf "$temp_folder"
main.sh
#!/usr/bin/env sh
project_path="$1"
temp_folder="$2"
workspace_number="$3"
feature_name=$(ls -t /my_project_path/.features | dmenu -p Feature -i | xargs)
if [[ "$feature_name" == "" ]]; then
echo "Invalid feature_name"
exit 1
fi
mkdir $temp_folder/profiles
sed -e "s/%{feature_name}/$feature_name/g" "$project_path/programs.json" > "$tem
p_folder/profiles/current_programs.json" && \
sed -e "s/%{feature_name}/$feature_name/g" "$project_path/layout.json" > "$temp_
folder/profiles/current_layout.json"
programs.json
[
{
"command": [
"/opt/visual-studio-code/code",
"/my_project_path/.features/%{feature_name}/%{feature_name}.code-workspace
"
],
"working_directory": "/my_project_path/.features/%{feature_name}"
},
{
"command": [
"/usr/lib/firefox/firefox"
],
"working_directory": "$HOME"
},
{
"command": [
"/usr/bin/xterm",
"-class",
"UXTerm",
"-u8",
"-bw",
"0",
"-e",
"bash --login -i <<< 'source /home/user/.venvs/project/%{feature_name}/bin
/activate; exec </dev/tty'"
],
"working_directory": "$HOME"
},
{
"command": [
"/usr/bin/xterm",
"-class",
"UXTerm",
"-u8",
"-bw",
"0",
"-e",
"bash --login -i <<< 'source /home/user/.venvs/project/%{feature_name}/bin
/activate; exec </dev/tty'"
],
"working_directory": "$HOME"
}
]
layout.json
After setting up your layout manually you can save it using i3.
Refences: