PyTermGUI 7.7.3__tar.gz → 7.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytermgui-7.7.3 → pytermgui-7.8.0}/CHANGELOG.md +39 -2
- {pytermgui-7.7.3 → pytermgui-7.8.0}/PKG-INFO +45 -19
- {pytermgui-7.7.3 → pytermgui-7.8.0}/README.md +19 -17
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pyproject.toml +13 -4
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/__init__.py +1 -1
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/animations.py +1 -1
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/ansi_interface.py +1 -1
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/colors.py +3 -3
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/exporters.py +2 -2
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/file_loaders.py +4 -4
- pytermgui-7.8.0/pytermgui/helpers.py +60 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/input.py +1 -5
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/inspector.py +1 -1
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/markup/macros.py +1 -1
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/markup/parsing.py +11 -5
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/palettes.py +5 -10
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/regex.py +6 -2
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/term.py +50 -19
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/base.py +0 -12
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/containers.py +47 -4
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/input_field.py +1 -2
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/window_manager/compositor.py +3 -1
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/window_manager/manager.py +10 -3
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/window_manager/window.py +3 -1
- pytermgui-7.7.3/examples/README.md +0 -19
- pytermgui-7.7.3/pytermgui/helpers.py +0 -113
- pytermgui-7.7.3/tests/__init__.py +0 -0
- pytermgui-7.7.3/tests/_exporter_targets.py +0 -1646
- pytermgui-7.7.3/tests/colorgrids.py +0 -122
- pytermgui-7.7.3/tests/test.json +0 -45
- pytermgui-7.7.3/tests/test.yaml +0 -103
- pytermgui-7.7.3/tests/test_animations.py +0 -114
- pytermgui-7.7.3/tests/test_auto.py +0 -68
- pytermgui-7.7.3/tests/test_colors.py +0 -113
- pytermgui-7.7.3/tests/test_dump_n_load.py +0 -34
- pytermgui-7.7.3/tests/test_exporters.py +0 -1063
- pytermgui-7.7.3/tests/test_fancy_repr.py +0 -17
- pytermgui-7.7.3/tests/test_helpers.py +0 -53
- pytermgui-7.7.3/tests/test_highlight_markup_literal.py +0 -8
- pytermgui-7.7.3/tests/test_layouts.py +0 -99
- pytermgui-7.7.3/tests/test_parser.py +0 -179
- pytermgui-7.7.3/tests/test_regex.py +0 -40
- pytermgui-7.7.3/tests/test_styles.py +0 -56
- {pytermgui-7.7.3 → pytermgui-7.8.0}/.gitignore +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/LICENSE +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/cmd.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/color_info.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/context_managers.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/enums.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/exceptions.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/fancy_repr.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/highlighters.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/markup/__init__.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/markup/aliases.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/markup/language.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/markup/style_maps.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/markup/tokens.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/prettifiers.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/pretty.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/py.typed +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/serialization.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/__init__.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/boxes.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/button.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/checkbox.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/collapsible.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/color_picker.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/fancy_repr.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/frames.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/inline.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/keyboard_button.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/pixel_matrix.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/slider.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/styles.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/widgets/toggle.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/win32console.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/window_manager/__init__.py +0 -0
- {pytermgui-7.7.3 → pytermgui-7.8.0}/pytermgui/window_manager/layouts.py +0 -0
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
## [7.8.0] - 2026-08-10
|
|
2
|
+
|
|
3
|
+
### Additions
|
|
4
|
+
|
|
5
|
+
- Add grapheme-aware wrapping with correct widths for CJK and emoji sequences
|
|
6
|
+
- Preserve ANSI styles and hyperlinks when wrapping text
|
|
7
|
+
- Document terminal compatibility and the project's archived status
|
|
8
|
+
|
|
9
|
+
### Bugfixes
|
|
10
|
+
|
|
11
|
+
- Fix terminal clearing, synchronized frame recording, and resize handling
|
|
12
|
+
- Fix multiline input cursor placement and nested container scrolling
|
|
13
|
+
- Fix uneven splitter columns and automatically sized scrollable windows
|
|
14
|
+
- Fix ANSI bright magenta, cyan, and white color mappings
|
|
15
|
+
- Fix cursor-home and erase sequences in ANSI exports
|
|
16
|
+
- Avoid busy-waiting for input on Windows
|
|
17
|
+
|
|
18
|
+
### Maintenance
|
|
19
|
+
|
|
20
|
+
- Modernize linting and packaging configuration
|
|
21
|
+
- Remove obsolete project assets and tooling
|
|
22
|
+
|
|
23
|
+
<!-- HATCH README END -->
|
|
24
|
+
|
|
25
|
+
## [7.7.4] - 2025-03-31
|
|
26
|
+
|
|
27
|
+
### Bugfixes
|
|
28
|
+
|
|
29
|
+
- Fix rapid input to \_GetchLinux
|
|
30
|
+
|
|
31
|
+
## [7.7.3] - 2024-12-29
|
|
32
|
+
|
|
33
|
+
### Bugfixes
|
|
34
|
+
|
|
35
|
+
- Fix getch mapping for Windows keys
|
|
36
|
+
|
|
1
37
|
## [7.7.2] - 2024-08-31
|
|
2
38
|
|
|
3
39
|
### Additions
|
|
@@ -5,8 +41,6 @@
|
|
|
5
41
|
- Stop allowing selection of closed Collapsible's items
|
|
6
42
|
- Clarify some documentation
|
|
7
43
|
|
|
8
|
-
<!-- HATCH README END -->
|
|
9
|
-
|
|
10
44
|
## [7.7.1] - 2024-02-24
|
|
11
45
|
|
|
12
46
|
### Additions
|
|
@@ -410,6 +444,9 @@
|
|
|
410
444
|
|
|
411
445
|
<!-- HATCH URI DEFINITIONS START -->
|
|
412
446
|
|
|
447
|
+
[7.8.0]: https://github.com/bczsalba/pytermgui/compare/v7.7.4...v7.8.0
|
|
448
|
+
[7.7.4]: https://github.com/bczsalba/pytermgui/compare/v7.7.3...v7.7.4
|
|
449
|
+
[7.7.3]: https://github.com/bczsalba/pytermgui/compare/v7.7.2...v7.7.3
|
|
413
450
|
[7.7.2]: https://github.com/bczsalba/pytermgui/compare/v7.7.1...v7.7.2
|
|
414
451
|
[7.7.1]: https://github.com/bczsalba/pytermgui/compare/v7.7.0...v7.7.1
|
|
415
452
|
[7.7.0]: https://github.com/bczsalba/pytermgui/compare/v7.6.0...v7.7.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyTermGUI
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.8.0
|
|
4
4
|
Summary: Python TUI framework with mouse support, modular widget system, customizable and rapid terminal markup language and more!
|
|
5
5
|
Project-URL: homepage, https://github.com/bczsalba/PyTermGUI
|
|
6
6
|
Project-URL: repository, https://github.com/bczsalba/PyTermGUI
|
|
@@ -26,13 +26,17 @@ Classifier: Topic :: Text Processing :: Markup
|
|
|
26
26
|
Classifier: Typing :: Typed
|
|
27
27
|
Requires-Python: >=3.8
|
|
28
28
|
Requires-Dist: typing-extensions
|
|
29
|
-
Requires-Dist: wcwidth
|
|
29
|
+
Requires-Dist: wcwidth>=0.5
|
|
30
|
+
Provides-Extra: docs
|
|
31
|
+
Requires-Dist: mkdocs-gen-files; extra == 'docs'
|
|
32
|
+
Requires-Dist: mkdocs-literate-nav; extra == 'docs'
|
|
33
|
+
Requires-Dist: mkdocs-material; extra == 'docs'
|
|
34
|
+
Requires-Dist: mkdocstrings[python]; extra == 'docs'
|
|
35
|
+
Requires-Dist: termage; extra == 'docs'
|
|
30
36
|
Provides-Extra: yaml
|
|
31
37
|
Requires-Dist: pyyaml; extra == 'yaml'
|
|
32
38
|
Description-Content-Type: text/markdown
|
|
33
39
|
|
|
34
|
-
<!---->
|
|
35
|
-
|
|
36
40
|

