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

Ansible navigator related fixes #523

Merged
merged 20 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 47 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,57 @@ $ pip install --user --upgrade --pre libtmux

<!-- Maintainers and contributors: Insert change notes for the next release above -->

### Breaking changes

#### `Session.new_window()` + `Window.split_window()`: No longer attaches by default

- 0.28 +: Now _defaults_ to `attach=False`.
- 0.27.1 and before: _defaults_ to `attach=True`.

Pass `attach=True` for the old behavior.

#### `Pane.resize_pane()` renamed to `Pane.resize()`: (#523)

This convention will be more consistent with `Window.resize()`.

#### `Pane.resize_pane()`: Params changed (#523)

- No longer accepts `-U`, `-D`, `-L`, `-R` directly, instead accepts
`ResizeAdjustmentDirection`.

### New features

#### `Pane.resize()`: Improved param coverage (#523)

- Learned to accept adjustments via `adjustment_direction` w/
`ResizeAdjustmentDirection` + `adjustment`.

- Learned to accept manual `height` and / or `width` (columns/rows or percentage)

- Zoom (and unzoom)

#### `Window.resize_window()`: New Method (#523)

If `Pane.resize_pane()` (now `Pane.resize()`) didn't work before, try resizing the window.

### Bug fixes

#### `Window.refresh()` and `Pane.refresh()`: Refresh more underlying state (#523)

#### `Obj._refresh`: Allow passing args (#523)

e.g. `-a` (all) to `list-panes` and `list-windows`

#### `Server.panes`: Fix listing of panes (#523)

Would list only panes in attached session, rather than all in a server.

### Improvement

