TunaTuna
ProDocs
ProDocs Download βeta

Configuration

Tuna keeps the configuration you may want to sync or edit in a TOML file named config.toml. You can manage Tuna entirely through Settings, but the file is useful for keeping the same setup on multiple Macs, putting your preferences in a dotfiles repository, or making a precise change by hand.

Where The File Lives

By default, Tuna uses:

~/Library/Application Support/Tuna/config.toml

Open Settings -> General -> Configuration to reveal the file, reload it, or choose a custom folder. A custom folder is useful for iCloud Drive, Dropbox, Syncthing, or a dotfiles checkout. Tuna always names the file config.toml inside the selected folder.

Tuna does not create the file on an untouched installation. The configuration is sparse: it only contains values that differ from Tuna’s built-in defaults, plus custom data such as hotkeys and Smart Links. Returning a setting to its default removes that override. If every override is removed, Tuna removes the empty file too.

How Saving And Reloading Work

Tuna loads config.toml at launch and writes changes made in Settings back to it automatically. Writes are atomic and slightly delayed so a series of quick changes produces one update.

When editing the file yourself:

  1. Make a backup or commit your current file.
  2. Save your changes.
  3. Choose Reload from Disk in Settings, run tuna config reload, or open tuna://config/reload.

Tuna validates the whole file before applying it. Unknown sections, unknown fields, invalid built-in values, duplicate IDs, and malformed item or action references make the reload fail rather than silently applying a partial configuration. Tuna leaves an unreadable file untouched and shows the error in Settings -> Logs.

Older configuration may need migration before Tuna can load it. If an entry refers to something that can no longer be restored, Tuna imports the remaining configuration and shows a Config Import Notice in Settings. The notice stays available until you acknowledge it, and Settings -> Logs contains the dropped-entry details.

If the file changes outside Tuna while Tuna also has unsaved changes, Tuna reports a conflict. You can reload the file to keep the external version or explicitly overwrite it with Tuna’s current state. Tuna will not silently choose one version.

A Small Example

You do not need to copy a complete template. Include only the values you want to override:

[settings]
screenPreference = "activeWindow"
appPresentationMode = "both"
backspaceBehavior = "deleteCharacters"
resultListNavigationBindings = "vimStyle"
typingTimeoutDuration = 1.5

The names and string values are case-sensitive.

Built-in Setting Values

All keys below live under [settings]. Booleans use true or false, strings use quotes, and numbers do not. The default shown is what Tuna uses when the key is absent.

Window And Results

Key Default Accepted values
themeIdentifier Default theme A theme’s identifier. The default theme is omitted from the file.
resultsRevealDelay 2.0 Seconds as a number.
showResultsImmediatelyOnActivation false true, false
mainWindowAnimationsEnabled true true, false
screenPreference "mouse" "mouse", "primary", "activeWindow"
appPresentationMode "statusBar" "statusBar", "dock", "both", "never"

Built-in theme identifiers are:

  • Default: com.brnbw.tuna.themes.default
  • Logic Board: com.brnbw.tuna.themes.logicboard
  • Normie Bar: com.brnbw.tuna.themes.NormieBar
  • Notch: com.brnbw.tuna.themes.Notch
  • Nuggets: com.brnbw.tuna.themes.nuggets

Search And Keyboard Behavior

Key Default Accepted values
typingTimeoutDuration 2.5 Seconds from 0.2 through 3.0; 3.0 means Off. Lower values are raised to 0.2.
backspaceBehavior "clearSearch" "clearSearch", "deleteCharacters"
spacebarBehavior "normal" "normal", "switchToTextMode", "jumpToTargetPane"
resultListNavigationBindings "arrowKeysOnly" "arrowKeysOnly", "macOSStandard", "vimStyle"
switchToTextModeWhenNoResults false true, false
holdToExecuteEnabled false true, false
pureStringRankingEnabled false true, false
preferStringPasteboardContent false true, false

Activation

The four trigger-type keys accept the same values:

  • fuzzyModeTriggerType
  • textModeTriggerType
  • comboModeTriggerType
  • talkModeTriggerType

