Skip to content

Commit

Permalink
Merge pull request #82 from AnonymouX47/global-settings
Browse files Browse the repository at this point in the history
Redefine and re-organize global settings
  • Loading branch information
AnonymouX47 authored Mar 8, 2023
2 parents 70b170b + ecc1af3 commit c7a6f38
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 60 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Extended `ITerm2Image.clear()` ([807a9ec]).
- Computed image size and `image.rendered_size` (regardless of the value of `image.scale`) can no longer be null (contain `0`) ([#78]).
- No more "Image size or scale too small" error at render time.
- **(BREAKING!)** Redefined gloabl settings and moved all to package top-level ([#82]).
- `term_image.utils.DEFAULT_QUERY_TIMEOUT` -> `term_image.DEFAULT_QUERY_TIMEOUT`
- `term_image.utils.set_query_timeout()` -> `term_image.set_query_timeout()`
- `term_image.utils.DISABLE_QUERIES` -> `term_image.disable_queries()` and `term_image.enable_queries()`
- `term_image.utils.SWAP_WIN_SIZE` -> `term_image.enable_win_size_swap()` and `term_image.disable_win_size_swap()`

### Removed
- The CLI and TUI ([#72]).
Expand All @@ -51,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#74]: https://github.com/AnonymouX47/term-image/pull/74
[#78]: https://github.com/AnonymouX47/term-image/pull/78
[#80]: https://github.com/AnonymouX47/term-image/pull/80
[#82]: https://github.com/AnonymouX47/term-image/pull/82
[b4533d5]: https://github.com/AnonymouX47/term-image/commit/b4533d5697d41fe0742c2ac895077da3b8d889dc
[97eceab]: https://github.com/AnonymouX47/term-image/commit/97eceab77e7448a18281aa6edb3fa8ec9e6564c5
[807a9ec]: https://github.com/AnonymouX47/term-image/commit/807a9ecad717e46621a5214dbf849369d3afbc0b
Expand Down
2 changes: 1 addition & 1 deletion docs/source/faqs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Why are colours not properly reproduced?
Why are images out of scale?
- If :ref:`auto-cell-ratio` is supported and enabled,

- set :py:data:`~term_image.utils.SWAP_WIN_SIZE` to ``True``.
- call :py:func:`~term_image.enable_win_size_swap`.
If this doesn't work, then open an issue `here
<https://github.com/AnonymouX47/term-image/issues>`_ with adequate details.

Expand Down
18 changes: 15 additions & 3 deletions docs/source/reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ Reference
Top-Level Definitions
---------------------

.. autofunction:: term_image.set_cell_ratio

.. autofunction:: term_image.get_cell_ratio
.. autodata:: term_image.DEFAULT_QUERY_TIMEOUT

.. autoclass:: term_image.AutoCellRatio
:show-inheritance:
Expand Down Expand Up @@ -56,6 +54,20 @@ Top-Level Definitions

See :py:func:`~term_image.set_cell_ratio`.

.. autofunction:: term_image.disable_queries

.. autofunction:: term_image.disable_win_size_swap

.. autofunction:: term_image.enable_queries

.. autofunction:: term_image.enable_win_size_swap

.. autofunction:: term_image.get_cell_ratio

.. autofunction:: term_image.set_cell_ratio

.. autofunction:: term_image.set_query_timeout

|

Expand Down
110 changes: 104 additions & 6 deletions src/term_image/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,108 @@

from __future__ import annotations

__all__ = ("set_cell_ratio", "get_cell_ratio", "AutoCellRatio")
__all__ = (
"DEFAULT_QUERY_TIMEOUT",
"AutoCellRatio",
"disable_queries",
"disable_win_size_swap",
"enable_queries",
"enable_win_size_swap",
"get_cell_ratio",
"set_cell_ratio",
"set_query_timeout",
)
__author__ = "Toluwaleke Ogundipe"

from enum import Enum, auto
from operator import truediv
from typing import Optional, Union

from . import utils
from .exceptions import TermImageError
from .utils import get_cell_size

version_info = (0, 6, 0, "dev0")
__version__ = ".".join(map(str, version_info))

#: Default timeout for :ref:`terminal-queries`
#:
#: See also: :py:func:`set_query_timeout`
DEFAULT_QUERY_TIMEOUT: float = utils._query_timeout # Final[float]


class AutoCellRatio(Enum):
"""Values for setting :ref:`auto-cell-ratio`."""

is_supported: Optional[bool]

FIXED = auto()
DYNAMIC = auto()


def disable_queries() -> None:
"""Disables :ref:`terminal-queries`.
To re-enable queries, call :py:func:`enable_queries`.
NOTE:
This affects all :ref:`dependent features <queried-features>`.
"""
utils._queries_enabled = False


def disable_win_size_swap():
"""Disables a workaround for terminal emulators that wrongly report window
dimensions swapped.
This workaround is disabled by default. While disabled, the window dimensions
reported by the :term:`active terminal` are used as-is.
NOTE:
This affects :ref:`auto-cell-ratio` computation and size computations for
:ref:`graphics-based`.
"""
if utils._swap_win_size:
utils._swap_win_size = False
utils.get_cell_size._invalidate_terminal_size_cache()
with utils._win_size_lock:
utils._win_size_cache[:] = (0,) * 4


def enable_queries() -> None:
"""Re-Enables :ref:`terminal-queries`.
Queries are enabled by default. To disable, call :py:func:`disable_queries`.
NOTE:
This affects all :ref:`dependent features <queried-features>`.
"""
if not utils._queries_enabled:
utils._queries_enabled = True
utils.get_cell_size._invalidate_terminal_size_cache()
utils.get_fg_bg_colors._invalidate_cache()
utils.get_terminal_name_version._invalidate_cache()
with utils._win_size_lock:
utils._win_size_cache[:] = (0,) * 4


def enable_win_size_swap():
"""Enables a workaround for terminal emulators that wrongly report window
dimensions swapped.
While enabled, the window dimensions reported by the :term:`active terminal` are
swapped. This workaround is required on some older VTE-based terminal emulators.
NOTE:
This affects :ref:`auto-cell-ratio` computation and size computations for
:ref:`graphics-based`.
"""
if not utils._swap_win_size:
utils._swap_win_size = True
utils.get_cell_size._invalidate_terminal_size_cache()
with utils._win_size_lock:
utils._win_size_cache[:] = (0,) * 4


def get_cell_ratio() -> float:
"""Returns the global :term:`cell ratio`.
Expand Down Expand Up @@ -91,13 +180,22 @@ def set_cell_ratio(ratio: Union[float, AutoCellRatio]) -> None:
)


class AutoCellRatio(Enum):
"""Values for setting :ref:`auto-cell-ratio`."""
def set_query_timeout(timeout: float) -> None:
"""Sets the timeout for :ref:`terminal-queries`.
is_supported: Optional[bool]
Args:
timeout: Time limit for awaiting a response from the terminal, in seconds.
FIXED = auto()
DYNAMIC = auto()
Raises:
TypeError: *timeout* is not a float.
ValueError: *timeout* is less than or equal to zero.
"""
if not isinstance(timeout, float):
raise TypeError(f"'timeout' must be a float (got: {type(timeout).__name__!r})")
if timeout <= 0.0:
raise ValueError(f"'timeout' must be greater than zero (got: {timeout!r})")

utils._query_timeout = timeout


_cell_ratio = 0.5
Expand Down
67 changes: 17 additions & 50 deletions src/term_image/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@
from __future__ import annotations

__all__ = (
"DEFAULT_QUERY_TIMEOUT",
"DISABLE_QUERIES",
"SWAP_WIN_SIZE",
"get_terminal_name_version",
"get_terminal_size",
"lock_tty",
"read_tty_all",
"set_query_timeout",
"write_tty",
)

Expand Down Expand Up @@ -46,21 +42,8 @@
else:
OS_IS_UNIX = True

#: Default timeout for :ref:`terminal-queries`
#:
#: See also: :py:func:`set_query_timeout`
DEFAULT_QUERY_TIMEOUT: float = 0.1 # Final[float]

#: If ``True``, :ref:`terminal-queries` are disabled, thereby affecting all
#: :ref:`dependent features <queried-features>`.
DISABLE_QUERIES: bool = False

#: A workaround for some terminal emulators (e.g older VTE-based ones) that wrongly
#: report window dimensions swapped.
#:
#: | If ``True``, the dimensions reported by the terminal emulator are swapped.
#: | This setting affects :ref:`auto-cell-ratio` computation.
SWAP_WIN_SIZE: bool = False
# NOTE: Any cached feature using a query should have it's cache invalidated in
# `term_image.enable_queries()`.

# Decorator Classes

Expand Down Expand Up @@ -308,7 +291,7 @@ def get_fg_bg_colors(
# The response might contain a "c"; can't stop reading at "c"
lambda s: not s.endswith(CSI_b),
)
if not DISABLE_QUERIES:
if _queries_enabled:
read_tty() # The rest of the response to `CSI c`

fg = bg = None
Expand Down Expand Up @@ -341,7 +324,7 @@ def get_terminal_name_version() -> Tuple[Optional[str], Optional[str]]:
# The response might contain a "c"; can't stop reading at "c"
lambda s: not s.endswith(CSI_b),
)
if not DISABLE_QUERIES:
if _queries_enabled:
read_tty() # The rest of the response to `CSI c`

match = response and NAME_VERSION.fullmatch(response.decode().rpartition(ESC)[0])
Expand Down Expand Up @@ -429,7 +412,7 @@ def get_window_size() -> Optional[Tuple[int, int]]:
if os.environ.get("SHELL", "").startswith("/data/data/com.termux/"):
size = (size[0], size[1] * 2)

size = size[:: -SWAP_WIN_SIZE or 1] if size else (0, 0)
size = size[:: -_swap_win_size or 1] if size else (0, 0)
_win_size_cache[:] = ts + size
return None if 0 in size else size

Expand All @@ -451,18 +434,20 @@ def query_terminal(
timeout: Time limit for awaiting a response from the terminal, in seconds
(infinite if negative).
If not given or ``None``, the value set by :py:func:`set_query_timeout`
(or :py:data:`DEFAULT_QUERY_TIMEOUT` if never set) is used.
If not given or ``None``, the value set by
:py:func:`~term_image.set_query_timeout`
(or :py:data:`~term_image.DEFAULT_QUERY_TIMEOUT` if never set) is used.
Returns:
`None` if :py:data:`DISABLE_QUERIES` is true, else the terminal's response
(empty, if no response is recieved after *timeout* is up).
`None` if queries are disabled (via :py:func:`~term_image.disable_queries`),
else the terminal's response (empty, if no response is recieved after
*timeout* is up).
ATTENTION:
Any unread input is discared before the query. If the input might be needed,
it can be read using :py:func:`read_tty()` before calling this fucntion.
"""
if DISABLE_QUERIES:
if not _queries_enabled:
return None

old_attr = termios.tcgetattr(_tty)
Expand Down Expand Up @@ -577,26 +562,6 @@ def read_tty_all() -> bytes:
return read_tty()


def set_query_timeout(timeout: float) -> None:
"""Sets the timeout for :ref:`terminal-queries`.
Args:
timeout: Time limit for awaiting a response from the terminal, in seconds.
Raises:
TypeError: *timeout* is not a float.
ValueError: *timeout* is less than or equal to zero.
"""
global _query_timeout

if not isinstance(timeout, float):
raise TypeError(f"'timeout' must be a float (got: {type(timeout).__name__!r})")
if timeout <= 0.0:
raise ValueError(f"'timeout' must be greater than zero (got: {timeout!r})")

_query_timeout = timeout


@unix_tty_only
@lock_tty
def write_tty(data: bytes) -> None:
Expand Down Expand Up @@ -638,8 +603,8 @@ def _process_start_wrapper(self, *args, **kwargs):
"terminal queries.\n"
"See https://term-image.readthedocs.io/en/stable/library/reference"
"/utils.html#terminal-queries\n"
"If any related issues occur, it's advisable to set "
"`term_image.utils.DISABLE_QUERIES = True`.\n"
"If any related issues occur, it's advisable to disable queries "
"using `term_image.disable_queries()`.\n"
"Simply set an 'ignore' filter for this warning (before starting "
"any subprocess) if not using any of the affected features.",
TermImageWarning,
Expand Down Expand Up @@ -705,7 +670,9 @@ def _process_run_wrapper(self, *args, set_tty_lock: bool = True, **kwargs):
END_SYNCED_UPDATE_b = END_SYNCED_UPDATE.encode()

# Private internal variables
_query_timeout = DEFAULT_QUERY_TIMEOUT
_query_timeout = 0.1
_queries_enabled: bool = True
_swap_win_size: bool = False
_tty: Optional[int] = None
_tty_lock = RLock()
_win_size_cache = [0] * 4
Expand Down

0 comments on commit c7a6f38

Please sign in to comment.