- Pane, Window: Improve parsing of option values that return numbers
(#520)
- `Obj._refresh`: Allow passing `list_extra_args` to ensure `list-windows` and
`list-panes` can return more than the target (#523)

### Tests

Expand Down
6 changes: 6 additions & 0 deletions docs/reference/constants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Constants

```{eval-rst}
.. automodule:: libtmux.constants
:members:
```
1 change: 1 addition & 0 deletions docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ servers
sessions
windows
panes
constants
common
exceptions
```
2 changes: 1 addition & 1 deletion src/libtmux/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# flake8: NOQA
"""libtmux, a typed, pythonic API wrapper for the tmux terminal multiplexer."""
from .__about__ import (
__author__,
__copyright__,
Expand Down
1 change: 0 additions & 1 deletion src/libtmux/common.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# flake8: NOQA: W605
"""Helper methods and mixins for libtmux.

libtmux.common
Expand Down
20 changes: 20 additions & 0 deletions src/libtmux/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Constant variables for libtmux."""
import enum
import typing as t


class ResizeAdjustmentDirection(enum.Enum):
"""Used for *adjustment* in ``resize_window``, ``resize_pane``."""

Up = "UP"
Down = "DOWN"
Left = "LEFT"
Right = "RIGHT"


RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP: t.Dict[ResizeAdjustmentDirection, str] = {
ResizeAdjustmentDirection.Up: "-U",
ResizeAdjustmentDirection.Down: "-D",
ResizeAdjustmentDirection.Left: "-L",
ResizeAdjustmentDirection.Right: "-R",
}
30 changes: 30 additions & 0 deletions src/libtmux/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,33 @@ class NoWindowsExist(WindowError):

def __init__(self, *args: object):
return super().__init__("No windows exist for object")


class AdjustmentDirectionRequiresAdjustment(LibTmuxException, ValueError):
"""If *adjustment_direction* is set, *adjustment* must be set."""

def __init__(self) -> None:
super().__init__("adjustment_direction requires adjustment")


class WindowAdjustmentDirectionRequiresAdjustment(
WindowError, AdjustmentDirectionRequiresAdjustment
):
"""ValueError for :meth:`libtmux.Window.resize_window`."""

pass


class PaneAdjustmentDirectionRequiresAdjustment(
WindowError, AdjustmentDirectionRequiresAdjustment
):
"""ValueError for :meth:`libtmux.Pane.resize_pane`."""

pass


class RequiresDigitOrPercentage(LibTmuxException, ValueError):
"""Requires digit (int or str digit) or a percentage."""

def __init__(self) -> None:
super().__init__("Requires digit (int or str digit) or a percentage.")
2 changes: 2 additions & 0 deletions src/libtmux/neo.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,14 @@ def _refresh(
obj_key: str,
obj_id: str,
list_cmd: "ListCmd" = "list-panes",
list_extra_args: "t.Optional[ListExtraArgs]" = None,
) -> None:
assert isinstance(obj_id, str)
obj = fetch_obj(
obj_key=obj_key,
obj_id=obj_id,
list_cmd=list_cmd,
list_extra_args=list_extra_args,
server=self.server,
)
assert obj is not None
Expand Down
146 changes: 128 additions & 18 deletions src/libtmux/pane.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# flake8: NOQA: W605
"""Pythonization of the :ref:`tmux(1)` pane.

libtmux.pane
Expand All @@ -11,7 +10,11 @@
import warnings
from typing import overload

from libtmux.common import tmux_cmd
from libtmux.common import has_gte_version, tmux_cmd
from libtmux.constants import (
RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP,
ResizeAdjustmentDirection,
)
from libtmux.neo import Obj, fetch_obj

from . import exc
Expand Down Expand Up @@ -71,7 +74,11 @@ class Pane(Obj):
def refresh(self) -> None:
"""Refresh pane attributes from tmux."""
assert isinstance(self.pane_id, str)
return super()._refresh(obj_key="pane_id", obj_id=self.pane_id)
return super()._refresh(
obj_key="pane_id",
obj_id=self.pane_id,
list_extra_args=("-a",),
)

@classmethod
def from_pane_id(cls, server: "Server", pane_id: str) -> "Pane":
Expand Down Expand Up @@ -122,31 +129,99 @@ def cmd(self, cmd: str, *args: t.Any, **kwargs: t.Any) -> tmux_cmd:
Commands (tmux-like)
"""

def resize_pane(self, *args: t.Any, **kwargs: t.Any) -> "Pane":
def resize(
self,
# Adjustments
adjustment_direction: t.Optional[ResizeAdjustmentDirection] = None,
adjustment: t.Optional[int] = None,
# Manual
height: t.Optional[t.Union[str, int]] = None,
width: t.Optional[t.Union[str, int]] = None,
# Zoom
zoom: t.Optional[bool] = None,
# Mouse
mouse: t.Optional[bool] = None,
# Optional flags
trim_below: t.Optional[bool] = None,
) -> "Pane":
"""Resize tmux pane.

Parameters
----------
target_pane : str
``target_pane``, or ``-U``,``-D``, ``-L``, ``-R``.
adjustment_direction : ResizeAdjustmentDirection, optional
direction to adjust, ``Up``, ``Down``, ``Left``, ``Right``.
adjustment : ResizeAdjustmentDirection, optional

Other Parameters
----------------
height : int
height : int, optional
``resize-pane -y`` dimensions
width : int
width : int, optional
``resize-pane -x`` dimensions

zoom : bool
expand pane

mouse : bool
resize via mouse

trim_below : bool
trim below cursor

Raises
------
exc.LibTmuxException
:exc:`exc.LibTmuxException`,
:exc:`exc.PaneAdjustmentDirectionRequiresAdjustment`,
:exc:`exc.RequiresDigitOrPercentage`

Returns
-------
:class:`Pane`

Notes
-----
Three types of resizing are available:

1. Adjustments: ``adjustment_direction`` and ``adjustment``.
2. Manual resizing: ``height`` and / or ``width``.
3. Zoom / Unzoom: ``zoom``.
"""
if "height" in kwargs:
proc = self.cmd("resize-pane", "-y%s" % int(kwargs["height"]))
elif "width" in kwargs:
proc = self.cmd("resize-pane", "-x%s" % int(kwargs["width"]))
else:
proc = self.cmd("resize-pane", args[0])
tmux_args: t.Tuple[str, ...] = ()

## Adjustments
if adjustment_direction:
if adjustment is None:
raise exc.PaneAdjustmentDirectionRequiresAdjustment()
tmux_args += (
f"{RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP[adjustment_direction]}",
str(adjustment),
)
elif height or width:
## Manual resizing
if height:
if isinstance(height, str):
if height.endswith("%") and not has_gte_version("3.1"):
raise exc.VersionTooLow
if not height.isdigit() and not height.endswith("%"):
raise exc.RequiresDigitOrPercentage
tmux_args += (f"-y{height}",)

if width:
if isinstance(width, str):
if width.endswith("%") and not has_gte_version("3.1"):
raise exc.VersionTooLow
if not width.isdigit() and not width.endswith("%"):
raise exc.RequiresDigitOrPercentage

tmux_args += (f"-x{width}",)
elif zoom:
## Zoom / Unzoom
tmux_args += ("-Z",)
elif mouse:
tmux_args += ("-M",)

if trim_below:
tmux_args += ("-T",)

proc = self.cmd("resize-pane", *tmux_args)

if proc.stderr:
raise exc.LibTmuxException(proc.stderr)
Expand Down Expand Up @@ -442,7 +517,7 @@ def get(self, key: str, default: t.Optional[t.Any] = None) -> t.Any:

.. deprecated:: 0.16

Deprecated by attribute lookup.e.g. ``pane['window_name']`` is now
Deprecated by attribute lookup, e.g. ``pane['window_name']`` is now
accessed via ``pane.window_name``.

"""
Expand All @@ -460,3 +535,38 @@ def __getitem__(self, key: str) -> t.Any:
"""
warnings.warn(f"Item lookups, e.g. pane['{key}'] is deprecated", stacklevel=2)
return getattr(self, key)

def resize_pane(
self,
# Adjustments
adjustment_direction: t.Optional[ResizeAdjustmentDirection] = None,
adjustment: t.Optional[int] = None,
# Manual
height: t.Optional[t.Union[str, int]] = None,
width: t.Optional[t.Union[str, int]] = None,
# Zoom
zoom: t.Optional[bool] = None,
# Mouse
mouse: t.Optional[bool] = None,
# Optional flags
trim_below: t.Optional[bool] = None,
) -> "Pane":
"""Resize pane, deprecated by :meth:`Pane.resize`.

.. deprecated:: 0.28

Deprecated by :meth:`Pane.resize`.
"""
warnings.warn(
"Deprecated: Use Pane.resize() instead of Pane.resize_pane()",
stacklevel=2,
)
return self.resize(
adjustment_direction=adjustment_direction,
adjustment=adjustment,
height=height,
width=width,
zoom=zoom,
mouse=mouse,
trim_below=trim_below,
)
9 changes: 7 additions & 2 deletions src/libtmux/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ def session(
session_name = "tmuxp"

if not server.has_session(session_name):
server.cmd("new-session", "-d", "-s", session_name)
server.new_session(
session_name=session_name,
)

# find current sessions prefixed with tmuxp
old_test_sessions = []
Expand All @@ -228,7 +230,10 @@ def session(

TEST_SESSION_NAME = get_test_session_name(server=server)

session = server.new_session(session_name=TEST_SESSION_NAME, **session_params)
session = server.new_session(
session_name=TEST_SESSION_NAME,
**session_params,
)

"""
Make sure that tmuxp can :ref:`test_builder_visually` and switches to
Expand Down
2 changes: 1 addition & 1 deletion src/libtmux/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ def panes(self) -> QueryList[Pane]:
Pane(server=self, **obj)
for obj in fetch_objs(
list_cmd="list-panes",
list_extra_args=["-s"],
list_extra_args=("-a",),
server=self,
)
]
Expand Down
6 changes: 5 additions & 1 deletion src/libtmux/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ def new_window(
self,
window_name: t.Optional[str] = None,
start_directory: None = None,
attach: bool = True,
attach: bool = False,
window_index: str = "",
window_shell: t.Optional[str] = None,
environment: t.Optional[t.Dict[str, str]] = None,
Expand Down Expand Up @@ -465,6 +465,10 @@ def new_window(
useful for long-running processes where the closing of the
window upon completion is desired.

.. versionchanged:: 0.28.0

``attach`` default changed from ``True`` to ``False``.

Returns
-------
:class:`Window`
Expand Down