Introduction
One of the oldest problems I run into with Operating Systems in general, the lower layer of my development environment, is saving/managing my workspace.
But what does “workspace saving” mean exactly, what am I trying to achieve here?
I don’t want my OS to be able to restore my windows when I restart, it’s not about that, I can deal with this problem by not rebooting. What I want is the ability to to close apps and programs in order to have a clean workspace that contains only what I need at the moment. I also want to be able to reopen group of windows at will, to me, these group of windows basically mean the same as a projet. That’s right, a group of windows and their states is a project.
So how would you go about achieving this? These are the solutions I was able to find :
Using a (autonomous) solution that means :
- A full-fledged IDE (other than VSCode)
- Paid software at the OS-level (on Windows for the most part)
Scripting
That is what I will be writing about.
How to achieve workspace switching at the os-layer through scripting
The first thing I have to think about is the usage. I want, through a script, command or whatever, be able to open a specific workspace. Something like workspace.sh [project] [feature]
for example.
I have to make a clear distinction between the project and the feature.
The project is in this case would represent the framework, the basis : the i3 layout, the setup scripts and the programs/scripts themselves. The feature could be 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
Let’s say I want to work on a project called foo
, on very this project I work simultaneously on 3 separate features. The first thing would be that I want to have one terminal, right where the project lives. I also want the shell session to start some init. scripts, that could be something like a Python venv for example. If I’m working on a Web application I would also need my browser opened up.
Scripting
Prerequisites
- i3
- i3-resurrect
- dmenu
Scripts
- 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.
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" > "$temp_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
- vscode
- firefox
- 2 xterm windows
[
{
"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 (see https://i3wm.org/docs/layout-saving.html) or i3-ressurect (see https://github.com/JonnyHaystack/i3-resurrect?tab=readme-ov-file#usage)
That’s about it, now you can save and restore your workspaces.
Thanks for reading.