ronantakizawa/codereview-bench huggingface dataset:
Repository: charmbracelet/bubbletea
File: tea.go (Go)

Code before:
	// treated as bits. These options can be set via various ProgramOptions.
	startupOptions startupOptions

	inputType inputType

	ctx    context.Context
	cancel context.CancelFunc

	msgs     chan Msg
	errs     chan error
	finished chan struct{}

	// where to send output, this will usually be os.Stdout.
	output        *termenv.Output
	restoreOutput func() error
	renderer      renderer

	// where to read inputs from, this will usually be os.Stdin.
	input        io.Reader
	cancelReader cancelreader.CancelReader
	readLoopDone chan struct{}
	console      console.Console

	// was the altscreen active before releasing the terminal?
	altScreenWasActive bool
	ignoreSignals      atomic.Bool

	// Stores the original reference to stdin for cases where input is not a
	// TTY on windows and we've automatically opened CONIN$ to receive input.
	// When the program exits this will be restored.
	//
	// Lint ignore note: the linter will find false positive on unix systems
	// as this value only comes into play on Windows, hence the ignore comment
	// below.
	windowsStdin *os.File //nolint:golint,structcheck,unused

	filter func(Model, Msg) Msg

	// fps is the frames per second we should set on the renderer, if
	// applicable,
	fps int
}

// Quit is a special command that tells the Bubble Tea program to exit.
func Quit() Msg {
	return QuitMsg{}
}

// QuitMsg signals that the program should quit. You can send a QuitMsg with
// Quit.
type QuitMsg struct{}

Review comment (suggestion):
`atomic.Bool` was only introduced in go1.19, use `uint32` and `atomic.StoreUint32` instead

Code after:
	// treated as bits. These options can be set via various ProgramOptions.
	startupOptions startupOptions

	inputType inputType

	ctx    context.Context
	cancel context.CancelFunc

	msgs     chan Msg
	errs     chan error
	finished chan struct{}

	// where to send output, this will usually be os.Stdout.
	output        *termenv.Output
	restoreOutput func() error
	renderer      renderer

	// where to read inputs from, this will usually be os.Stdin.
	input        io.Reader
	cancelReader cancelreader.CancelReader
	readLoopDone chan struct{}
	console      console.Console

	// was the altscreen active before releasing the terminal?
	altScreenWasActive bool
	ignoreSignals      uint32

	// Stores the original reference to stdin for cases where input is not a
	// TTY on windows and we've automatically opened CONIN$ to receive input.
	// When the program exits this will be restored.
	//
	// Lint ignore note: the linter will find false positive on unix systems
	// as this value only comes into play on Windows, hence the ignore comment
	// below.
	windowsStdin *os.File //nolint:golint,structcheck,unused

	filter func(Model, Msg) Msg

	// fps is the frames per second we should set on the renderer, if
	// applicable,
	fps int
}

// Quit is a special command that tells the Bubble Tea program to exit.
func Quit() Msg {
	return QuitMsg{}
}

// QuitMsg signals that the program should quit. You can send a QuitMsg with
// Quit.
type QuitMsg struct{}
Repository: charmbracelet/bubbletea
File: tea.go (Go)

Code before:
}

func (p *Program) execBatchMsg(msg BatchMsg) {
	// Execute commands one at a time.
	g, _ := errgroup.WithContext(p.ctx)
	for _, cmd := range msg {
		cmd := cmd
		if cmd == nil {
			continue
		}
		g.Go(func() error {
			msg := cmd()
			switch msg := msg.(type) {
			case BatchMsg:
				p.execBatchMsg(msg)
			case sequenceMsg:
				p.execSequenceMsg(msg)
			default:
				p.Send(msg)
			}
			return nil
		})
	}

	//nolint:errcheck
	g.Wait() // wait for all commands from batch msg to finish
}