Their default is "shortcut". Accepted values are "disabled", "shortcut", "doublePress", and "modifier".

The four double-press keys also share one value set:

  • activationDoublePressTrigger
  • textModeDoublePressTrigger
  • comboModeDoublePressTrigger
  • talkModeDoublePressTrigger

Their default is "disabled". Accepted values are "disabled", "leftCommand", "rightCommand", "leftOption", and "rightOption".

comboModeModifierTrigger and talkModeModifierTrigger default to "disabled". They accept "disabled", "rightCommand", "leftCommand", "rightOption", "leftOption", "rightCommandOption", "leftCommandOption", and "hyper".

These fields choose how a mode is triggered; the actual app hotkey chords are stored in the [hotkeys] section described below.

Built-in Hyper

Key Default Accepted values
physicalHyperKeySource "off" "off", "capsLock", "rightOption", "rightCommand"
physicalHyperKeyQuickPressBehavior "doesNothing" "doesNothing", "togglesCapsLock", "triggersEscape"
shortcutDisplayUsesHyperSymbol true true, false

The quick-press behavior matters when a physical key is being used as Hyper. Right Option and Right Command preserve their normal quick press; Caps Lock can toggle Caps Lock or act as Escape.

Clipboard And Shelf

Key Default Accepted values
clipboardHistoryEnabled true true, false
clipboardHistoryRetention "oneMonth" "oneDay", "sevenDays", "oneMonth", "threeMonths", "sixMonths", "oneYear", "unlimited"
clipboardIgnoredBundleIdentifiers Password-manager defaults An array of application bundle identifier strings. Supplying it replaces the entire list.
showTasksIndicatorWhenHidden true true, false
shelfWindowAlwaysOnTop true true, false
shelfAutoCloseWhenTasksComplete false true, false
shelfCatalogEnabled true true, false

The built-in clipboard ignore list contains:

clipboardIgnoredBundleIdentifiers = [
  "com.1password.1password",
  "com.agilebits.onepassword7",
  "com.apple.Passwords",
  "com.apple.keychainaccess",
  "com.bitwarden.desktop",
  "com.dashlane.Dashlane",
  "com.keepersecurity.KeeperPasswordManager",
  "com.nordpass.NordPass",
]

Clipboard retention beyond one month requires Tuna Pro.

Catalogs And Diagnostics

Key Default Accepted values
advancedCatalogsEnabled true true, false
textActionsFileExtension "txt" A file extension without the leading dot.
proxyDiagnosticsLoggingEnabled false true, false
devicesDiagnosticsLoggingEnabled false true, false

Older files may contain catalogPeriodicRescanEnabled and catalogPeriodicRescanIntervalMinutes. Tuna accepts these keys for compatibility but ignores them; catalogs now update at startup, on demand, or in response to filesystem changes.

Combo Mode

Key Default Accepted values
comboModeCheatsheetBehavior "delay" "never", "delay", "always"
comboModeCheatsheetDelayMS 2000 Milliseconds as a non-negative integer.
comboModeCheatsheetExpandGroups false true, false
comboModeCheatsheetShowIcons true true, false
comboModeCheatsheetShowDetails true true, false
comboModeModifierConfiguration "controlGroupOptionSticky" "controlGroupOptionSticky", "optionGroupControlSticky"
comboModeKeyboardLayoutBehavior "respectCurrentLayout" "respectCurrentLayout", "forceUS"
comboModeBackspaceBehavior "resetToRoot" "resetToRoot", "stepBack"
comboModeThemeStyle "inherit" "inherit", "breadcrumb", "cheatsheet", "none"

Talk Mode Presentation

Key Default Accepted values
dictationActivationMode "pushToTalk" "pushToTalk", "toggle", "hybrid"
dictationWindowPosition "bottomCenter" "center", "topLeft", "topCenter", "topRight", "bottomLeft", "bottomCenter", "bottomRight"

Older files may contain dictationPresentationStyle. Tuna accepts but ignores this retired key; Talk Mode now always uses its dedicated floating window.

