Workspaces

Automated Context Switching

Zach Wolpe
3 min readApr 7, 2024

If you’re doing a lot, you’re probably doing a lot of context-switching.

We’re all balancing multiple projects at work, passion projects, personal finance, education etc. Being effective requires effective context switching.

Compartmentalize, remove distractions & focus.

I like to keep my work setup as minimal & clean as possible — minimising the number of tabs and applications open. If my workspace is cluttered, so are my thoughts.

Naturally, a workspace seldom stays minimal.

My simple way to automate context switching with yaml files.

A great context-switching workflow should have a few characteristics:

  • Quick startup: minimise startup time.
  • Minimize cognitive load: outsource memory where possible & trust your system.
  • Able to shut down & switch tasks: Stop leaving every application open for the next day.

I need a way to effectively compartmentalise, focus deeply and easily spin up or shut down a project.

Workspaces

My solution is extremely simple — but proving so powerful it’s worth sharing. YAML!

Let’s call each independent task (a work project, personal finance, education, or any distinct, independent task) a workspace.

  1. Setup YAML config files that store all the metadata for a workspace.
  2. Use Bash or equivalent shell scripts to launch a config file.

That’s it.

Implementation

Step 1. Setting up workspace config files

Anything can be done from the terminal so any application can be added.

Here is my template yaml config file:

firefox :
- https://<URL>.com/

chrome :
- https://<URL>.com/

papers :
- <PATH.pdf>

code :
- ~/Desktop/µπ/workspaces

finder :
- <path to folder>

excel :
- <path to excel file>

Step 2. Writing a .sh script to parse the yaml config

To keep the solution extendable, I chose to execute shell commands from a node.js script.

// modules
const {exec} = require('child_process');
const yaml = require('js-yaml');
const fs = require('fs');

// execute shell, zsh, bash, etc using exec
function execute_shell(shellCommand) {
exec(shellCommand, (error, stdout, stderr) => {
if (error) {
console.error(`Error: ${error.message}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
}

// Generate shell/terminal command to launch applications
function generate_launch_script(launch_type, launch_value) {
let launchTypes = {
'excel' : 'open -a Microsoft\\ Excel',
'chrome' : 'open -a Google\\ Chrome',
'firefox': 'open -a firefox -g',
'papers' : 'open -a Preview.app',
'cursor' : 'cursor -n',
'code' : 'cursor -n',
'finder' : 'open',
'open' : 'open',
}

return launchTypes[launch_type] + ' ' + launch_value;
}

// execute yaml files
function execute_yaml(yaml_file='workspace.yaml') {
try {
const doc = yaml.load(fs.readFileSync(yaml_file, 'utf8'));

for (const key in doc) {
if (doc.hasOwnProperty(key)) {
const value = doc[key];

// loop through each key type
for (const _index in value) {
if (value.hasOwnProperty(_index)) {
const value2 = value[_index];
// generate and exceute the shell command
let _exe_string = generate_launch_script(key, value2);
console.log('>>', _exe_string);
execute_shell(_exe_string);
}
}
}
}

} catch (e) {
console.log(e);
}
}


// ------------------------------------------------------------>>
// RUN -------------------------------------------------------->>

// load yaml file(s)
const args = process.argv.slice(2);
try {
for (const arg of args) {
// console.log('yaml file :', arg);
execute_yaml(arg);
}
} catch (e) {
console.log(e);
}

// RUN -------------------------------------------------------->>
// ------------------------------------------------------------>>

Run the script from the terminal, passing the config files as arguments.

node index.js <config_1.yaml> <config_2.yaml>

Usage

Keep an up-to-date yaml configfile for each distinct task. The yaml keeps links to all the relevant documentation, papers, code repositories, files & whatever else a project requires.

Isolate tasks, spin up & shut down tasks easily & reduce cognitive load.

--

--