From 167ee675051b4b41f19a7987add264ccc474daec Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:02:24 -0600 Subject: [PATCH 01/17] docs(README) Update minimum tmux version to 3.2+ Reflects the minimum version bump in v1.57.0 via libtmux 0.48.0. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 849fc35c36..1a1de04be9 100644 --- a/README.md +++ b/README.md @@ -293,7 +293,7 @@ See donation options at . # Project details -- tmux support: 1.8+ +- tmux support: 3.2+ - python support: >= 3.10, pypy, pypy3 - Source: - Docs: From ca1df54b30c5aa572c41ec8d898ba8190523ac72 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:02:56 -0600 Subject: [PATCH 02/17] docs(about) Update minimum tmux version to 3.2+ - Update minimum version requirement from 1.8 to 3.2 - Remove outdated version reference for unique IDs feature (available since 1.8) --- docs/about.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/about.md b/docs/about.md index 71007d950c..0d380728db 100644 --- a/docs/about.md +++ b/docs/about.md @@ -41,7 +41,7 @@ well tested and adopted. ### Missing -**Version support** tmuxp only supports `tmux >= 1.8`. Teamocil and +**Version support** tmuxp only supports `tmux >= 3.2`. Teamocil and tmuxinator may have support for earlier versions. ### Differences @@ -64,7 +64,7 @@ format [^id4]. See {ref}`cli-freeze`. **JSON config** JSON config support. See {ref}`Examples`. -**ORM-based API** via [libtmux] - Utilizes tmux >= 1.8's unique ID's for +**ORM-based API** via [libtmux] - Utilizes tmux's unique IDs for panes, windows and sessions to create an object relational view of the tmux {class}`~libtmux.Server`, its {class}`~libtmux.Session`, {class}`~libtmux.Window`, and {class}`~libtmux.Pane`. From 09cb257869a602fbd72908b2bfb1b981892d1808 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:03:34 -0600 Subject: [PATCH 03/17] docs(about_tmux) Update tmux version requirement to 3.2+ - Update from "written for version 1.8" to "requires tmux 3.2 or newer" - Update tmux homepage link to GitHub (sourceforge is outdated) --- docs/about_tmux.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/about_tmux.md b/docs/about_tmux.md index e69c2268f9..5cb20f86c7 100644 --- a/docs/about_tmux.md +++ b/docs/about_tmux.md @@ -222,9 +222,8 @@ For the freshest results on how to get tmux installed on your system, "How to install tmux on \" will do, as directions change and are slightly different between distributions. -This documentation is written for version **1.8**. It's important that -you have the latest stable release of tmux. The latest stable version is -viewable on the [tmux homepage](http://tmux.sourceforge.net/). +tmuxp requires tmux **3.2 or newer**. The latest stable version is +viewable on the [tmux homepage](https://github.com/tmux/tmux). **Mac OS X** users may install the latest stable version of tmux through [MacPorts](http://www.macports.org/), From 1e1765b170e81f596f5f7d98b88eb89fb3a12061 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:04:02 -0600 Subject: [PATCH 04/17] plugin(TMUX_MIN_VERSION) Update to 3.2 Update the plugin system's minimum tmux version constant from 1.8 to 3.2. Also fix comment typo ("libtmux" -> "tmuxp"). --- src/tmuxp/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tmuxp/plugin.py b/src/tmuxp/plugin.py index e6356f8bf9..84be58d96d 100644 --- a/src/tmuxp/plugin.py +++ b/src/tmuxp/plugin.py @@ -11,8 +11,8 @@ from .__about__ import __version__ from .exc import TmuxpPluginException -#: Minimum version of tmux required to run libtmux -TMUX_MIN_VERSION = "1.8" +#: Minimum version of tmux required to run tmuxp +TMUX_MIN_VERSION = "3.2" #: Most recent version of tmux supported TMUX_MAX_VERSION = None From 417e96c54070ba4dbf284ba42af5a2a3796e8fa8 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:05:38 -0600 Subject: [PATCH 05/17] builder! Remove tmux < 3.0 environment variable warning Remove dead code that warned users about environment variable support requiring tmux 3.0+. Since tmux 3.2+ is now the minimum version, environment variables are always supported. - Remove warning blocks for windows and panes - Remove unused has_lt_version import --- src/tmuxp/workspace/builder.py | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/tmuxp/workspace/builder.py b/src/tmuxp/workspace/builder.py index 9cf8fb0cc1..b430794335 100644 --- a/src/tmuxp/workspace/builder.py +++ b/src/tmuxp/workspace/builder.py @@ -9,7 +9,7 @@ import typing as t from libtmux._internal.query_list import ObjectDoesNotExist -from libtmux.common import has_gte_version, has_lt_version +from libtmux.common import has_gte_version from libtmux.pane import Pane from libtmux.server import Server from libtmux.session import Session @@ -406,25 +406,6 @@ def iter_create_windows( pass environment = panes[0].get("environment", window_config.get("environment")) - if environment and has_lt_version("3.0"): - # Falling back to use the environment of the first pane for the window - # creation is nice but yields misleading error messages. - pane_env = panes[0].get("environment") - win_env = window_config.get("environment") - if pane_env and win_env: - target = "panes and windows" - elif pane_env: - target = "panes" - else: - target = "windows" - logger.warning( - ( - "Cannot set environment for new %s. " - "You need tmux 3.0 or newer for this." - ), - target, - ) - environment = None window = session.new_window( window_name=window_name, @@ -513,16 +494,6 @@ def get_pane_shell( "environment", window_config.get("environment"), ) - if environment and has_lt_version("3.0"): - # Just issue a warning when the environment comes from the pane - # configuration as a warning for the window was already issued when - # the window was created. - if pane_config.get("environment"): - logger.warning( - "Cannot set environment for new panes. " - "You need tmux 3.0 or newer for this.", - ) - environment = None assert pane is not None From c72d4a5a28d6c4f324dba1aa3703c106ca0625fc Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:06:20 -0600 Subject: [PATCH 06/17] builder! Remove tmux 2.6 version check for terminal size The terminal size detection feature was gated behind a tmux 2.6+ check. Since tmux 3.2+ is now the minimum version, this check is always true. - Simplify condition to only check TMUXP_DETECT_TERMINAL_SIZE env var - Remove unused has_gte_version import --- src/tmuxp/workspace/builder.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tmuxp/workspace/builder.py b/src/tmuxp/workspace/builder.py index b430794335..fbc94776c3 100644 --- a/src/tmuxp/workspace/builder.py +++ b/src/tmuxp/workspace/builder.py @@ -9,7 +9,6 @@ import typing as t from libtmux._internal.query_list import ObjectDoesNotExist -from libtmux.common import has_gte_version from libtmux.pane import Pane from libtmux.server import Server from libtmux.session import Session @@ -253,10 +252,7 @@ def build(self, session: Session | None = None, append: bool = False) -> None: "start_directory" ] - if ( - has_gte_version("2.6") - and os.getenv("TMUXP_DETECT_TERMINAL_SIZE", "1") == "1" - ): + if os.getenv("TMUXP_DETECT_TERMINAL_SIZE", "1") == "1": terminal_size = shutil.get_terminal_size( fallback=(get_default_columns(), get_default_rows()), ) From 93436f9a96e379b2ba762ae26c1bfd3463bc6856 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:06:58 -0600 Subject: [PATCH 07/17] cli(load) Remove outdated tmux 2.6 docstring note Remove historical documentation about tmux 2.6 layout behavior changes. This is no longer relevant as a "versionchanged" note since tmux 3.2+ is now the minimum version. --- src/tmuxp/cli/load.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/tmuxp/cli/load.py b/src/tmuxp/cli/load.py index f4139b4950..90ed7759bf 100644 --- a/src/tmuxp/cli/load.py +++ b/src/tmuxp/cli/load.py @@ -275,27 +275,6 @@ def load_workspace( prompt to cleanup (``$ tmux kill-session``) the session on the user's behalf. An exception raised during this process means it's not easy to predict how broken the session is. - - .. versionchanged:: tmux 2.6+ - - In tmux 2.6, the way layout and proportion's work when interfacing - with tmux in a detached state (outside of a client) changed. Since - tmuxp builds workspaces in a detached state, the WorkspaceBuilder isn't - able to rely on functionality requiring awarness of session geometry, - e.g. ``set-layout``. - - Thankfully, tmux is able to defer commands to run after the user - performs certain actions, such as loading a client via - ``attach-session`` or ``switch-client``. - - Upon client switch, ``client-session-changed`` is triggered [1]_. - - References - ---------- - .. [1] cmd-switch-client.c hook. GitHub repo for tmux. - - https://github.com/tmux/tmux/blob/2.6/cmd-switch-client.c#L132. - Accessed April 8th, 2018. """ # get the canonical path, eliminating any symlinks if isinstance(workspace_file, (str, os.PathLike)): From 8a6c1578d5cf03ab11d8c571d9efdc9c8b8cd929 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:07:50 -0600 Subject: [PATCH 08/17] tests(test_load) Remove tmux 2.1 skip marker Remove skip marker for test_load_workspace_name_match_regression_252. This test was skipped for tmux < 2.1, which is no longer relevant now that tmux 3.2+ is the minimum version. --- tests/cli/test_load.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/cli/test_load.py b/tests/cli/test_load.py index 2afa27c698..fec4605f85 100644 --- a/tests/cli/test_load.py +++ b/tests/cli/test_load.py @@ -9,7 +9,6 @@ import libtmux import pytest -from libtmux.common import has_lt_version from libtmux.server import Server from libtmux.session import Session @@ -96,10 +95,6 @@ def test_load_workspace_named_session( assert session.name == "tmuxp-new" -@pytest.mark.skipif( - has_lt_version("2.1"), - reason="exact session name matches only tmux >= 2.1", -) def test_load_workspace_name_match_regression_252( tmp_path: pathlib.Path, server: Server, From ed293955bbc62cf7c4b72ca655ba7aba843b26ae Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:08:55 -0600 Subject: [PATCH 09/17] tests(test_builder) Remove tmux < 3.0 skip and delete obsolete test - Remove skip marker from test_environment_variables (was for tmux < 3.0) - Delete test_environment_variables_warns_prior_to_tmux_3_0 entirely (tested warning behavior that no longer exists) --- tests/workspace/test_builder.py | 56 --------------------------------- 1 file changed, 56 deletions(-) diff --git a/tests/workspace/test_builder.py b/tests/workspace/test_builder.py index 82f1d6482c..e6dbfeb006 100644 --- a/tests/workspace/test_builder.py +++ b/tests/workspace/test_builder.py @@ -386,10 +386,6 @@ def f(w: Window) -> bool: assert w.name != "top" -@pytest.mark.skipif( - has_lt_version("3.0"), - reason="needs -e flag for new-window and split-window introduced in tmux 3.0", -) def test_environment_variables( session: Session, ) -> None: @@ -431,58 +427,6 @@ def test_environment_variables( assert pane.capture_pane()[1] == "PANE" -@pytest.mark.skipif( - has_gte_version("3.0"), - reason="warnings are not needed for tmux >= 3.0", -) -def test_environment_variables_warns_prior_to_tmux_3_0( - session: Session, - caplog: pytest.LogCaptureFixture, -) -> None: - """Warns when environmental variables cannot be set prior to tmux 3.0.""" - workspace = ConfigReader._from_file( - test_utils.get_workspace_file("workspace/builder/environment_vars.yaml"), - ) - workspace = loader.expand(workspace) - - builder = WorkspaceBuilder(session_config=workspace, server=session.server) - builder.build(session) - - # environment on sessions should work as this is done using set-environment - # on the session itself - assert session.getenv("FOO") == "SESSION" - assert session.getenv("PATH") == "/tmp" - - assert ( - sum( - 1 - for record in caplog.records - if "Cannot set environment for new windows." in record.message - ) - # From window_overrides and both_overrides, but not - # both_overrides_in_first_pane. - == 2 - ), "Warning on creating windows missing" - assert ( - sum( - 1 - for record in caplog.records - if "Cannot set environment for new panes." in record.message - ) - # From pane_overrides and both_overrides, but not both_overrides_in_first_pane. - == 2 - ), "Warning on creating panes missing" - assert ( - sum( - 1 - for record in caplog.records - if "Cannot set environment for new panes and windows." in record.message - ) - # From both_overrides_in_first_pane. - == 1 - ) - - def test_automatic_rename_option( server: Server, monkeypatch: pytest.MonkeyPatch, From 6c727f030279c2632960497c434a3afc3415b7a2 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:09:36 -0600 Subject: [PATCH 10/17] tests(test_builder) Remove tmux 2.3 conditionals Remove conditional pane-border-format setup and assertion. The feature is always available since tmux 3.2+ is now the minimum version. --- tests/workspace/test_builder.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/workspace/test_builder.py b/tests/workspace/test_builder.py index e6dbfeb006..63678789fb 100644 --- a/tests/workspace/test_builder.py +++ b/tests/workspace/test_builder.py @@ -12,7 +12,7 @@ import libtmux import pytest from libtmux._internal.query_list import ObjectDoesNotExist -from libtmux.common import has_gte_version, has_lt_version +from libtmux.common import has_lt_version from libtmux.exc import LibTmuxException from libtmux.pane import Pane from libtmux.session import Session @@ -296,8 +296,7 @@ def test_window_options( ) workspace = loader.expand(workspace) - if has_gte_version("2.3"): - workspace["windows"][0]["options"]["pane-border-format"] = " #P " + workspace["windows"][0]["options"]["pane-border-format"] = " #P " builder = WorkspaceBuilder(session_config=workspace, server=session.server) @@ -310,8 +309,7 @@ def test_window_options( assert len(session.windows) == window_count assert isinstance(w, Window) assert w.show_window_option("main-pane-height") == 5 - if has_gte_version("2.3"): - assert w.show_window_option("pane-border-format") == " #P " + assert w.show_window_option("pane-border-format") == " #P " assert len(session.windows) == window_count window_count += 1 From 93ed73093fd2790aadd527e01f3924add3f04188 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:10:06 -0600 Subject: [PATCH 11/17] tests(test_builder) Remove tmux 3.2a skip marker Remove skip marker from test_start_directory_sets_session_path. This test uses a format introduced in tmux 3.2a, which is now the minimum version. --- tests/workspace/test_builder.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/workspace/test_builder.py b/tests/workspace/test_builder.py index 63678789fb..14b8a36b0b 100644 --- a/tests/workspace/test_builder.py +++ b/tests/workspace/test_builder.py @@ -598,10 +598,6 @@ def f(path: str, p: Pane) -> bool: assert retry_until(f_) -@pytest.mark.skipif( - has_lt_version("3.2a"), - reason="needs format introduced in tmux >= 3.2a", -) def test_start_directory_sets_session_path(server: Server) -> None: """Test start_directory setting path in session_path.""" workspace = ConfigReader._from_file( From 5035aba6f63c8e966228954dadb0c4164d9373f7 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 29 Nov 2025 18:12:21 -0600 Subject: [PATCH 12/17] tests(test_builder) Remove tmux 2.9 skip markers and cleanup imports - Remove skip markers from test_layout_main_horizontal and test_issue_800_default_size_many_windows - Remove unused has_lt_version import These features are always available since tmux 3.2+ is now the minimum version. --- tests/workspace/test_builder.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/workspace/test_builder.py b/tests/workspace/test_builder.py index 14b8a36b0b..19a7d6d04b 100644 --- a/tests/workspace/test_builder.py +++ b/tests/workspace/test_builder.py @@ -12,7 +12,6 @@ import libtmux import pytest from libtmux._internal.query_list import ObjectDoesNotExist -from libtmux.common import has_lt_version from libtmux.exc import LibTmuxException from libtmux.pane import Pane from libtmux.session import Session @@ -1380,10 +1379,6 @@ def f(path: str, p: Pane) -> bool: assert retry_until(f_) -@pytest.mark.skipif( - has_lt_version("2.9"), - reason="needs option introduced in tmux >= 2.9", -) def test_layout_main_horizontal(session: Session) -> None: """Test that tmux's main-horizontal layout is used when specified.""" yaml_workspace = test_utils.get_workspace_file("workspace/builder/three_pane.yaml") @@ -1461,7 +1456,6 @@ class DefaultSizeNamespaceFixture(t.NamedTuple): DEFAULT_SIZE_FIXTURES, ids=[f.test_id for f in DEFAULT_SIZE_FIXTURES], ) -@pytest.mark.skipif(has_lt_version("2.9"), reason="default-size only applies there") def test_issue_800_default_size_many_windows( server: Server, monkeypatch: pytest.MonkeyPatch, From 0c0b2d4007f2362bfdb186814c0f8246f44efaa5 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 30 Nov 2025 05:45:54 -0600 Subject: [PATCH 13/17] docs(quickstart) Python 3.7 -> 3.9 --- docs/quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 92d1a254fd..b1753e1664 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -4,7 +4,7 @@ ## Installation -Ensure you have at least tmux **>= 1.8** and python **>= 3.7**. +Ensure you have at least tmux **>= 1.8** and python **>= 3.9**. ```console $ pip install --user tmuxp From 006752d8a37e967b34d40125fb8ffa875add0de4 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 30 Nov 2025 05:46:08 -0600 Subject: [PATCH 14/17] docs(quickstart) Update minimum tmux version to 3.2+ Update installation requirements to reflect the new minimum tmux version. --- docs/quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index b1753e1664..6b52b4e1f1 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -4,7 +4,7 @@ ## Installation -Ensure you have at least tmux **>= 1.8** and python **>= 3.9**. +Ensure you have at least tmux **>= 3.2** and python **>= 3.9**. ```console $ pip install --user tmuxp From 5059478d4c201a428649df112b7ada98431e1134 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 30 Nov 2025 05:46:34 -0600 Subject: [PATCH 15/17] docs(AGENTS) Update minimum tmux version to 3.2+ --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index d683bc4b40..2ed8260713 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -121,4 +121,4 @@ windows: - **Doctest format**: Use narrative descriptions with blank lines between sections - **Complex examples**: Move to `tests/examples//test_.py` - **Minimum Python**: 3.9+ (as per README) -- **Minimum tmux**: 1.8+ (as per README) +- **Minimum tmux**: 3.2+ (as per README) From 1fe721450caac5901f3ebdccb6231cd26e91ea7d Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 30 Nov 2025 05:47:21 -0600 Subject: [PATCH 16/17] docs(examples) Remove tmux 3.0 version note for environment variables Environment variable support is always available now that tmux 3.2+ is the minimum version. --- docs/configuration/examples.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/configuration/examples.md b/docs/configuration/examples.md index 97b2a369a1..9651341309 100644 --- a/docs/configuration/examples.md +++ b/docs/configuration/examples.md @@ -266,8 +266,7 @@ tmuxp will set session, window and pane environment variables. ```{note} -Setting environment variables for windows and panes requires tmuxp 1.19 or -newer and tmux 3.0 or newer. +Setting environment variables for windows and panes requires tmuxp 1.19 or newer. ``` ````{tab} YAML From 818b24a5df6fcef65a8803bef0ff1bda07e7b615 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 30 Nov 2025 05:49:19 -0600 Subject: [PATCH 17/17] docs(CHANGES) Note PR #993 --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 2f4b48b94c..f698580086 100644 --- a/CHANGES +++ b/CHANGES @@ -35,7 +35,7 @@ _Future release notes will be placed here_ ### Breaking changes -#### Minimum tmux version bumped to 3.2+ (#992) +#### Minimum tmux version bumped to 3.2+ (#992, #993) tmux versions below 3.2a are now disabled (via libtmux v0.49.0).