Other Configuration Sections

Tuna writes these top-level sections when they contain non-default or user-created data:

Section What it contains
[catalogs] Per-catalog browse sort, global-search scope, and search-priority overrides. Priorities are -2, -1, 1, or 2; 0 means no override and is omitted.
[catalogConfiguration] Folder depth overrides, custom folders, script directories, and custom items. Custom item kinds are "url", "path", and "text"; custom-folder entry types are "directory" and "file"; filters are "folders" and "extensions". Paths may use ~.
[Catalogsettings](/docs/catalogsettings) String values declared by built-in or installed extensions. Available keys and values depend on the extension. A present list replaces all stored extension settings; omitting the section leaves them untouched.
[hotkeys] Tuna’s five app hotkeys—activate, Text Mode, Combo Mode, stage Finder selection, and dictation—plus custom command hotkeys.
[comboMode] The complete non-default Combo Mode binding tree.
[smartLinks] The complete Smart Links list when it differs from the built-in list.
[aliases] Explicit aliases and their ordered exact-result targets.
[actionPreferences] Sparse action ordering and default-action overrides.

These structures use canonical catalog references. The easiest and safest way to author them is to make the change in Tuna, then inspect the TOML Tuna writes. Smart Links are identified by their unique name — commands refer to them as tuna.smart-links/<name> — and Combo bindings carry no persisted identity at all. Custom hotkeys have a UUID id, which you may omit when authoring by hand: Tuna assigns one on load and writes it back on the next save.

App hotkeys, custom hotkeys, aliases, and action-preference overrides have no built-in entries. The built-in Combo tree opens Safari (s), Terminal (t), Finder (f), Messages (m), Notes (n), Downloads (d), and the home folder (h). Tuna omits that tree from the file until it is customized.

Catalog Objects

[catalogs] contains three complete arrays. Catalog IDs must be canonical and unique within each array. Sort-order values come from the catalog’s declared sort options. For an already-known catalog, an omitted global scope means all current and future items are included. A newly discovered catalog first uses the extension’s declared initial scope, and Tuna then persists that choice. A "none" scope excludes all current and future items without an item list. Partial selections use "only" or "excluding" with item IDs; these respectively exclude or include future items. Search priority is -2, -1, 1, or 2 (0 removes the override).

Global item scopes apply only to item-bearing source and snapshot catalogs. Enabled browse-root and live-search entries remain available in global search; a browse root’s scope belongs to its contents catalog, not its navigation entry. Tuna ignores and removes scopes saved for browse-root, live-search, or hidden catalogs. To hide a navigation entry, disable its catalog in Settings instead.

[catalogs]

[[catalogs.sortOrders]]
catalogIdentifier = "tuna.applications.all"
sortOrder = "name"

[[catalogs.globalScopes]]
catalogIdentifier = "example.catalog"
scope = { kind = "only", itemIDs = ["inbox", "today"] }

[[catalogs.searchPriorities]]
catalogIdentifier = "example.catalog"
level = 1

[catalogConfiguration] contains four complete arrays:

Array Required fields Optional fields
folderDepthOverrides catalogIdentifier, depthRawValue
customFolders UUID id, path, depthRawValue entryType, filterMode, fileExtensions
scriptsDirectories UUID id, path
customItems UUID id, kind, value label

depthRawValue = 0 means unlimited; positive values are depth limits. A custom folder’s omitted entryType means "directory", and omitted filterMode means all items. Entry types are "directory" and "file"; filters are "folders" and "extensions". An extensions filter uses fileExtensions. Filters apply to directory entries; file entries always include the selected file. Custom item kinds are "url", "path", and "text". Paths may start with ~.

[catalogConfiguration]

[[catalogConfiguration.folderDepthOverrides]]
catalogIdentifier = "tuna.user-folders"
depthRawValue = 2

[[catalogConfiguration.customFolders]]
id = "ad9cf00d-dbd5-4437-8f2d-352488004a87"
path = "~/Projects"
depthRawValue = 0
entryType = "directory"
filterMode = "extensions"
fileExtensions = ["md", "txt"]