// Run initializes the program and runs its event loops, blocking until it gets
// terminated by either [Program.Quit], [Program.Kill], or its signal handler.
// Returns the final model.
func (p *Program) Run() (Model, error) {
	handlers := handlers{}
	cmds := make(chan Cmd)
	p.errs = make(chan error)
	p.finished = make(chan struct{}, 1)

	defer p.cancel()

	switch p.inputType {
	case defaultInput:
		p.input = os.Stdin

		// The user has not set a custom input, so we need to check whether or
		// not standard input is a terminal. If it's not, we open a new TTY for
		// input. This will allow things to "just work" in cases where data was
		// piped in or redirected to the application.
		//
		// To disable input entirely pass nil to the [WithInput] program option.
		f, isFile := p.input.(*os.File)
		if !isFile {

Review comment (suggestion):
Since we're not using or returning errors, I would use a waitgroup instead

Code after:
			}
			if msg == nil {
				continue
			}

			// Handle special internal messages.
			switch msg := msg.(type) {
			case QuitMsg:
				return model, nil

			case InterruptMsg:
				return model, ErrInterrupted

			case SuspendMsg:
				if suspendSupported {
					p.suspend()
				}

			case clearScreenMsg:
				p.renderer.clearScreen()

			case enterAltScreenMsg:
				p.renderer.enterAltScreen()

			case exitAltScreenMsg:
				p.renderer.exitAltScreen()

			case enableMouseCellMotionMsg, enableMouseAllMotionMsg:
				switch msg.(type) {
				case enableMouseCellMotionMsg:
					p.renderer.enableMouseCellMotion()
				case enableMouseAllMotionMsg:
					p.renderer.enableMouseAllMotion()
				}
				// mouse mode (1006) is a no-op if the terminal doesn't support it.
				p.renderer.enableMouseSGRMode()

				// XXX: This is used to enable mouse mode on Windows. We need
				// to reinitialize the cancel reader to get the mouse events to
				// work.
				if runtime.GOOS == "windows" && !p.mouseMode {
					p.mouseMode = true
					p.initCancelReader(true) //nolint:errcheck,gosec
				}

			case disableMouseMsg:
				p.disableMouse()

				// XXX: On Windows, mouse mode is enabled on the input reader
				// level. We need to instruct the input reader to stop reading
				// mouse events.
Repository: charmbracelet/bubbletea
File: tea.go (Go)

Code before:
type Program struct {
	initialModel Model

	// Configuration options that will set as the program is initializing,
	// treated as bits. These options can be set via various ProgramOptions.
	startupOptions startupOptions

	inputType inputType

	ctx    context.Context
	cancel context.CancelFunc

	msgs     chan Msg
	errs     chan error
	finished chan struct{}

	// where to send output, this will usually be os.Stdout.
	output        *termenv.Output
	restoreOutput func() error
	renderer      renderer

	// where to read inputs from, this will usually be os.Stdin.
	input io.Reader
	// tty is null if input is not a TTY.
	tty          *os.File
	ttyState     *term.State
	cancelReader cancelreader.CancelReader
	readLoopDone chan struct{}

	// was the altscreen active before releasing the terminal?
	altScreenWasActive bool
	ignoreSignals      uint32

	filter func(Model, Msg) Msg

	// fps is the frames per second we should set on the renderer, if
	// applicable,
	fps int
}

// Quit is a special command that tells the Bubble Tea program to exit.
func Quit() Msg {
	return QuitMsg{}
}

// QuitMsg signals that the program should quit. You can send a QuitMsg with
// Quit.
type QuitMsg struct{}

// NewProgram creates a new Program.
func NewProgram(model Model, opts ...ProgramOption) *Program {

Review comment (suggestion):
this could prob be called `previousTtyState` or something like that, since it is the state the term had before `MakeRaw` 🤔

Code after:
// Program is a terminal user interface.
type Program struct {
	initialModel Model

	// Configuration options that will set as the program is initializing,
	// treated as bits. These options can be set via various ProgramOptions.
	startupOptions startupOptions

	inputType inputType

	ctx    context.Context
	cancel context.CancelFunc

	msgs     chan Msg
	errs     chan error
	finished chan struct{}

	// where to send output, this will usually be os.Stdout.
	output        *termenv.Output
	restoreOutput func() error
	renderer      renderer

	// where to read inputs from, this will usually be os.Stdin.
	input io.Reader
	// tty is null if input is not a TTY.
	tty              *os.File
	previousTtyState *term.State
	cancelReader     cancelreader.CancelReader
	readLoopDone     chan struct{}

	// was the altscreen active before releasing the terminal?
	altScreenWasActive bool
	ignoreSignals      uint32

	bpWasActive bool // was the bracketed paste mode active before releasing the terminal?

	filter func(Model, Msg) Msg

	// fps is the frames per second we should set on the renderer, if
	// applicable,
	fps int
}

// Quit is a special command that tells the Bubble Tea program to exit.
func Quit() Msg {
	return QuitMsg{}
}

// QuitMsg signals that the program should quit. You can send a QuitMsg with
// Quit.
type QuitMsg struct{}
Repository: charmbracelet/bubbletea
File: commands.go (Go)

Code before:
			}
		}
		return nil
	}
}

