termbox2 icon indicating copy to clipboard operation
termbox2 copied to clipboard

FR: support "inline TUIs"

Open sullyj3 opened this issue 1 year ago • 4 comments

Currently tb_init always clears the screen and switches to the alternate screen buffer. This means that you can only write TUIs which use the whole terminal screen.

Some TUIs instead operate inline in the shell, rendering below the current command prompt. Fzf is a great example, it provides scripts which allow you to press ctrl-t to get an inline tui for selecting a file path to insert into your command. Another use case is providing dynamically updating progress for a running command, eg loading bars, spinners, etc.

My feature request is an alternate api to tb_init (or a change to the tb_init api) which doesn't clear the screen and doesn't switch to the alternate screen, to support these kinds of UIs.

Is this something you'd be willing to incorporate?

sullyj3 avatar Jul 23 '24 05:07 sullyj3

I think that would be a worthy addition.

trapexit avatar Jul 23 '24 18:07 trapexit

Hello, thanks for the FR. I like the idea and agree a separate API or library is the right choice.

I've thought it would be cool to pair this with an alternative to readline, which has a lot of room for improvement IMO. The main alternatives are editline, tecla, and linenoise. I don't know much about the first two, but they appear to be similar to readline. linenoise is tight and simple but IMO lacks some important features, like being able to interleave a prompt with other i/o.

I wonder how useful it'd be without a prompt feature. I'm curious what others think.

If you don't need to support exotic terminals, and you just want to reposition the cursor, you can get by with a few very portable escape codes. Here's a spinner for example:

#!/bin/bash

spinner=('-' '\' '|' '/')
si=0
n=100

printf '\x1b7' # save cursor

while true; do
  s=${spinner[si % ${#spinner[@]}]}
  let si+=1
  printf '\x1b8' # restore cursor
  printf '%s spinning' "$s"
  let n-=1
  test $n -gt 0 || break
  sleep 0.05
done

printf '\x1b8' # restore cursor
printf '\x1b[K' # clear line

echo done

adsr avatar Jul 26 '24 03:07 adsr

I was experimenting with not switching to alt screen this evening and with a couple hacks:

image

I'm not yet convinced we should add this feature, but I'm slightly more open to it now after seeing there wouldn't be that many extra conditionals.

One thing to figure out is how to handle when there's not many lines (or no lines) after the cursor. I'm not sure how other non-alt-screen TUIs do it, but I suppose you could print some newlines to get the terminal to scroll. No idea what the API would look like that for that. Also some stuff to figure out with resizing, mouse events, etc. Suggestions welcome.

adsr avatar Oct 04 '24 23:10 adsr

This would be really great! the dagger.io CLI is another great example of an "inline" TUI that cleverly interleaves itself with the scroll back history of your primary screen.

cowboyd avatar Nov 06 '25 20:11 cowboyd