Skip to content

Commit

Permalink
tests / fix: Fix v1.13.1 pane spacing issue (#809)
Browse files Browse the repository at this point in the history
This may negate the fix from #737 (for #667 and #704)
that helped certain layouts.

If a client hasn't yet been attached, 80x24 isn't enough 
to handle workspace building splitting the panes out.
  • Loading branch information
tony authored Sep 10, 2022
2 parents 2b75fb2 + afeb47e commit b2b6f53
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 11 deletions.
28 changes: 28 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,34 @@ $ pipx install --suffix=@next 'tmuxp' --pip-args '\--pre' --force
- Add [flake8-bugbear](https://github.com/PyCQA/flake8-bugbear) (#807)
- Add [flake8-comprehensions](https://github.com/adamchainz/flake8-comprehensions) (#808)

## tmuxp 1.13.x (2022-09-10)

### Bug fixes

- Layout size has been bumped for those experiencing layout spacing issues
(#809, fixes #800)

If you encounter issues with pane spacing, consider passing an `option` like
so:

```yaml
session_name: main-pane-height
start_directory: "~"
options:
default-size: 999x999
windows:
- window_name: my window name
layout: main-horizontal
options:
main-pane-height: 30
panes:
- shell_command: top
- shell_command: top
- shell_command: top
- shell_command: echo "hey"
- shell_command: echo "moo"
```
## tmuxp 1.13.1 (2022-08-21)
### Bug fixes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
session_name: many-windows-issue
windows:
- window_name: moo
layout: main-horizontal
panes:
- echo hello
- echo hello
- echo hello
- echo hello
- echo hello
- echo hello
- echo hello
97 changes: 95 additions & 2 deletions tests/test_workspacebuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@
import pathlib
import textwrap
import time
import typing as t

import pytest

import kaptan

import libtmux
from libtmux import Window
from libtmux.common import has_gte_version, has_lt_version
from libtmux.test import retry_until, temp_session
from libtmux.window import Window
from tmuxp import config, exc
from tmuxp.cli.load import load_plugins
from tmuxp.workspacebuilder import WorkspaceBuilder

from .constants import EXAMPLE_PATH, FIXTURE_PATH
from .fixtures import utils as test_utils

if t.TYPE_CHECKING:
from libtmux.server import Server


def test_split_windows(session):
yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml")
Expand Down Expand Up @@ -1209,11 +1213,100 @@ def height(p):
def width(p):
return int(p._info["pane_width"])

assert height(main_horizontal_pane) > height(panes[0])
main_horizontal_pane_height = height(main_horizontal_pane)
pane_heights = [height(pane) for pane in panes]
# TODO: When libtmux has new pane formatters added, use that to detect top / bottom
assert all(
main_horizontal_pane_height != pane_height for pane_height in pane_heights
), "The top row should not be the same size as the bottom row (even though it can)"
assert all(
pane_heights[0] == pane_height for pane_height in pane_heights
), "The bottom row should be uniform height"
assert width(main_horizontal_pane) > width(panes[0])

def is_almost_equal(x, y):
return abs(x - y) <= 1

assert is_almost_equal(height(panes[0]), height(panes[1]))
assert is_almost_equal(width(panes[0]), width(panes[1]))


class DefaultSizeNamespaceFixture(t.NamedTuple):
test_id: str
TMUXP_DEFAULT_SIZE: t.Optional[str]
raises: bool
confoverrides: t.Dict[str, t.Any]


DEFAULT_SIZE_FIXTURES = [
DefaultSizeNamespaceFixture(
test_id="default-behavior",
TMUXP_DEFAULT_SIZE=None,
raises=False,
confoverrides={},
),
DefaultSizeNamespaceFixture(
test_id="v1.13.1 default-size-breaks",
TMUXP_DEFAULT_SIZE=None,
raises=True,
confoverrides={"options": {"default-size": "80x24"}},
),
DefaultSizeNamespaceFixture(
test_id="v1.13.1-option-workaround",
TMUXP_DEFAULT_SIZE=None,
raises=False,
confoverrides={"options": {"default-size": "800x600"}},
),
]


@pytest.mark.parametrize(
DefaultSizeNamespaceFixture._fields,
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,
test_id: str,
TMUXP_DEFAULT_SIZE: t.Optional[str],
raises: bool,
confoverrides: t.Dict[str, t.Any],
) -> None:
"""Recreate default-size issue.
v1.13.1 added a default-size, but this can break building workspaces with
a lot of panes.
See also: https://github.com/tmux-python/tmuxp/issues/800
"""
yaml_config = test_utils.read_config_file(
"regressions/issue_800_default_size_many_windows.yaml"
)
sconfig = kaptan.Kaptan(handler="yaml")
sconfig = sconfig.import_config(yaml_config).get()
sconfig = config.expand(sconfig)
sconfig = config.trickle(sconfig)

if isinstance(confoverrides, dict):
for k, v in confoverrides.items():
sconfig[k] = v

if TMUXP_DEFAULT_SIZE is not None:
monkeypatch.setenv("TMUXP_DEFAULT_SIZE", TMUXP_DEFAULT_SIZE)

builder = WorkspaceBuilder(sconf=sconfig, server=server)

if raises:
with pytest.raises(Exception):
builder.build()

builder.session.kill_session()

with pytest.raises(libtmux.exc.LibTmuxException, match="no space for new pane"):
builder.build()
return

builder.build()
assert len(server.list_sessions()) == 1
21 changes: 12 additions & 9 deletions tmuxp/workspacebuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@

logger = logging.getLogger(__name__)

DEFAULT_WIDTH = "800"
DEFAULT_HEIGHT = "600"
DEFAULT_SIZE = f"{DEFAULT_WIDTH}x{DEFAULT_HEIGHT}"


class WorkspaceBuilder:

Expand Down Expand Up @@ -205,22 +209,21 @@ def build(self, session=None, append=False):
"Session name %s is already running." % self.sconf["session_name"]
)
else:
new_session_kwargs = {}
if "start_directory" in self.sconf:
session = self.server.new_session(
session_name=self.sconf["session_name"],
start_directory=self.sconf["start_directory"],
)
else:
session = self.server.new_session(
session_name=self.sconf["session_name"]
)
new_session_kwargs["start_directory"] = self.sconf[
"start_directory"
]
session = self.server.new_session(
session_name=self.sconf["session_name"]
)

assert self.sconf["session_name"] == session.name
assert len(self.sconf["session_name"]) > 0

if has_gte_version("2.9"):
# Use tmux default session size, overwrite Server::new_session
session.set_option("default-size", "80x24")
session.set_option("default-size", DEFAULT_SIZE)

self.session = session
self.server = session.server
Expand Down

0 comments on commit b2b6f53

Please sign in to comment.