-
Notifications
You must be signed in to change notification settings - Fork 112
Improved option management, add hook management #516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6cd43f0 to
3399c7d
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #516 +/- ##
==========================================
- Coverage 46.77% 43.99% -2.79%
==========================================
Files 18 22 +4
Lines 1708 2305 +597
Branches 277 362 +85
==========================================
+ Hits 799 1014 +215
- Misses 799 1145 +346
- Partials 110 146 +36 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Closed
e5c6186 to
37898a4
Compare
97d74c1 to
36c5907
Compare
why: The g parameter should emit DeprecationWarning like set_option() does what: - Add deprecation warning when g parameter is used - Follow same pattern as set_option() (lines 669-671) - Ensures backward compatibility while guiding users to global_
why: Deprecation warnings should use proper DeprecationWarning category to be properly filtered by Python's warning system what: - Update all 4 instances of g deprecation warning to use category=DeprecationWarning - Affects set_option, _show_options_raw, _show_option_raw, show_option
why: Verify that show_option() emits DeprecationWarning when deprecated g parameter is used what: - Add test_show_option_g_parameter_emits_deprecation_warning test - Ensures backward compatibility warning is properly raised
why: The global_ parameter was accepted but not forwarded, preventing users from querying server-wide hooks with -g flag what: - Forward global_=global_ when calling _show_hook()
why: CHANGES documented bulk hook APIs that don't exist in HooksMixin what: - Remove get_hook_indices, get_hook_values, append_hook, clear_hook - These methods were documented but never implemented - Keep only the implemented methods: set_hook, show_hook, show_hooks, unset_hook, run_hook, set_hooks
why: Server.set_hook() was broken - HOOK_SCOPE_FLAG_MAP[Server] was "" which added an empty string argument to tmux commands. Server/global hooks require -g flag per tmux documentation. what: - Change OptionScope.Server from "" to "-g" in HOOK_SCOPE_FLAG_MAP - Fixes Server.set_hook(), Server.show_hooks(), Server.run_hook()
why: Control-mode hooks like %output, %window-add have % prefix that
Hooks.from_stdout() strips when creating attributes, but show_hook()
didn't strip it before lookup, causing all %-prefixed hooks to return
None.
what:
- Add lstrip("%") before replace("-", "_") in show_hook() attribute lookup
why: The g parameter was silently ignored in set_hook(), breaking backward compatibility. Code calling set_hook(..., g=True) would not get global behavior. what: - Add DeprecationWarning when g parameter is used - Forward g value to global_ for backward compatibility - Matches pattern used in OptionsMixin.set_option()
why: Hooks set globally (with global_=True) could not be run via run_hook() because it had no way to pass -g flag to tmux. what: - Add global_: bool | None = None parameter to run_hook() - Add -g flag handling when global_ is True
why: The SparseArray-specific branch at lines 248-251 was unreachable dead code. Since SparseArray inherits from dict, isinstance(value, dict) returns True and the dict branch handles it correctly first. what: - Remove unreachable SparseArray branch that contained buggy logic - Add comment explaining dict branch handles SparseArray too
why: tmux set-hook does not accept -F flag (only set-option does).
Verified against ~/study/c/tmux/cmd-set-option.c:65 which shows
set-hook accepts "agpRt:uw" only.
what:
- Remove _format parameter from set_hook() signature
- Remove _format flag handling code
why: tmux set-hook does not accept -o flag (only set-option does).
Verified against ~/study/c/tmux/cmd-set-option.c:65 which shows
set-hook accepts "agpRt:uw" only.
what:
- Remove prevent_overwrite parameter from set_hook() signature
- Remove prevent_overwrite flag handling code
why: tmux set-hook does not accept -q flag (only set-option does).
Verified against ~/study/c/tmux/cmd-set-option.c:65 which shows
set-hook accepts "agpRt:uw" only.
what:
- Remove ignore_errors parameter from set_hook() signature
- Remove ignore_errors flag handling code
why: tmux set-hook (used with -u for unset) does not accept -q flag.
Verified against ~/study/c/tmux/cmd-set-option.c:65 which shows
set-hook accepts "agpRt:uw" only.
what:
- Remove ignore_errors parameter from unset_hook() signature
- Remove ignore_errors flag handling code
why: tmux show-hooks does not accept -q flag.
Verified against ~/study/c/tmux/cmd-show-options.c:67 which shows
show-hooks accepts "gpt:w" only.
what:
- Remove ignore_errors parameter from show_hooks() signature
- Remove ignore_errors flag handling code
- Remove ignore_errors from docstring parameters
…rameter
why: tmux show-hooks does not accept -q flag.
Verified against ~/study/c/tmux/cmd-show-options.c:67 which shows
show-hooks accepts "gpt:w" only.
what:
- Remove ignore_errors parameter from _show_hook() signature
- Remove ignore_errors parameter from show_hook() signature
- Remove ignore_errors flag handling code
- Remove ignore_errors from _show_hook() call in show_hook()
why: Verify show_option correctly handles bracketed array indices like 'status-format[0]'. Currently returns None instead of the value. what: - Add ShowOptionIndexedTestCase NamedTuple with test_id pattern - Add parametrized test_show_option_indexed_array test - Test verifies indexed query returns value, base name returns SparseArray - Test follows TDD RED phase (currently failing as expected)
why: Querying 'status-format[0]' returned None because explode_arrays() transforms the key to 'status-format', losing the original indexed key. what: - Parse raw output first before exploding arrays - Direct lookup for indexed queries (key with brackets found in raw dict) - For base name queries, continue with explode_arrays transformation - Avoids duplicating regex parsing logic already in explode_arrays()
…test why: The test `test_deprecated_window_methods_emit_warning[show_window_option_global]` triggered two warnings: the expected one (Window method deprecated) and an unexpected secondary one (g argument deprecated). The secondary warning leaked to pytest output. what: - Add @pytest.mark.filterwarnings to ignore "g argument is deprecated" warning - Test still validates the primary deprecation warning via pytest.warns()
why: Per tmux.1, terminal-overrides entries are colon-separated strings where
the first part is a terminal pattern and remaining parts are individual
features. The previous code used `split(":", maxsplit=1)` which collapsed all
features after the pattern into a single key.
what:
- Split on all colons, not just the first
- Iterate over each feature part individually
- Add parametrized tests for multi-feature entries
why: When calling show_hook("session-renamed[0]"), the code attempted to find
an attribute named "session_renamed[0]" on the Hooks dataclass, which doesn't
exist. Per tmux.1, hooks are array options that can be queried by index.
what:
- Extract index from bracketed suffix before attribute lookup
- Return specific indexed value from SparseArray when present
- Add parametrized tests for indexed hook lookups
why: tmux appends "*" to option names that are inherited from parent scopes (e.g., "visual-activity*" when the value comes from global scope). The lookup code was checking for the exact option name, missing inherited values. what: - Check for both exact key and key with "*" suffix in raw output lookup - Check for inherited marker in exploded output lookup as well - Fix test to properly capture inherited value before set/unset cycle
why: When tmux outputs inherited array options with -A flag (e.g., "status-format[0]*"), the asterisk was being stripped during explosion. This caused inconsistency: scalar inherited options preserved the "*" marker but array options did not. what: - Update regex to capture trailing "*" in new `inherited` group - Append "*" to base key when inherited marker is present - Ensures inherited array options like "status-format[0]*" produce "status-format*" keys, consistent with scalar inherited options
…tests why: Ensure explode_arrays correctly preserves the "*" marker for inherited array options (e.g., "status-format[0]*" → "status-format*"), consistent with scalar inherited options. what: - Add ExplodeArraysInheritedCase NamedTuple for parametrized tests - Add 3 test cases: inherited arrays, non-inherited arrays, mixed indices - Import explode_arrays function for direct unit testing
why: Users upgrading to 0.50.0 need clear guidance on deprecated methods and the new unified options/hooks API. what: - Document new unified options API (show_options, show_option, set_option, unset_option) available on all tmux objects - Document new hooks API (set_hook, show_hook, show_hooks, unset_hook) - Add deprecation notes for Window.set_window_option(), Window.show_window_option(), Window.show_window_options() - Add deprecation notes for `g` parameter in favor of `global_` - Include before/after code examples for each migration
why: Users need a conceptual guide explaining the unified options/hooks API, when to use different methods, and how to work with indexed hooks. what: - Create docs/topics/options_and_hooks.md with comprehensive guide - Cover getting/setting options with show_options(), show_option(), set_option(), unset_option() - Cover hooks API with set_hook(), show_hook(), show_hooks(), unset_hook() - Document indexed hooks and SparseArray return type - Include bulk hook operations with set_hooks() - Add tmux version compatibility table - Add options_and_hooks to topics/index.md toctree - All doctests pass via pytest --doctest-glob
why: Users following the quickstart guide need to see basic options usage alongside other common operations like creating windows and panes. what: - Add "Working with options" section before "Final notes" - Include examples for show_option(), show_options(), set_option(), unset_option() - Add seealso reference to the detailed options-and-hooks topic guide - All doctests pass via pytest --doctest-glob
53b9186 to
d24226e
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
OptionsMixin, HooksMixin, and SparseArray
Extracted from #513
Warning
APIs below are subject to change (both params, return types, and structures)
Summary
This PR introduces a comprehensive refactor of tmux option and hook management
through new mixin classes (
OptionsMixin,HooksMixin) and aSparseArraydata structure for handling tmux's indexed arrays.
Key additions:
OptionsMixin- Unified option management across Server, Session, Window,and Pane
HooksMixin- Hook management with bulk operations APISparseArray- Data structure for tmux's sparse indexed arrays(e.g.,
command-alias[0],command-alias[99])Changes
New internal:
SparseArrayA dict-based data structure that preserves sparse indices while maintaining
list-like behavior:
This is essential for handling tmux options like
command-alias[0],command-alias[5],terminal-features[0], etc.New internal:
OptionsMixinUnified option management across all tmux objects (Server, Session, Window,
Pane).
High-level API:
show_options()- Returns structured data with SparseArray preservationshow_option(option)- Returns a single option valueset_option(option, value, **kwargs)- Set an option with full flag supportunset_option(option)- Unset/remove an optionLow-level API:
_show_options()- Map of options split by key with raw values_show_options_raw()- Raw stdout fromtmux show-options_show_option()- Single option raw value_show_option_raw()- Raw stdout fromtmux show-option [option]Backward compatibility:
gparameter is still accepted but deprecated in favor ofglobal_gwill emit aDeprecationWarningNew internal:
HooksMixinHook management for tmux 3.0+ with full support for indexed hooks.
Basic operations:
set_hook(hook, value)- Set a hookshow_hook(hook)- Get current hook value (returnsSparseArrayfor indexedhooks)
show_hooks()- Get all hooksunset_hook(hook)- Remove a hookrun_hook(hook)- Run a hook immediately (useful for testing)Bulk operations:
set_hooks(hook, values)- Set multiple hooks at onceWorking with indexed hooks:
New features
set_option()params_format-Funset-uglobal_-gunset_panes-Uprevent_overwrite-osuppress_warnings-qappend-ashow_option()/show_options()paramsscope- Specify option scope (Server, Session, Window, Pane)global_- Show global optionsinclude_inherited- Include inherited options (with*suffix in tmux)include_hooks- Include hooks in outputBreaking changes
Deprecations
Window.set_window_option()deprecated in favor ofWindow.set_option()Window.show_window_option()deprecated in favor ofWindow.show_option()Window.show_window_options()deprecated in favor ofWindow.show_options()gparameter deprecated in favor ofglobal_(emitsDeprecationWarning)New constants
OptionScopeenum:Server,Session,Window,PaneOPTION_SCOPE_FLAG_MAP- Maps scope to tmux flags (-s,-w,-p)HOOK_SCOPE_FLAG_MAP- Maps scope to hook flagstmux Version Compatibility
-w,-p)client-active,window-resizedhookspane-title-changedhookTesting
tests/test_options.py)tests/test_hooks.py)tmux versions
gparameter deprecation warningFiles Changed
New Files
src/libtmux/options.pysrc/libtmux/hooks.pysrc/libtmux/_internal/sparse_array.pysrc/libtmux/_internal/constants.pytests/test_options.pytests/test_hooks.pytests/test/test_sparse_array.pydocs/api/options.mddocs/api/hooks.mddocs/internals/sparse_array.mddocs/internals/constants.mdModified Files
src/libtmux/constants.pysrc/libtmux/common.pysrc/libtmux/server.pysrc/libtmux/session.pysrc/libtmux/window.pysrc/libtmux/pane.pyCHANGEStests/test_window.pytests/test_session.pytests/legacy_api/test_window.pytests/legacy_api/test_session.py