Skip to content

Parentheses and Braces Syntax

Jari Sundell edited this page Jun 16, 2026 · 4 revisions

Scripting: Parentheses and Braces Syntax

Configuration commands use parentheses (...) and braces {...} to create function objects (cmd + args list) and list objects.

Syntax

  • (...) instantiates an internal torrent::Object with a function flag for runtime evaluation and command execution.
  • ((...)) escapes the function object when passing it directly as an argument to commands like method.set_key, schedule, and event triggers.
  • {...} constructs a list object.
  • {(...)} wraps and escapes embedded function objects so you do not need to individually double-quote or double-parenthesize each nested function block.

1. Parentheses (...) — Functional Evaluation

Behavior

  • Automatically generates a key/args dictionary object with the function flag.
  • Expands commands in arguments that are not double-parenthesis: (cmd, arg1, ((...)), arg2)
  • The parser may expands arguments (or turn ((...)) into (...)), depending on context.

Detailed Explanation

A single-parenthesis block (cmd, ...) is a function object.

A double-parenthesis block ((cmd, ...)) is a nested function object, and turns into a function object when passed as argument to e.g. scheduler.

A bracket+parenthesis block {(cmd, ...), ...} is a list of function objects, and does not expand function objects in arguments.

The parser splits any non-quoted string by commas, transforming elements into distinct objects of various types. For functions, this is a dict-key + dict-value(list) marked with the function flag.

Examples

# Depth-2 double parentheses escape the method, bypassing outer quotes entirely
method.set_key = event.download.finished, clear_label, ((d.custom.set, label, ""))

# Calls d.custom.set if incomplete.
(if, (d.custom, incomplete), (d.custom.set, incomplete, 0))

# Returns either a string "incomplete" or "foo-bar" and passes it to print.
print=(if, (d.custom, incomplete), incomplete, (cat, foo-, bar))

2. Braces {...} — List Objects and Advanced Escaping

Behavior

  • {...} builds a native list object containing literal strings or distinct argument tokens.
  • {(...)} acts as a structural wrapper that escapes embedded function blocks, preventing the parser from breaking up inner function commas.

Detailed Explanation

Braces are strictly used for grouping items into a list object. Inside a basic brace vector {item1, item2}, commas do not trigger rTorrent functions; they serve as list element dividers. This is primarily used to isolate command flags sent straight to the operating system execution vector.

Combining braces and parentheses into the {(...)} syntax provides an elegant alternative for handling complex event bindings. Wrapping your logical conditions and actions inside a brace-escaped block allows you to nest multiple standard function objects freely. This structure guarantees that rTorrent treats the entire expression as a contained sequence of executable actions, completely eliminating the need to double-quote or double-parenthesize every single inner function object manually.

Structural Comparison

Feature Parentheses (...) Braces {...}
Parser Type torrent::Object (with Function Flag) List Object Vector
Comma Action Splits program method arguments Splits list object tokens
Evaluation Evaluates and updates data dynamically Treats contents as raw literal values

Syntax Evolution: Old Style vs. New Style

Old Style (Legacy String & Quote Escaping)

The legacy configuration relies heavily on string wrapper passing. This forces nested arguments into multiple layers of outer quotation marks and escaped inner quotes (\\"), which are error-prone and harder to parse:

schedule = foo, 0, 10, "load.start=~/Download/watch_old/*.torrent,\"d.custom.set=incomplete,1\""
method.set_key=event.download.finished, cldvar,"branch=d.custom=incomplete,\"d.custom.set=incomplete,0\""
method.set_key=event.download.erased, rm_files,"branch=d.custom=incomplete,\"execute={rm,-rf,--,\$d.base_path=}\""
method.set_key=event.download.erased, rm_torrent_files,"branch=d.custom=incomplete,d.delete_tied="

New Style (Pure Parenthesis Tree / Escaped Functions)

The preferred, modern alternative drops all quotation marks entirely. By leveraging parenthetical evaluation arrays, function blocks are safely escaped as deep arguments. Note that variables must also be cleanly escaped as functional blocks (e.g., ((d.base_path))) inside the deepest execution layers to protect their argument commas from higher parser steps:

schedule = foo, 0, 10, ((load.start, ~/Download/watch_old/*.torrent, ((d.custom.set, incomplete, 1)) ))
method.set_key = event.download.finished, cldvar, ((branch, ((d.custom, incomplete)), ((d.custom.set, incomplete, 0)) ))
method.set_key = event.download.erased, rm_files, ((branch, ((d.custom, incomplete)), ((execute, rm, -rf, --, ((d.base_path)) )) ))
method.set_key = event.download.erased, rm_torrent_files, ((branch, ((d.custom, incomplete)), ((d.delete_tied)) ))

Alternative Approach: Function List {(...)}

Instead of handling complex multi-layered parenthesis escapes for inner commands and paths, you can pass the logic block as a list containing a function. This acts as a robust literal shield, completely removing the need to escape the deepest arguments or variables (allowing you to use a flat (d.base_path) call cleanly):

# Passes the block as a list-wrapped function, preventing argument parsing issues inside the shell command
method.set_key = event.download.erased, rm_files, {(branch, ((d.custom, incomplete)), ((execute, rm, -rf, --, (d.base_path) )) )}

Clone this wiki locally