// setWindowTitleMsg is an internal message used to set the window title.
type setWindowTitleMsg string

// SetWindowTitle produces a command that sets the terminal title.
//
// For example:
//
//	func (m model) Init() Cmd {
//	    // Set title.
//	    return tea.SetWindowTitle("My App")
//	}
func SetWindowTitle(title string) Cmd {
	return func() Msg {
		return setWindowTitleMsg(title)
	}
}

type windowSizeMsg struct{}

// WindowSize is a command that queries the terminal for its current size.
func WindowSize() Cmd {
	return func() Msg {
		return windowSizeMsg{}
	}
}


Review comment (suggestion):
```suggestion
// WindowSize is a command that queries the terminal for its current size. It
// delivers the results to Update via a [WindowSizeMsg]. Keep in mind that
// WindowSizeMsgs will automatically be delivered to Update when the [Program]
// starts and when the window dimensions change so in many cases you will not
// need to explicitly invoke this command.
```

Code after:
			}
		}
		return nil
	}
}

// setWindowTitleMsg is an internal message used to set the window title.
type setWindowTitleMsg string

// SetWindowTitle produces a command that sets the terminal title.
//
// For example:
//
//	func (m model) Init() Cmd {
//	    // Set title.
//	    return tea.SetWindowTitle("My App")
//	}
func SetWindowTitle(title string) Cmd {
	return func() Msg {
		return setWindowTitleMsg(title)
	}
}

type windowSizeMsg struct{}

// WindowSize is a command that queries the terminal for its current size. It
// delivers the results to Update via a [WindowSizeMsg]. Keep in mind that
// WindowSizeMsgs will automatically be delivered to Update when the [Program]
// starts and when the window dimensions change so in many cases you will not
// need to explicitly invoke this command.
func WindowSize() Cmd {
	return func() Msg {
		return windowSizeMsg{}
	}
}
Repository: charmbracelet/bubbletea
File: options.go (Go)

Code before:
//
//		return msg
//	}
//
//	p := tea.NewProgram(Model{}, tea.WithFilter(filter));
//
//	if _,err := p.Run(); err != nil {
//		fmt.Println("Error running program:", err)
//		os.Exit(1)
//	}
func WithFilter(filter func(Model, Msg) Msg) ProgramOption {
	return func(p *Program) {
		p.filter = filter
	}
}

// WithFPS sets a custom maximum FPS at which the renderer should run. If
// less than 1, the default value of 60 will be used. If over 120, the FPS
// will be capped at 120.
func WithFPS(fps int) ProgramOption {
	return func(p *Program) {
		p.fps = fps
	}
}

//	WithReportFocus enables reporting when the terminal gains and lost focus.
//
// You can then check for FocusMsg and BlurMsg in your model's Update method.
func WithReportFocus() ProgramOption {
	return func(p *Program) {
		p.startupOptions |= withReportFocus
	}
}


Review comment (suggestion):
```suggestion
// WithReportFocus enables reporting when the terminal gains and lost focus.
```

Code after:
//
//		return msg
//	}
//
//	p := tea.NewProgram(Model{}, tea.WithFilter(filter));
//
//	if _,err := p.Run(); err != nil {
//		fmt.Println("Error running program:", err)
//		os.Exit(1)
//	}
func WithFilter(filter func(Model, Msg) Msg) ProgramOption {
	return func(p *Program) {
		p.filter = filter
	}
}

// WithFPS sets a custom maximum FPS at which the renderer should run. If
// less than 1, the default value of 60 will be used. If over 120, the FPS
// will be capped at 120.
func WithFPS(fps int) ProgramOption {
	return func(p *Program) {
		p.fps = fps
	}
}

