Skip to content

Config reference

Configure Hunk with TOML settings in your user config or a project's .hunk/config.toml. Include only the settings you want to change.

For a walkthrough, start with the configuration guide. This page lists every supported preference, table, and default.

FileLocationUse for
User (XDG override)$XDG_CONFIG_HOME/hunk/config.tomlPersonal preferences
User (fallback)$HOME/.config/hunk/config.toml, or %USERPROFILE%/.config/hunk/config.toml when HOME is unavailablePersonal preferences
Repository/project.hunk/config.toml at the project rootProject-specific settings

Hunk searches upward from the working directory for the nearest directory containing .hunk or recognized by a loaded VCS backend as a repository root. That directory supplies the project config. No user config is loaded if none of the user-path environment variables is set.

Create your user config with a few settings:

theme = "terminal"
mode = "auto"
line_numbers = true
wrap_lines = false

Omitted settings use the built-in defaults below. Shared settings belong above all table headers: in TOML, keys after [show] belong to that table until another table begins.

Add a command table to the same config file and repeat the settings you want to override. Other settings are inherited. This changes command preferences, not command implementations or keyboard shortcuts.

mode = "auto"
[vcs]
mode = "split"
watch = true
[show]
mode = "unified"
[diff]
wrap_lines = true

With this config and no repository overrides:

InvocationResult
hunk diffSplit layout, watch enabled
hunk showUnified layout
hunk diff --files before.ts after.tsAutomatic layout, wrapping enabled
hunk show --mode splitSplit layout; the explicit flag wins

Repository hunk diff uses [vcs]. [diff] only applies to two-file comparisons. Table names are fixed; do not infer additional tables from CLI command names.

TableApplies to
[open]complete documents and directory browsing (hunk open)
[vcs]working-tree and target reviews (hunk diff)
[show]commit and target display reviews (hunk show)
[stash-show]stash reviews (hunk stash show)
[diff]two-file comparisons (hunk diff --files <left> <right>)
[patch]patch-file reviews (hunk patch)
[difftool]Git difftool pair reviews (hunk difftool)

[pager] applies when a diff opens as a pager session: Git output displayed by hunk pager, or any review launched with --pager. It overrides the matching command table within the same file, not in ordinary interactive reviews. hunk pager reviews match [patch].

[pager]
mode = "unified"
wrap_lines = true

Try it for one Git invocation:

Terminal window
git -c core.pager="hunk pager" diff

Pager reviews start with the files pane closed, even if sidebar = true, and hide the menu bar unless a config layer sets menu_bar. Non-diff input goes to a plain-text pager instead; these view preferences do not configure that fallback. See Git pager and difftool for permanent setup.

Layers apply from lowest to highest precedence:

  1. built-in defaults
  2. user config top-level keys, then the matching command table, then [pager] when pager chrome is active
  3. repository .hunk/config.toml top-level keys, matching command table, and pager table
  4. explicit CLI options

A repository's top-level setting can override a user command-specific setting. For example:

# User config
[show]
mode = "unified"
# Repository .hunk/config.toml
mode = "split"

hunk show uses split; hunk show --mode unified uses unified. Flags such as --no-wrap also override a configured wrap_lines = true. See the CLI reference for available flags.

Preference keys may appear at top level, in a command table, or in [pager], except that user-only preferences are ignored in repository config. Theme definitions, extension tables, and keybindings belong at the root, never nested in command tables.

Persistent application state uses an absolute $XDG_STATE_HOME/hunk/state.json, falling back to ~/.local/state/hunk/state.json (or the platform home equivalent). On first use, Hunk copies legacy state from the config directory only when the new file is absent, retains the original, and continues using it if migration fails. Existing new state always takes precedence. Global extensions remain in $XDG_CONFIG_HOME/hunk/extensions/ or ~/.config/hunk/extensions/.

Choose diff layout. auto uses split on wide terminals and unified on narrow ones; split and unified force that layout.

  • Type: string
  • Accepted: auto, split, unified, or deprecated alias stack
  • Built-in default: auto

Minimum available diff width, in columns, for split diffs in auto mode, after side panes and outer padding; narrower diff areas show unified diffs.

  • Type: integer
  • Accepted: a positive number of terminal columns
  • Built-in default: 160

Select the color theme. terminal follows the terminal palette; auto chooses a light or dark GitHub theme from the terminal background (dark fallback).

  • Type: string
  • Accepted: terminal, auto, a built-in theme id, or a custom theme id
  • Built-in default: github-dark-default

Show old and new line-number columns.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: true

Set terminal-cell tab stops used for display and wrapping.

  • Type: integer
  • Accepted: 1 through 16
  • Built-in default: 4

Rows between files in the review stream, including the ─ rule. 1 keeps the current rule; 0 hides it; larger values add blank rows above it.

  • Type: integer
  • Accepted: 0 through 8
  • Built-in default: 1