[[catalogConfiguration.scriptsDirectories]]
id = "2ed52442-1f05-4bb1-bf3a-665e1a4249ac"
path = "~/.local/bin"

[[catalogConfiguration.customItems]]
id = "f3ac968c-4742-4ae0-8e38-b7ff61e6884a"
kind = "url"
value = "https://tunaformac.com"
label = "Tuna"

Each [Catalogsettings](/docs/catalogsettings) object has a catalogIdentifier and a string-to-string values table. Available keys come from that catalog’s declaration. A present list replaces all extension settings; omit the section to leave them untouched.

[Catalogsettings](/docs/catalogsettings)
catalogIdentifier = "example.catalog"

[catalogSettings.values]
ProjectRoot = "~/Projects"
View = "assigned"

Smart Links request fallback icons directly from each website by default. Its built-in UseFavicone value is "false". Set it to "true" to opt in to sending each Smart Link host to favicone.com in exchange for higher-resolution icons:

[Catalogsettings](/docs/catalogsettings)
catalogIdentifier = "tuna.smart-links"

[catalogSettings.values]
UseFavicone = "true"

Smart Links Objects

Each [[smartLinks.entries]] object has four required fields:

Field Meaning
name The title shown in Tuna, and the entry’s identity: saved commands and hotkeys refer to tuna.smart-links/<name>. Names must be unique (case-insensitive).
template URL template. Usually contains {{input}} or {{clipboard}}.
requiresInput Whether Tuna requires a target value before opening the link.
enabled Whether the entry is available in the Smart Links catalog.
[[smartLinks.entries]]
name = "GitHub Search"
template = "https://github.com/search?q={{input}}"
requiresInput = true
enabled = true

[[smartLinks.entries]]
name = "Tuna Website"
template = "https://tunaformac.com"
requiresInput = false
enabled = true

Renaming a Smart Link in Tuna’s Settings rewrites every command that refers to it. Renaming one by editing this file does not — commands referring to the old name stop resolving until you update them.

The entries are a complete ordered list, not a patch. To deliberately clear them, use:

[smartLinks]
entries = []

Names and templates must not be empty, and names must be unique (case-insensitive). See Smart Links for template placeholders and filters.

All built-ins have requiresInput = true and enabled = true:

Name Template
Google https://www.google.com/search?q={{input}}
DuckDuckGo https://duckduckgo.com/?q={{input}}
Bing https://www.bing.com/search?q={{input}}
Wikipedia https://en.wikipedia.org/wiki/Special:Search?search={{input}}
YouTube https://www.youtube.com/results?search_query={{input}}
GitHub https://github.com/search?q={{input}}
Stack Overflow https://stackoverflow.com/search?q={{input}}

Alias Objects

Aliases are explicit, synced configuration. Each [[aliases.entries]] object contains a case-insensitive abbreviation and an ordered list of exact catalog targets:

[[aliases.entries]]
abbreviation = "d"
targets = [
  { catalogID = "tuna.smart-links", id = "Dictionary" },
  { catalogID = "tuna.smart-links", id = "DuckDuckGo" },
]

Target order is priority order when several items share an alias. Catalog and item IDs must use the canonical reference grammar. Tuna trims and lowercases abbreviations; they must be non-empty and unique case-insensitively. Every targets array must be non-empty and contain unique references. A present aliases list replaces all explicit aliases; use entries = [] to clear them. Omitting the section leaves current aliases unchanged. Learned usage and ranking remain local to each Mac and are not written to config.toml.

Combo Mode Binding Objects

[comboMode] contains one required bindings array. Every binding has an optional single-character key, an optional label, an optional iconPath, and a destination object. Destination types are "url", "group", "command", and "route".

This example contains a website, a nested group, and a Tuna search route:

[comboMode]

[[comboMode.bindings]]
key = "w"
label = "Tuna Website"

[comboMode.bindings.destination]
type = "url"
url = "https://tunaformac.com"

[[comboMode.bindings]]
key = "g"
label = "Go"

[comboMode.bindings.destination]
type = "group"

