Skip to content

Configuring Contour

Contour offers a wide range of configuration options that can be customized, including color scheme, shell, initial working directory, and more. The configuration options can be categorized into several groups:

  • Global options: These settings determine the overall behavior of the terminal and apply to all profiles.
  • Profiles: With profiles, you can configure the terminal more granularly and create multiple profiles that can be easily switched between.
  • Color scheme: Contour allows you to define different color schemes for the terminal and choose which one to use for each of the profiles.

On Unix systems, the main configuration file is located at ~/.config/contour/contour.yml and is both read from and auto-generated there. On Windows systems, the file is located at %LocalAppData%\contour\contour.yml.

Please note that on Unix systems, the environment variable XDG_CONFIG_HOME (by default set to ~/.config) is taken into account.

By default, on Unix systems, Contour is executed with the following arguments contour config ~/.config/contour/contour.yml profile main. If the configuration file includes a default_profile variable, it will be used as the default profile. Otherwise, the first profile listed in the file will be the default one.

How to

Load specific configuration file

contour config /path/to/file/with/configuration.yml

Set profile for current session

you can utilize the profile parameter with the contour command
contour profile one_of_profiles

Global options

Let's go through the different sections of the global configurations in the file:

defaults_edition

option names the generation of built-in defaults the configuration file is written against, so a setting the file does not spell out keeps the value it had when the file was written. classic is the defaults of every release before the 2026 redesign, and is what a file without the key gets. native2026 is the redesign's: JetBrains Mono (Cascadia Mono on Windows) at 13pt on macOS and 12pt elsewhere, a 100x30 page with 8x6 margins, the contour-dark/contour-light color schemes, the status line without hard-coded colors, a silent bell, 10000 lines of scrollback, a steady block cursor, links decorated while the follow modifier (Command on macOS) is held, unfocused panes dimmed, a tab bar shown only for two or more tabs, a scrollbar that follows the system's scroll bar setting (scrollbar.mode: system, where classic always shows it), a hovered link's target shown only while the follow modifier is held (hyperlink_hover_tooltip: false), and GUI chrome that follows the terminal background (theme: terminal, where classic follows the OS). Under native2026 colors: default, the stock scheme left unmodified, also means the contour-dark/contour-light pair, so an existing configuration follows dark mode; naming any other scheme keeps it fixed. Under native2026 the default profile's contour-dark and contour-light palettes come from the built-in schemes: a color_schemes: entry of either name takes effect only when a profile names it in colors:. A freshly generated configuration states native2026. A settings.yml beside the file may set the key too, and wins.

platform_plugin

option allows you to override the auto-detected platform plugin to be loaded. You can specify values like auto, xcb, cocoa, direct2d, or winrt to determine the platform plugin. The default value is auto.

renderer

section contains configuration options related to the VT Renderer, which is responsible for rendering the terminal onto the screen. It includes the backend option to specify the Qt RHI graphics API, with possible values of auto (the native backend per platform), OpenGL, vulkan, direct3d11, direct3d12, metal, or software. The other options in this section control the tile mapping and caching for performance optimization.

word_delimiters

option defines the delimiters to be used when selecting words in the terminal. It is a string of characters that act as delimiters.

extended_word_delimiters

option defines the delimiters to be used when selecting words in the second time. It is a string of characters that act as delimiters. By default word delimiters are used.

command_palette_recent_count

option sets how many recently used commands the command palette pins above its alphabetical list. The palette is opened with the OpenCommandPalette action (bound to Ctrl+Shift+P by default), and the list of recent commands is remembered across restarts in the command-history.yml file beside your configuration file. Set it to 0 to turn the "recently used" section off entirely. The default value is 5.

pty_read_buffer_size

option sets the most bytes taken from the PTY in one read, and so the most parsed in one go. Larger batches parse output faster; smaller ones show a flood of it in smaller steps. It is an advanced option and should be used with caution. The default value is 65536. A change applies to sessions opened afterwards.

pty_buffer_object_size

option sets the size in bytes per PTY Buffer Object. It is an advanced option for internal storage and should be changed carefully. The default value is 1048576. A change applies to sessions opened afterwards.

default_profile_name

option determines the default profile to use in the terminal.

early_exit_threshold

option determines the early threshold time. If the shell ends earlier than the specified threshold without a successful exit status, its pane stays open with the shell's last output and a footer naming how it ended (its exit code or signal): Return restarts the shell in the same pane, and the ClosePane binding (Ctrl+Shift+X by default) closes it. A shell that exits successfully -- exit or Ctrl+D -- closes the pane at once.

spawn_new_process

flag determines whether a new process should be spawned when creating a new terminal. The default value is false.

reflow_on_resize

option controls whether or not the lines in the terminal should be reflowed when a resize event occurs. The default value is true. A change applies to sessions opened afterwards.

snap_to_rows

option aligns startup and manually resized window heights to complete terminal rows. The default is false. Applies to a single visible pane, including a zoomed split pane. Font metrics, window chrome and configured margins are taken into account. Windows snaps during resizing; macOS snaps when manual resizing ends; X11 uses window-manager size hints. Wayland has no resize-increment hint, so only startup sizing is supported there. Maximized and fullscreen sizes are unrestricted. Fractional scaling can leave less than one logical pixel of rounding slack. A change applies at the next startup or manual resize.

connect_picker_on_start

option makes a plain launch, one with no command-line arguments such as a Dock, Spotlight or launcher start, show the Connect picker first: a small window asking whether the new window's sessions live in this computer's daemon, in this window only, or on a saved host. The default is false. contour connect shows the picker whatever this says, and a launch with arguments never does. Also the "Ask every time Contour starts" switch of the picker and of Settings.

remember_window_position

option remembers the last normal window position and monitor, without saving window size. The default is true on Windows and false on other platforms. Enable it to opt in on macOS and X11; Wayland leaves placement to the compositor. The first window restores its location at startup. The window-position.yml side file stores monitor-relative x/y coordinates and a zero-based monitor index. Disabling the option stops reading and writing position state.

tab_switch_on_horizontal_wheel

option controls whether a horizontal mouse wheel tilt (or a horizontal trackpad swipe) over the tab strip or the terminal switches to the previous/next tab. An application that has requested mouse reporting keeps receiving the horizontal wheel; holding the bypass modifier switches tabs anyway. An explicit WheelLeft/WheelRight entry in input_mapping takes precedence. The default value is true.

Whether hovering a link (OSC 8 or detected) shows its target without holding the follow modifier. While the modifier is held the target always shows. A local file:// target is shown as a plain path. Defaults to false; a configuration written before the 2026 defaults keeps true.

progress_timeout

How long an application's progress indicator (OSC 9;4) stays on screen without being updated, in milliseconds.

0 (the default) disables expiry entirely: the indicator persists until the application clears it with state 0, which is what the sequence specifies and what ConEmu and Windows Terminal do. The terminal cannot tell a long-running operation from an application that died holding one, so a non-zero value trades that fidelity for a guard against a bar left stranded on screen. Applications using the protocol are expected to refresh it about once a second, so a timeout well above that -- 15000 or so -- is the useful range.

notification_close_timeout

How long after showing a desktop notification that asked to hear of its close (c=1) the terminal waits before assuming the desktop closed it, in milliseconds.

This only applies where a close cannot be observed. Contour normally learns that a notification was dismissed or expired from the desktop itself and reports it back to the application as the OSC 99 p=close event. Inside a Flatpak sandbox that is impossible: the only reachable service is the org.freedesktop.portal.Notification portal, which has no close signal of any kind, so an application that asked for close events (c=1) would otherwise wait forever.

A notification that states its own lifetime through w= is answered after that instead -- the application already said what it wanted. Only w=-1, "whatever the desktop does", falls back to this value.

Two cases are deliberately never answered, because there is no moment at which an answer would be true: 0 here, which disables the assumption outright, and w=0 on the notification, which asks for a popup that never expires on its own. An application that requested close events in either case is not told.

A notification that asked for no close event -- a command's finish notice among them -- is never assumed closed: assuming it would only make it impossible to withdraw, and its click, from the desktop's notification history, would go unanswered.

Read once per terminal session, so a changed value reaches sessions opened after the reload.

Because the report is a timer rather than an observation, it is marked untracked on the wire, so an application can tell the two apart.

accessibility_announcements

Whether events with no representation in the accessibility tree -- the bell, a desktop notification, a mode change -- are announced to assistive technology. Costs nothing while no assistive client is attached. See Accessibility.

accessibility_caret_reporting

Whether the terminal reports where the caret is to assistive technology, which is how a screen magnifier follows what you are typing. Costs nothing while no assistive client is attached. Turn it off to rule the caret reports out when diagnosing input latency. See Accessibility.

tab_bar_position

Selects where the GUI tab strip (tab bar) is placed within the window. Valid values (ignore-case):

  • Top — the tab strip is drawn above the terminal content. This is the default.
  • Bottom — the tab strip is drawn below the terminal content.

tab_bar_visibility

Selects when the GUI tab strip (tab bar) is shown. Valid values (ignore-case):

  • Always — the tab strip is always shown. This is the classic default.
  • Never — the tab strip is never shown.
  • Multiple — the tab strip is shown only when the window has more than one tab, and hidden while a single tab remains. This is the native2026 default.

gui_config_locked

flag, when true, opens the in-app settings page read-only and prevents the GUI from writing any of its side files (profiles/, colorschemes/, settings.yml), so this hand-maintained configuration file stays the single source of truth. The default value is false.

theme

option selects the light/dark appearance of the GUI chrome (title bar, tab strip, command palette, settings pages, dialogs) independently of the operating system. Possible values are terminal (follow the terminal's background), system (follow the OS color scheme), dark, and light. The terminal grid keeps following the OS light/dark preference through its own color scheme. The default value is terminal under defaults_edition: native2026 and system under classic.

ui_style

Selects how the application's own chrome is painted: the tab strip and title bar, and the controls (buttons, fields, menu entries, combo boxes) inside menus, popups and the settings page. This selects a shape, not a color: both styles take their colors from the operating system palette and follow the theme setting. Valid values (ignore-case):

  • native — platform-native GUI chrome. This is the default.
  • terminal — the chrome is quantized to whole character cells of a monospace font and its corners are squared off, so the window reads as one continuous TUI rather than as a GUI wrapped around a terminal. Tabs keep every GUI affordance (drag to reorder, tear off, rename, close, context menu); only their appearance changes.

This is the recommended way to get the terminal look now that a window can hold split panes: the indicator status line's {Tabs} item still works, but it is drawn per pane, so a split window would show one tab list per pane instead of one per window.

The Qt Quick Controls half of the style is selected once, before the first control is created, so a change takes effect on the next start rather than live.

window_control_style

Selects how the window's own minimize/maximize/close controls are drawn, and which side of the tab bar they sit on. These are drawn only while the native title bar is hidden (show_title_bar is false, the default), which is when the tab bar doubles as the title bar; with the native frame shown, the operating system draws them itself. Valid values (ignore-case):

  • auto — match the host: macOS gets macos, Windows gets windows, and anything else (KDE Plasma included) gets linux. This is the default.
  • windows — trailing (right) edge, flush rectangular buttons in minimize/maximize/close order, with a red close hover.
  • macos — leading (left) edge, traffic lights in close/minimize/zoom order. The dots reveal their glyphs while the group is hovered and grey out while the window is inactive.
  • plasma — trailing (right) edge, like windows but with the circular hover fills of KDE Plasma's Breeze decoration.
  • linux — round buttons with the desktop's themed icons, in the order and on the side (or sides) the desktop's own button layout names: GNOME's button-layout, KWin's ButtonsOnLeft and ButtonsOnRight, or GTK's gtk-decoration-layout. Where none is set, minimize, maximize and close sit at the trailing (right) edge.

Independent of ui_style: every value works in both the native and the terminal chrome, and takes its extents from whichever of those is active — so under ui_style: terminal the controls stay quantized to whole character cells, and the traffic lights are drawn as coloured cell-wide dots.

Unlike ui_style, this applies immediately when changed from the settings page.

chrome_density

Selects how much room the window chrome takes. Valid values (ignore-case):

  • comfortable — once a tab is split, its panes are cards with a header each and a 6 pt gap between them. This is the default.
  • minimal — panes are separated by 1 pt lines and carry no header; hold Alt (Option on macOS) for half a second to show the headers. On macOS a tab that is not split gets a bare 28 pt band.

A change is applied live.

secure_input

Shows a lock while the program in a pane hides what you type (a password prompt) and, on macOS, turns on Secure Keyboard Entry while that pane has focus. auto or off.

ui_font_family

Font family the terminal-style chrome is drawn with. When empty (the default) the chrome inherits the regular font family of the profile the window is running (-p/--profile, else default_profile), which is what makes it match the terminal grid below it. Ignored while ui_style is native, where the chrome uses the platform UI font. Takes effect on the next start.

ui_font_size

Font size, in points, the terminal-style chrome is drawn with. When 0 (the default) the chrome inherits the font size of the profile the window is running. Ignored while ui_style is native. Takes effect on the next start.

grapheme_clustering

Whether DEC mode 2027 starts out set. While set, a late codepoint may widen its grapheme cluster -- U+FE0F widens a cluster to two columns -- but a cluster never narrows again. While unset, a cell is measured by plain wcwidth() with no clustering. Applications may still toggle the mode at runtime. A change applies to sessions opened afterwards.

text_scaling_method

How a glyph is enlarged for scaled text (kitty text sizing protocol, OSC 66). stretch magnifies the ordinary-size glyph: free to rasterize, no extra atlas entries, but softer at large scales. rerasterize asks the font for the glyph at the larger size: crisp at any scale, at the cost of a rasterization and an atlas entry per glyph and scale.

bypass_mouse_protocol_modifiers

option specifies the keyboard modifier (e.g., Shift) that can be used to bypass the terminal's mouse protocol and select screen content.

mouse_block_selection_modifiers

option determines the modifier (e.g., Control) that needs to be pressed to initiate block selection using the left mouse button.

on_mouse_selection

option selects the action to perform when a text selection has been made. Possible values include None, CopyToClipboard, and CopyToSelectionClipboard.

live

option determines whether the instance should reload the configuration files whenever they change. The default value is false.

experimental_features

images

section contains configuration options related to inline images. It includes options like sixel_scrolling, sixel_register_count, and good_image_protocol to control various aspects of image rendering. The maximum image size is derived from the screen size; max_width and max_height are deprecated and ignored.

daemon

section decides whether sessions are hosted by a daemon process, so they outlive the window.

daemon:
  mode: auto
  socket: ""
  size_policy: latest
  history_limit: 1000
  restore:
    scrollback: true
    scrollback_lines: 1000
    rerun_programs: []
    interval: 30
mode in_process keeps sessions in the GUI process, auto uses a daemon and falls back to in-process with a notice, required fails when no daemon can be reached. socket The daemon's socket path; empty selects the default. size_policy Which client's size wins when several are attached: latest, smallest or largest. history_limit Scrollback lines per session, -1 for unlimited; unset uses the hosting profile's history.limit. restore.scrollback Whether a restored pane gets its scrollback back; the snapshot file may hold secrets that were on screen, and is readable by your user only. restore.scrollback_lines The most scrollback lines kept per pane, from 0 to 100000; the live scrollback stays history_limit. restore.rerun_programs Programs a restored pane runs again when it was running one of them, such as [vim, htop]; nothing is re-run unless listed. restore.interval How often, in seconds, a changed workspace is written; at least 5.

quick_terminal

section sets a global hotkey that slides a terminal down from the top of the screen under the pointer, full width and 40 % of its height, in Minimal density.

quick_terminal:
  hotkey: { mods: [Control], key: '`' }
  hide_on_focus_loss: true
hotkey The chord, spelled as an input mapping spells it; it needs at least one of Control, Alt and Super. Unbound (~) by default. hide_on_focus_loss Whether the quick terminal hides when it loses the focus.

folding

configuration controls output folding: collapsing a finished command's output down to the prompt line it was entered at, and expanding it again.

folding:
  enabled: true
  show_markers: true
  auto_collapse_on_new_command: false
  on_jump_into_fold: expand
Folding is driven entirely by the OSC 133 semantic marks a shell with shell integration emits, so no additional escape sequence is involved and any shell that already speaks OSC 133 works. Only FINISHED commands fold, which is why the prompt you are typing at never does. enabled Whether folding is available at all. When false the actions below do nothing and no fold markers are drawn.
show_markers Whether the gutter's block column, left of the grid, draws fold markers: a boxed minus on a foldable prompt line whose output is showing, a boxed plus once it is collapsed, and a bar down the side of the block joining the two. Clicking anywhere on that column toggles the fold. Note that the column costs one column of terminal width; it is reserved while this, gutter.exit_status or gutter.user_marks is on.
auto_collapse_on_new_command Whether a command's output is collapsed automatically as soon as the next prompt appears, so that only the command you are running now is shown in full.
on_jump_into_fold What a Vi-mode jump that targets a line inside a collapsed block does: expand opens the block so the cursor lands on what it was aiming at, skip leaves it collapsed and stops at its prompt line instead. Plain motions (j, k, {, }, ++ctrl+d++, ++ctrl+u++) always step over a collapsed block regardless of this setting.

The actions CollapseAllFolds, ExpandAllFolds, CollapseLastFold, ToggleLastFold and ToggleFold can be bound to keys; ScrollMarkUp and ScrollMarkDown already move the viewport from one prompt to the next.

gutter

configuration controls the gutter: the strip left of the grid that carries per-line timestamps, line numbers and the block column.

gutter:
  exit_status: true
  user_marks: true
  block_column_width: 2
  bold_on_hover: true
  line_numbers: off
  line_number_width: 6
  timestamps: false
  timestamp_format: '%H:%M:%S'
The gutter's width follows this configuration and never its content, so a growing line number cannot resize the page in the middle of a command's output. The block column is reserved while fold markers (folding.show_markers), exit status or user marks are on, block_column_width cells wide. exit_status Colour each command's fold controls by how it ended -- the colour scheme's block_status colours -- draw a triangle beside a running command, and a dot beside a finished one that shows no fold control: one with nothing to fold, or any one while fold markers are off. Hovering the block column shows the exit code, duration, start time, working directory and command line.
user_marks Draw a diamond beside every row marked with vi-mode mm.
block_column_width The block column's width in cells, 1 or 2. At 2, the default, its fold controls and marks are drawn across both cells at twice the size, and a click anywhere in the column -- the blank strip left of it included -- lands on it.
bold_on_hover Draw the fold under the pointer -- its line, its box and its end -- one stroke heavier, as well as at full strength: a failed command's, already heavy, heavier still. Its colours are the color scheme's fold_marker.hover and block_status_hover.
line_numbers off, absolute (every row's number, counted from the session's first row, so the numbers stay put while history scrolls away), relative (every row's distance from the cursor row, counting a collapsed block as one row -- exactly what j and k count) or hybrid (the cursor row's own number, every other row's distance), as vim's nu and rnu. In vi mode the distance counts from the vi cursor.
line_number_width Columns the line numbers take, 3 to 10. A longer number shows its last digits after an ellipsis.
timestamps Show the time each row was first reached. A row shows it only where it differs from the row above, so a long output does not repeat one second.
timestamp_format A std::format chrono specification in local time, such as %H:%M or %a %H:%M:%S. It must begin with a % conversion, so a leading literal such as [%H:%M] is refused, and so is a leading width or alignment such as 8%H or >%H, which std::format would pad the timestamp with. Every character it spells must take exactly one column, so a double-width character (a CJK ideograph, say) or a combining mark is refused as well. A format that cannot be drawn is reported when the configuration loads, and the default is kept.

In vi normal mode, za, zo, zc, zM and zR toggle, open and close the block under the cursor, and close or open all of them, as in vim.

osc_context

configuration controls whether Contour reads OSC 3008, systemd's hierarchical context signalling (UAPI.15): the nested stack of contexts a shell, run0, ssh or a container runtime opens around whatever runs inside it.

osc_context:
  enabled: true
  max_depth: 16
  max_retained_contexts: 256
  derive_markers: when_alone
  tinting: boundaries
systemd 258 and later ship a shell snippet that emits these sequences around every interactive command with no configuration at all, so on such a system Contour learns command boundaries, exit statuses (including whether a command crashed or was interrupted, which OSC 133 cannot express) and working directories without any shell integration being installed. enabled Whether the sequences are read at all. When false nothing is tracked, nothing is derived and nothing is tinted.
max_depth How deep the context stack may grow. Beyond it, further contexts are ignored -- the NEWER ones, so that a program cannot push the context established above it out of the stack.
max_retained_contexts How many contexts are remembered for scrolled-back output that still refers to them. Older ones are forgotten, and output belonging to them simply stops being attributed.
derive_markers Whether OSC 3008 may stand in for a shell integration that is not installed. when_alone derives prompt and command marks from it only while OSC 133 has said nothing; once a shell integration speaks, it owns the marks for the rest of the session. never leaves marks entirely to OSC 133.
tinting Which contexts may tint the page background. The colours themselves come from the colour scheme's tint: map, which no shipped scheme sets, so nothing is tinted until you choose a colour there. Note that a context is something the session announced: anything that can write to your terminal can announce one, or fail to announce one, so the absence of a tint is not a statement that nothing is elevated.

command_blocks

configuration controls what the terminal remembers about each shell command it saw run.

command_blocks:
  max_records: 1000
  pager: less -R
  pager_format: sgr
A command block is one prompt and the output of the command run at it, delimited by the OSC 133 marks a shell with shell integration emits -- or, without one, by systemd's OSC 3008 contexts. For each block the terminal keeps its command line, exit status, duration, start time and working directory, even after the block's rows have left the scrollback. max_records How many blocks one session remembers; the oldest are forgotten first. At least 1, at most 1000000. A change applies to sessions opened afterwards.
pager The program the OpenCommandOutput action ("Open Output in Pager", Ctrl+Shift+G) opens a command's output with when its binding names none. It is read as a profile's shell: is: a string naming a program runs as it is; otherwise its first word is the program and the rest its arguments -- on Windows passed on as written, so C:\Tools\less.exe -R needs no quoting. A binding's own program: is read the same way. The output is written to a private file that is appended as the last argument and deleted when the pane closes. Defaults to less -R (more on Windows).
pager_format Whether the pager renders colours: sgr writes the output with its SGR sequences, plain as text only. Defaults to sgr, which both less -R and Windows more (inside the terminal's pseudo console) render. A binding's own format: wins, and a binding that names its own program: gets sgr.

default_layout_name

Name of the layout to open at startup, instead of a single default tab. Saved remote hosts that "Attach to Host" lists.### git_drawings fmt formatted doc thin

box_arc_style

fmt formatted doc round

braille_style

fmt formatted doc circle

Default global parameters

platform_plugin: auto
renderer:
    backend: auto
    tile_hashtable_slots: 4096
    tile_cache_count: 4000
    tile_direct_mapping: true
word_delimiters: " /\\()\"'-.,:;<>~!@#$%^&*+=[]{}~?|│"
read_buffer_size: 65536
pty_buffer_size: 1048576
default_profile: main
spawn_new_process: false
reflow_on_resize: true
bypass_mouse_protocol_modifier: Shift
mouse_block_selection_modifier: Control
on_mouse_select: CopyToSelectionClipboard
live_config: false
images:
    sixel_scrolling: true
    sixel_register_count: 4096

The default profile is automatically the top (first) defined profile in the configuration file, but can be explicitly set to an order-independent name using default_profile configuration key.

Profiles

Profiles is the main part of user specific customizations, you can create more than one profile and chose which you want to use during startup or define in configuration file.

By default each profile inherites values from default_profile. This means that you can specify only values that you want to change in respect to default profile, for example you can create new profile to use bash as a shell preserving other configuration from main profile

profiles:
    main:
    # default profile here
    bash:
        shell: "/usr/bin/bash"

For the full list of options see generated configuration file on your system or Profiles section of documentation.

Color Schemes

In contour you can specify different colors inside terminal, for example text background and foreground, cursor properties, selection colors and plenty others. You can configure your color profiles, whereas a color can be expressed in standard web format, with a leading # followed by red/green/blue values, 7 characters in total. You may alternatively use 0x as prefix instead of #. For example 0x102030 is equal to '#102030'.

Syntax for color schemes repeat the one of profiles. First color scheme inside configuration file must be named default, each other color schemes inherit values from default color scheme. Example of configuration for color_schemes

color_schemes:
    default:
    # values for default color scheme
    different_selection:
      selection:
        background: '#fff0f0'

For the full list of options see generated configuration file on your system or Colors section of documentation.