There are a lot of things you can do with the OS X defaults command. This post isn’t intended to detail them, but a little searching can turn up a lot of neat tricks.

Basically, defaults reads and writes system and application preferences from the command line. Using it requires knowing the “domain” of the preference file (e.g. “com.apple.Safari”), or using the “-app” parameter. I generally stick with the domain, especially when I’m writing or deleting preferences, just to make sure I’m doing it where I think I’m doing it.

This code–when added to your ~/.bash_profile–will allow tab completion of domain names. You can type defaults read com.brett<tab> to see any preference files in a domain starting with “com.brett” (which would bring up Marked’s preferences). It’s not overly complex and doesn’t do any handling of the command type (read, write, delete, etc.), but it’s handy if you toy with preferences much:

## Bash completion for `defaults` domains
## e.g. `defaults read com.apple[TAB]`

_complete_domain ()
{
	local cur
	local LC_ALL='C'
	cur=${COMP_WORDS[COMP_CWORD]}
	cur=${cur//\./\\\.} # escape dots for grep
	local IFS="
"
	COMPREPLY=( $(defaults domains | tr ',' '\n' | sed 's/^[ \t]*//;s/[ \t]*$//'|grep -i "^$cur") )
	return 0
}

complete -o bashdefault -o default -o nospace -F _complete_domain defaults 2>/dev/null || complete -o default -o nospace -F _complete_domain defaults

If you want to complete on the “app” parameter, you could add a check for “-app” as the previous item in the sequence and include something along the lines of the application completions I posted a while back.

You may commence deriding me for not using zsh now.

Also, shortly after figuring this out I found the defaults completion plugin in bash-it. It’s better.