[[comboMode.bindings.destination.bindings]]
key = "s"
label = "Search Tuna"

[comboMode.bindings.destination.bindings.destination]
type = "route"

[comboMode.bindings.destination.bindings.destination.route]
type = "search"
query = "Tuna"

A command destination embeds the same saved-command object used by a custom hotkey:

[comboMode]

[[comboMode.bindings]]
key = "e"
label = "Open Example"

[comboMode.bindings.destination]
type = "command"

[comboMode.bindings.destination.command]
type = "savedCommand"
subjectIdentifiers = ["url:https://example.com"]
actionIdentifier = "tuna.common-actions/open-url"
behavior = "run"
presentation = "automatic"

Saved-command behavior is "run" or "stage"; presentation is "automatic", "show", or "hidden". A command may also have a targetIdentifier. Subject and target values use canonical item references, while the action uses catalog-id/action-id. See URL Schemes for the reference grammar.

type, subjectIdentifiers, behavior, and presentation are required. Run requires an action. Stage may omit the action, but a target always requires one, and Stage cannot use "hidden". External URL destinations must have a non-tuna scheme. iconPath may be an app path, image path, or SF Symbol name.

Route objects can open Tuna search, Text Mode, Combo Mode, Talk Mode, Settings, configuration reload, or extension-development actions. Let Tuna’s Combo Mode editor generate these objects so all fields match the selected route.

Route type values and optional fields are: search (query), text (value), combo, talk, settings (pane), configurationReload, and extensionDevelopment (action is "reload" or "rescan", with optional bundleIdentifier).

The bindings array is a complete tree. bindings = [] deliberately clears Combo Mode; removing the whole section leaves the currently stored configuration alone.

Hotkey Objects

[hotkeys] has an optional app object and a required custom array. App shortcuts are named activate, textMode, comboMode, stageFinderSelection, and dictation. A custom hotkey’s id is optional when authoring by hand; Tuna adopts the stored hotkey with the same command or assigns a fresh identity, and writes it back on the next save.

[hotkeys]

[[hotkeys.custom]]

[hotkeys.custom.shortcut]
carbonKeyCode = 18
carbonModifiers = 6400

[hotkeys.custom.command]
type = "savedCommand"
subjectIdentifiers = ["text:hello"]
actionIdentifier = "tuna.common-actions/run-text-as-shell-command"
behavior = "run"
presentation = "hidden"

[hotkeys.app]
activate = { carbonKeyCode = 49, carbonModifiers = 2304 }
textMode = { carbonKeyCode = 17, carbonModifiers = 2304 }

carbonKeyCode and carbonModifiers are the macOS key representation used by Tuna’s shortcut library. They are intentionally low-level: record shortcuts in Settings -> Hotkeys, then copy or debug the generated values instead of calculating them by hand. A missing shortcut on a custom hotkey means the command exists but has no assigned chord.

The custom array is a complete replacement. Including [hotkeys] with custom = [] removes all custom hotkeys. If the section is present but [hotkeys.app] or one of its five fields is absent, that app shortcut is cleared on reload. Removing the entire [hotkeys] section leaves current hotkeys alone.

Every custom hotkey UUID must be unique. Its command follows the saved-command shape described in the Combo Mode section above. A staged command cannot use presentation = "hidden" because staging requires Tuna’s interface.

Action Preference Objects

Action preferences are sparse overrides layered on top of Tuna and extension defaults. The section contains three required arrays:

[actionPreferences]

[[actionPreferences.typeOrderOverrides]]
typeID = "com.tuna.type.url"
actions = [
  { catalogIdentifier = "tuna.common-actions", actionID = "open-url" },
  { catalogIdentifier = "tuna.common-actions", actionID = "copy-to-clipboard" },
]

[[actionPreferences.itemDefaultOverrides]]
scopeKind = "item"
scopeIdentifier = "tuna.smart-links/GitHub Search"
action = { catalogIdentifier = "tuna.smart-links.actions", actionID = "open-smart-link" }

