libtmux Reference MCP Search
On this page

Python API reference

2005 symbols, extracted from source. Every type name in a signature links to its own entry; every cross-reference in a doc comment resolves against the same table.

By module 26 modules

  • libtmux 14
  • libtmux.__about__ 4
  • libtmux._compat 9
  • libtmux.client 1
  • libtmux.common 25
  • libtmux.constants 11
  • libtmux.exc 29
  • libtmux.formats 5
  • libtmux.hooks 4
  • libtmux.neo 19
  • libtmux.options 18
  • libtmux.pane 1
  • libtmux.pytest_plugin 14
  • libtmux.server 3
  • libtmux.session 1
  • libtmux.window 1
  • libtmux._internal.constants 9
  • libtmux._internal.control_mode 1
  • libtmux._internal.dataclasses 1
  • libtmux._internal.env 5
  • libtmux._internal.query_list 21
  • libtmux._internal.sparse_array 4
  • libtmux._internal.types 1
  • libtmux._vendor._structures 4
  • libtmux._vendor.version 19
  • Types 2
Server 1 type
Session 1 type
Window 2 types
Pane 2 types
Client 1 type
Hooks 1 type
Options 2 types
Layout and geometry 1 type
Environment 1 type
Versions 3 types
Commands 3 types
Errors 20 types
InvalidVersion 1 members

Raised when a version string is not a valid version.

_TmuxVersionUnavailable 0 members

Internal signal: this tmux predates the -V flag (pre-1.7).

LibTmuxException 2 members

Base Exception for libtmux Errors.

DeprecatedError 2 members

Raised when a deprecated function, method, or parameter is used.

TmuxCommandNotFound 2 members

Application binary for tmux not found.

NotInsideTmux 2 members

Raised when the process is not running inside a tmux pane.

ObjectDoesNotExist 2 members

A lookup expected one object and matched none.

MultipleObjectsReturned 2 members

A lookup expected one object and matched several.

TmuxObjectDoesNotExist 2 members

tmux has no object with the id that was asked for.

VersionTooLow 2 members

Raised if tmux below the minimum version to use libtmux.

OptionError 2 members

Root error for any error involving invalid, ambiguous or bad options.

UnknownOption 2 members

Option unknown to tmux show-option(s) or show-window-option(s).

UnknownColorOption 2 members

Unknown color option.

InvalidOption 2 members

Option invalid to tmux.

AmbiguousOption 2 members

Option that could potentially match more than one.

WaitTimeout 2 members

Function timed out without meeting condition.

TmuxTimeout 1 members

A tmux command did not return within its timeout.

VariableUnpackingError 2 members

Error unpacking variable.

AdjustmentDirectionRequiresAdjustment 2 members

If *adjustment_direction* is set, *adjustment* must be set.

RequiresDigitOrPercentage 2 members

Requires digit (int or str digit) or a percentage.