// WithReportFocus enables reporting when the terminal gains and lost focus.
//
// You can then check for FocusMsg and BlurMsg in your model's Update method.
func WithReportFocus() ProgramOption {
	return func(p *Program) {
		p.startupOptions |= withReportFocus
  }
}

// WithEnhancedKeyboard enables support for enhanced keyboard features. This
// unambiguously reports more key combinations than traditional terminal
// keyboard sequences. This might also enable reporting of release key events
// depending on the terminal emulator supporting it.
//
// This is a syntactic sugar for WithKittyKeyboard(3) and WithXtermModifyOtherKeys(1).
func WithEnhancedKeyboard() ProgramOption {
	return func(p *Program) {
		WithKittyKeyboard(3)(p)
		WithModifyOtherKeys(1)(p)
	}
}

// WithKittyKeyboard enables support for the Kitty keyboard protocol. This
// protocol enables more key combinations and events than the traditional
// ambiguous terminal keyboard sequences.
//
Repository: charmbracelet/bubbletea
File: color.go (Go)

Code before:

		r, _ := strconv.ParseUint(parts[0], 16, 32)
		g, _ := strconv.ParseUint(parts[1], 16, 32)
		b, _ := strconv.ParseUint(parts[2], 16, 32)
		a, _ := strconv.ParseUint(parts[3], 16, 32)

		return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), uint8(shift(a))}
	}
	return color.Black
}

func getMaxMin(a, b, c float64) (max, min float64) {
	if a > b {
		max = a
		min = b
	} else {
		max = b
		min = a
	}
	if c > max {
		max = c
	} else if c < min {
		min = c
	}
	return max, min
}

func round(x float64) float64 {
	return math.Round(x*1000) / 1000
}

// rgbToHSL converts an RGB triple to an HSL triple.
func rgbToHSL(r, g, b uint8) (h, s, l float64) {
	// convert uint32 pre-multiplied value to uint8
	// The r,g,b values are divided by 255 to change the range from 0..255 to 0..1:
	Rnot := float64(r) / 255
	Gnot := float64(g) / 255
	Bnot := float64(b) / 255
	Cmax, Cmin := getMaxMin(Rnot, Gnot, Bnot)
	Δ := Cmax - Cmin
	// Lightness calculation:
	l = (Cmax + Cmin) / 2
	// Hue and Saturation Calculation:
	if Δ == 0 {
		h = 0
		s = 0
	} else {
		switch Cmax {
		case Rnot:
			h = 60 * (math.Mod((Gnot-Bnot)/Δ, 6))
		case Gnot:

Review comment (suggestion):
```suggestion
	return max(a, b, c), min(a, b, c)
```


Code after:

		r, _ := strconv.ParseUint(parts[0], 16, 32)
		g, _ := strconv.ParseUint(parts[1], 16, 32)
		b, _ := strconv.ParseUint(parts[2], 16, 32)
		a, _ := strconv.ParseUint(parts[3], 16, 32)

		return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), uint8(shift(a))}
	}
	return color.Black
}

func getMaxMin(a, b, c float64) (max, min float64) {
	// TODO: use go1.21 min/max functions
	if a > b {
		max = a
		min = b
	} else {
		max = b
		min = a
	}
	if c > max {
		max = c
	} else if c < min {
		min = c
	}
	return max, min
}

func round(x float64) float64 {
	return math.Round(x*1000) / 1000
}

