Created
January 30, 2021 00:31
-
-
Save mattdeboard/753662934944d6454a6bbbd7b76045cd to your computer and use it in GitHub Desktop.
Modify workspace settings dynamically by passing a custom settings fragment when starting VS Code at the command line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# VS Code does not have workspace settings per user. Or user settings | |
# per workspace. Either way, I made this script because when I open up | |
# my Rails repo, I want it to have a different visual theme than my | |
# TypeScript repo. | |
# This script creates a workspace file dynamically with modifications | |
# specified in `custom` variable. When the VS Code process exits, it | |
# cleans up the temporary file. | |
# Usage: ./dynamic_workspace.sh <parent workspace file | |
# to mod> <JSON settings string OR /path/to/settings_changes.json> | |
# Example usage: | |
# Say we want to set a custom theme for ourselves in only this workspace. | |
# Passing a string: | |
# ./dynamic_workspace.sh myProject.code-workspace '{"settings": {"workbench.colorTheme": "Monokai Dimmed"}}' | |
# Passing a file: | |
# ./dynamic_workspace.sh myProject.code-workspace custom-settings.json | |
# This is a `jq` function to deeply merge two objects | |
read -r -d '' deepmerge <<-"EOM" | |
def deepmerge(a;b): | |
reduce b[] as $item (a; | |
reduce ($item | keys_unsorted[]) as $key (.; | |
$item[$key] as $val | ($val | type) as $type | .[$key] = if ($type == "object") then | |
deepmerge({}; [if .[$key] == null then {} else .[$key] end, $val]) | |
elif ($type == "array") then | |
(.[$key] + $val | unique) | |
else | |
$val | |
end) | |
); | |
deepmerge({}; .) | |
EOM | |
# Create a workspace file in the current directory | |
tmppath=$(pwd)/dyn.code-workspace | |
# Erase the temp file if it already exists for some reason | |
if [ -e $tmppath ]; then rm $tmppath; fi | |
tmpworkspace=$(mktemp $tmppath) | |
# Generate the new workspace file, with the settings modifications | |
# data. It will merge the settings mod with the content of the settings | |
# file that's passed as the first argument to the script. | |
if [[ -e $2 ]]; then | |
jq -sM "$deepmerge" "$1" "$2" >$tmpworkspace | |
else | |
jq -sM "$deepmerge" "$1" <(echo "$2") >$tmpworkspace | |
fi | |
# Run the VS Code process, and tell it to wait. | |
code -w "$tmpworkspace" & | |
# Grab the PID of the VS Code process we just started | |
PID=$! | |
# While the temporary file still exists, check if the VS Code process is | |
# still running. If it's not, remove the temp file. | |
while [[ -e $tmpworkspace ]]; do | |
if [[ $(ps -p $PID | wc -l) -eq 1 ]]; then | |
rm $tmpworkspace | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment