Files
zterm/README.md

4.9 KiB

zterm Terminal User Interface Library

zterm is a terminal user interface library to implement terminal (fullscreen or inline) applications.

Note

Only builds using the master version are tested to work.

Usage

To add or update zterm as a dependency in your project run the following command:

zig fetch --save git+https://gitea.yves-biener.de/yves-biener/zterm

Add the dependency to your module as follows in your build.zig:

const zterm: *Dependency = b.dependency("zterm", .{
    .target = target,
    .optimize = optimize,
});
// ...
exe.root_module.addImport("zterm", zterm.module("zterm"));

For an example you can take a look at build.zig for an example.


Design Goals

This project draws heavy inspiration from clay in the way the layout is declared by the user. As terminal applications usually are rendered in intermediate mode, the rendering is also part of the event loop. Such that every time an event happens a render call will usually be done as well. However this is not strickly necessary and can be separated to have a fixed rendering of every 16ms (i.e. for 60 fps), etc.

There is only one generic container which contains properties and elements (or children) which can also be containers, such that each layout in the end is a tree.

The library is designed to be very basic and not to provide any more complex elements such as input fields, drop-down menu's, buttons, etc. Some of them are either easy to implement yourself, specific for you needs or a too complex to be provided by the library effectively. For these use-cases there may be other libraries that build on top of this one to provide the complex elements as some sort of pre-built elements for you to use in your application (or you create them yourself).

There are only very few system events, that are used by the built-in containers and properties accordingly. For you own widgets (i.e. a collection of elements) you can extend the events to include your own events to communicate between elements, effect the control flow and the corresponding generated layouts and much more.

As this is a terminal based layout library it also provides a rendering pipeline alongside the event loop implementation. Usually the event loop is waiting blocking and will only cause a re-draw (intermediate mode) after each event. Even though the each frame is regenerated from scratch each render loop, the corresponding application is still pretty performant as the renderer uses a double buffered intermediate mode implementation to only apply the changes from each frame to the next to the terminal.

This library is also designed to work accordingly in ssh hosted environments, such that an application created using this library can be accessed directly via ssh. This provides security through the ssh protocol and can defer the synchronization process, as users may access the same running instance. Which is the primary use-case for myself to create this library in the first place.


Roadmap

  • Container rendering
    • Layout
      • direction
        • vertical
        • horizontal
      • padding
      • gap
      • alignment
        • center
        • left
        • right
      • sizing
        • width
        • height
        • options
          • fit
          • grow
          • fixed
          • percent
    • Border
      • sides
      • corners
      • separators
    • Rectangle
    • Scroll
      • vertical
      • horizontal
      • scroll bar(s)

Decorations should respect the layout and the viewport accordingly. This means that scrollbars are always visible (except there is no need to have a scrollbar) irrelevant depending on the size of the content. The rectangle apply to all cells of the content (and may be overwritten by child elements contents). The border of an element should be around independent of the scrolling of the contents, just like padding.

  • fit: adjust virtual space of container by the size of its children (i.e. a container needs to be able to get the necessary size of its children)

  • grow: use as much space as available (what exactly would be the difference between this option and fit?)

  • fixed: use exactly as much cells (in the specified direction)

  • center: elements should have their anchor be placed accordingly to their size and the viewport size.

  • left: the anchor remains at zero (relative to the location of the container on the screen) -> similar to the current implementation!

  • right: the anchor is fixed to the right side (i.e. size of the contents - size of the viewport)

Input

How is the user input handled in the containers? Should there be active containers? Some input may happen for a specific container (i.e. when using mouse input). How would I handle scrolling for outer and inner elements of a container?