// rgbToHSL converts an RGB triple to an HSL triple.
func rgbToHSL(r, g, b uint8) (h, s, l float64) {
	// convert uint32 pre-multiplied value to uint8
	// The r,g,b values are divided by 255 to change the range from 0..255 to 0..1:
	Rnot := float64(r) / 255
	Gnot := float64(g) / 255
	Bnot := float64(b) / 255
	Cmax, Cmin := getMaxMin(Rnot, Gnot, Bnot)
	Δ := Cmax - Cmin
	// Lightness calculation:
	l = (Cmax + Cmin) / 2
	// Hue and Saturation Calculation:
	if Δ == 0 {
		h = 0
		s = 0
	} else {
		switch Cmax {
		case Rnot:
			h = 60 * (math.Mod((Gnot-Bnot)/Δ, 6))
Repository: charmbracelet/bubbletea
File: key_sequences.go (Go)

Code before:
	idx := bytes.Index(input, []byte(bpEnd))
	inputLen := len(bpStart) + idx + len(bpEnd)
	if idx == -1 {
		// We have encountered the end of the input buffer without seeing
		// the marker for the end of the bracketed paste.
		// Tell the outer loop we have done a short read and we want more.
		return true, 0, nil
	}

	// The paste is everything in-between.
	paste := input[:idx]

	// All there is in-between is runes, not to be interpreted further.
	k := Key{Type: KeyRunes, Paste: true}
	for len(paste) > 0 {
		r, w := utf8.DecodeRune(paste)
		if r != utf8.RuneError {
			k.Runes = append(k.Runes, r)
		}
		paste = paste[w:]
	}

	return true, inputLen, KeyMsg(k)
}

// detectReportFocus detects a focus report sequence.
func detectReportFocus(input []byte) (hasRF bool, width int, msg Msg) {
	switch {
	case bytes.Equal(input, []byte("\x1b[I")):
		return true, 3, FocusMsg{}
	case bytes.Equal(input, []byte("\x1b[O")):
		return true, 3, BlurMsg{}
	}
	return false, 0, nil
}


Review comment (suggestion):
```suggestion
// detectReportFocus detects a focus report sequence.
//nolint: gomnd
``` 

Code after:
	idx := bytes.Index(input, []byte(bpEnd))
	inputLen := len(bpStart) + idx + len(bpEnd)
	if idx == -1 {
		// We have encountered the end of the input buffer without seeing
		// the marker for the end of the bracketed paste.
		// Tell the outer loop we have done a short read and we want more.
		return true, 0, nil
	}

	// The paste is everything in-between.
	paste := input[:idx]

	// All there is in-between is runes, not to be interpreted further.
	k := Key{Type: KeyRunes, Paste: true}
	for len(paste) > 0 {
		r, w := utf8.DecodeRune(paste)
		if r != utf8.RuneError {
			k.Runes = append(k.Runes, r)
		}
		paste = paste[w:]
	}

	return true, inputLen, KeyMsg(k)
}

// detectReportFocus detects a focus report sequence.
// nolint: gomnd
func detectReportFocus(input []byte) (hasRF bool, width int, msg Msg) {
	switch {
	case bytes.Equal(input, []byte("\x1b[I")):
		return true, 3, FocusMsg{}
	case bytes.Equal(input, []byte("\x1b[O")):
		return true, 3, BlurMsg{}
	}
	return false, 0, nil
}
Repository: charmbracelet/bubbletea
File: tea.go (Go)

Code before:

	case customInput:
		// (There is nothing extra to do.)
	}

	// Handle signals.
	if !p.startupOptions.has(withoutSignalHandler) {
		p.handlers.add(p.handleSignals())
	}

	// Recover from panics.
	if !p.startupOptions.has(withoutCatchPanics) {
		defer p.recoverFromPanic()
	}

	// Check if output is a TTY before entering raw mode, hiding the cursor and
	// so on.
	if err := p.initTerminal(); err != nil {
		return p.initialModel, err
	}
	if p.renderer == nil {
		stdr, ok := os.LookupEnv("TEA_STANDARD_RENDERER")
		if has, _ := strconv.ParseBool(stdr); ok && has {
			p.renderer = newRenderer(p.output)
		} else {
			// If no renderer is set use the ferocious one.
			p.renderer = newCursedRenderer(p.output, p.getenv("TERM"), p.useHardTabs)
		}
	}

	// Get the color profile and send it to the program.
	if !p.startupOptions.has(withColorProfile) {
		p.profile = colorprofile.Detect(p.output.Writer(), p.environ)
	}

	// Set the color profile on the renderer and send it to the program.
	p.renderer.setColorProfile(p.profile)
	go p.Send(ColorProfileMsg{p.profile})

	// Get the initial window size.
	resizeMsg := WindowSizeMsg{Width: p.width, Height: p.height}
	if p.ttyOutput != nil {
		// Set the initial size of the terminal.
		w, h, err := term.GetSize(p.ttyOutput.Fd())
		if err != nil {
			return p.initialModel, err
		}

		resizeMsg.Width, resizeMsg.Height = w, h
	}


