mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Running the integration tests in a loop under the race detector eventually hung in demo/bisect. The goroutine dump shows the cycle: a background worker's task.Done() held the task manager's mutex while blocking on the unbuffered idle-listener channel send, and the test runner goroutine — the only reader of that channel — was itself blocked in NewTask on that same mutex, on its way to enqueueing a caption render (SetCaption -> Render -> OnUIThread). Neither side could proceed: the notification couldn't be delivered until the test goroutine got the mutex, and the mutex couldn't be released until the notification was delivered. The root problem is that the busy-to-idle notification is a blocking rendezvous performed while holding the mutex, so it needs the waiter's cooperation at a moment where the waiter may legitimately need the mutex first. Make the notification fire-and-forget instead: WaitUntilIdle waits on a condition variable and re-checks "is any task busy?" under the mutex, and the busy-to-idle transition broadcasts, which never blocks. Waiting is now level-triggered rather than edge-triggered, which is also more robust: a wait can no longer be satisfied by a stale idle transition produced by an unrelated background task, because the predicate is evaluated against the current state. This relies on the previous commit having made replayed input events carry their task from submission; without that, the wait could return in the window where an event is in flight but not yet picked up by the main loop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| attribute.go | ||
| AUTHORS | ||
| CHANGES_tcell.md | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| doc.go | ||
| edit.go | ||
| escape.go | ||
| escape_test.go | ||
| flush_test.go | ||
| gui.go | ||
| gui_others.go | ||
| gui_windows.go | ||
| key.go | ||
| keybinding.go | ||
| LICENSE | ||
| README.md | ||
| scrollbar.go | ||
| scrollbar_test.go | ||
| task.go | ||
| task_manager.go | ||
| task_manager_test.go | ||
| tcell_driver.go | ||
| text_area.go | ||
| text_area_test.go | ||
| user_event_queue_test.go | ||
| view.go | ||
| view_test.go | ||
GOCUI - Go Console User Interface
Minimalist Go package aimed at creating Console User Interfaces. A community fork based on the amazing work of jroimartin
Features
- Minimalist API.
- Views (the "windows" in the GUI) implement the interface io.ReadWriter.
- Support for overlapping views.
- The GUI can be modified at runtime (concurrent-safe).
- Global and view-level keybindings.
- Mouse support.
- Colored text.
- Customizable editing mode.
- Easy to build reusable widgets, complex layouts...
About fork
This fork has many improvements over the original work from jroimartin.
- Written ontop of TCell
- Better wide character support
- Support for 1 Line height views
- Better support for running in docker container
- Customize frame colors
- Improved code comments and quality
- Many small improvements
- Change Visibility of views
For information about this org see: awesome-gocui/about.
Installation
Execute:
$ go get github.com/awesome-gocui/gocui
Documentation
Execute:
$ go doc github.com/awesome-gocui/gocui
Or visit godoc.org to read it online.
Example
See the _example folder for more examples
package main
import (
"fmt"
"log"
"github.com/awesome-gocui/gocui"
)
func main() {
g, err := gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
log.Panicln(err)
}
defer g.Close()
g.SetManagerFunc(layout)
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
log.Panicln(err)
}
if err := g.MainLoop(); err != nil && !gocui.IsQuit(err) {
log.Panicln(err)
}
}
func layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
if v, err := g.SetView("hello", maxX/2-7, maxY/2, maxX/2+7, maxY/2+2, 0); err != nil {
if !gocui.IsUnknownView(err) {
return err
}
if _, err := g.SetCurrentView("hello"); err != nil {
return err
}
fmt.Fprintln(v, "Hello world!")
}
return nil
}
func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
Screenshots
Projects using gocui
- komanda-cli: IRC Client For Developers.
- vuls: Agentless vulnerability scanner for Linux/FreeBSD.
- wuzz: Interactive cli tool for HTTP inspection.
- httplab: Interactive web server.
- domainr: Tool that checks the availability of domains based on keywords.
- gotime: Time tracker for projects and tasks.
- claws: Interactive command line client for testing websockets.
- terminews: Terminal based RSS reader.
- diagram: Tool to convert ascii arts into hand drawn diagrams.
- pody: CLI app to manage Pods in a Kubernetes cluster.
- kubexp: Kubernetes client.
- kcli: Tool for inspecting kafka topics/partitions/messages.
- fac: git merge conflict resolver
- jsonui: Interactive JSON explorer for your terminal.
- cointop: Interactive terminal based UI application for tracking cryptocurrencies.
- lazygit: simple terminal UI for git commands.
- lazydocker: The lazier way to manage everything docker.
Note: if your project is not listed here, let us know! :)


