Skip to content

Releases: RaphGL/TermCL

TermCL 0.8

05 Oct 18:52

Choose a tag to compare

Breaking changes

Redefining Inputs

Manually parsing keyboard and mouse input is annoying, it also makes adding custom backends harder due to it being tied to how terminals process the inputs rather than just the inputs being given. So I've changed the signature for both read and read_blocking. They still return an Input but it's been redefined to:

Input :: union {
    Keyboard_Input,
    Mouse_Input,
}

This makes it easier to use but it also makes it easier to extend to other backends as well.

If for some reason you still need to access the raw bytes returned from the terminal, use the raw variants: read_raw and read_raw_blocking acessible through the termcl/term package. This package also contains the parse_mouse_input and parse_keyboard_input functions so that you can still convert raw input into Input.

Custom backends

As was hinted before, the addition of cell buffers allowed for the potential use of custom backends to render to other targets, such as other escape code standards or GUIs. For now I'm adding an SDL3 backend so that TUIs can be ported to GUIs. There's still some ironing out to do so there might be some different behavior between the terminal and the backend, but as long as you test your code on both TUI and GUI, it shouldn't be too big of a problem.

How it works

The library uses a VTable with implementations for backend specific stuff. This VTable looks like this:

Backend_VTable :: struct {
	init_screen:    proc(allocator: runtime.Allocator) -> Screen,
	destroy_screen: proc(screen: ^Screen),
	get_term_size:  proc() -> Window_Size,
	set_term_mode:  proc(screen: ^Screen, mode: Term_Mode),
	blit:           proc(win: ^Window),
	read:           proc(screen: ^Screen) -> Input,
	read_blocking:  proc(screen: ^Screen) -> Input,
}

You set it by calling the set_backend function:

set_backend :: proc(backend: Backend_VTable) {

Or by just passing the backend's vtable when calling init_screen.

All you have to do is import the backend you want to use and call it's own set_backend function. For current users, the only modification they need to do is to import termcl/term and call term.set_backend() and everything should keep working as it was before.

For people attempting to use the SDL3 backend, if you're were previously doing "frame capping" by using a timer, be aware that that will screw up the event handling on SDL3, so you should do everything besides the rendering on another thread if that is the case (like you would normally do for any SDL3 program). Other than that, most programs can easily be rendered as a GUI by just swapping the backend.

Additions

  • Added SDL3 backend

Fixes

  • Removed generics to rely on subtyping instead so that the binary size of the library is smaller
  • Fixed enable_alt_buffer dispatching wrong escape code for disabling the alternate buffer

TermCL 0.7

08 Sep 19:53

Choose a tag to compare

Fixes

  • Fixed reset_styles not working properly with the new optimizations

Additions

  • Added get_window_size, this should be preferred over get_term_size whenever possible
  • Added resize_window

TermCL 0.6

27 Aug 22:49

Choose a tag to compare

Breaking Changes

  • set_color_style_* functions were all removed and instead there's now a single set_color_style. With this a new Any_Color union type was introduced, so now the function can accept any color value supported
  • RGB_Color was renamed to Color_RGB for consistency
  • get_term_size no longer receives a ^Screen as an argument, thus no longer forcing people to store screen just to call this function

Additions

  • Added the termcl/raw package which unlike the termcl package, it provides little abstraction over the escape codes, it simply writes all escape codes to a strings.Builder which you can then write to the terminal
  • Improved performance: release builds are now 400% faster
  • Added fire animation example #22 (by @via-dev)
  • Added a wiki

Fixes

  • Made windows retain internal state about color and text styles so that they avoid

TermCL 0.5

21 Jul 23:26

Choose a tag to compare

This is a very minor release. Just to ensure that the library is usable on Windows :(

Fixes

  • Fixed missing import on Windows

Added

  • Added alt detection to parse_keyboard_input

TermCL 0.4

09 Jul 22:06

Choose a tag to compare

Breakages

  • Input_Seq was renamed to Keyboard_Input for consistency with Mouse_Input

Additions

  • Added missing symbols in parse_keyboard_input: <, > and ?
  • Added MacOS syscall to get terminal size

Fixes

  • Fixed windows of size 0 causing a floating point exception in runtime
  • Fixed mouse input events being pressed when the key was None

TermCL 0.3

12 Jun 13:27

Choose a tag to compare

Added

  • Added window_coord_from_global and global_coord_from_window so that cursors can be converted from and to window coordinates. This can be used to leverage the Window isolation to create your own custom widgets or to check that the mouse is hovering inside of a window.

Fixes

  • Cbreak and Raw modes now draw to an alternate screen buffer. Preserving user terminal content and preventing undesirable scrolling in these modes on Windows.
  • Fixed library not compiling on Odin 2025-06 due to breaking change in the odin compiler (encoding/ansi got moved to terminal/ansi)

Changes

  • set_color_style_rgb has been changed to set_color_style_rgb :: proc(win: $T/^Window, fg: Maybe(RGB_Color), bg: Maybe(RGB_Color)) so that it's consistent with set_color_style_8 and also so that fg can be set to default

Aside from these the library technically now introduces widgets under termcl/widgets but it's not advised to use them just yet unless you just want to test them or contribute changes/improvements.
At the moment only button, panel and progress widgets have been written.

TermCL 0.2

30 May 23:20

Choose a tag to compare

Release of shame.

This fixes a typo in the source code that was raising an error and also improves performance by avoiding allocations and printf

TermCL 0.1

30 May 14:53

Choose a tag to compare

This is the first "stable" release. Going forward I'll attempt to not break the API and will only do so if necessary. (though the library API has barely changed so far as it is)

Going forward what I want to do is to keep fixing bugs, improving platform compatibility if necessary and creating a widgets library on top of it using the windows as an abstraction.