Skip to content
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

tests / fix: Fix v1.13.1 pane spacing issue #809

Merged
merged 7 commits into from
Sep 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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