Blank rows before each hunk after the first in a file.

  • Type: integer
  • Accepted: 0 through 8
  • Built-in default: 0

Wrap long diff lines instead of keeping one visual row.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: false

Show hunk metadata rows in the review stream.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: true

Show the top application menu bar.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: true

Animate panes as they open and close.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: true

Show the files pane if it fits, keep it closed, or let the responsive layout decide. Pager sessions always open with the files pane closed.

  • Type: string or boolean
  • Accepted: "auto", true, or false
  • Built-in default: auto

Let the terminal background show through Hunk surfaces.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: false
  • Aliases: transparentBackground (deprecated)

Request moved-line coloring for Git reviews. true requests zebra coloring when Git has no diff.colorMoved setting; an explicit Git setting takes precedence, even when this preference is false.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: not set; Git uses its diff.colorMoved setting

Mark the current line as a full-row highlight or on its line number. off restores plain j/k scrolling.

  • Type: string
  • Accepted: row, number, or off
  • Built-in default: row

Keep the current line at least this many rows clear of the viewport top/bottom edge while stepping through a diff, like Vim's scrolloff.

  • Type: integer
  • Accepted: 0 through 40
  • Built-in default: 5

Set review rows per vertical wheel event. auto keeps cadence-based acceleration from one to three rows.

  • Type: string or integer
  • Accepted: auto or 1 through 10
  • Built-in default: auto
  • Scope: user config only

Select the version-control adapter explicitly. An explicit id outranks detection; an id no loaded backend owns falls back to detection with a startup notice.

  • Type: string
  • Accepted: git, jj, sl, or an id a loaded extension backend registers
  • Built-in default: detected from the checkout (Git fallback)

Reload supported review inputs when their source changes.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: false

Hide untracked files from working-tree reviews.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: false

Show agent notes when a review opens.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: false

Include diff signs and line numbers in copied selections.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: false

Ask before discarding view changes that can be persisted.

  • Type: boolean
  • Accepted: true or false
  • Built-in default: true

To change the keys that trigger actions, use [keybindings] in your user config:

[keybindings]
"hunk.review.nextHunk" = ["]", "ctrl+n"]
"hunk.app.quit" = "ctrl+x"

Your bindings replace that command's default keys. Repository config cannot remap keys. See Keybindings for command ids, unbinding, conflicts, and chord syntax.

Choose a built-in theme with theme = "catppuccin-mocha". terminal follows your terminal palette; auto selects a light or dark GitHub theme from the terminal background. See the theme guide for selection and previews.

To customize colors:

theme = "custom"
[custom_theme]
base = "catppuccin-mocha"
accent = "#7fd1ff"

The theme inherits its base and overrides only the colors you supply.

Use root [themes.<id>] tables to keep several custom themes:

theme = "midnight-ink"
[themes.midnight-ink]
base = "catppuccin-mocha"
accent = "#7fd1ff"
[themes.paper-trail]
base = "github-light-default"

Each accepts the same keys as [custom_theme]. Select one with theme = "<id>" or --theme <id>; [custom_theme] itself has the id custom. Ids use lowercase letters or digits separated by - or _. Reserved ids (built-in themes, auto, and custom) are skipped with a startup notice. Same-id theme tables merge field by field across user and repository config, with repository values winning.

custom_theme.label accepts a non-empty display name. Every semantic color below accepts a six-digit #rrggbb value:

KeyDescription
custom_theme.backgroundMain application background.
custom_theme.panelPane and menu backgrounds.
custom_theme.panelAltAlternate backgrounds, including diff metadata and the status line.
custom_theme.borderPane separators and borders.
custom_theme.accentActive controls and highlighted UI elements.
custom_theme.accentMutedTinted backgrounds for selected controls and tree entries.
custom_theme.textDefault foreground text.
custom_theme.mutedSecondary labels and metadata text.
custom_theme.addedBgAdded-line background.
custom_theme.removedBgRemoved-line background.
custom_theme.movedAddedBgBackground for the added side of moved lines.
custom_theme.movedRemovedBgBackground for the removed side of moved lines.
custom_theme.contextBgUnchanged-line background.
custom_theme.addedContentBgEmphasized changed text within added lines.
custom_theme.removedContentBgEmphasized changed text within removed lines.
custom_theme.contextContentBgContent background within unchanged lines.
custom_theme.addedSignColorAddition markers in the diff gutter.
custom_theme.removedSignColorDeletion markers in the diff gutter.
custom_theme.lineNumberBgLine-number column background.
custom_theme.lineNumberFgLine-number text.
custom_theme.selectedHunkSelected-hunk highlighting.
custom_theme.badgeAddedAddition-count badges.
custom_theme.badgeRemovedDeletion-count badges.
custom_theme.badgeNeutralNeutral badges and file-header labels.
custom_theme.fileNewNew-file status indicators.
custom_theme.fileDeletedDeleted-file status indicators.
custom_theme.fileRenamedRenamed-file status indicators.
custom_theme.fileModifiedModified-file status indicators.
custom_theme.fileUntrackedUntracked-file status indicators.
custom_theme.noteBorderNote-card borders and inline note guides.
custom_theme.noteBackgroundNote-card body background.
custom_theme.noteTitleBackgroundNote-card title background.
custom_theme.noteTitleTextNote-card title text.

