Skip to content

DevShedLabs/mac-sethandler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

sethandler

A tiny macOS CLI that sets the default app for a file type — the thing System Settings → General → Login Items & Extensions → Default web browser does, but for any file extension or Uniform Type Identifier (UTI), and scriptable.

Useful when you want .csv (or .log, .env, whatever) to always open in a specific app without hunting through Finder's "Get Info" → "Open with" → "Change All..." dialog by hand.

How it works

macOS decides which app opens a file type via LaunchServices, using a UTI (Uniform Type Identifier) — a reverse-DNS-style string like public.plain-text or com.microsoft.excel.csv — rather than the file extension directly. sethandler resolves the extension you give it to a UTI, then calls the same LaunchServices API (LSSetDefaultRoleHandlerForContentType) that Finder uses, registering your chosen app's bundle ID as the default handler for that type.

This changes a systemwide, persistent setting (stored by LaunchServices, not by this tool) — the same thing Finder's "Change All..." does. It affects every file of that type for your macOS user account, not just files opened through this CLI.

Requirements

  • macOS
  • The target app must already be installed (LaunchServices needs to know its bundle ID exists — see Finding a bundle ID below)

Build

swiftc sethandler.swift -o sethandler

No dependencies beyond the Swift toolchain that ships with Xcode / Xcode Command Line Tools (xcode-select --install if swiftc isn't found).

Usage

sethandler <bundle_id> <extension_or_uti> [more extensions/UTIs...]

Arguments starting with . are treated as file extensions and resolved to a UTI automatically. Anything else is assumed to already be a UTI.

Examples

Make an app the default handler for .csv and .tsv files:

sethandler com.devshed.coder .csv .tsv

✅ Set handler for UTI: public.comma-separated-values-text
✅ Set handler for UTI: public.tab-separated-values-text

Set a default handler across several extensions at once:

sethandler com.microsoft.VSCode .js .ts .tsx .json

Target a UTI directly instead of an extension:

sethandler com.devshed.coder public.comma-separated-values-text

Output

✅ Set handler for UTI: public.comma-separated-values-text
❌ Failed for UTI: .foobar (-54)

A ❌ usually means the extension didn't resolve to a known UTI, or the bundle ID isn't registered with LaunchServices (the app has never been launched, or isn't installed).

Finding a bundle ID

osascript -e 'id of app "Coder"'

or read it directly from the app bundle:

defaults read /Applications/Coder.app/Contents/Info.plist CFBundleIdentifier

Verifying it worked

Right-click any file of that type in Finder → Get Info → "Open with:" should now show your app selected. Alternatively, if you have duti installed (brew install duti):

duti -x csv

Caveats

  • Changes are systemwide for your user account — there's no per-tool or per-folder scoping.
  • Some apps re-register themselves as the default handler for their own file types on launch (common with editors/IDEs). If your setting reverts, that's the other app reclaiming it, not a bug in sethandler — rerun it after opening the other app, or check that app's settings for an "always reopen as default" preference.
  • Requires the target extension to resolve to a UTI that Apple's system or an installed app has already declared. Fully custom/unregistered extensions may need the owning app to declare a UTExportedTypeDeclarations entry in its own Info.plist before sethandler can target them.

License

MIT © DevShed Labs — see LICENSE.

About

Lets you to set almost any file extension on Mac to open in the app of your choice by default.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages