Skip to content

Reference: Merge Key Syntax

Abstract

Dracon extends the standard YAML merge key (<<:) to provide fine-grained control over how dictionaries (mappings) and lists (sequences) are combined during configuration composition.

Syntax

The extended merge key follows the pattern:

<<{dict_opts}[list_opts]@target_path: source_node
  • <<:: The merge key indicator.
  • {dict_opts} (Optional): Controls dictionary merging.
  • [list_opts] (Optional): Controls list merging.
  • @target_path (Optional): KeyPath specifying a sub-key within the current mapping where the merge should apply (relative path). Defaults to the current mapping.
  • source_node: The node providing data to merge (e.g., *anchor, !include ..., inline mapping/list).

Dictionary Options ({dict_opts})

Placed inside {}. Combine one mode option with one priority option. Optional depth modifier.

  • Mode:
  • + (Default): Append/Recurse. Adds new keys. For existing keys, recursively merges if both values are dicts (up to dict_depth). Otherwise, resolves conflict based on priority.
  • ~: Replace. Adds new keys. For existing keys, always replaces the entire value based on priority (no recursion).
  • Priority:
  • > (Default with +): Existing Wins. Keep the value from the dictionary containing the <<: key.
  • < (Default with ~): New Wins. Keep the value from the source_node.
  • Depth:
  • N (integer, e.g., {+2>}): Limits recursion depth for + mode to N levels. Deeper levels are resolved by priority without recursion.

Note

If {} is omitted or empty and no @target_path is specified, defaults to {+>} (Append/Recurse, Existing Wins). If @target_path is specified, the default usually implies an override intent, changing to {<+} (Append/Recurse, New Wins).

List Options ([list_opts])

Placed inside []. Combine one mode option with one priority option. Applies only when both the existing and new values for a key are lists.

  • Mode:
  • ~ (Default): Replace. The entire list is replaced by one of the lists based on priority.
  • +: Concatenate. The lists are combined into a single list.
  • Priority:
  • > (Default): Existing Wins / Appends. In ~ mode, keeps the existing list. In + mode, appends the new list's elements (existing + new).
  • <: New Wins / Prepends. In ~ mode, keeps the new list. In + mode, prepends the new list's elements (new + existing).
  • Depth:
  • N (integer, e.g., [+1<]): Limits recursion depth within nested structures during list concatenation (less common).

Note

If [] is omitted or empty, it defaults to [~>] (Replace, Existing Wins).

Combined Default (<<:)

If only <<: is used without any {} or [] options and no @target_path, the effective default behavior is <<{+>}[~>]:

  • Dictionaries: Append/Recurse, Existing Wins.
  • Lists: Replace, Existing Wins.

Examples

Syntax Dictionary Behavior List Behavior Description
<<: Append/Recurse, Existing Wins ({+>}) Replace, Existing Wins ([~>]) Default merge: recursive dicts, replace lists, existing wins.
<<{<+}: Append/Recurse, New Wins Replace, Existing Wins ([~>]) Common override pattern (new file wins dict keys)
<<[+>]: Append/Recurse, Existing Wins ({+>}) Concatenate, Existing first Append new list items to existing list
<<[+<]: Append/Recurse, Existing Wins ({+>}) Concatenate, New first Prepend new list items to existing list
<<{~<}[~>]: Replace, New Wins Replace, Existing Wins Dict values fully replaced (new wins), list kept existing
<<@target: Append/Recurse, New Wins ({<+}) Replace, New Wins ([~<]) Implicit default for targeted merge (override subkey)

Note

The order of {} and [] does not matter (e.g., <<{+<}[+>] is the same as <<[+>]{+<}).