lazygit.go

  1// Package lazygit provides a dialog component for embedding lazygit in the TUI.
  2package lazygit
  3
  4import (
  5	"context"
  6	"fmt"
  7	"image/color"
  8	"os"
  9
 10	"github.com/charmbracelet/crush/internal/terminal"
 11	"github.com/charmbracelet/crush/internal/tui/components/dialogs"
 12	"github.com/charmbracelet/crush/internal/tui/components/dialogs/termdialog"
 13	"github.com/charmbracelet/crush/internal/tui/styles"
 14)
 15
 16// DialogID is the unique identifier for the lazygit dialog.
 17const DialogID dialogs.DialogID = "lazygit"
 18
 19// NewDialog creates a new lazygit dialog. The context controls the lifetime
 20// of the lazygit process - when cancelled, the process will be killed.
 21func NewDialog(ctx context.Context, workingDir string) *termdialog.Dialog {
 22	configFile := createThemedConfig()
 23
 24	cmd := terminal.PrepareCmd(
 25		ctx,
 26		"lazygit",
 27		nil,
 28		workingDir,
 29		[]string{"LG_CONFIG_FILE=" + configFile},
 30	)
 31
 32	return termdialog.New(termdialog.Config{
 33		ID:         DialogID,
 34		Title:      "Lazygit",
 35		LoadingMsg: "Starting lazygit...",
 36		Term:       terminal.New(terminal.Config{Context: ctx, Cmd: cmd}),
 37		OnClose: func() {
 38			if configFile != "" {
 39				_ = os.Remove(configFile)
 40			}
 41		},
 42	})
 43}
 44
 45// colorToHex converts a color.Color to a hex string.
 46func colorToHex(c color.Color) string {
 47	r, g, b, _ := c.RGBA()
 48	return fmt.Sprintf("#%02x%02x%02x", r>>8, g>>8, b>>8)
 49}
 50
 51// createThemedConfig creates a temporary lazygit config file with Crush theme.
 52func createThemedConfig() string {
 53	t := styles.CurrentTheme()
 54
 55	config := fmt.Sprintf(`gui:
 56  border: rounded
 57  showFileTree: true
 58  showRandomTip: false
 59  showCommandLog: false
 60  showBottomLine: true
 61  showPanelJumps: false
 62  nerdFontsVersion: ""
 63  showFileIcons: false
 64  theme:
 65    activeBorderColor:
 66      - "%s"
 67      - bold
 68    inactiveBorderColor:
 69      - "%s"
 70    searchingActiveBorderColor:
 71      - "%s"
 72      - bold
 73    optionsTextColor:
 74      - "%s"
 75    selectedLineBgColor:
 76      - "%s"
 77    inactiveViewSelectedLineBgColor:
 78      - "%s"
 79    cherryPickedCommitFgColor:
 80      - "%s"
 81    cherryPickedCommitBgColor:
 82      - "%s"
 83    markedBaseCommitFgColor:
 84      - "%s"
 85    markedBaseCommitBgColor:
 86      - "%s"
 87    unstagedChangesColor:
 88      - "%s"
 89    defaultFgColor:
 90      - default
 91`,
 92		colorToHex(t.BorderFocus),
 93		colorToHex(t.Border),
 94		colorToHex(t.Warning),
 95		colorToHex(t.FgHalfMuted),
 96		colorToHex(t.Primary),
 97		colorToHex(t.BgSubtle),
 98		colorToHex(t.Secondary),
 99		colorToHex(t.BgOverlay),
100		colorToHex(t.Warning),
101		colorToHex(t.BgOverlay),
102		colorToHex(t.Error),
103	)
104
105	f, err := os.CreateTemp("", "crush-lazygit-*.yml")
106	if err != nil {
107		return ""
108	}
109	defer f.Close()
110
111	_, _ = f.WriteString(config)
112	return f.Name()
113}