package core import ( "strings" ) const CommandOutputExitMessage = "Press ENTER to continue" const CommandOutputScrollMessage = "Use j/k to scroll" type CommandOutput struct { Title string Lines []string ScrollOffset int // Not implemented yet // Height is computing via lines and title Inline bool // Show inline instead of the window IsError bool } // CommandOutput.Height: Compute the height (in lines) based on the line count, and title. func (c *CommandOutput) Height() int { if c.Inline { return 1 } var h int h += len(c.Lines) if strings.TrimSpace(c.Title) != "" { h++ } // Padding: // +1 for 'enter key...' message // +1 for top bar (border) h += 2 return h } // CommandOutput.IsActive: Is the command output in a state that should be displayed. func (c *CommandOutput) IsActive() bool { return len(c.Lines) > 0 } // maxOutputWindowHeight: Calculates the max height of the output window. This is simply // just 3/4 of the terminal height. This allows the title to always be shown, but also // allows the user to not totally lose mental context when viewing a large output. func maxOutputWindowHeight(termHeight int) int { return int(float64(termHeight) * 0.75) } // CommandOutput.Viewport: Returns a list of the lines in the current viewport, depends on // the height of the terminal. This function should be in place of the Lines property. func (c *CommandOutput) Viewport(height int) []string { start := c.ScrollOffset end := maxOutputWindowHeight(height) + start // Clamp end to available lines if end > len(c.Lines) { end = len(c.Lines) } return c.Lines[start:end] } // CommandOutput.ScrollDown: Manages the scrolling down logic and handles bounds checks. // This function depends on the height on the terminal. func (c *CommandOutput) ScrollDown(height int) { if (c.ScrollOffset + maxOutputWindowHeight(height)) < len(c.Lines) { c.ScrollOffset++ } } // CommandOutput.ScrollUp: Manages the scrolling up logic and handles bounds checks. func (c *CommandOutput) ScrollUp() { if c.ScrollOffset > 0 { c.ScrollOffset-- } }