|
|
37
41
|
|
|
38
42
|
> Python TUI framework with mouse support, modular widget system, customizable and rapid terminal markup language and more!
|
|
@@ -45,26 +49,20 @@ pip3 install pytermgui
|
|
|
45
49
|
<a href="https://pypi.org/project/pytermgui">
|
|
46
50
|
<img alt="PyPi project" src="https://img.shields.io/pypi/v/pytermgui?color=brightgreen">
|
|
47
51
|
</a>
|
|
48
|
-
|
|
49
|
-
<img
|
|
50
|
-
</a>
|
|
51
|
-
<a href="http://ptg.bczsalba.com/">
|
|
52
|
-
<img src="https://img.shields.io/badge/documentation-up%20to%20date-brightgreen">
|
|
52
|
+
<a href="https://ptg.bczsalba.com/">
|
|
53
|
+
<img src="https://img.shields.io/badge/documentation-gray">
|
|
53
54
|
</a>
|
|
54
55
|
<a href="https://github.com/bczsalba/pytermgui/actions/workflows/pytest.yml">
|
|
55
56
|
<img src="https://github.com/bczsalba/pytermgui/actions/workflows/pytest.yml/badge.svg">
|
|
56
57
|
</a>
|
|
57
58
|
</p>
|
|
58
|
-
<p align=center>
|
|
59
|
-
<a href="https://discord.gg/g4bqMvpG4U">
|
|
60
|
-
<img src="https://img.shields.io/discord/999374285686706367?label=join%20our%20discord">
|
|
61
|
-
</a>
|
|
62
59
|
</p>
|
|
63
60
|
|
|
64
|
-
|
|
61
|
+
<hr>
|
|
62
|
+
|
|
63
|
+
## Archival notice
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
those libraries will be the primary focus of development going forward.
|
|
65
|
+
PyTermGUI is no longer in development. The latest release will remain available, alongside its documentation. The MIT license allows for free modification of the library, as long as you include credit to its original author. Thank you for everything.
|
|
68
66
|
|
|
69
67
|
<hr>
|
|
70
68
|
|
|
@@ -97,20 +95,48 @@ Additionally, there are a couple of neat tools to make your general Python devel
|
|
|
97
95
|
- A pretty printer for both the REPL and IPython
|
|
98
96
|
- A way to create SVG and HTML screenshots of your terminal
|
|
99
97
|
|
|
98
|
+
### Terminal compatibility
|
|
99
|
+
|
|
100
|
+
PyTermGUI relies on ANSI virtual-terminal sequences for rendering, cursor reports,
|
|
101
|
+
keyboard input, and mouse input. On Windows, support depends on the terminal emulator's
|
|
102
|
+
ANSI compatibility. [Windows Terminal](https://github.com/microsoft/terminal) supports
|
|
103
|
+
the expected cursor and mouse protocols, while the legacy Windows Console Host
|
|
104
|
+
(`conhost.exe`) may provide reduced functionality. This does not depend on whether
|
|
105
|
+
PowerShell or Command Prompt is running inside the emulator. Mouse support also depends
|
|
106
|
+
on the emulator forwarding the requested events.
|
|
107
|
+
|
|
100
108
|
## Latest release
|
|
101
109
|
|
|
102
|
-
### [7.
|
|
110
|
+
### [7.8.0] - 2026-08-10
|
|
103
111
|
|
|
104
112
|
### Additions
|
|
105
113
|
|
|
106
|
-
-
|
|
107
|
-
-
|
|
114
|
+
- Add grapheme-aware wrapping with correct widths for CJK and emoji sequences
|
|
115
|
+
- Preserve ANSI styles and hyperlinks when wrapping text
|
|
116
|
+
- Document terminal compatibility and the project's archived status
|
|
117
|
+
|
|
118
|
+
### Bugfixes
|
|
119
|
+
|
|
120
|
+
- Fix terminal clearing, synchronized frame recording, and resize handling
|
|
121
|
+
- Fix multiline input cursor placement and nested container scrolling
|
|
122
|
+
- Fix uneven splitter columns and automatically sized scrollable windows
|
|
123
|
+
- Fix ANSI bright magenta, cyan, and white color mappings
|
|
124
|
+
- Fix cursor-home and erase sequences in ANSI exports
|
|
125
|
+
- Avoid busy-waiting for input on Windows
|
|
126
|
+
|
|
127
|
+
### Maintenance
|
|
128
|
+
|
|
129
|
+
- Modernize linting and packaging configuration
|
|
130
|
+
- Remove obsolete project assets and tooling
|
|
108
131
|
|
|
109
132
|
|
|
110
133
|
Read the full changelog [here](https://github.com/bczsalba/pytermgui/blob/master/CHANGELOG.md).
|
|
111
134
|
|
|
112
135
|
|
|
113
136
|
|
|
137
|
+
[7.8.0]: https://github.com/bczsalba/pytermgui/compare/v7.7.4...v7.8.0
|
|
138
|
+
[7.7.4]: https://github.com/bczsalba/pytermgui/compare/v7.7.3...v7.7.4
|
|
139
|
+
[7.7.3]: https://github.com/bczsalba/pytermgui/compare/v7.7.2...v7.7.3
|
|
114
140
|
[7.7.2]: https://github.com/bczsalba/pytermgui/compare/v7.7.1...v7.7.2
|
|
115
141
|
[7.7.1]: https://github.com/bczsalba/pytermgui/compare/v7.7.0...v7.7.1
|
|
116
142
|
[7.7.0]: https://github.com/bczsalba/pytermgui/compare/v7.6.0...v7.7.0
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
<!---->
|
|
2
|
-
|
|
3
1
|

|
|
4
2
|
|
|
5
3
|
> Python TUI framework with mouse support, modular widget system, customizable and rapid terminal markup language and more!
|
|
@@ -12,26 +10,20 @@ pip3 install pytermgui
|
|
|
12
10
|
<a href="https://pypi.org/project/pytermgui">
|
|
13
11
|
<img alt="PyPi project" src="https://img.shields.io/pypi/v/pytermgui?color=brightgreen">
|
|
14
12
|
</a>
|
|
15
|
-
|
|
16
|
-
<img
|
|
17
|
-
</a>
|
|
18
|
-
<a href="http://ptg.bczsalba.com/">
|
|
19
|
-
<img src="https://img.shields.io/badge/documentation-up%20to%20date-brightgreen">
|
|
13
|
+
<a href="https://ptg.bczsalba.com/">
|
|
14
|
+
<img src="https://img.shields.io/badge/documentation-gray">
|
|
20
15
|
</a>
|
|
21
16
|
<a href="https://github.com/bczsalba/pytermgui/actions/workflows/pytest.yml">
|
|
22
17
|
<img src="https://github.com/bczsalba/pytermgui/actions/workflows/pytest.yml/badge.svg">
|
|
23
18
|
</a>
|
|
24
19
|
</p>
|
|
25
|
-
<p align=center>
|
|
26
|
-
<a href="https://discord.gg/g4bqMvpG4U">
|
|
27
|
-
<img src="https://img.shields.io/discord/999374285686706367?label=join%20our%20discord">
|
|
28
|
-
</a>
|
|
29
20
|
</p>
|
|
30
21
|
|
|
31
|
-
|
|
22
|
+
<hr>
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
## Archival notice
|
|
25
|
+
|
|
26
|
+
PyTermGUI is no longer in development. The latest release will remain available, alongside its documentation. The MIT license allows for free modification of the library, as long as you include credit to its original author. Thank you for everything.
|
|
35
27
|
|
|
36
28
|
<hr>
|
|
37
29
|
|
|
@@ -64,6 +56,16 @@ Additionally, there are a couple of neat tools to make your general Python devel
|
|
|
64
56
|
- A pretty printer for both the REPL and IPython
|
|
65
57
|
- A way to create SVG and HTML screenshots of your terminal
|
|
66
58
|
|
|
59
|
+
### Terminal compatibility
|
|
60
|
+
|
|
61
|
+
PyTermGUI relies on ANSI virtual-terminal sequences for rendering, cursor reports,
|
|
62
|
+
keyboard input, and mouse input. On Windows, support depends on the terminal emulator's
|
|
63
|
+
ANSI compatibility. [Windows Terminal](https://github.com/microsoft/terminal) supports
|
|
64
|
+
the expected cursor and mouse protocols, while the legacy Windows Console Host
|
|
65
|
+
(`conhost.exe`) may provide reduced functionality. This does not depend on whether
|
|
66
|
+
PowerShell or Command Prompt is running inside the emulator. Mouse support also depends
|
|
67
|
+
on the emulator forwarding the requested events.
|
|
68
|
+
|
|
67
69
|
<!-- HATCH README END -->
|
|
68
70
|
|
|
69
71
|
## Examples
|
|
@@ -181,9 +183,9 @@ We use algorithms based on human vision to convert and downgrade colors when the
|
|
|
181
183
|
|
|
182
184
|
## Questions? See the docs!
|
|
183
185
|
|
|
184
|
-
Pretty much every
|
|
186
|
+
Pretty much every name in the library, private or public, has an insightful docstring attached to it, alongside walkthrough-based documentation articles. See them all on the [documentation website](https://ptg.bczsalba.com)!
|
|
185
187
|
|
|
186
188
|
|
|
187
|
-
##
|
|
189
|
+
## Project status
|
|
188
190
|
|
|
189
|
-
|
|
191
|
+
PyTermGUI has reached its final release and is no longer under active development. The repository and its documentation are retained as an archive for existing users.
|
|
@@ -13,7 +13,7 @@ description = """\
|
|
|
13
13
|
license = {text = "MIT"}
|
|
14
14
|
|
|
15
15
|
requires-python = ">=3.8"
|
|
16
|
-
dependencies = ["wcwidth", "typing_extensions"]
|
|
16
|
+
dependencies = ["wcwidth>=0.5", "typing_extensions"]
|
|
17
17
|
|
|
18
18
|
keywords = [
|
|
19
19
|
"terminal",
|
|
@@ -53,6 +53,13 @@ documentation = "https://ptg.bczsalba.com"
|
|
|
53
53
|
|
|
54
54
|
[project.optional-dependencies]
|
|
55
55
|
yaml = ["PyYAML"]
|
|
56
|
+
docs = [
|
|
57
|
+
"mkdocs-material",
|
|
58
|
+
"mkdocs-gen-files",
|
|
59
|
+
"mkdocs-literate-nav",
|
|
60
|
+
"mkdocstrings[python]",
|
|
61
|
+
"termage",
|
|
62
|
+
]
|
|
56
63
|
|
|
57
64
|
[project.scripts]
|
|
58
65
|
ptg = "pytermgui.cmd:main"
|
|
@@ -63,9 +70,8 @@ path = "pytermgui/__init__.py"
|
|
|
63
70
|
[tool.hatch.build]
|
|
64
71
|
include = [
|
|
65
72
|
"/pytermgui",
|
|
66
|
-
"/
|
|
67
|
-
"
|
|
68
|
-
"CHANGELOG.md",
|
|
73
|
+
"/README.md",
|
|
74
|
+
"/CHANGELOG.md",
|
|
69
75
|
]
|
|
70
76
|
|
|
71
77
|
[tool.hatch.metadata.hooks.fancy-pypi-readme]
|
|
@@ -96,6 +102,9 @@ start-after = "\n<!-- HATCH URI DEFINITIONS START -->"
|
|
|
96
102
|
[tool.mypy]
|
|
97
103
|
show_error_codes = true
|
|
98
104
|
|
|
105
|
+
[tool.pylint.main]
|
|
106
|
+
py-version = "3.8"
|
|
107
|
+
|
|
99
108
|
[tool.pylint.messages_control]
|
|
100
109
|
disable = [
|
|
101
110
|
"fixme",
|
|
@@ -23,7 +23,7 @@ from typing import TYPE_CHECKING, Any, Callable
|
|
|
23
23
|
if TYPE_CHECKING:
|
|
24
24
|
from .widgets import Widget
|
|
25
25
|
else:
|
|
26
|
-
Widget = Any
|
|
26
|
+
Widget = Any # pylint: disable=invalid-name
|
|
27
27
|
|
|
28
28
|
__all__ = ["Animator", "FloatAnimation", "AttrAnimation", "animator", "is_animated"]
|
|
29
29
|
|
|
@@ -68,9 +68,9 @@ XTERM_NAMED_COLORS = {
|
|
|
68
68
|
10: "ansi-bright-green",
|
|
69
69
|
11: "ansi-bright-yellow",
|
|
70
70
|
12: "ansi-bright-blue",
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
13: "ansi-bright-magenta",
|
|
72
|
+
14: "ansi-bright-cyan",
|
|
73
|
+
15: "ansi-bright-white",
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
NAMED_COLORS = {
|
|
@@ -273,7 +273,7 @@ def token_to_css(token: Token, invert: bool = False) -> str:
|
|
|
273
273
|
|
|
274
274
|
# We take this many arguments for future proofing and customization, not much we can
|
|
275
275
|
# do about it.
|
|
276
|
-
def to_html( # pylint: disable=too-many-arguments, too-many-locals
|
|
276
|
+
def to_html( # pylint: disable=too-many-arguments, too-many-locals, R0917
|
|
277
277
|
obj: Widget | StyledText | str,
|
|
278
278
|
prefix: str | None = None,
|
|
279
279
|
inline_styles: bool = False,
|
|
@@ -441,7 +441,7 @@ def _make_tag(tagname: str, content: str = "", **attrs) -> str:
|
|
|
441
441
|
|
|
442
442
|
# This is a bit of a beast of a function, but it does the job and IMO reducing it
|
|
443
443
|
# into parts would just make our lives more complicated.
|
|
444
|
-
def to_svg( # pylint: disable=too-many-locals, too-many-arguments, too-many-statements, R0912
|
|
444
|
+
def to_svg( # pylint: disable=too-many-locals, too-many-arguments, too-many-statements, R0912, R0917
|
|
445
445
|
obj: Widget | StyledText | str,
|
|
446
446
|
prefix: str | None = None,
|
|
447
447
|
chrome: bool = True,
|
|
@@ -131,14 +131,14 @@ from . import widgets as widgets_m
|
|
|
131
131
|
from .markup import tim
|
|
132
132
|
from .serialization import Serializer
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
_yaml_error = None
|
|
135
135
|
|
|
136
136
|
try:
|
|
137
137
|
import yaml
|
|
138
138
|
except ImportError as import_error:
|
|
139
139
|
# yaml is explicitly checked to be None later
|
|
140
140
|
yaml = None # type: ignore
|
|
141
|
-
|
|
141
|
+
_yaml_error = import_error
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
__all__ = ["WidgetNamespace", "FileLoader", "YamlLoader", "JsonLoader"]
|
|
@@ -412,10 +412,10 @@ class YamlLoader(FileLoader):
|
|
|
412
412
|
def __init__(self, serializer: Serializer | None = None) -> None:
|
|
413
413
|
"""Initialize object, check for installation of PyYAML."""
|
|
414
414
|
|
|
415
|
-
if
|
|
415
|
+
if _yaml_error is not None:
|
|
416
416
|
raise RuntimeError(
|
|
417
417
|
"YAML implementation module not found. Please install `PyYAML` to use `YamlLoader`."
|
|
418
|
-
) from
|
|
418
|
+
) from _yaml_error
|
|
419
419
|
|
|
420
420
|
super().__init__()
|
|
421
421
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Helper methods and functions for pytermgui."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Iterator
|
|
6
|
+
|
|
7
|
+
from wcwidth import wrap as wcwidth_wrap
|
|
8
|
+
|
|
9
|
+
from .regex import real_length
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"break_line",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def break_line(
|
|
17
|
+
line: str, limit: int, non_first_limit: int | None = None, fill: str | None = None
|
|
18
|
+
) -> Iterator[str]:
|
|
19
|
+
"""Breaks a line into a `list[str]` with maximum `limit` length per line.
|
|
20
|
+
|
|
21
|
+
Uses wcwidth.wrap() for proper word-boundary breaking, grapheme cluster
|
|
22
|
+
handling, and wide character support. ANSI sequences are preserved and
|
|
23
|
+
propagated across line breaks.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
line: The line to split. May or may not contain ANSI sequences.
|
|
27
|
+
limit: The maximum amount of characters allowed in each line, excluding
|
|
28
|
+
non-printing sequences.
|
|
29
|
+
non_first_limit: The limit after the first line. If not given, defaults
|
|
30
|
+
to `limit`.
|
|
31
|
+
fill: Optional character to pad lines to the limit width.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
if line in ["", "\x1b[0m"]:
|
|
35
|
+
yield ""
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
def _pad_line(text: str, width: int) -> str:
|
|
39
|
+
if fill is None:
|
|
40
|
+
return text
|
|
41
|
+
|
|
42
|
+
count = width - real_length(text)
|
|
43
|
+
if count > 0:
|
|
44
|
+
return text + count * fill
|
|
45
|
+
return text
|
|
46
|
+
|
|
47
|
+
if non_first_limit is None:
|
|
48
|
+
non_first_limit = limit
|
|
49
|
+
|
|
50
|
+
for segment in line.split("\n"):
|
|
51
|
+
if not segment:
|
|
52
|
+
yield _pad_line("", limit)
|
|
53
|
+
limit = non_first_limit
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
wrapped = wcwidth_wrap(segment, limit)
|
|
57
|
+
|
|
58
|
+
for wrapped_line in wrapped:
|
|
59
|
+
yield _pad_line(wrapped_line, limit)
|
|
60
|
+
limit = non_first_limit
|
|
@@ -5,10 +5,6 @@ Credits:
|
|
|
5
5
|
|
|
6
6
|
- Original getch implementation: [Danny Yoo](https://code.activestate.com/recipes/134892)
|
|
7
7
|
- Modern additions & idea: [kcsaff](https://github.com/kcsaff/getkey)
|
|
8
|
-
|
|
9
|
-
Note that the original link seems to no longer be active, but an archive can be found
|
|
10
|
-
on [GitHub](https://github.com/ActiveState/code/tree/master/recipes/Python/
|
|
11
|
-
134892_getchlike_unbuffered_character_reading_stdboth).
|
|
12
8
|
"""
|
|
13
9
|
|
|
14
10
|
# pylint doesn't see the C source
|
|
@@ -134,7 +130,7 @@ class _GetchUnix:
|
|
|
134
130
|
|
|
135
131
|
descriptor = sys.stdin.fileno()
|
|
136
132
|
old_settings = termios.tcgetattr(descriptor)
|
|
137
|
-
tty.setcbreak(descriptor)
|
|
133
|
+
tty.setcbreak(descriptor, termios.TCSANOW)
|
|
138
134
|
|
|
139
135
|
try:
|
|
140
136
|
yield self._read(1)
|
|
@@ -175,7 +175,7 @@ def inspect(target: object, **inspector_args: Any) -> Inspector:
|
|
|
175
175
|
class Inspector(Container):
|
|
176
176
|
"""A widget to inspect any Python object."""
|
|
177
177
|
|
|
178
|
-
def __init__( # pylint: disable=too-many-arguments
|
|
178
|
+
def __init__( # pylint: disable=too-many-arguments, R0917
|
|
179
179
|
self,
|
|
180
180
|
target: object = None,
|
|
181
181
|
show_private: bool = False,
|
|
@@ -211,6 +211,11 @@ def tokenize_ansi( # pylint: disable=too-many-locals, too-many-branches, too-ma
|
|
|
211
211
|
if cursor < start:
|
|
212
212
|
yield PlainToken(text[cursor:start])
|
|
213
213
|
|
|
214
|
+
if matchobj.groups()[4] is not None:
|
|
215
|
+
cursor = end
|
|
216
|
+
yield ClearToken("/~")
|
|
217
|
+
continue
|
|
218
|
+
|
|
214
219
|
if link_osc != (None, None):
|
|
215
220
|
cursor = end
|
|
216
221
|
uri, label = link_osc
|
|
@@ -225,6 +230,9 @@ def tokenize_ansi( # pylint: disable=too-many-locals, too-many-branches, too-ma
|
|
|
225
230
|
|
|
226
231
|
cursor = end
|
|
227
232
|
|
|
233
|
+
if full.endswith(("J", "K")):
|
|
234
|
+
continue
|
|
235
|
+
|
|
228
236
|
code = ""
|
|
229
237
|
|
|
230
238
|
# Position
|
|
@@ -233,9 +241,7 @@ def tokenize_ansi( # pylint: disable=too-many-locals, too-many-branches, too-ma
|
|
|
233
241
|
if posmatch is not None:
|
|
234
242
|
ypos, xpos = posmatch.groups()
|
|
235
243
|
if not ypos and not xpos:
|
|
236
|
-
|
|
237
|
-
f"Cannot parse cursor when no position is supplied. Match: {posmatch!r}"
|
|
238
|
-
)
|
|
244
|
+
ypos = xpos = "1"
|
|
239
245
|
|
|
240
246
|
yield CursorToken(content, int(ypos) or None, int(xpos) or None)
|
|
241
247
|
continue
|
|
@@ -481,7 +487,7 @@ def optimize_tokens(tokens: list[Token]) -> Iterator[Token]:
|
|
|
481
487
|
applied.append(tkn)
|
|
482
488
|
yield tkn
|
|
483
489
|
|
|
484
|
-
def _remove_redundant_color(token: Token) -> None:
|
|
490
|
+
def _remove_redundant_color(token: Token, new: Color) -> None:
|
|
485
491
|
"""Removes non-functional colors.
|
|
486
492
|
|
|
487
493
|
These happen in the following ways:
|
|
@@ -513,7 +519,7 @@ def optimize_tokens(tokens: list[Token]) -> Iterator[Token]:
|
|
|
513
519
|
if Token.is_color(token):
|
|
514
520
|
new = token.color
|
|
515
521
|
|
|
516
|
-
_remove_redundant_color(token)
|
|
522
|
+
_remove_redundant_color(token, new)
|
|
517
523
|
|
|
518
524
|
if not any(token.markup == applied.markup for applied in current_tag_group):
|
|
519
525
|
current_tag_group.append(token)
|
|
@@ -241,23 +241,18 @@ class Palette:
|
|
|
241
241
|
for shadenumber in range(-SHADE_COUNT, SHADE_COUNT + 1):
|
|
242
242
|
if shadenumber > 0:
|
|
243
243
|
shadeindex = f"+{shadenumber}"
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
blended = color.blend(
|
|
245
|
+
white, SHADE_INCREMENT * shadenumber
|
|
246
|
+
)
|
|
246
247
|
|
|
247
248
|
elif shadenumber == 0:
|
|
248
249
|
shadeindex = ""
|
|
249
|
-
|
|
250
|
-
else:
|
|
251
|
-
shadeindex = str(shadenumber)
|
|
252
|
-
blend_color = black
|
|
253
|
-
blend_multiplier = -1
|
|
254
|
-
|
|
255
|
-
if shadenumber == 0:
|
|
256
250
|
blended = color
|
|
257
251
|
|
|
258
252
|
else:
|
|
253
|
+
shadeindex = str(shadenumber)
|
|
259
254
|
blended = color.blend(
|
|
260
|
-
|
|
255
|
+
black, -SHADE_INCREMENT * shadenumber
|
|
261
256
|
)
|
|
262
257
|
|
|
263
258
|
data[f"{name}{shadeindex}"] = blended
|
|
@@ -7,8 +7,12 @@ from typing import Match
|
|
|
7
7
|
from wcwidth import wcswidth
|
|
8
8
|
|
|
9
9
|
RE_LINK = re.compile(r"(?:\x1b\]8;;([^\\]*)\x1b\\([^\\]*?)\x1b\]8;;\x1b\\)")
|
|
10
|
-
RE_ANSI_NEW = re.compile(
|
|
11
|
-
|
|
10
|
+
RE_ANSI_NEW = re.compile(
|
|
11
|
+
rf"(\x1b\[(.*?)[mHJK])|{RE_LINK.pattern}|(\x1b\]8;;\x1b\\)|(\x1b_G(.*?)\x1b\\)"
|
|
12
|
+
)
|
|
13
|
+
RE_ANSI = re.compile(
|
|
14
|
+
r"(?:\x1b\[(.*?)[mHJK])|(?:\x1b\](.*?)\x1b\\)|(?:\x1b_G(.*?)\x1b\\)"
|
|
15
|
+
)
|
|
12
16
|
RE_MACRO = re.compile(r"(![a-z0-9_\-]+)(?:\(([\w\/\.?\-=:]+)\))?")
|
|
13
17
|
RE_MARKUP = re.compile(r"((\\*)\[([^\[\]]*)\])")
|
|
14
18
|
RE_POSITION = re.compile(r"\x1b\[(\d*?)(?:;(\d*))?H")
|