Review comment (suggestion):
```suggestion
			// If no renderer is set use the cursed one.
```

Code after:

	case customInput:
		// (There is nothing extra to do.)
	}

	// Handle signals.
	if !p.startupOptions.has(withoutSignalHandler) {
		p.handlers.add(p.handleSignals())
	}

	// Recover from panics.
	if !p.startupOptions.has(withoutCatchPanics) {
		defer p.recoverFromPanic()
	}

	// Check if output is a TTY before entering raw mode, hiding the cursor and
	// so on.
	if err := p.initTerminal(); err != nil {
		return p.initialModel, err
	}
	if p.renderer == nil {
		stdr, ok := os.LookupEnv("TEA_STANDARD_RENDERER")
		if has, _ := strconv.ParseBool(stdr); ok && has {
			p.renderer = newRenderer(p.output)
		} else {
			// If no renderer is set use the cursed one.
			p.renderer = newCursedRenderer(p.output, p.getenv("TERM"), p.useHardTabs)
		}
	}

	// Get the color profile and send it to the program.
	if !p.startupOptions.has(withColorProfile) {
		p.profile = colorprofile.Detect(p.output.Writer(), p.environ)
	}

	// Set the color profile on the renderer and send it to the program.
	p.renderer.setColorProfile(p.profile)
	go p.Send(ColorProfileMsg{p.profile})

	// Get the initial window size.
	resizeMsg := WindowSizeMsg{Width: p.width, Height: p.height}
	if p.ttyOutput != nil {
		// Set the initial size of the terminal.
		w, h, err := term.GetSize(p.ttyOutput.Fd())
		if err != nil {
			return p.initialModel, err
		}

		resizeMsg.Width, resizeMsg.Height = w, h
	}
Repository: charmbracelet/bubbletea
File: options.go (Go)

Code before:
// properly rendering double width characters such as emojis and CJK
// characters.
//
// See https://mitchellh.com/writing/grapheme-clusters-in-terminals
func WithGraphemeClustering() ProgramOption {
	return func(p *Program) {
		p.startupOptions |= withGraphemeClustering
	}
}

// WithColorProfile sets the color profile that the program will use. This is
// useful when you want to force a specific color profile. By default, Bubble
// Tea will try to detect the terminal's color profile from environment
// variables and terminfo capabilities. Use [tea.WithEnvironment] to set custom
// environment variables.
func WithColorProfile(profile colorprofile.Profile) ProgramOption {
	return func(p *Program) {
		p.startupOptions |= withColorProfile
		p.profile = profile
	}
}

// WithInitialSize sets the initial size of the terminal window. This is useful
// when you have a faulty terminal that doesn't report its size correctly, or
// if you're testing your program in a non-interactive environment.
func WithInitialSize(width, height int) ProgramOption {
	return func(p *Program) {
		p.width = width
		p.height = height
	}
}


Review comment (suggestion):
Perhaps rename this to `WithWindowSize` to match with WindowSizeMsg 🤔

Code after:
// properly rendering double width characters such as emojis and CJK
// characters.
//
// See https://mitchellh.com/writing/grapheme-clusters-in-terminals
func WithGraphemeClustering() ProgramOption {
	return func(p *Program) {
		p.startupOptions |= withGraphemeClustering
	}
}

// WithColorProfile sets the color profile that the program will use. This is
// useful when you want to force a specific color profile. By default, Bubble
// Tea will try to detect the terminal's color profile from environment
// variables and terminfo capabilities. Use [tea.WithEnvironment] to set custom
// environment variables.
func WithColorProfile(profile colorprofile.Profile) ProgramOption {
	return func(p *Program) {
		p.startupOptions |= withColorProfile
		p.profile = profile
	}
}

// WithWindowSize sets the initial size of the terminal window. This is useful
// when you need to set the initial size of the terminal window, for example
// during testing or when you want to run your program in a non-interactive
// environment.
func WithWindowSize(width, height int) ProgramOption {
	return func(p *Program) {
		p.width = width
		p.height = height
	}
}