cutler 0.4.0

Powerful, declarative settings management for your Mac, with speed.
docs.rs failed to build cutler-0.4.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: cutler-0.1.5

cutler

Powerful, declarative settings management for your Mac, with speed.

Release Builds Rust Tests

[!WARNING] Although cutler is solid enough for daily-driving now, expect breaking changes before the v1 release.

[!IMPORTANT] The prebuilt binaries are compiled and shipped from macOS 14 on arm64. Intel Macs will require a manual compilation of the project.

Table of Contents

Overview

If you use macOS, you might be familiar with changing settings using the built-in System Settings app or the defaults command in the terminal. Both methods can be tedious—and the terminal option usually involves manual tweaks. That’s where cutler makes things simpler!

cutler is a straightforward command-line tool that lets you specify your macOS preferences in an easy-to-read TOML file. It wraps the defaults command so you can quickly apply or undo settings when needed. In addition to managing macOS defaults, cutler now supports executing external commands so that you don't have to write another shell script to automate things.

Check out the Usage section for more details.

Installation

brew install hitblast/tap/cutler

Besides using Homebrew as shown above, you can install the project in a couple of other ways:

  • Using cargo:
cargo install cutler
  • Using mise:
# NOTE: This will compile the binary manually for your system.
mise use -g cargo:cutler

[!TIP] If none of these installation methods work for you, try checking out the latest GitHub release. You can also use the periodic release workflows, which have a retention period of 90 days.

Usage

cutler looks for your configuration in a file named config.toml, checking the following locations in order:

  • $XDG_CONFIG_HOME/cutler/config.toml
  • ~/.config/cutler/config.toml
  • ~/.config/cutler.toml
  • config.toml in the current directory (fallback)

It respects your $XDG_CONFIG_HOME setting, so you don't have to worry about path issues. Just place your config.toml file in one of these locations and you're set.

To easily get started, simply type the following command to generate a prebuilt configuration:

cutler init

Anatomy

Here’s a basic example of a TOML configuration for cutler:

[dock]
tilesize = 46

[menuextra.clock]
FlashDateSeparators = true

For more details on the different defaults domains and available values on macOS, take a look at the Resources section. The TOML above translates into these commands:

defaults write com.apple.dock "tilesize" -int "46"
defaults write com.apple.menuextra.clock "FlashDateSeparators"

You can also configure settings for NSGlobalDomain like this:

[NSGlobalDomain]
ApplePressAndHoldEnabled = true

[NSGlobalDomain.com.apple.mouse]
linear = true

cutler converts the above TOML into:

defaults write NSGlobalDomain "ApplePressAndHoldEnabled" -bool true
defaults write NSGlobalDomain com.apple.mouse.linear -bool true

[!WARNING] Currently, cutler does not verify the integrity of domains or keys under NSGlobalDomain. Please review these settings manually before applying any changes.

Defaults and External Commands

Beyond managing macOS defaults, cutler now supports an [external] section that allows you to run any external command after applying the defaults. This is particularly useful when you want to trigger additional scripts or commands as part of your configuration. For example:

# Define reusable variables here:
[external.variables]
common_args = ["Hello", "World"]

[external]
  [[external.command]]
  cmd = "echo"
  # If you reference a variable (for example, $common_args) and it isn’t defined
  # in the [external.variables] section, cutler will fall back and try to resolve it
  # from the environment (e.g. $PATH).
  args = ["$common_args", "$PATH"]
  sudo = false

This roughly translates to:

echo Hello World /usr/local/bin:/usr/bin:...

If you don't want to run into additional giberish, the external commands only require the cmd field to run, so it can be as simple as:

[external]
  [[external.command]]
  cmd = "echo"

Applying Changes and Status Review

Once your configuration file is ready (including your defaults and external commands), apply your settings by running:

cutler apply

After cutler updates the defaults, it will also:

  1. Execute any external commands defined in the [external] section.
  2. Restart necessary system services on your Mac so that the new settings take effect.
  3. Create a snapshot file named .cutler_snapshot in your home directory. This file records your configuration state and helps with reverting later on.

To verify current settings against your configuration, run:

cutler status

To revert modifications, run:

cutler unapply

Now, when it comes to managing the configuration file itself, there is a config command which has two other subcommands:

# Shows the contents of the configuration file.
cutler config show

# Unapplies and deletes the configuration file.
cutler config delete

You can add --verbose for more detail on what happens behind the scenes. For additional information about all available commands, run:

cutler help

Shell Completions

Cutler currently supports automatically generating shell completions for Bash and Zsh, making it easier to use the project for power users.

Installing Shell Completions

Generate completions with:

# For bash users
cutler completion bash

# For zsh users
cutler completion zsh

# Specify a different output directory:
cutler completion bash --dir ~/.local/share/bash-completion/completions
cutler completion zsh --dir ~/.zfunc

Bash Completion Setup

Assuming you've generated the completion script using the command given above, you can source it like this for temporary use:

source ./cutler.bash

For permanent use, add to your ~/.bashrc:

source /path/to/cutler.bash > ~/.bashrc

Zsh Completion Setup

  1. Make sure you have a directory for custom completions:
mkdir -p ~/.zfunc
  1. Assuming you've already generated the configuration file from the command given above, you can copy the completion file:
cp _cutler ~/.zfunc/
  1. Then, add to your ~/.zshrc:
fpath=(~/.zfunc $fpath)
autoload -U compinit && compinit
  1. Restart your shell or run:
source ~/.zshrc

Resources

Finding the ideal set of macOS defaults can be challenging. Visit the macOS defaults website for a comprehensive list of available settings.

Sample configuration files are preincluded with this repository for you to have a look at and get hold of the tool quickly:

Contributing

This is a personal project aimed at making the task of setting up a Mac more straightforward. Contributions are always welcome! Feel free to help out by creating a pull request or submitting an issue.

License

This project is licensed under the MIT License.