The world according to Sven-S. Porst

Mac OS X is a reasonably nice operating system. But it does have its idiosyncrasies. For example, the OS thinks you want to hide the ‘extension’ part of a file name by default. Or it thinks that tiny print dialogues are more useful than large ones. And while the machine will remember your changes to these settings, it does so on a per-application basis in many cases and you will have to adjust things to meet your preference for each application you are using.

Unless you tweak things a little, that is. As most current Mac applications will use the OS’s defaults system for storing preferences, those are easy to adjust. You can view them by opening the ‘com.companyname.applicationame.plist’ files in your Library folder’s Preferences folder. And you can edit those files using the Property List Editor that is a part of Apple’s developer tools.

But there’s another, less pretty, and more powerful way of editing preferences. This requires you to use the Terminal and use the defaults command. The defaults command can do a number of things and the most useful ones are reading, writing and deleting settings. The command itself usually takes a form like this:

defaults verbapplication key [value]

where the components work as follows.

verb

The most common options for the verb are read, write and delete. Each of them does what its name suggests.

application

This is also known as the domain of the defaults. There are various ways to specify it. The most common one is using the bundle identifier of the application whose defaults should be changed. This also happens to be the name (without the final .plist) of the application’s preference file.

Another option would be to use the -app specifier and just give the name of the application whose preferences should be edited. This can be handy, but it has two problems: First, that application names are more likely to contain spaces than bundle identifiers (which can contain spaces but in practice rarely do); and thus application names can be hard to enter in the Terminal. Second, that application names can be localised and as a consequence the name the application shows you isn’t necessarily the same name the system uses for the application. This is particularly problematic if you are not using the system in English.

Yet another option is to explicitly give the path of the preference file you want to edit without the trainling ‘.plist’ part of the name. This can be handy if you want to edit a copy of a preference file that is not currently in the Preferences folder.

In short, to access the current preferences of your Font Book application, say, you can use either of these statements:

com.apple.fontbook

-app “Font Book”

~/Library/Preferences/com.apple.fontbook

While what we have seen so far is great for very specific access to preferences, we still have a trump up our sleeve. And that’s the option to apply a preference globally. Which means that any application which does not have the preference set will get the globally set value as a default. To set such a global preference use the NSGlobalDomain specifier.

These global settings are stored in the file .GlobalPreferences.plist inside the Preferences folder of your Library folder. For reasons I do not understand, Apple chose to make that file invisible, although it contains some of your data.

key

Each preference that is stored has a name, known as the key. You will have to know the correct key to read and write data successfully. Typically the key describes the preference it represents. E.g.: NSFontPanelPreviewHeight.

value

If you want to write data to the preferences, you have to specify the data’s type and the data itself. The data’s type has to be specified using a leading -. Common data types and usages are -string "Hello World", -integer 27, -boolean YES and -float 1.618. It is usually a good idea to write data with the correct type as some applications don’t handle potential ambiguity well. If you don’t specify the data’s type, -string will be implicitly used.

While these are the most common options, plenty of advanced and hard-to-type options are possible as well. You can also add or add entrys to arrays and dictionaries as well as having the ability to provide a ready-made property list for insertion into the preferences.

Once you know this (or have read the manual page of the defaults command line tool), all that remains to do is digging through your existing preferences and figuring out which of these are likely to be settings that stem from system-wide frameworks and can be used by many applications. The next step would be to isolate those keys and their preferred values and then using the defaults tool to write them to NSGlobalDomain so all applications which haven’t written their own preference for that setting yet will use your preferred value.

A final thing worth saying is that it is advisable to only use the defaults command for manipulating an application’s settings when the application in question isn’t running. Doing otherwise will make it quite likely that the application overwrites your changes later on. (While the defaults system is good in the sense that it’s quite powerful and simple, it’s not good enough to keep applications informed about external changes. A shame, but we’ll have to live with it.)

So now we just need to find out a few keys that applications like to use. I’ll start you off with a small list here:

NSColorPanelMode (string)

A number identifying the colour picker that the colour picker displays when opening.

NSColorPanelVisibleSwatchRows (integer)

The number of swatch rows at the bottom of the colour picker.

NSColorPickerPageableNameListDefaults (string)

The name of the list of colours used in the third colour picker; preceded by a 1.

NSColorPickerSlidersDefaults (string)

Number specifying the type of slider colour picker you get to see by default.

NSColorPickerUserDefaults (string)

Name of the image in Library/Colors/ which is displayed by default in the image palette (4th) colour picker.

NSToolbar Configuration com.apple.NSColorPanel (dictionary)

This seems to have a single entry called ‘TB Is Shown’ (integer).

NSWindow Frame NSColorPanel (string)

String of 8 space delimited integers indicating the size and position of the colour panel.

NSNavBrowserPreferedColumnContentWidth (float)

Column width used by the navigation sheet in column mode. You can set this manually by holding the option key while resizing a column (and thus all columns).

NSNavLastRootDirectory (string)

Previously used ‘root’ folder of the open/save sheet.

NSNavLastUserSetHideExtensionButtonState (boolean)

Whether or not file name extensions are hidden in the save sheet.

NSNavPanelExpandedSizeForOpenMode (string)

Pair of numbers à la {700, 300} giving the size of the expanded open sheet.

The width of the open/save sheet’s sidebar. Setting it to 0.0 doesn’t work, unfortunately.

NavPanelFileListModeForOpenMode (integer)

Number giving the mode of the open/save sheet’s panel. 1 is column mode, 2 is list mode, 3 is icon mode. This is stored in the global preferences by default.

NSFontPanelAttributes (string)

Pair of integers separated by ‘, ‘. The first indicates the visibility of the style pane in the font panel. The second one isn’t clear to me; I’ve seen it have values 0 and 13.

NSFontPanelPreviewHeight (float)

The height of the font panel’s preview section.

NSWindow Frame com.apple.typographypanelFONTNAME (string)

Location and size of the typography panel for the font FONTNAME given as a space separated string of 8 integers.

NSWindow Frame NSFontPanel (string)

Location and size of the font panel given as a space separated string of 8 integers.

PMPrintingExpandedStateForPrint (boolean)

Whether or not the print sheet appears in its large form in X.5.

And that is that.

Once you are a X.5 user and have gotten into the spirit of using the defaults command, you may also want to liberate your X.5 Dock of its fake perspective, wavy background, reflections and ugly shadows using

defaults write com.apple.dock no-glass -boolean YES

After which you should kill the Dock using Activity Monitor or killall Dock as you’re using a Terminal window anyway. Bliss.