Errors — Session 2 types
Errors — Window 5 types
Errors — Pane 3 types
Internal 7 types
Internal — Options 5 types
Other 4 types
Functions and constants 0 types
__all__ = ( "Client", "Pane", "Server", "Session", "Window", "__author__", "__copyright__", "__description__", "__email__", "__license__", "__package_name__", "__title__", "__version__", )
constant [source]
constant [source]
__all__
__all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "parse"]
constant [source]
constant [source]
__all__
__author__ = "Tony Narlock"
constant [source]
constant [source]
__author__
__description__ = "Typed scripting library / ORM / API wrapper for tmux"
constant [source]
constant [source]
__description__
__docs__ = "https://libtmux.git-pull.com"
constant [source]
constant [source]
__docs__
__email__ = "[email protected]"
constant [source]
constant [source]
__email__
__github__ = "https://github.com/tmux-python/libtmux"
constant [source]
constant [source]
__github__
__license__ = "MIT"
constant [source]
constant [source]
__license__
__package_name__ = "libtmux"
constant [source]
constant [source]
__package_name__
__pypi__ = "https://pypi.org/project/libtmux/"
constant [source]
constant [source]
__pypi__
__title__ = "libtmux"
constant [source]
constant [source]
__title__
__tracker__ = "https://github.com/tmux-python/libtmux/issues"
constant [source]
constant [source]
__tracker__
__version__ = "0.62.0"
constant [source]
constant [source]
__version__
_CONTEXT_ONLY_TOKENS : frozenset[str] = frozenset( { "command_list_alias", "command_list_name", "command_list_usage", "current_file", "search_match", } )
constant [source]
constant [source]
_CONTEXT_ONLY_TOKENS
_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE)
constant [source]
constant [source]
_legacy_version_component_re
_legacy_version_replacement_map = { "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", }
constant [source]
constant [source]
_legacy_version_replacement_map
_local_version_separators = re.compile(r"[\._-]")
constant [source]
constant [source]
_local_version_separators
_SCOPE_OVERRIDES : dict[str, str] = { "cursor_x": "pane", # ft->wp->base.cx "cursor_y": "pane", # ft->wp->base.cy "cursor_flag": "pane", # ft->wp->base.mode "cursor_character": "pane", # ft->wp "mouse_all_flag": "pane", # ft->wp->base.mode MODE_MOUSE_ALL "mouse_any_flag": "pane", # ft->wp->base.mode ALL_MOUSE_MODES "mouse_button_flag": "pane", # ft->wp->base.mode MODE_MOUSE_BUTTON "mouse_sgr_flag": "pane", # ft->wp->base.mode MODE_MOUSE_SGR "mouse_standard_flag": "pane", # ft->wp->base.mode MODE_MOUSE_STANDARD "scroll_region_lower": "pane", # ft->wp->base.rlower "scroll_region_upper": "pane", # ft->wp->base.rupper "alternate_saved_x": "pane", # ft->wp->base.saved_cx "alternate_saved_y": "pane", # ft->wp->base.saved_cy "history_bytes": "pane", # ft->wp "history_limit": "pane", # ft->wp->base.grid->hlimit "history_size": "pane", # ft->wp->base.grid->hsize "insert_flag": "pane", # ft->wp->base.mode MODE_INSERT "keypad_cursor_flag": "pane", # ft->wp->base.mode MODE_KCURSOR "keypad_flag": "pane", # ft->wp->base.mode MODE_KKEYPAD "origin_flag": "pane", # ft->wp->base.mode MODE_ORIGIN "wrap_flag": "pane", # ft->wp->base.mode MODE_WRAP "active_window_index": "session", # ft->s->curw->idx "last_window_index": "session", # ft->s # tmux 3.7 pane-scope tokens that don't carry the pane_ prefix. "bracket_paste_flag": "pane", # ft->wp->screen->mode MODE_BRACKETPASTE "synchronized_output_flag": "pane", # ft->wp->base.mode MODE_SYNC }
constant [source]
constant [source]
_SCOPE_OVERRIDES
_SCOPE_PREFIXES : tuple[tuple[str, str], ...] = ( ("copy_cursor_", "event"), ("pane_", "pane"), ("window_", "window"), ("session_", "session"), ("client_", "client"), ("buffer_", "buffer"), ("mouse_", "event"), ("cursor_", "event"), ("selection_", "event"), ("scroll_", "event"), ("popup_", "event"), )
constant [source]
constant [source]
_SCOPE_PREFIXES
_UNIVERSAL_TOKENS : frozenset[str] = frozenset( { "config_files", "host", "host_short", "line", "next_session_id", "pid", "socket_path", "start_time", "uid", "user", "version", } )
constant [source]
constant [source]
_UNIVERSAL_TOKENS
_V = t.TypeVar("_V")
constant [source]
constant [source]
_V
_Version = collections.namedtuple( "_Version", ["epoch", "release", "dev", "pre", "post", "local"], )
constant [source]
constant [source]
_Version
_VERSION_PATTERN = r""" v? (?: (?:(?P<epoch>[0-9]+)!)? # epoch (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment (?P<pre> # pre-release [-_\.]? (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) [-_\.]? (?P<pre_n>[0-9]+)? )? (?P<post> # post release (?:-(?P<post_n1>[0-9]+)) | (?: [-_\.]? (?P<post_l>post|rev|r) [-_\.]? (?P<post_n2>[0-9]+)? ) )? (?P<dev> # dev release [-_\.]? (?P<dev_l>dev) [-_\.]? (?P<dev_n>[0-9]+)? )? ) (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version """
constant [source]
constant [source]
_VERSION_PATTERN
CLIENT_FORMATS = [ "client_cwd", "client_height", "client_width", "client_tty", "client_termname", "client_created", "client_created_string", "client_activity", "client_activity_string", "client_prefix", "client_utf8", "client_readonly", "client_session", "client_last_session", ]
constant [source]
constant [source]
CLIENT_FORMATS
CmpKey = tuple[ int, tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType, ]
constant [source]
constant [source]
CmpKey
CommandAliases = dict[str, str]
constant [source]
constant [source]
CommandAliases
console_encoding = sys.stdout.encoding
constant [source]
constant [source]
console_encoding
ConvertedValue : TypeAlias = str | int | bool | None
constant [source]
constant [source]
ConvertedValue
ConvertedValues : TypeAlias = ( ConvertedValue | list[ConvertedValue] | dict[str, ConvertedValue] | SparseArray[ConvertedValue] )
constant [source]
constant [source]
ConvertedValues
DEFAULT_OPTION_SCOPE : _DefaultOptionScope = _DefaultOptionScope()
constant [source]
constant [source]
DEFAULT_OPTION_SCOPE
ExplodedComplexUntypedOptionsDict : TypeAlias = dict[ str, str | int | list[str | int] | dict[str, list[str | int]] | SparseArray[str | int] | None, ]
constant [source]
constant [source]
ExplodedComplexUntypedOptionsDict
ExplodedUntypedOptionsDict : TypeAlias = dict[ str, str | int | list[str] | dict[str, list[str]], ]
constant [source]
constant [source]
ExplodedUntypedOptionsDict
FIELD_VERSION : dict[str, str] = { # Post-3.2a additions (verified against tmux's format.c at each gated # release tag, e.g. https://github.com/tmux/tmux/blob/3.6a/format.c). "pane_dead_signal": "3.3", "pane_dead_time": "3.3", # tmux 3.7 additions (verified against format.c / tmux.1 at the 3.7 tag). "bracket_paste_flag": "3.7", "pane_flags": "3.7", "pane_floating_flag": "3.7", "pane_pb_progress": "3.7", "pane_pb_state": "3.7", "pane_pipe_pid": "3.7", "pane_x": "3.7", "pane_y": "3.7", "pane_z": "3.7", "pane_zoomed_flag": "3.7", "synchronized_output_flag": "3.7", }
constant [source]
constant [source]
FIELD_VERSION

Minimum tmux version that registers each format token.

Field names absent from this dict default to "3.2a" (always-safe within the supported tmux range). Entries here represent tokens added after 3.2a that need explicit gating to keep the -F template compatible with older tmux versions.

FORMAT_SEPARATOR = os.environ.get("LIBTMUX_TMUX_FORMAT_SEPARATOR", "␞")
constant [source]
constant [source]
FORMAT_SEPARATOR
HOOK_SCOPE_FLAG_MAP : dict[OptionScope, str] = { OptionScope.Server: "-g", OptionScope.Session: "", OptionScope.Window: "-w", OptionScope.Pane: "-p", }
constant [source]
constant [source]
HOOK_SCOPE_FLAG_MAP
HookArray : TypeAlias = "dict[str, SparseArray[str]]"
constant [source]
constant [source]
HookArray
HookArray : TypeAlias = "dict[str, SparseArray[str]]"
constant [source]
constant [source]
HookArray
HookDict = dict[str, t.Any]
constant [source]
constant [source]
HookDict
HookValues = dict[int, str] | SparseArray[str] | list[str]
constant [source]
constant [source]
HookValues
InfiniteTypes = InfinityType | NegativeInfinityType
constant [source]
constant [source]
InfiniteTypes
Infinity = InfinityType()
constant [source]
constant [source]
Infinity
LegacyCmpKey = Tuple[int, Tuple[str, ...]]
constant [source]
constant [source]
LegacyCmpKey
LocalTuple = ( SubLocalType | tuple[SubLocalType, str] | tuple[NegativeInfinityType, SubLocalType] )
constant [source]
constant [source]
LocalTuple
LocalType = NegativeInfinityType | tuple[LocalTuple, ...]
constant [source]
constant [source]
LocalType
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
logger = logging.getLogger(__name__)
constant [source]
constant [source]
logger
LOOKUP_NAME_MAP : Mapping[str, LookupProtocol] = { "eq": lookup_exact, "exact": lookup_exact, "iexact": lookup_iexact, "contains": lookup_contains, "icontains": lookup_icontains, "startswith": lookup_startswith, "istartswith": lookup_istartswith, "endswith": lookup_endswith, "iendswith": lookup_iendswith, "in": lookup_in, "nin": lookup_nin, "regex": lookup_regex, "iregex": lookup_iregex, }
constant [source]
constant [source]
LOOKUP_NAME_MAP
LooseVersion = LegacyVersion
constant [source]
constant [source]
LooseVersion
NegativeInfinity = NegativeInfinityType()
constant [source]
constant [source]
NegativeInfinity
no_arg = object()
constant [source]
constant [source]
no_arg
OPTION_SCOPE_FLAG_MAP : dict[OptionScope, str] = { OptionScope.Server: "-s", OptionScope.Session: "", OptionScope.Window: "-w", OptionScope.Pane: "-p", }
constant [source]
constant [source]
OPTION_SCOPE_FLAG_MAP
OptionDict : TypeAlias = dict[str, t.Any]
constant [source]
constant [source]
OptionDict
OutputRaw = dict[str, t.Any]
constant [source]
constant [source]
OutputRaw
OutputsRaw = list[OutputRaw]
constant [source]
constant [source]
OutputsRaw
PANE_DIRECTION_FLAG_MAP : dict[PaneDirection, list[str]] = { # -v is assumed, but for explicitness it is passed PaneDirection.Above: ["-v", "-b"], PaneDirection.Below: ["-v"], PaneDirection.Right: ["-h"], PaneDirection.Left: ["-h", "-b"], }
constant [source]
constant [source]
PANE_DIRECTION_FLAG_MAP
PANE_FORMATS = [ "history_size", "history_limit", "history_bytes", "pane_index", "pane_width", "pane_height", "pane_title", "pane_id", "pane_active", "pane_dead", "pane_in_mode", "pane_synchronized", "pane_tty", "pane_pid", "pane_start_command", "pane_start_path", "pane_current_path", "pane_current_command", "cursor_x", "cursor_y", "scroll_region_upper", "scroll_region_lower", "saved_cursor_x", "saved_cursor_y", "alternate_on", "alternate_saved_x", "alternate_saved_y", "cursor_flag", "insert_flag", "keypad_cursor_flag", "keypad_flag", "wrap_flag", "mouse_standard_flag", "mouse_button_flag", "mouse_any_flag", "mouse_utf8_flag", # tmux 3.7 "pane_flags", "pane_floating_flag", "pane_x", "pane_y", "pane_z", "pane_zoomed_flag", "pane_pb_progress", "pane_pb_state", "pane_pipe_pid", "bracket_paste_flag", "synchronized_output_flag", ]
constant [source]
constant [source]
PANE_FORMATS
PaneDict = dict[str, t.Any]
constant [source]
constant [source]
PaneDict
PrePostDevType = InfiniteTypes | tuple[str, int]
constant [source]
constant [source]
PrePostDevType
RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP : dict[ResizeAdjustmentDirection, str] = { ResizeAdjustmentDirection.Up: "-U", ResizeAdjustmentDirection.Down: "-D", ResizeAdjustmentDirection.Left: "-L", ResizeAdjustmentDirection.Right: "-R", }
constant [source]
constant [source]
RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP
SCOPES_BY_LIST_CMD : dict[str, frozenset[str]] = { "list-sessions": frozenset({"universal", "session", "window", "pane"}), "list-windows": frozenset({"universal", "session", "window", "pane"}), "list-panes": frozenset({"universal", "session", "window", "pane"}), "list-clients": frozenset({"universal", "session", "window", "pane", "client"}), }
constant [source]
constant [source]
SCOPES_BY_LIST_CMD

Format-token scopes a given tmux list-* subcommand can resolve.

A token whose scope is in the set is safe to include in that subcommand's -F template. A token whose scope is *outside* the set may be unavailable for that command, so libtmux leaves it out.

The relationship is asymmetric: when tmux lists a parent object, it can also report fields for that parent's active child. A session row can include its current window and active pane fields, and a client row can include the attached session, current window, and active pane. client scope is the exception in the other direction: it appears only in list-clients because session/window/pane listings do not have a client attachment to report.

SESSION_FORMATS = [ "session_name", "session_windows", "session_width", "session_height", "session_id", "session_created", "session_created_string", "session_attached", # "session_grouped", Apparently unused in tmux. "session_group", ]
constant [source]
constant [source]
SESSION_FORMATS
SessionDict = dict[str, t.Any]
constant [source]
constant [source]
SessionDict
StrPath : TypeAlias = "str | PathLike[str]"
constant [source]
constant [source]
StrPath
SubLocalType = InfiniteTypes | int | str
constant [source]
constant [source]
SubLocalType
T = t.TypeVar("T")
constant [source]
constant [source]
T
T = t.TypeVar("T")
constant [source]
constant [source]
T
T = t.TypeVar("T")
constant [source]
constant [source]
T
TerminalFeatures = dict[str, list[str]]
constant [source]
constant [source]
TerminalFeatures
TerminalOverride = dict[str, str | None]
constant [source]
constant [source]
TerminalOverride
TerminalOverrides = dict[str, TerminalOverride]
constant [source]
constant [source]
TerminalOverrides
TMUX : t.Final = "TMUX"
constant [source]
constant [source]
TMUX

Environment variable tmux exports with socket_path,server_pid,session_id.

TMUX_MAX_VERSION = "3.7"
constant [source]
constant [source]
TMUX_MAX_VERSION
TMUX_MIN_VERSION = "3.2a"
constant [source]
constant [source]
TMUX_MIN_VERSION
TMUX_PANE : t.Final = "TMUX_PANE"
constant [source]
constant [source]
TMUX_PANE

Environment variable tmux exports with the pane's id, e.g. %3.

UntypedOptionsDict : TypeAlias = dict[str, str | None]
constant [source]
constant [source]
UntypedOptionsDict
USING_ZSH = "zsh" in os.getenv("SHELL", "")
constant [source]
constant [source]
USING_ZSH
VERSION_PATTERN = _VERSION_PATTERN
constant [source]
constant [source]
VERSION_PATTERN

A string containing the regular expression used to match a valid version.

The pattern is not anchored at either end, and is intended for embedding in larger expressions (for example, matching a version number as part of a file name). The regular expression should be compiled with the re.VERBOSE and re.IGNORECASE flags set.

:meta hide-value:

VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool]
constant [source]
constant [source]
VersionComparisonMethod
WINDOW_DIRECTION_FLAG_MAP : dict[WindowDirection, str] = { WindowDirection.Before: "-b", WindowDirection.After: "-a", }
constant [source]
constant [source]
WINDOW_DIRECTION_FLAG_MAP
WINDOW_FORMATS = [ # format_window() "window_id", "window_name", "window_width", "window_height", "window_layout", "window_panes", # format_winlink() "window_index", "window_flags", "window_active", "window_bell_flag", "window_activity_flag", "window_silence_flag", ]
constant [source]
constant [source]
WINDOW_FORMATS
WindowDict = dict[str, t.Any]
constant [source]
constant [source]
WindowDict
WindowOptionDict = dict[str, t.Any]
constant [source]
constant [source]
WindowOptionDict

Pick the winlink row tmux would select.

A list-windows listing enumerates winlinks -- (session, index, window) edges -- not windows. link-window can attach one window to a session at several indexes at once, so the same window_id may appear on several rows, each with a different window_index.

tmux selects the current winlink when it contains the window, otherwise the first. #{window_active} identifies the current row, and the lowest window_index is tmux's first -- chosen explicitly here, so the caller need not pre-sort the rows.

Examples

One row is the whole answer:

>>> from libtmux.neo import _best_winlink
>>> _best_winlink([{"window_id": "@0", "window_index": "1"}])["window_index"]
'1'

A window linked into one session twice gives two rows. When the session is sitting on the higher-indexed link, that is the one tmux acts on:

>>> _best_winlink([
...     {"window_id": "@0", "window_index": "1", "window_active": "0"},
...     {"window_id": "@0", "window_index": "5", "window_active": "1"},
... ])["window_index"]
'5'

When the session is sitting on some *other* window, neither link is current, and tmux falls back to the first:

>>> _best_winlink([
...     {"window_id": "@0", "window_index": "1", "window_active": "0"},
...     {"window_id": "@0", "window_index": "5", "window_active": "0"},
... ])["window_index"]
'1'

The fallback reads the lowest index, not the first row, so a listing that happened to arrive high-index-first still answers tmux's first:

>>> _best_winlink([
...     {"window_id": "@0", "window_index": "5", "window_active": "0"},
...     {"window_id": "@0", "window_index": "1", "window_active": "0"},
... ])["window_index"]
'1'
Parameters
  • rows ( OutputsRaw ) – Non-empty rows for one object id in one session. Order does not matter: the current winlink wins, otherwise the lowest window_index.

Returns

OutputRaw The row naming the winlink tmux would act on.

_cmpkey ( epoch : int , release : tuple[int, ...] , pre : tuple[str, int] | None , post : tuple[str, int] | None , dev : tuple[str, int] | None , local : tuple[SubLocalType] | None ) CmpKey
function [source]
function [source]
_cmpkey
_fetch_or_empty ( server : Server , list_cmd : str , kwargs : t.Any ) list[dict[str, t.Any]]
function [source]
function [source]
_fetch_or_empty

Wrap fetch_objs : treat a not-yet-started server as empty.

A fresh Server can be introspected via Server.sessions , Server.windows , etc. before the daemon is up. Other tmux errors, such as socket permission failures, still propagate.

_format_query ( query : t.Mapping[str, t.Any] ) str
function [source]
function [source]
_format_query

Render a QueryList.get lookup back as key=value text.

Examples

>>> from libtmux.exc import _format_query
>>> _format_query({"pane_id": "%0"})
"pane_id='%0'"
>>> _format_query({"window_name": "shared", "window_index": "1"})
"window_name='shared', window_index='1'"
>>> _format_query({})
''
_is_daemon_not_up_error ( stderr_text : str ) bool
function [source]
function [source]
_is_daemon_not_up_error

Return True if the error indicates the tmux server is not running.

tmux signals this in two ways: 1. "no server running" (socket exists but no daemon is listening) 2. "error connecting to ... (No such file or directory)" (socket file is missing)

_is_target_not_found_error ( stderr_text : str ) bool
function [source]
function [source]
_is_target_not_found_error

Return True if tmux failed because the -t target does not exist.

A live tmux server rejects an unknown target with can't find <kind>: <target> on stderr (cmd_find_target in tmux's cmd-find.c), for every object kind and every supported tmux version. Every *other* failure -- a stopped daemon, a missing socket, a permission error -- says something else, and stays a LibTmuxException .

This is the mirror image of libtmux.server._is_daemon_not_up_error : together they answer "is the object gone, or is the server gone?" from the same stderr text.

Examples

>>> from libtmux.neo import _is_target_not_found_error
>>> _is_target_not_found_error("can't find pane: %99")
True
>>> _is_target_not_found_error("can't find window: @99")
True
>>> _is_target_not_found_error("can't find session: $99")
True

A server that isn't there is a different answer:

>>> _is_target_not_found_error("no server running on /tmp/tmux-1000/default")
False
>>> _is_target_not_found_error(
...     "error connecting to /tmp/tmux-1000/nope (No such file or directory)"
... )
False
Parameters
Returns

bool True when the object named by -t does not exist on a reachable server.

_legacy_cmpkey ( version : str ) LegacyCmpKey
function [source]
function [source]
_legacy_cmpkey
_no_version_flag_fallback ( ) str
function [source]
function [source]
_no_version_flag_fallback

Return a synthetic version string when tmux lacks -V.

OpenBSD ships a -V-less base tmux, so assume the maximum supported version; any other platform is genuinely too old.

_normalize_tmux_version ( version : str ) LooseVersion
function [source]
function [source]
_normalize_tmux_version

Convert a tmux version string into a comparable LooseVersion .

tmux master is reported as "master" (or e.g. "3.6a-master"); treat it as larger than any tagged release.

Examples

>>> from libtmux.neo import _normalize_tmux_version
>>> _normalize_tmux_version("3.6a") < _normalize_tmux_version("master")
True
>>> _normalize_tmux_version("3.2a") < _normalize_tmux_version("3.6a")
True
_parse_letter_version ( letter : str , number : str | bytes | t.SupportsInt ) tuple[str, int] | None
function [source]
function [source]
_parse_letter_version
_parse_local_version ( local : str ) LocalType | None
function [source]
function [source]
_parse_local_version

Take a string like abc.1.twelve and turns it into ("abc", 1, "twelve").

_parse_version_parts ( s : str ) Iterator[str]
function [source]
function [source]
_parse_version_parts
_query_version ( tmux_bin : str | None = None ) str
function [source]
function [source]
_query_version

Return the raw tmux -V version token, letter suffix intact.

Runs tmux -V and extracts the version token (e.g. "3.7a", "master", "next-3.8"). Not memoized -- get_version and get_version_str each cache their own result on top of this query.

Parameters
  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

str Raw version token from tmux -V.

Raises
_reap_test_server ( socket_name : str | None ) None
function [source]
function [source]
_reap_test_server

Kill the tmux daemon on socket_name and unlink the socket file.

Invoked from the server and TestServer fixture finalizers to guarantee teardown even when the daemon has already exited (kill is a no-op then) and the socket file was left on disk. tmux does not reliably unlink(2) its socket on non-graceful exit, so /tmp/tmux-<uid>/ otherwise accumulates stale entries across test runs.

Conservative: suppresses LibTmuxException / OSError on both the kill and the unlink. A finalizer that raises replaces the real test failure with a cleanup error, and cleanup failures are not actionable (socket already gone, permissions changed, race with a concurrent pytest-xdist worker).

_split_records ( stdout : list[str] , field_count : int ) list[str]
function [source]
function [source]
_split_records

Regroup -F output into one string per object.

tmux writes one record per line, but any format value may itself contain a newline -- pane_current_path for a directory whose name has one -- and that splits the record across output lines. Iterating lines then hands parse_output a fragment with too few values, which its strict zip rejects, so one directory breaks every object on the server rather than the one pane in it.

Regrouping on the separator is exact rather than merely better: the template from get_output_format terminates *every* field with a separator, so one record holds exactly field_count of them and a newline is never one. Nothing is split on newlines, so a value may contain any number of them, in any position.

Raises
  • LibTmuxExceptionIf the values do not divide into whole records, which means a value contained the separator itself.

_token_scope ( field_name : str ) str
function [source]
function [source]
_token_scope

Resolve a format token's scope from its name.

Returns "universal" for cross-scope tokens (e.g. version, socket_path, host). Returns "event" for runtime-only tokens that never appear in a list-* output (mouse, cursor, selection, popup). Returns "context" for tokens registered outside format.c's static table (only resolve in a specific command or mode context). Returns "pane" / "window" / "session" / "client" / "buffer" for scope-prefixed tokens.

Fields that don't match any prefix, override, or known-token table fall back to "unknown". "unknown" is intentionally absent from every SCOPES_BY_LIST_CMD entry, so an unclassified field is excluded from every list-* -F template — preventing a future untracked field from being silently emitted under a list command where it might crash older tmux. Add such a field to _SCOPE_OVERRIDES (or the appropriate prefix / known-token table) to admit it.

Examples

>>> from libtmux.neo import _token_scope
>>> _token_scope("pane_id")
'pane'
>>> _token_scope("window_zoomed_flag")
'window'
>>> _token_scope("client_name")
'client'
>>> _token_scope("version")
'universal'
>>> _token_scope("mouse_x")
'event'

Tokens whose name doesn't carry a scope prefix can still be scope-gated via _SCOPE_OVERRIDES (verified against tmux's format_cb_*). The override also corrects prefix-misclassified tokens — e.g. mouse_all_flag is a per-pane mode bit, not a runtime mouse event:

>>> _token_scope("mouse_all_flag")
'pane'
>>> _token_scope("active_window_index")
'session'

Context-only tokens (registered outside format.c's static table) route to the "context" scope and are excluded from every list-* -F template:

>>> _token_scope("command_list_alias")
'context'
>>> _token_scope("search_match")
'context'

Unclassified tokens fall back to "unknown", also excluded from every list command:

>>> _token_scope("libtmux_test_nonexistent_token")
'unknown'
clear_env ( monkeypatch : pytest.MonkeyPatch ) None
function [source]
function [source]
clear_env

Clear out any unnecessary environment variables that could interrupt tests.

tmux show-environment tests were being interrupted due to a lot of crazy env vars.

config_file ( user_path : pathlib.Path ) pathlib.Path
function [source]
function [source]
config_file

Return fixture for .tmux.conf configuration.

  • base-index -g 1

These guarantee pane and windows targets can be reliably referenced and asserted.

Note: You will need to set the home directory, see set_home.

control_mode ( server : Server , session : Session ) t.Callable[[], ControlMode]
function [source]
function [source]
control_mode

Return ControlMode context manager factory.

Returns a callable that creates ControlMode context managers bound to the test's server and session. Use as a context manager to spawn a control-mode tmux client.

While the control-mode client is active, Server.list_clients() will include it.

Examples

>>> from libtmux._internal.control_mode import ControlMode
>>> def test_example(control_mode):
...     with control_mode() as ctl:
...         assert ctl.client_name != ''
convert_value ( value : _V | None ) ConvertedValue | _V | None
function [source]
function [source]
convert_value

Convert raw option strings to python types.

Examples

>>> convert_value("on")
True
>>> convert_value("off")
False
>>> convert_value("1")
1
>>> convert_value("50")
50
>>> convert_value("%50")
'%50'
convert_values ( value : _V | None ) ConvertedValues | _V | None
function [source]
function [source]
convert_values

Recursively convert values to python types via convert_value .

>>> convert_values(None)

>>> convert_values("on") True >>> convert_values("off") False

>>> convert_values(["on"]) [True] >>> convert_values(["off"]) [False]

>>> convert_values({"window_index": "1"}) {'window_index': 1}

>>> convert_values({"visual-bell": "on"}) {'visual-bell': True}

explode_arrays ( _dict : UntypedOptionsDict , force_array : bool = False ) ExplodedUntypedOptionsDict
function [source]
function [source]
explode_arrays

Explode flat, naive options dict's option arrays.

Examples

>>> import io
>>> many_more_options = io.StringIO(r'''
... terminal-features[0] xterm*:clipboard:ccolour:cstyle:focus
... terminal-features[1] screen*:title
... ''')
>>> many_more_flat_dict = parse_options_to_dict(many_more_options)
>>> many_more_flat_dict == {
... "terminal-features[0]": "xterm*:clipboard:ccolour:cstyle:focus",
... "terminal-features[1]": "screen*:title",}
True
>>> explode_arrays(many_more_flat_dict) == {
... "terminal-features": {0: "xterm*:clipboard:ccolour:cstyle:focus",
... 1: "screen*:title"}}
True

tmux arrays allow non-sequential indexes, so we need to support that:

>>> explode_arrays(parse_options_to_dict(io.StringIO(r'''
... terminal-features[0] xterm*:clipboard:ccolour:cstyle:focus
... terminal-features[5] screen*:title
... '''))) == {
... "terminal-features": {0: "xterm*:clipboard:ccolour:cstyle:focus",
... 5: "screen*:title"}}
True

Use force_array=True for hooks, which always use array format:

>>> from libtmux._internal.sparse_array import SparseArray
>>> hooks_output = io.StringIO(r'''
... session-renamed[0] display-message 'renamed'
... session-renamed[5] refresh-client
... pane-focus-in[0] run-shell 'echo focus'
... ''')
>>> hooks_exploded = explode_arrays(
...     parse_options_to_dict(hooks_output),
...     force_array=True,
... )

Each hook becomes a SparseArray preserving indices:

>>> isinstance(hooks_exploded["session-renamed"], SparseArray)
True
>>> hooks_exploded["session-renamed"][0]
"display-message 'renamed'"
>>> hooks_exploded["session-renamed"][5]
'refresh-client'
>>> sorted(hooks_exploded["session-renamed"].keys())
[0, 5]
function [source]
function [source]
explode_complex

Explode arrayed option's complex values.

Examples

>>> import io
>>> explode_complex(explode_arrays(parse_options_to_dict(io.StringIO(r'''
... terminal-features[0] xterm*:clipboard:ccolour:cstyle:focus
... terminal-features[5] screen*:title
... '''))))
{'terminal-features': {'xterm*': ['clipboard', 'ccolour', 'cstyle', 'focus'], 'screen*': ['title']}}
>>> explode_complex(explode_arrays(parse_options_to_dict(io.StringIO(r'''
... terminal-features[0] xterm*:clipboard:ccolour:cstyle:focus
... terminal-features[5] screen*:title
... ''')))) == {
... "terminal-features": {"xterm*": ["clipboard", "ccolour", "cstyle", "focus"],
... "screen*": ["title"]}}
True
>>> explode_complex(explode_arrays(parse_options_to_dict(io.StringIO(r'''
... command-alias[0] split-pane=split-window
... command-alias[1] splitp=split-window
... command-alias[2] "server-info=show-messages -JT"
... ''')))) == {
... "command-alias": {"split-pane": "split-window",
... "splitp": "split-window",
... "server-info": "show-messages -JT"}}
True
>>> explode_complex(explode_arrays({"terminal-features": {0: "xterm*:clipboard:ccolour:cstyle:focus",
... 1: "screen*:title"}}))
{'terminal-features': {0: 'xterm*:clipboard:ccolour:cstyle:focus', 1: 'screen*:title'}}
>>> explode_complex(explode_arrays({"terminal-features": {0: "xterm*:clipboard:ccolour:cstyle:focus",
... 8: "screen*:title"}})) == SparseArray({'terminal-features': {0:
... 'xterm*:clipboard:ccolour:cstyle:focus', 8: 'screen*:title'}})
True
>>> explode_complex(explode_arrays(parse_options_to_dict(io.StringIO(r'''
... terminal-overrides[0] xterm-256color:Tc
... terminal-overrides[1] *:U8=0
... ''')))) == {
... "terminal-overrides": {"xterm-256color": {"Tc": None},
... "*": {"U8": 0}}}
True
>>> explode_complex(explode_arrays(parse_options_to_dict(io.StringIO(r'''
... user-keys[100] "\e[test"
... user-keys[6] "\e\n"
... user-keys[0] "\e[5;30012~"
... ''')))) == {
... "user-keys": {0: "\\e[5;30012~",
... 6: "\\e\\n",
... 100: "\\e[test"}}
True
>>> explode_complex(explode_arrays(parse_options_to_dict(io.StringIO(r'''
... status-format[0] "#[align=left range=left #{E:status-left-style}]#[push-default]#{T;=/#{status-left-length}:status-left}#[pop-default]#[norange default]#[list=on align=#{status-justify}]#[list=left-marker]<#[list=right-marker]>#[list=on]#{W:#[range=window|#{window_index} #{E:window-status-style}#{?#{&&:#{window_last_flag},#{!=:#{E:window-status-last-style},default}}, #{E:window-status-last-style},}#{?#{&&:#{window_bell_flag},#{!=:#{E:window-status-bell-style},default}}, #{E:window-status-bell-style},#{?#{&&:#{||:#{window_activity_flag},#{window_silence_flag}},#{!=:#{E:window-status-activity-style},default}}, #{E:window-status-activity-style},}}]#[push-default]#{T:window-status-format}#[pop-default]#[norange default]#{?window_end_flag,,#{window-status-separator}},#[range=window|#{window_index} list=focus #{?#{!=:#{E:window-status-current-style},default},#{E:window-status-current-style},#{E:window-status-style}}#{?#{&&:#{window_last_flag},#{!=:#{E:window-status-last-style},default}}, #{E:window-status-last-style},}#{?#{&&:#{window_bell_flag},#{!=:#{E:window-status-bell-style},default}}, #{E:window-status-bell-style},#{?#{&&:#{||:#{window_activity_flag},#{window_silence_flag}},#{!=:#{E:window-status-activity-style},default}}, #{E:window-status-activity-style},}}]#[push-default]#{T:window-status-current-format}#[pop-default]#[norange list=on default]#{?window_end_flag,,#{window-status-separator}}}#[nolist align=right range=right #{E:status-right-style}]#[push-default]#{T;=/#{status-right-length}:status-right}#[pop-default]#[norange default]"
... status-format[1] "#[align=centre]#{P:#{?pane_active,#[reverse],}#{pane_index}[#{pane_width}x#{pane_height}]#[default] }"
... ''')))) == {
... "status-format": {0: "#[align=left range=left #{E:status-left-style}]#[push-default]#{T;=/#{status-left-length}:status-left}#[pop-default]#[norange default]#[list=on align=#{status-justify}]#[list=left-marker]<#[list=right-marker]>#[list=on]#{W:#[range=window|#{window_index} #{E:window-status-style}#{?#{&&:#{window_last_flag},#{!=:#{E:window-status-last-style},default}}, #{E:window-status-last-style},}#{?#{&&:#{window_bell_flag},#{!=:#{E:window-status-bell-style},default}}, #{E:window-status-bell-style},#{?#{&&:#{||:#{window_activity_flag},#{window_silence_flag}},#{!=:#{E:window-status-activity-style},default}}, #{E:window-status-activity-style},}}]#[push-default]#{T:window-status-format}#[pop-default]#[norange default]#{?window_end_flag,,#{window-status-separator}},#[range=window|#{window_index} list=focus #{?#{!=:#{E:window-status-current-style},default},#{E:window-status-current-style},#{E:window-status-style}}#{?#{&&:#{window_last_flag},#{!=:#{E:window-status-last-style},default}}, #{E:window-status-last-style},}#{?#{&&:#{window_bell_flag},#{!=:#{E:window-status-bell-style},default}}, #{E:window-status-bell-style},#{?#{&&:#{||:#{window_activity_flag},#{window_silence_flag}},#{!=:#{E:window-status-activity-style},default}}, #{E:window-status-activity-style},}}]#[push-default]#{T:window-status-current-format}#[pop-default]#[norange list=on default]#{?window_end_flag,,#{window-status-separator}}}#[nolist align=right range=right #{E:status-right-style}]#[push-default]#{T;=/#{status-right-length}:status-right}#[pop-default]#[norange default]",
... 1: "#[align=centre]#{P:#{?pane_active,#[reverse],}#{pane_index}[#{pane_width}x#{pane_height}]#[default] }",
... }}
True
fetch_obj ( server : Server , obj_key : str , obj_id : str , list_cmd : ListCmd = "list-panes" , list_extra_args : ListExtraArgs = None ) OutputRaw
function [source]
function [source]
fetch_obj

Fetch the single list-* row whose *obj_key* equals *obj_id*.

A listing enumerates winlinks, so a window linked into one session at two indexes matches twice. _best_winlink then picks the row tmux itself would act on, rather than whichever sorted last.

Examples

>>> from libtmux.neo import fetch_obj
>>> fetch_obj(
...     server=pane.server,
...     obj_key="pane_id",
...     obj_id=pane.pane_id,
...     list_cmd="list-panes",
...     list_extra_args=("-t", pane.pane_id),
... )["pane_id"] == pane.pane_id
True

A pane that does not exist on a live server is a TmuxObjectDoesNotExist , not a bare tmux error:

>>> from libtmux import exc
>>> try:
...     fetch_obj(
...         server=pane.server,
...         obj_key="pane_id",
...         obj_id="%99999",
...         list_cmd="list-panes",
...         list_extra_args=("-t", "%99999"),
...     )
... except exc.TmuxObjectDoesNotExist as e:
...     print(e)
Could not find pane_id=%99999 for list-panes ('-t', '%99999')
Parameters
  • server ( Server ) – The tmux server to query.

  • obj_key ( str ) – Identity field to match, e.g. "pane_id".

  • obj_id ( str ) – Value the identity field must equal, e.g. "%3".

  • list_cmd ( ListCmd ) – tmux list subcommand to run.

  • list_extra_args ( ListExtraArgs ) – Extra arguments appended verbatim to the tmux command, e.g. ("-t", "%3") to scope the listing to one object's parent.

Returns

OutputRaw The matching row, as a dict of tmux format fields.

Raises
  • TmuxObjectDoesNotExistWhen the object does not exist -- whether tmux said so on stderr (can't find pane: %99, for a -t-scoped listing) or the object simply never appeared in the rows.

  • LibTmuxExceptionFor every other tmux failure, notably an unreachable server.

fetch_objs ( server : Server , list_cmd : ListCmd , list_extra_args : ListExtraArgs = None , filter : str | None = None , # noqa: A002 ) OutputsRaw
function [source]
function [source]
fetch_objs

Fetch a listing of raw data from a tmux command.

Runs a tmux list command (e.g. list-sessions) with the format string from get_output_format and parses each line of output into a dict.

Examples

>>> from libtmux.neo import fetch_objs
>>> objs = fetch_objs(server=server, list_cmd="list-sessions")
>>> isinstance(objs, list)
True
>>> isinstance(objs[0], dict)
True
>>> 'session_id' in objs[0]
True
Parameters
  • server ( Server ) – The tmux server to query.

  • list_cmd ( ListCmd ) – The tmux list command to run, e.g. "list-sessions", "list-windows", or "list-panes".

  • list_extra_args ( ListExtraArgs ) – Extra arguments appended to the tmux command (e.g. ("-a",) for all windows/panes, or ["-t", session_id] to filter).

  • filter ( str | None ) – Filter expression evaluated by tmux (-f flag). tmux omits rows whose expanded expression is false before libtmux parses the result. tmux silently expands a malformed filter (unclosed #{...}, unknown format token) to empty, which is treated as false — every row is suppressed and no stderr is emitted. A bad filter is indistinguishable from "filter matched nothing"; verify the expression against the FORMATS section of tmux(1). See native-filtering for the typed wrappers that share this caveat. Warning: added 0.57

Returns

OutputsRaw A list of dicts, each mapping tmux format field names to their non-empty string values.

Raises
get_libtmux_version ( ) LooseVersion
function [source]
function [source]
get_libtmux_version

Return libtmux version is a PEP386 compliant format.

Returns

distutils.version.LooseVersion libtmux version

get_output_format ( list_cmd : str = "list-panes" , tmux_version : str = "3.2a" ) tuple[tuple[str, ...], str]
function [source]
function [source]
get_output_format

Return field names and tmux format string filtered by scope and version.

Only emits tokens whose scope is reachable from *list_cmd* (per SCOPES_BY_LIST_CMD ) and whose minimum tmux version (per FIELD_VERSION ) is at or below *tmux_version*. Runtime-only tokens (mouse_*, cursor_*, popups) are excluded from every list-* template — they only resolve in event-time format contexts.

Examples

>>> from libtmux.neo import get_output_format
>>> fields, fmt = get_output_format("list-sessions", "3.6a")
>>> 'session_id' in fields
True
>>> 'pane_id' in fields  # active pane for the listed session
True
>>> 'client_name' in fields  # upward not allowed
False
>>> 'server' in fields
False

Pane scope picks up window and session tokens too:

>>> fields, _ = get_output_format("list-panes", "3.6a")
>>> all(t in fields for t in ('pane_id', 'window_id', 'session_id'))
True

list-clients adds fields for the attached client:

>>> fields, _ = get_output_format("list-clients", "3.6a")
>>> 'client_name' in fields
True
>>> 'pane_id' in fields
True
Parameters
  • list_cmd ( str ) – The tmux list subcommand the format string is being built for. Determines which token scopes are reachable.

  • tmux_version ( str ) – The live tmux version. Used to gate post-3.2a tokens. Defaults to "3.2a" (the project's minimum) for safe fallback when the caller can't yet detect the version.

Returns

tuple[tuple[str, ...], str] A tuple of (field_names, tmux_format_string) restricted to tokens the given *list_cmd* and *tmux_version* can resolve.

get_version ( tmux_bin : str | None = None ) LooseVersion
function [source]
function [source]
get_version

Return tmux version.

If tmux is built from git master, the version returned will be the latest version appended with -master, e.g. 2.4-master.

If using OpenBSD's base system tmux, the version will have -openbsd appended to the latest version, e.g. 2.4-openbsd.

Parameters
Returns

distutils.version.LooseVersion tmux version according to *tmux_bin* if provided, otherwise the system tmux from shutil.which

get_version_str ( tmux_bin : str | None = None ) str
function [source]
function [source]
get_version_str

Return the tmux version string verbatim, preserving letter suffixes.

get_version normalizes point releases for numeric comparison ("3.7a" becomes LooseVersion("3.7")). This helper keeps the raw suffix, so callers can distinguish patch releases whose behavior differs -- for example the tmux 3.7 break-pane crash, reverted in 3.7a.

Examples

>>> isinstance(get_version_str(), str)
True
Parameters
  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

str Raw tmux version, e.g. "3.7a". Git builds return "master"; OpenBSD base tmux returns "<max>-openbsd".

handle_option_error ( error : str ) type[exc.OptionError]
function [source]
function [source]
handle_option_error

Raise exception if error in option command found.

In tmux 3.0, show-option and show-window-option return invalid option instead of unknown option. See https://github.com/tmux/tmux/blob/3.0/cmd-show-options.c.

In tmux >2.4, there are 3 different types of option errors:

  • unknown option
  • invalid option
  • ambiguous option

In tmux <2.4, unknown option was the only option.

All errors raised will have the base error of exc.OptionError . So to catch any option error, use except exc.OptionError.

Examples

>>> result = server.cmd(
...     'set-option',
...     'unknown-option-name',
... )
>>> bool(isinstance(result.stderr, list) and len(result.stderr))
True
>>> import pytest
>>> from libtmux import exc
>>> with pytest.raises(exc.OptionError):
...     handle_option_error(result.stderr[0])
Parameters
  • error ( str ) – Error response from subprocess call.

Raises
has_gt_version ( min_version : str , tmux_bin : str | None = None ) bool
function [source]
function [source]
has_gt_version

Return True if tmux version greater than minimum.

Parameters
  • min_version ( str ) – tmux version, e.g. '3.2a'

  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

bool True if version above min_version

has_gte_version ( min_version : str , tmux_bin : str | None = None ) bool
function [source]
function [source]
has_gte_version

Return True if tmux version greater or equal to minimum.

Parameters
  • min_version ( str ) – tmux version, e.g. '3.2a'

  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

bool True if version above or equal to min_version

has_lt_version ( max_version : str , tmux_bin : str | None = None ) bool
function [source]
function [source]
has_lt_version

Return True if tmux version less than minimum.

Parameters
  • max_version ( str ) – tmux version, e.g. '3.2a'

  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

bool True if version below max_version

has_lte_version ( max_version : str , tmux_bin : str | None = None ) bool
function [source]
function [source]
has_lte_version

Return True if tmux version less or equal to minimum.

Parameters
  • max_version ( str ) – tmux version, e.g. '3.2a'

  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

bool True if version below or equal to max_version

has_minimum_version ( raises : bool = True , tmux_bin : str | None = None ) bool
function [source]
function [source]
has_minimum_version

Return True if tmux meets version requirement. Version >= 3.2a.

Parameters
  • raises ( bool ) – raise exception if below minimum version requirement

  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

bool True if tmux meets minimum required version.

Raises
has_version ( version : str , tmux_bin : str | None = None ) bool
function [source]
function [source]
has_version

Return True if tmux version installed.

Parameters
  • version ( str ) – version number, e.g. '3.2a'

  • tmux_bin ( str | None ) – Path to tmux binary. If *None*, uses the system tmux.

Returns

bool True if version matches

home_path ( tmp_path_factory : pytest.TempPathFactory ) pathlib.Path
function [source]
function [source]
home_path

Temporary /home/ path.

home_user_name ( ) str
function [source]
function [source]
home_user_name

Return default username to set for user_path fixture.

is_sparse_array_list ( items : ExplodedComplexUntypedOptionsDict ) TypeGuard[HookArray]
function [source]
function [source]
is_sparse_array_list
keygetter ( obj : Mapping[str, t.Any] , path : str ) t.Any | str | list[str] | Mapping[str, str] | None
function [source]
function [source]
keygetter

Fetch values in objects and keys, supported nested data.

**With dictionaries**:

>>> keygetter({ "food": { "breakfast": "cereal" } }, "food") {'breakfast': 'cereal'}

>>> keygetter({ "food": { "breakfast": "cereal" } }, "food__breakfast") 'cereal'

**With objects**:

>>> from typing import List, Optional >>> from dataclasses import dataclass, field

>>> @dataclass() ... class Food: ... fruit: List[str] = field(default_factory=list) ... breakfast: Optional[str] = None

>>> @dataclass() ... class Restaurant: ... place: str ... city: str ... state: str ... food: Food = field(default_factory=Food)

>>> restaurant = Restaurant( ... place="Largo", ... city="Tampa", ... state="Florida", ... food=Food( ... fruit=["banana", "orange"], breakfast="cereal" ... ) ... )

>>> restaurant Restaurant(place='Largo', city='Tampa', state='Florida', food=Food(fruit=['banana', 'orange'], breakfast='cereal'))

>>> keygetter(restaurant, "food") Food(fruit=['banana', 'orange'], breakfast='cereal')

>>> keygetter(restaurant, "food__breakfast") 'cereal'

lookup_contains ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_contains
lookup_endswith ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_endswith
lookup_exact ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_exact
lookup_icontains ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_icontains
lookup_iendswith ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_iendswith
lookup_iexact ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_iexact
lookup_in ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_in
lookup_iregex ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_iregex
lookup_istartswith ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_istartswith
lookup_nin ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_nin
lookup_regex ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_regex
lookup_startswith ( data : str | list[str] | Mapping[str, str] , rhs : str | list[str] | Mapping[str, str] | re.Pattern[str] ) bool
function [source]
function [source]
lookup_startswith
pane_id_from_env ( env : t.Mapping[str, str] | None = None ) str
function [source]
function [source]
pane_id_from_env

Return the pane id recorded in $TMUX_PANE.

The % sigil is load-bearing: libtmux passes this id straight to tmux as a -t target, and tmux's cmd_find routes a target to its pane slot *by sigil*. A sigil-less value would be matched against session names instead, silently resolving to the wrong object.

Examples

>>> from libtmux._internal.env import pane_id_from_env
>>> pane_id_from_env({"TMUX_PANE": "%3"})
'%3'
>>> pane_id_from_env({})
Traceback (most recent call last):
...
libtmux.exc.NotInsideTmux: Not inside a tmux pane: $TMUX_PANE is unset or empty
>>> pane_id_from_env({"TMUX_PANE": "3"})
Traceback (most recent call last):
...
libtmux.exc.NotInsideTmux: Not inside a tmux pane: $TMUX_PANE is not a pane id...
Parameters
Returns

str The pane id, e.g. "%3".

Raises
  • NotInsideTmuxWhen $TMUX_PANE is unset, empty, or is not a %-prefixed id.

parse ( version : str ) Version
function [source]
function [source]
parse

Parse the given version string.

Examples

>>> parse('1.0.dev1')
<Version('1.0.dev1')>
Raises
parse_lookup ( obj : Mapping[str, t.Any] , path : str , lookup : str ) t.Any | None
function [source]
function [source]
parse_lookup

Check if field lookup key, e.g. "my__path__contains" has comparator, return val.

If comparator not used or value not found, return None.

>>> parse_lookup({ "food": "red apple" }, "food__istartswith", "__istartswith") 'red apple'

It can also look up objects:

>>> from dataclasses import dataclass

>>> @dataclass() ... class Inventory: ... food: str

>>> item = Inventory(food="red apple")

>>> item Inventory(food='red apple')

>>> parse_lookup(item, "food__istartswith", "__istartswith") 'red apple'

parse_options_to_dict ( stdout : t.IO[str] ) UntypedOptionsDict
function [source]
function [source]
parse_options_to_dict

Process subprocess.stdout options or hook output to flat, naive, untyped dict.

Does not explode arrays or deep values.

Examples

>>> import io
>>> raw_options = io.StringIO("status-keys vi")
>>> parse_options_to_dict(raw_options) == {"status-keys": "vi"}
True
>>> int_options = io.StringIO("message-limit 50")
>>> parse_options_to_dict(int_options) == {"message-limit": "50"}
True
>>> empty_option = io.StringIO("user-keys")
>>> parse_options_to_dict(empty_option) == {"user-keys": None}
True
>>> array_option = io.StringIO("command-alias[0] split-pane=split-window")
>>> parse_options_to_dict(array_option) == {
... "command-alias[0]": "split-pane=split-window"}
True
>>> array_option = io.StringIO("command-alias[40] split-pane=split-window")
>>> parse_options_to_dict(array_option) == {
... "command-alias[40]": "split-pane=split-window"}
True
>>> many_options = io.StringIO(r'''status-keys
... command-alias[0] split-pane=split-window
... ''')
>>> parse_options_to_dict(many_options) == {
... "command-alias[0]": "split-pane=split-window",
... "status-keys": None,}
True
>>> many_more_options = io.StringIO(r'''
... terminal-features[0] xterm*:clipboard:ccolour:cstyle:focus
... terminal-features[1] screen*:title
... ''')
>>> parse_options_to_dict(many_more_options) == {
... "terminal-features[0]": "xterm*:clipboard:ccolour:cstyle:focus",
... "terminal-features[1]": "screen*:title",}
True
>>> quoted_option = io.StringIO(r'''
... command-alias[0] "choose-session=choose-tree -s"
... ''')
>>> parse_options_to_dict(quoted_option) == {
... "command-alias[0]": "choose-session=choose-tree -s",
... }
True
parse_output ( output : str , list_cmd : str = "list-panes" , tmux_version : str = "3.2a" ) OutputRaw
function [source]
function [source]
parse_output

Parse a tmux -F line into a dict keyed by Obj field name.

The (*list_cmd*, *tmux_version*) pair must match what was passed to get_output_format when the -F template was built — otherwise the field order won't line up with the split values.

Examples

>>> from libtmux.neo import get_output_format, parse_output
>>> from libtmux.formats import FORMAT_SEPARATOR
>>> fields, fmt = get_output_format("list-sessions", "3.6a")
>>> values = [''] * len(fields)
>>> values[fields.index('session_id')] = '$1'
>>> result = parse_output(
...     FORMAT_SEPARATOR.join(values) + FORMAT_SEPARATOR,
...     list_cmd="list-sessions",
...     tmux_version="3.6a",
... )
>>> result['session_id']
'$1'
>>> 'pane_id' in result
False
Parameters
Returns

OutputRaw A dict mapping field names to non-empty string values.

raise_if_stderr ( proc : tmux_cmd , subcommand : str ) None
function [source]
function [source]
raise_if_stderr

Raise LibTmuxException tagged with the tmux subcommand on stderr.

Centralizes the if proc.stderr: raise exc.LibTmuxException(proc.stderr) pattern scattered across the wrappers. Tags the exception with the originating tmux subcommand so downstream consumers (e.g. libtmux-mcp's handle_tool_errors) keep the "which tmux command failed" context.

Examples

>>> from libtmux.common import raise_if_stderr
>>> from libtmux import exc
>>> proc = session.cmd("display-message", "-p", "#{session_id}")
>>> raise_if_stderr(proc, "display-message")  # no stderr → no raise
Parameters
  • proc ( tmux_cmd ) – Result of a Server.cmd / Session.cmd / etc. call.

  • subcommand ( str ) – The tmux subcommand the wrapper invoked, e.g. "last-window", "swap-pane". Surfaces in str(exc) as a "<subcommand>: …" prefix.

Raises
reraise ( tp : t.Type[BaseException] , value : BaseException , tb : types.TracebackType ) t.NoReturn
function [source]
function [source]
reraise
resolve_env ( env : t.Mapping[str, str] | None = None ) t.Mapping[str, str]
function [source]
function [source]
resolve_env

Return *env*, defaulting to the live process environment.

Examples

>>> from libtmux._internal.env import resolve_env
>>> resolve_env({"TMUX_PANE": "%1"})
{'TMUX_PANE': '%1'}
>>> resolve_env() is os.environ
True
Parameters
Returns

typing.Mapping The mapping to read tmux variables from.

server ( request : pytest.FixtureRequest , monkeypatch : pytest.MonkeyPatch , config_file : pathlib.Path ) Server
function [source]
function [source]
server

Return new, temporary libtmux.Server .

>>> from libtmux.server import Server

>>> def test_example(server: Server) -> None: ... assert isinstance(server, Server) ... session = server.new_session('my session') ... assert len(server.sessions) == 1 ... assert [session.name.startswith('my') for session in server.sessions]

.. :: >>> locals().keys() dict_keys(...)

>>> source = ''.join([e.source for e in request._pyfuncitem.dtest.examples][:3]) >>> pytester = request.getfixturevalue('pytester')

>>> pytester.makepyfile(**{'whatever.py': source}) PosixPath(...)

>>> result = pytester.runpytest('whatever.py', '--disable-warnings') ===...

>>> result.assert_outcomes(passed=1)

session ( request : pytest.FixtureRequest , session_params : dict[str, t.Any] , server : Server ) Session
function [source]
function [source]
session

Return new, temporary libtmux.Session .

>>> from libtmux.session import Session

>>> def test_example(session: "Session") -> None: ... assert isinstance(session.name, str) ... assert session.name.startswith('libtmux_') ... window = session.new_window(window_name='new one') ... assert window.name == 'new one'

.. :: >>> locals().keys() dict_keys(...)

>>> source = ''.join([e.source for e in request._pyfuncitem.dtest.examples][:3]) >>> pytester = request.getfixturevalue('pytester')

>>> pytester.makepyfile(**{'whatever.py': source}) PosixPath(...)

>>> result = pytester.runpytest('whatever.py', '--disable-warnings') ===...

>>> result.assert_outcomes(passed=1)

session_check_name ( session_name : str | None ) None
function [source]
function [source]
session_check_name

Raise exception session name invalid, modeled after tmux function.

tmux(1) session names may not be empty, or include periods or colons. These delimiters are reserved for noting session, window and pane.

Parameters
  • session_name ( str | None ) – Name of session.

Raises
session_params ( ) dict[str, t.Any]
function [source]
function [source]
session_params

Return default session creation parameters.

>>> import pytest >>> from libtmux.session import Session

>>> @pytest.fixture ... def session_params(session_params): ... return { ... 'x': 800, ... 'y': 600, ... }

>>> def test_example(session: "Session") -> None: ... assert isinstance(session.name, str) ... assert session.name.startswith('libtmux_') ... window = session.new_window(window_name='new one') ... assert window.name == 'new one'

.. :: >>> locals().keys() dict_keys(...)

>>> source = ''.join([e.source for e in request._pyfuncitem.dtest.examples][:4]) >>> pytester = request.getfixturevalue('pytester')

>>> pytester.makepyfile(**{'whatever.py': source}) PosixPath(...)

>>> result = pytester.runpytest('whatever.py', '--disable-warnings') ===...

>>> result.assert_outcomes(passed=1)

socket_path_from_env ( env : t.Mapping[str, str] | None = None ) str
function [source]
function [source]
socket_path_from_env

Return the tmux socket path recorded in $TMUX.

$TMUX is "<socket_path>,<server_pid>,<session_id>". The pid and session id are integers, so any comma in the value belongs to the socket path -- split from the *right*.

The pid and session id are deliberately discarded: both are frozen at pane spawn, and the session id goes stale as soon as the pane's window is moved between sessions.

Examples

>>> from libtmux._internal.env import socket_path_from_env
>>> socket_path_from_env({"TMUX": "/tmp/tmux-1000/default,84215,0"})
'/tmp/tmux-1000/default'

A comma in the socket path is safe, because the split runs from the right:

>>> socket_path_from_env({"TMUX": "/tmp/od,d/sock,84215,3"})
'/tmp/od,d/sock'

Outside tmux there is nothing to read:

>>> socket_path_from_env({})
Traceback (most recent call last):
...
libtmux.exc.NotInsideTmux: Not inside a tmux pane: $TMUX is unset or empty
Parameters
Returns

str Path of the tmux server's socket.

Raises
  • NotInsideTmuxWhen $TMUX is unset, empty, or not shaped like tmux's triple.

TestServer ( request : pytest.FixtureRequest ) type[Server]
function [source]
function [source]
TestServer

Create a temporary tmux server that cleans up after itself.

This is similar to the server pytest fixture, but can be used outside of pytest. The server will be killed when the test completes.

Examples

>>> server = Server()  # Create server instance
>>> server.new_session()
Session($... ...)
>>> server.is_alive()
True
>>> # Each call creates a new server with unique socket
>>> server2 = Server()
>>> server2.socket_name != server.socket_name
True
user_path ( home_path : pathlib.Path , home_user_name : str ) pathlib.Path
function [source]
function [source]
user_path

Ensure and return temporary user directory.

Note: You will need to set the home directory, see set_home.

zshrc ( user_path : pathlib.Path ) pathlib.Path
function [source]
function [source]
zshrc

Suppress ZSH default message.

Needs a startup file .zshenv, .zprofile, .zshrc, .zlogin.

Esc

Type to search.