File: termhelpers.py

package info (click to toggle)
python-curtsies 0.4.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 420 kB
  • sloc: python: 4,021; sh: 6; makefile: 5
file content (67 lines) | stat: -rw-r--r-- 2,004 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import tty
import termios
import fcntl
import os

from typing import IO, ContextManager, Type, List, Union, Optional
from types import TracebackType

_Attr = list[Union[int, list[Union[bytes, int]]]]


class Nonblocking(ContextManager):
    """
    A context manager for making an input stream nonblocking.
    """

    def __init__(self, stream: IO) -> None:
        self.stream = stream
        self.fd = self.stream.fileno()

    def __enter__(self) -> None:
        self.orig_fl = fcntl.fcntl(self.fd, fcntl.F_GETFL)
        fcntl.fcntl(self.fd, fcntl.F_SETFL, self.orig_fl | os.O_NONBLOCK)

    def __exit__(
        self,
        type: type[BaseException] | None = None,
        value: BaseException | None = None,
        traceback: TracebackType | None = None,
    ) -> None:
        fcntl.fcntl(self.fd, fcntl.F_SETFL, self.orig_fl)


class Termmode(ContextManager):
    def __init__(self, stream: IO, attrs: _Attr) -> None:
        self.stream = stream
        self.attrs = attrs

    def __enter__(self) -> None:
        self.original_stty = termios.tcgetattr(self.stream)
        termios.tcsetattr(self.stream, termios.TCSANOW, self.attrs)

    def __exit__(
        self,
        type: type[BaseException] | None = None,
        value: BaseException | None = None,
        traceback: TracebackType | None = None,
    ) -> None:
        termios.tcsetattr(self.stream, termios.TCSANOW, self.original_stty)


class Cbreak(ContextManager[Termmode]):
    def __init__(self, stream: IO) -> None:
        self.stream = stream

    def __enter__(self) -> Termmode:
        self.original_stty = termios.tcgetattr(self.stream)
        tty.setcbreak(self.stream, termios.TCSANOW)
        return Termmode(self.stream, self.original_stty)

    def __exit__(
        self,
        type: type[BaseException] | None = None,
        value: BaseException | None = None,
        traceback: TracebackType | None = None,
    ) -> None:
        termios.tcsetattr(self.stream, termios.TCSANOW, self.original_stty)