[custom_theme.syntax_scopes] accepts non-empty Shiki/TextMate scope names and six-digit hex colors. Add overrides to your custom theme; quote keys containing dots:

[custom_theme.syntax_scopes]
"comment" = "#6e85a7"
"punctuation.definition.comment" = "#6e85a7"

These are syntax token colors, distinct from the UI and diff backgrounds above. See the theme guide for scope matching behavior.

The deprecated [custom_theme.syntax] table remains accepted for one compatibility window with these semantic keys: custom_theme.syntax.default, custom_theme.syntax.keyword, custom_theme.syntax.string, custom_theme.syntax.comment, custom_theme.syntax.number, custom_theme.syntax.function, custom_theme.syntax.property, custom_theme.syntax.type, custom_theme.syntax.variable, custom_theme.syntax.operator, custom_theme.syntax.punctuation. Hunk normalizes them into exact scope overrides and emits a startup notice.

custom_theme.base accepts these ids and defaults to github-dark-default. theme also accepts these ids, plus terminal and auto:

  • andromeeda
  • aurora-x
  • ayu-dark
  • ayu-light
  • ayu-mirage
  • catppuccin-frappe
  • catppuccin-latte
  • catppuccin-macchiato
  • catppuccin-mocha
  • dark-plus
  • dracula
  • dracula-soft
  • everforest-dark
  • everforest-light
  • github-dark
  • github-dark-default
  • github-dark-dimmed
  • github-dark-high-contrast
  • github-light
  • github-light-default
  • github-light-high-contrast
  • gruvbox-dark-hard
  • gruvbox-dark-medium
  • gruvbox-dark-soft
  • gruvbox-light-hard
  • gruvbox-light-medium
  • gruvbox-light-soft
  • horizon
  • horizon-bright
  • houston
  • kanagawa-dragon
  • kanagawa-lotus
  • kanagawa-wave
  • laserwave
  • light-plus
  • material-theme
  • material-theme-darker
  • material-theme-lighter
  • material-theme-ocean
  • material-theme-palenight
  • min-dark
  • min-light
  • monokai
  • night-owl
  • night-owl-light
  • nord
  • one-dark-pro
  • one-light
  • plastic
  • poimandres
  • red
  • rose-pine
  • rose-pine-dawn
  • rose-pine-moon
  • slack-dark
  • slack-ochin
  • snazzy-light
  • solarized-dark
  • solarized-light
  • synthwave-84
  • tokyo-night
  • vesper
  • vitesse-black
  • vitesse-dark
  • vitesse-light

These aliases remain accepted by theme and custom_theme.base, then normalized to their replacements:

Legacy IDReplacement
graphitegithub-dark-default
midnightgithub-dark-dimmed
papergithub-light-default
emberdark-plus
zenburneverforest-dark

[extensions] controls extension loading. It is root-only and does not accept command or [pager] overrides. For example, disable the bundled GitHub integration:

[extensions]
disabled = ["hunk.gh"]

enabled = false and --no-extensions turn off user extensions; bundled VCS backends still load. Selectable bundled extensions such as hunk.gh can be disabled by id.

KeyTypeAcceptedBuilt-in defaultDescription
extensions.enabledbooleantrue or falsetrueLoad user extensions. --no-extensions forces this off for one run, and bundled VCS backends stay loaded either way.
extensions.pathsarray of stringsentry file or directory paths[]Extension entry points loaded at startup. Paths a repository config contributes are trust-gated before they run.
extensions.disabledarray of stringsexact extension identities[]Disable selectable bundled or user extensions before their factories or modules execute. User and repository lists combine as a union.

Repository .hunk/config.toml paths are kept separate from user paths: Hunk prompts for trust before executing repository-declared extension code, and --no-extensions disables user extensions entirely for one run.

Each extension reads its own settings from a root [extension.<id>] table. For example, after installing the collapse-generated example extension:

[extension.collapse-generated]
patterns = ["*.lock", "generated/*"]

These keys belong to that extension, not Hunk's preference catalog. Repository tables merge over user tables key by key, and Hunk reports which extension settings the repository overrides. See Extensions for installation, trust, loading controls, and examples.

ProblemCheck
[diff] does not affect hunk diffUse [vcs] for repository reviews.
A preference seems ignoredCheck repository config, then explicit CLI flags. Later layers win.
A shared setting affects only one commandMove it above all table headers.
A shortcut remap has no effectPut [keybindings] in user config; check command ids and reported conflicts.
Custom colors have no effectSelect the custom theme by id and keep its definition at the root.