A powerful little TUI framework š
We hope youāre ready for winter. Unless youāre in the southern hemisphere (like @caarlos0) in which case, we hope youāre ready for summer. In either case, we hope you have a happy new year if the Julian calendar is something youāre into.
There are a bunch of good features in this release and a ton of input-related improvements. Read on for more!
Bubble Tea now supports Extended Mouse Mode (aka SGR mode) which makes now mouse support in Bubble Tea way, way better.
Prior to this release Bubble Tea used the X10 mouse protocol. X10 was last released in 1986: a time when screen resolutions were smaller, memory limits were low, and a terminal sizes were tiny. For terminals and mice this meant that the mouse tracking stopped after the 127th horizontal cell. Well, thanks to the elite abilities of @aymanbagabas Bubble Tea can now track mouse movements across the entire terminal window, no matter how enormous.
And that's not all: Bubble Tea now has higher fidelity access to mouse operations such as shift, ctrl, and alt modifiers, mouse button release events, and a big range of mouse button and mouse wheel events.
For details see the docs for the new and improved MouseEvent
.
@aymanbagabas also wanted to be able to set the terminal window title with Bubble Tea, so he added the SetWindowTitle
Cmd
. Now setting the window title is as simple as:
func (m Model) Update(msg tea.Msg) (tea.Model. tea.Cmd) {
return m, tea.SetWindowTitle("oh my")
}
Have you ever thought āBubble Tea is too fast and I just canāt handle it?ā Or perhaps 60fps is too slow and you want to go full 120fps. Now, thanks to @tomfeiginās WithFPS
ProgramOption
you can:
// Letās go with the classic soap opera frame rate
p := tea.NewProgram(model, tea.WithMaxFPS(45))
@knz is just incredible. He took a look at Bubble Teaās input parser and whipped it into shape with what felt like a flick of the wrist. Keyboard input is now more efficient than ever and very large amounts of input can be parsed with the greatest of ease. It's hard to overstate how impactful his contributions areāand there are more in the pipe.
SetWindowTitle
command by @aymanbagabas in https://github.com/charmbracelet/bubbletea/pull/611
ReleaseTerminal
/RestoreTerminal
thread safe by @caarlos0 in https://github.com/charmbracelet/bubbletea/pull/791
Full Changelog: https://github.com/charmbracelet/bubbletea/compare/v0.24.2...v0.25.0
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.
This point release fixes a race condition that could occur when stopping the default renderer:
Full Changelog: https://github.com/charmbracelet/bubbletea/compare/v0.24.1...v0.24.2
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.
This point release fixes a regression introduced in v0.24.0
in which keyboard and mouse input would be lost when piping and redirecting into a program with default inputs. Special thanks to @pomdtr forā¦piping up about the regression.
Full Changelog: https://github.com/charmbracelet/bubbletea/compare/v0.24.0...v0.24.1
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.
It is finally time for another Bubble Tea release!
This release contains 31 commits by 14 contributors. Thank you everyone! š
Without further ado, here's a list of the most important changes:
The tea.QuitMsg
is now exported and you can use tea.WithFilter
to filter which messages your model will receive:
func filter(m tea.Model, msg tea.Msg) tea.Msg {
if _, ok := msg.(tea.QuitMsg); !ok {
return msg
}
model := m.(myModel)
if model.hasChanges {
return nil
}
return msg
}
p := tea.NewProgram(Model{}, tea.WithFilter(filter));
if _,err := p.Run(); err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
We are introducing an our very own /x
package, which contains the teatest
package.
With teatest
, you can easily run a tea.Program
, assert its final model and/or output.
This package required a couple of new methods on Bubble Tea, namely Program.Wait()
, WithoutSignals
.
You can see an example usage in the simple
example.
We try hard to not let any of them pass, but we know, sometimes a few of them do. This release also gets rid of a bunch of them.
Full Changelog: https://github.com/charmbracelet/bubbletea/compare/v0.23.2...v0.24.0
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.
This is a small maintenance release with two small but acute fixes from our wonderful community. Thanks for the support! š
Msg
Cmd
is not nil before invoking (to avoid a nil pointer exception) by @nderjung in https://github.com/charmbracelet/bubbletea/pull/640
BatchMsg
to Sequence
by @stoffeastrom in https://github.com/charmbracelet/bubbletea/pull/581
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.
This bugfix release addresses an issue that was introduced by v0.23.0
and prevented programs from re-using stdin
after a tea.Program
had finished execution.
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.
If you are closely following Bubble Tea's development, you may have already noticed that we have been really busy fixing a lot of issues and merged more than just a couple of feature requests in recent weeks. This v0.23.0
release is in fact our biggest update since the initial release of the package: in the last 3 months over 100 commits have reached us by more than 30 individual contributors! Thank you everyone! š
Here's a quick overview of what has changed:
Don't want to render your beautiful TUI to stdout
? A buffer or an alternative file descriptor like stderr
seems more
appropriate? We got you covered now:
p := tea.NewProgram(model, tea.WithOutput(os.Stderr))
var buf bytes.Buffer
p := tea.NewProgram(model, tea.WithOutput(&buf))
We've introduced the aptly named method Program.Run
which replaces and deprecates the existing Program.Start
and
Program.StartReturningModel
methods. This unifies and clarifies the blocking behavior of the Bubble Tea program execution.
The old methods will continue to work for now, but please update your programs accordingly:
p := tea.NewProgram(model, tea.WithOutput(os.Stderr))
model, err := p.Run() // instead of p.Start or p.StartReturningModel
...
The initialization and tear-down methods of tea.Program
have been revised and some long-standing problems have been resolved. We couldn't list every single fix in the release notes, so please check out the full changelog below!
We would like to particularly thank @knz who is the sole author of more than a dozen PRs since the last release. Outstanding work!
tea.WithOutput
)tea.WithoutSignalHandler
tea.ClearScreen
, tea.ShowCursor
commandsBatchMsg
Program.Run
Program.Send
on shutdownProgram.Start
, Program.StartReturningModel
: please use Program.Run
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.
This is a small release with a big impact for Chinese, Japanese, and Korean users on Windows. The long as short of it is that if youāre using a multi-byte character set thatās not UTF-8, Bubble Tea will covert stuff for you so things work as expected. For details see https://github.com/charmbracelet/bubbletea/pull/343.
š¤ Enormous thanks to @mattn for the contribution as well as his Go libraries that make CJK support in the Charm ecosystem possible.
š¾ Also, thanks to @aklyachkin, if Bubble Tea on AIX is something you want your dream is a now a reality.
Full Changelog: https://github.com/charmbracelet/bubbletea/compare/v0.22.0...v0.22.1
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Slack.
Now you can print unmanaged output above your inline applications. This means you can print stuff above your app that won't be cleared on the next render. Itās super useful for cases where you want to build an apt
-like package manager.
This release introduces two new Cmd
s that print output above your inline Bubble Tea program:
tea.Println("Hello, Bubble Tea")
tea.Printf("%s, %s", "Hello", "Bubble Tea")
Use it anytime you want to add log-type info to the terminalās scrollback buffer, such as building your own package manager š¦. And keep in mind that these methods are no-opās in altscreen mode.
For details see the full example and the docs.
@fiws has been bugging us to implement this forever and then @Adjective-Object swooped in and did it with style and grace! Itās been a great collaboration all around.
Full Changelog: https://github.com/charmbracelet/bubbletea/compare/v0.21.0...v0.22.0
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Slack.
Finally! This update allows you to run blocking, interactive processes from Bubble Tea like vim
, htop
, curl
, and even entire shells like fish
. It also adds a bunch of new keybindings. Read on for more!
As we were saying, you can now spawn interactive processes in the terminal from Bubble Tea and resume Bubble Tea when they exit. For example, you could have your Bubble Tea program spawn vim
to edit a file, or temporarily open a shell, like fish
. Hereās what it looks like:
type editorFinishedMsg struct{ err error }
func openInVim(path string) tea.Cmd {
c := exec.Command("vim", path)
return tea.ExecProcess(c, func(err error) tea.Msg {
return editorFinishedMsg{err}
})
}
See the full example for details.
Prior to this update, you couldn't bind to the functions keys. Isn't that crazy? @mrusme certainly thought so. With this update you can can now respond to F1 through F20, modifiers included.
And thanks to @bwahharharrr you can also now bind to arrow keys with the ctrl, shift and alt modifiers.
KeySpace
by @bashbunni in https://github.com/charmbracelet/bubbletea/pull/289 and https://github.com/charmbracelet/bubbletea/pull/315
Full Changelog: https://github.com/charmbracelet/bubbletea/compare/v0.20.0...v0.21.0
Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Slack.