A Bash Script for Default File Associations


As a software engineer, juggling files in dozens of formats—from source code to config and markup—is a daily reality. Opening these files in the right editor is crucial for productivity, yet macOS doesn't always make it easy to set your preferred editor for every relevant extension. Recently, I ran into this challenge: I wanted all my engineering-related files to open in Zed, my favorite lightweight editor. Here’s how I solved that problem quickly using a Bash script.
The Problem
Before my solution, every time I encountered a new file type—say, a .tsx
React file, a .dockerignore
config, or even obscure extensions like .erl
for Erlang—I had to manually set the default app for that format. It was slow and tedious, and often required digging into system settings or context menus. As my project stack grew to include new languages and frameworks, this became unmanageable.
The Solution
I decided to automate the entire process using a purpose-built Bash script and the macOS tool duti
. duti
allows command-line management of file associations, making it perfect for bulk operations.
Building the Script
The heart of the solution lay in combining two ideas:
A comprehensive list of extensions relevant to software engineering (covering everything from
.c
for C,.py
for Python, to.yaml
for config files).Automation with Bash, looping through the list and setting Zed as the default app for each file type.
Here’s the script I used:
#!/bin/bash
# My Editor Id, you can get your desired editor id by running `osascript -e 'id of app "Visual Studio Code"'`
ZED_ID="dev.zed.Zed"
EXTENSIONS=(
"c" "cpp" "cc" "h" "hpp"
"java" "class"
"js" "jsx" "ts" "tsx"
"py" "pyw"
"rb"
"sh" "bash"
"bat" "cmd"
"go"
"php"
"swift"
"cs"
"pl" "pm"
"lua"
"kt" "kts"
"scala"
"rs"
"r"
"dart"
# skip this cause it should open in browser by default
# "html" "htm" "xhtml"
"xml" "json" "yml" "yaml"
"css" "scss" "sass" "less"
"md"
"sql"
"asm" "s"
"m" "mm"
"ex" "exs"
"erl"
"hs"
"lisp" "cl"
"groovy"
"fs" "fsi" "fsx"
"vue"
"coffee"
"ini" "conf" "cfg" "toml" "env"
"dockerfile" "dockerignore"
"gemspec" "gradle" "pom.xml"
"lock" "package" "yarn.lock"
"pbxproj" "xcworkspace" "xcodeproj"
"sln" "csproj" "vbproj"
"make" "mak" "mk"
"gitignore" "gitattributes"
"proto"
"f90" "f" "for"
"pas"
"adb" "ads"
"matlab"
"ps1"
"hbs"
"jade" "pug"
"ejs"
"tpl"
)
for ext in "${EXTENSIONS[@]}"; do
duti -s "$ZED_ID" .$ext all
done
echo "All specified code file extensions are now set to open with Zed."
How It Worked
Single command execution: Instead of manually changing settings for each extension, I saved this script as
associate_
zed.sh
, made it executable, and ran it once.Instant results: Every file with an extension in the list now opens seamlessly in Zed across Finder and other apps.
Easy maintenance: If I start working in a new language, I just add its extension to the
EXTENSIONS
array and rerun the script.
Impact on My Workflow
No more interruptions: I never have to deal with files opening in the wrong editor or having to right-click and choose "Open With..." ever again.
Onboarding made easy: Sharing the script with teammates lets everyone standardize their dev environment with a single command.
Adaptable: If I ever switch to a different editor, I only need to change the
ZED_ID
variable.
Conclusion
Automating file extension associations rescued me from a frustrating, repetitive setup process and turned onboarding into a breeze. For anyone who spends their day immersed in code across a spectrum of formats, this simple Bash script is a game-changer.
The time saved lets me focus on actual engineering work—not wrangling file associations. If you’re using Zed (or any editor), I highly recommend this approach to dramatically simplify your dev environment setup.
You can find my code in this gist also.
Subscribe to my newsletter
Read articles from Saiful Alam directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Saiful Alam
Saiful Alam
An Expert software engineer in Laravel and React. Creates robust backends and seamless user interfaces. Committed to clean code and efficient project delivery, In-demand for delivering excellent user experiences.