Options¶
Helpers for tmux options.
Option parsing function trade testability and clarity for performance.
Tmux options¶
Options in tmux consist of empty values, strings, integers, arrays, and complex shapes.
Marshalling types from text:
Integers: buffer-limit 50 to {'buffer-limit': 50}
Booleans: exit-unattached on to {'exit-unattached': True}
Exploding arrays:
command-alias[1] split-pane=split-window to
{'command-alias[1]': {'split-pane=split-window'}}
However, there is no equivalent to the above type of object in Python (a sparse array), so a SparseArray is used.
Exploding complex shapes:
"choose-session=choose-tree -s" to {'choose-session': 'choose-tree -s'}
Finally, we need to convert hyphenated keys to underscored attribute names and assign values, as python does not allow hyphens in attribute names.
command-alias is command_alias in python.
Options object¶
Dataclasses are used to provide typed access to tmux’ option shape.
Extra data gleaned from the options, such as user options (custom data) and an option being inherited,
User options¶
There are also custom user options, preceded with @, which exist are stored to Options.context.user_options as a dictionary.
> tmux set-option -w my-custom-variable my-value invalid option: my-custom-option
> tmux set-option -w @my-custom-option my-value > tmux show-option -w @my-custom-optione my-value
Inherited options¶
tmux show-options -A can include inherited options. The raw output of an inherited
option is detected by the key having a *:
visual-activity* on
visual-bell* off
A list of options that are inherited is kept at Options.context._inherited_options and
Options.context.inherited_options.
They are mixed with the normal options,
to differentiate them, run show_options() without include_inherited=True.
-
libtmux.options.handle_option_error(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, useexcept exc.OptionError.- Parameters:
error (str) – Error response from subprocess call.
- Return type:
:raises
exc.OptionError,exc.UnknownOption,exc.InvalidOption,: :raisesexc.AmbiguousOption: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])
-
libtmux.options.convert_value(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'
-
libtmux.options.convert_values(value)¶
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}
-
libtmux.options.parse_options_to_dict(stdout)¶
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
-
libtmux.options.explode_arrays(_dict, force_array=False)¶
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=Truefor 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]
- Parameters:
_dict (UntypedOptionsDict)
force_array (bool)
- Return type:
ExplodedUntypedOptionsDict
-
libtmux.options.explode_complex(_dict)¶
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
- Parameters:
_dict (ExplodedUntypedOptionsDict)
- Return type:
ExplodedComplexUntypedOptionsDict