[[actionPreferences.itemDefaultOverrides]]
scopeKind = "type"
scopeIdentifier = "com.tuna.type.text-snippet"
action = { catalogIdentifier = "tuna.common-actions", actionID = "copy-to-clipboard" }

[[actionPreferences.applicationOrderOverrides]]
bundleIdentifier = "com.apple.Safari"
actions = [
  { catalogIdentifier = "tuna.common-actions", actionID = "open" },
  { catalogIdentifier = "tuna.common-actions", actionID = "reveal" },
]
  • typeOrderOverrides replaces the action order for one type ID. A direct type override wins; otherwise Tuna combines overrides inherited from parent types.
  • itemDefaultOverrides chooses one default action for either a canonical item reference or a type ID. scopeKind is "item" or "type" and determines how scopeIdentifier is parsed.
  • applicationOrderOverrides replaces the action order used for one application bundle identifier.

Each scope, type, and normalized application bundle identifier may appear only once. An action may appear only once within an order. References to an unavailable extension are retained so the preference starts working again if that extension returns. Resetting an order or default in Settings removes its object and reveals the current built-in or extension default.

All three arrays describe the complete set of overrides. To reset all action preferences through the file, keep the section and set all three arrays to []. Removing the section leaves current preferences alone.

Catalog enablement is intentionally not stored in config.toml. Installed extensions and available catalogs can differ from Mac to Mac, so Tuna resolves their current availability locally. Likewise, built-in action rankings are resolved live; only your overrides are saved.

Cross-Section Debugging Example

This fragment defines one Smart Link, opts in to favicone.com icons, and refers to that same item from Combo Mode, a custom hotkey, an alias, and an item default. Item and alias objects spell the key catalogID; action objects spell it catalogIdentifier.

[[smartLinks.entries]]
name = "Docs Search"
template = "https://tunaformac.com/docs/search?q={{input}}"
requiresInput = true
enabled = true

[Catalogsettings](/docs/catalogsettings)
catalogIdentifier = "tuna.smart-links"

[catalogSettings.values]
UseFavicone = "true"

[[comboMode.bindings]]
key = "d"
label = "Docs"

[comboMode.bindings.destination]
type = "group"

[[comboMode.bindings.destination.bindings]]
key = "s"
label = "Search Docs"

[comboMode.bindings.destination.bindings.destination]
type = "command"

[comboMode.bindings.destination.bindings.destination.command]
type = "savedCommand"
subjectIdentifiers = ["tuna.smart-links/Docs Search"]
actionIdentifier = "tuna.smart-links.actions/open-smart-link"
behavior = "run"
presentation = "automatic"

[[hotkeys.custom]]
[hotkeys.custom.command]
type = "savedCommand"
subjectIdentifiers = ["tuna.smart-links/Docs Search"]
actionIdentifier = "tuna.smart-links.actions/open-smart-link"
behavior = "stage"
presentation = "show"

[[aliases.entries]]
abbreviation = "docs"
targets = [{ catalogID = "tuna.smart-links", id = "Docs Search" }]

[actionPreferences]
typeOrderOverrides = []
applicationOrderOverrides = []

[[actionPreferences.itemDefaultOverrides]]
scopeKind = "item"
scopeIdentifier = "tuna.smart-links/Docs Search"
action = { catalogIdentifier = "tuna.smart-links.actions", actionID = "open-smart-link" }

For the command references used by custom hotkeys, Combo Mode, and action preferences, see URL Schemes. For the corresponding UI, see Hotkeys and Activation, Combo Mode, and Smart Links.

Syncing Between Macs

Choose the same custom config folder on each Mac, or manage config.toml with your normal sync tool. Tuna keeps paths portable where it can by writing locations inside your home directory with ~.

Some references can still be machine-specific: an application or extension may not exist on every Mac, a custom path may point to local content, and a hotkey may conflict with another system setup. Tuna retains valid references to temporarily unavailable extensions so they work again when the extension returns.

Before resolving a sync conflict, quit Tuna on the other Mac or reload both copies so neither has pending local changes. Treat config.toml as one document: Tuna validates and applies it as a whole.