Pytermgui Versions Save

Python TUI framework with mouse support, modular widget system, customizable and rapid terminal markup language and more!

v6.3.0

1 year ago

The previous InputField implementation was highly restrained by the lacking (and slow) break_line implementation present at the time. Since that was recently improved a lot, the manually placed restrictions didn't make much sense anymore. There is now support for multiline text editing, syntax highlighters and more!

Changelog

Refactors

  • Refactor InputField (6cd72d677ba139d7a31ae59020e508ae1edadc36)

  • Start caching Token.sequence to improve performance (9638e9513796b51a64a58134b39b245397732854)

  • Start lazy-evaluating terminal resolution (4a7c25baa6097bf216833ca74712713577acb8d9)

    Some terminals don't support this feature, so we used to have a very short (0.01) second timeout for an emulator to respond. This was way too short in some situations, leaving the response to be printed to STDOUT instead of being captured. The bigger problem was that there is basically no code in the wild that actually uses this feature: it was implemented for the still-upcoming image support, but no other systems really use it. Because of this, it was pretty useless to query it on every startup.

Bugfixes

  • Use SVG export prefix as the class of the generated text elements (7c977f15fdb43649aa02f7e924290dbfdcc61e09, #67)

    Previously, the text style selector selected every SVG in the document. This was problematic, as it messed up non-PTG SVGs displayed alongside our own.

  • Fix Inspector not resizing to custom global terminals (0bb071711586ad8ee129fd85df14ea9eae3b06bb)

Additions

  • Add break_line fill argument (1426edc9627577764d4e286a3a65f8b6593afb46)

    This is currently unused by the library at large, but it allows padding out every yielded line to the target width using the given character. Can be pretty useful.

  • Add chrome SVG argument (182258517ff0e7d459b9c7a42a9413ffeed629fc)

Showcase

Here is a simple file I wrote using sandbox/input_field.py, a file created from examples/boilerplate.py in barely any code. Try it yourself!

Screenshot 2022-06-05 at 14 09 13

v6.2.2

1 year ago

Web compatibility strikes again. While Chrome supports alignment-baseline for SVG text tags, Firefox only supports dominant-baseline. Then, Safari comes in as a unicorn proclaiming (very quietly) that it supports neither.

All hail dy, I guess!

Changelog

Bugfixes

  • Fix text being misaligned in both Firefox and Safari

Refactors

  • Reduce redundancy in SVG export dimensions

v6.2.1

1 year ago

This release mainly targets my new mkdocs plugin, termage, which allows you to insert SVGs of Python program output, generated at build time. Its documentation website is still waiting for DNS propagation, but it uses the plugin as well. You can expect a revamp of the documentation using mkdocs and termage very soon!

For that system to work, WindowManager needed to gain the capability of running in headless mode, so that it can render an output and quit without interaction.

Changelog

Bugfixes

  • Fix \n being escaped when highlighting python (48a365a24f9b837108a1cf946bcc86af3b84cda0)

Refactors

  • Add WindowManager.autorun class attribute (6ea6044afcb7e11603fd2c5ed00ffe0ef2a7e699)

Showcase

The aforementioned documentation website: 127 0 0 1_8000_ (1)

v6.2.0

1 year ago

Changelog

Bugfixes

  • Fix StandardColor HEX and RGB being indexed from the wrong pool (66384acbb838df6f4c262b03fe595df8fbeb6fd5)
  • Fix overly greedy yeeting optimization of ttype=POSITION tokens (2f7a5616f0909499d1f391eed4f75b77bc667a82)
  • Fix ttype=POSITION tokens acting unpredictably when multiple were present in a string (c2c227f074c762a6607b4b5be7ba6d4da969c68e)

Additions

  • Add WindowManager.autorun attribute (ab0fd94871bd5f03246ef24db8f6d39a7f4d41b4)

Refactors

  • Implement usage of SVG tags when exporting (589e65003daab3cb374589b6eaa1fa6176272834)

    Previously, we were using foreignObject SVG tags to render inner content. This worked, but only in browsers, and looked ever so slightly different between each of them. We now use the proper SVG tags, and thus our exports are now real images not linked to browsers!

    You can also now export screenshots from a WindowManager application, and they look the same as they did in your terminal. This is allowed by the 2 position token fixes above. As with the previous version, this uses your terminal's background & foreground colors, as well as its size when generating. Makes it actually look like it's a screenshot of your terminal!

export

Showcase

All of the images here are straight-up SVGs dragged into the release note, no conversions or anything necessary.

screenshot export

Thank you to everyone for the 1000 stars the project recently reached. It's an incredible achievement, and I am beyond grateful for the support.

⭐ 🚀

v6.1.0

2 years ago

This version was mostly for bugfixing, but it introduces the new __fancy_repl__ protocol into the library.

The purpose of this protocol is for objects to gain control over how they are displayed in a pretty REPL environment. See the docs for more info.

There is also now support for string format specs for Color objects. You can now do things like:

markup = f"[{color:tim}]Text"

and I think that's pretty neat.

Changelog

Additions

  • Introduce __fancy_repr__ protocol (09bcb0ef1b92a5217b12576f7a60e2a62e292c49)

    This protocol is somewhat inspired by rich's __rich__, but tries to be agnostic to the underlying ANSI interface used. It can be used to customize highlighting an object's repr output.

    It is already implemented by all the Color classes, and RegexHighlighter. More (probably) to come.

  • Add Color format specifiers (c529c2c0b805ff9fe5f357023f70e55a3ee8f985)

  • Add Animation.pause & Animation.unpause (bf7ddbdf554c3228ca0860c6adfa900721147e1c)

Bugfixes

  • Fix scrolled widgets not getting positioned correctly (29a2aebcf1d98dae215497170e14039eccd1f290)
  • Fix an issue with 2-bit colors being interpreted as 8-bit ones (632ac1b957b3369e139dff17639d90b10efb00cd, #56)

Refactors

  • Improve highlight_python vs strings (8a9f63a7977facbddb7855ce1f14f33fa1a82929, 9e1042fa85df3123be5a099f299321c65e565206)

Showcase

Screenshot 2022-05-17 at 17 09 46

v6.0.0

2 years ago

This version was originally meant to focus on the new layout system, but things got out of hand quickly. In the end, we have the aforementioned feature, alongside a completely reimagined & much more useful CLI, a regex-based syntax highlighting base, major performance improvements and some general QOL things. There unfortunately are some (relatively minor) API changes, which is why this version is 6.0.0 instead of 5.1.0.

Changelog

  • Remove Window.allow_fullscreen, Window.toggle_fullscreen (114da3a3d769d6abd72a8727ed036b1e947c0a23)

    These methods are no longer really relevant in the new layout-based system. They were also handled in a really odd way from the library's side, so it should be one less bug-prone area to figure out. You can now set windows fullscreen using the layout system:

     manager.layout.add_slot("Body")
     manager.add(window, assign="body")
    

    More on the layout API later.

Refactors

  • Add new, customizable window blur styles (114da3a3d769d6abd72a8727ed036b1e947c0a23)

    The old style was visually impressive, however also prone to causing bugs that could not be resolved with either stripping functionality or changing the library source. The new version follows traditional and modern TUIs more closely by only changing the color of borders, and is actually customizable. However, since there are new styles for both blurred and focused states for both the corner and border set of characters, a small helper was also added, Window.set_focus_styles.

  • Rename all builtin aliases to follow the domain.item naming scheme (3a416f5f7d2dbc80328478ea16fddb4e980d1437)

  • Improve animation stability (c806b975c7815c876eb6845637c9f125c2f26c61, 05b61268479696298873cf616b4696ccab77b8fe)

  • Start caching real_length, strip_markup & strip_ansi results (a07ce9f606eaa96ee923e97a437edf375b89552d, 532e3ccc66fee81e4e9bfc0df0407ca72e4705c0)

    This was altogether a sub-10 line change, but it actually has huge performance implications. It will also be useful for the future, more advanced compositing running at an acceptable speed.

  • Refactor StyledText to only tokenize on-demand (b15eba881cb7a83b0c5302ae6855ec949db5a4b6)

  • Rewrite the pattern used to match markup to improve how escapes are handled (d656b7534d15769c375e9f083adc7896052ba4a1, 5a37470ac072746ee54c2029a01dcaf00832a7d8)

  • Introduce new, layout based CLI with an RGB colorpicker & inspector (31433362b208c5cc3f4c879004e69c913f361980)

    This started off as a way to showcase the new layouts, and wasn't even supposed to be a full rewrite. However, I eventually realized how ridiculously over-engineered the previous CLI was, so I decided to come up with a new system. There is a new app, Inspector, which basically runs the inspect function interactively, and can be called from the command line with no interaction. There is also now an RGB color picker, and some bindings to the new highlight_python function (more on that later).

    For some reason my favorite part of this new module is the output of -v:

    Screenshot 2022-05-12 at 23 37 24

Additions

  • Add Collapsible widget (114da3a3d769d6abd72a8727ed036b1e947c0a23)

  • Add new highlighters module with RegexHighlighter class (7e6cd024739b880aa53ef3b9c2ca9414c15493e9, 6bd3d4a3d7b8be179c4aeb7aa73079a57c29f8b3)

    This class can be used to statically highlight any type of text, combining regex with TIM. Since it's fully based around regex it will never be a full highlighter, a'la Pygments, but I feel like that is outside of the scope of the library. See an example of this in the showcase section.

  • Add is_scroll, is_primary & is_secondary helpers to MouseEvent (522e4dd939c13824b4c6c6bade69ebb8bfdf51bb)

  • Add Terminal.no_record context (b7d4976efc6756548b3903c77b3878f6972b156c)

  • Add WindowManager.alert and WindowManager.float methods (53e9b84c177e24aab3546ab57bfb218274ea06ac)

    The alert function is pretty much the exact same in terms of functionality to the one that came before it, though it's been refactored a bit. The toast method however is completely new to the library, but it's goal and general look & feel come from the Android feature of the same name. I personally think it looks dope, and you catch a glance at it on ptg startup!

  • Add layout assign parameter to WindowManager.add (6c95ac0c416290e810ffa9a012e422d3ca2861bc)

  • Add window manager Layout class (8250d6d7bebe687b53a0ee3e6f7169f2ffa0883d)

    This really is the feature of this update. Essentially, layouts let you define sizes & positions for your windows, which is then continually applied whenever the terminal resizes or windows are removed/added. It also tries to be minimal but expressive in its syntax, and do as many dynamic things as possible.

    For example, take the following code:

     manager.layout = ptg.Layout()
     manager.layout.add_slot("Header", height=5)
     manager.layout.add_break()
     manager.layout.add_slot("Sidebar", width=0.2)
     manager.layout.add_slot("Body")
     manager.layout.add_break()
     manager.layout.add_slot("Footer", height=3)
    

    It creates a 3-row layout. The first row just contains a header with a height of 5, and spanning the entire terminal in its width. The second row contains a sidebar that is 20% of the terminal's width, and a body that fills whatever remaining space it has. Finally, we have a footer, that is 3 characters height and once again spans the entire terminal.

    You may have noticed that the second row had no height definitions whatsoever. This is because the layout can calculate the remaining height for the row based on the slots with static dimensions. In effect, this means that you only need to specify the 'defining dimension' for each slot, and the rest will be calculated by the library. This Dimension system may in the future be extended into the realm of widgets, and I have plans of first adding the ability to nest layouts, and maybe eventually adding a layout-based container widget.

    Screenshot 2022-05-12 at 23 49 27

Bugfixes

  • Fix overly greedy optimization in MarkupLanguage.parse getting rid of important unsetters (32e30b5e50e5d71f89c2d5a64775820dce805f99)
  • Fix / not being handled properly in various places (2b15e5174582082999352140faafccbe05fa2670, e3e9e87ccb137a378406139e5d1f57c5decb4ce2)

Showcase

Screenshot 2022-05-12 at 23 02 27 Screenshot 2022-05-12 at 23 02 55 Screenshot 2022-05-12 at 23 04 02 Screenshot 2022-05-12 at 23 05 36

Closing thoughts

That's all for now. Next up should be either a full ScrollView widget that wraps around an inner Container, a more efficient compositing method, a universal & real-life user tested color palette or a combination of all. Since I'm currently quite busy with university I'm not sure when I'll get around to creating a new release, but it shouldn't be too far off.

As a final note, this release might be the one to push the library over 1000 stars. Thank you to everyone who has ever used PTG, raised an issue or even just checked it out or left a critical HackerNews comment for it. I never imagined my work to become this popular, and I can't wait to see where it ends up.

Ok, bye

:rocket:

v5.0.0

2 years ago

Pretentious title, I know.

This version is essentially a rewrite of the window_manager module. There is now better task distribution, things are cleaner, and there is one less 1000+ line module in the library.

The biggest change was moving all printing logic into a new module compositor. At the moment this does basically the same thing as WindowManager used to, albeit a slight bit more optimized, but in the future implementing a difference-only drawer should be relatively simple.

The animation system also got completely rewritten. I'm still not fully satisfied with some aspects, but this should be the last API-breaking set of changes done to it for the foreseeable future. The TL;DR of this would be something like:

  • A single Animation base class
  • Looping animations
  • An exposed FloatAnimation that simply transitions its state from 0.0 to 1.0 over the given duration
  • Better logic, usage of elapsed time instead of independent measurements & framerate calculations

Overall, this release provides much better internal structure and stability, plus some extra features and additions. The upcoming couple of releases will focus more on the feature side of things, but there is at least one similar refactor planned (for the ansi_interface module), though likely involving less API changes.


Items marked in bold are API breaking changes.

Refactors

  • Refactor window_manager.py into 3 files under window_manager submodule
  • Refactor the entire animation system (71cf2619baf2885d801bb6ef3bc45b62f3de7dad)
  • Move scrolling behaviour into new ScrollableWidget class (37f8ffae651d7804fac07175901bd3e35aa5baab)
  • Improve Terminal API (d0209fbf2e59950f220375f857baac35e6d7dee3)
  • Rename widgets/layoutswidgets/containers (e06608d4f2ba88216ca73a6fcbd1ddcde62a54c0)

Additions

  • Add StyleManager.__call__ method that sets the given **kwargs keys and values (2e69cbf27ca235ef958d5ef4d3d62ffda413abd8)
  • Add (currently unused) Widget.get_change helper (48d3e5c78237a7998e93055db0a9b5550b374242)

Showcase

As this is an internal refactor based update, there isn't much to showcase. Toggling fullscreen on a Window is now animated, and some other animations are improved.

Here is a random SVG screenshot.

screenshot

Unrelated note on browser rendering oddities HTML engines seem to render `foreignObject` SVG-s just slightly differently to eachother. Here is what the above looks like on Chrome for my machine:

_Users_lapis_Code_Projects_pytermgui_screenshot svg

In comparison, my phone's GitHub app tends to render text off the "terminal" panel for some reason, and even the browser tends to render the colored unicode blocks incorrectly, often adding a border around them. Odd!

v4.3.2

2 years ago

This release is focused on fixing two bugs, #46 and #42. It also introduces the getch_timeout function, which is pretty neat, though sadly special functionality is limited to POSIX systems.

Bugfixes

  • Improve how pixel size is received and fix process hanging when the terminal does not support it (49ff24445329e6f3581c1cf34c5265225ef765bd, #42)
  • Fix stream truncation raising an error on Windows (6f304ab3c4e3276f591009fe92b580c01b78dd8a, #46)

Additions

  • Add getch_timeout method (49ff24445329e6f3581c1cf34c5265225ef765bd)

v4.3.1

2 years ago

This release fixes some minor inconveniences that slipped through the last version release.

Bugfixes

  • Fix #45 by catching errno.EINVAL on stream truncation (f8b1d3f3846dd19fbdad6a064ba1e99e3472e9d3, #45)
  • Fix Container first lines sometimes having wrong indentations in SVG exports (9c32ac9e298786449f101cad8d2664584304ffa7)
  • Fix Helpers app not showing any bindings (61dbed9be42220b96c42eb97105ccda0f2071bc4)

v4.3.0

2 years ago

This version improves the Terminal class and gives it some extra abilities, which are then used by some new modules.

Anything written to the terminal can now be recorded by it, simply using the terminal.record context manager. This will then give you a new Recorder instance, which contains all the data written to the terminal in the context. This can then be exported to static HTML, or even a terminal-mimicking SVG!

The recording and subsequent outputs also respect positional printing, thus your screenshots will be accurate regardless of what weird thing you might be doing. Other than the extra functionality mentioned above, this release was a great stress-test for TIM and related utilities, and a lot of minor but important improvements have been made during the process.

Additions

  • Re-introduce Helpers ptg app (ac5687076507dc2fdb7ab6f87a71a48fc00dcd70)
  • Add F-keys to input.keys (5157546c9c9729266b1744321fa2b155f14bf9a4)
  • Add terminal Recorder class, ability to record anything written to the terminal using a context (b8c49e0ec823afbdfc9d0b31758055316abb6657)
  • Add Color.hex property (ffbb4567ab65e8d2c9c3c691628419e1925135f1)
  • Add Color default fore & background setter and getters, using the terminal’s palette (5b2c4a3ff9ef586a19c709def766d082adaeda8b)
  • Add LINK and POSITION TIM token types (309e30171084a06a424d6562a3f72585eca8d73b, 401aad8d19da6fb3f70be70f170817726c728a37)
  • Add exporters module to generate HTML pages and SVG screenshots from any terminal content (a01a6f8670dc2ecc8e4860b423ffc9a1bba012a4, d6060d5ffe042ae76c2867cf139ecc2fc2e869b7, cd69680cd01e55bed3ac4e0f6dc8b0cfd9f9572a)
  • Add style construction argument to Label (9f7336eb31a8052827beff460ee6d2dd6dc24a45)
  • Add tim.get\_styled\_plains method (8c05e69c82925f08c2a6f0b559d52dd8154d3e15)

Refactors

  • Slightly optimize how WindowManager.print works (99bad926f9cd44c3610acbe7dea1d008cce50315)
  • Move regex-related utilities into regex.py (e8befc10b97109edbc1a35b0f1bfdcfe550992bf)

Showcase

These screenshots are all directly coming from PTG, and are not actual native screenshots taken by the operating system.

recording screenshot pagoda