tui

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ThemeDark  = "dark"
	ThemeLight = "light"
)

Theme constants.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App struct {
	// contains filtered or unexported fields
}

App is the main Bubble Tea model for the TUI.

func NewApp

func NewApp(f markdown.File, opts AppOptions) *App

NewApp creates a new App model reviewing f. With f.Diff the raw view shows the diff instead of the full source and is where the review starts. Marking sections viewed updates f.Viewed in place, for the caller to persist.

func (*App) Init

func (a *App) Init() tea.Cmd

Init implements tea.Model.

func (*App) Result

func (a *App) Result() markdown.FileResult

Result returns the final result after the TUI exits.

func (*App) Update

func (a *App) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model.

func (*App) View

func (a *App) View() tea.View

View implements tea.Model.

type AppMode

type AppMode int

AppMode represents the current application mode.

const (
	ModeNormal      AppMode = iota // Section list navigation
	ModeComment                    // Comment input
	ModeCommentList                // Comment list management
	ModeConfirm                    // Confirmation dialog
	ModeHelp                       // Help overlay
	ModeSearch                     // Section search
	ModeLineSelect                 // Visual line selection in raw view
)

type AppOptions

type AppOptions struct {
	Theme     string // "dark" or "light"
	MultiFile bool   // part of a multi-file flow: dialogs say "finish/skip this file" instead of "submit/quit"
	// Load reads the file again when R is pressed; nil when it cannot be
	// reloaded (e.g. a PR file).
	Load markdown.Loader
}

AppOptions configures the TUI appearance.

type CommentEditor

type CommentEditor struct {
	// contains filtered or unexported fields
}

CommentEditor wraps a textarea for entering review comments.

func NewCommentEditor

func NewCommentEditor() *CommentEditor

NewCommentEditor creates a new CommentEditor.

func (*CommentEditor) Close

func (c *CommentEditor) Close()

Close closes the comment editor.

func (*CommentEditor) Cursor added in v0.8.1

func (c *CommentEditor) Cursor() *tea.Cursor

Cursor returns the textarea's cursor position relative to its own rendered output. The caller must offset it by the textarea's absolute screen origin before assigning it to tea.View.Cursor. Returns nil when the textarea is using the virtual cursor or is not focused.

func (*CommentEditor) CycleDecoration

func (c *CommentEditor) CycleDecoration()

CycleDecoration cycles to the next decoration.

func (*CommentEditor) CycleLabel

func (c *CommentEditor) CycleLabel()

CycleLabel cycles to the next action label.

func (*CommentEditor) CycleLabelReverse

func (c *CommentEditor) CycleLabelReverse()

CycleLabelReverse cycles to the previous action label.

func (*CommentEditor) DecorationLabel

func (c *CommentEditor) DecorationLabel() markdown.Decoration

DecorationLabel returns the current decoration.

func (*CommentEditor) FormatLabel

func (c *CommentEditor) FormatLabel() string

FormatLabel returns the combined action and decoration label for display.

func (*CommentEditor) FormatLineRef added in v0.6.0

func (c *CommentEditor) FormatLineRef() string

FormatLineRef returns a line reference string for display.

func (*CommentEditor) IsEdit added in v0.13.0

func (c *CommentEditor) IsEdit() bool

IsEdit reports whether the editor edits an existing comment.

func (*CommentEditor) Label

func (c *CommentEditor) Label() markdown.ActionType

Label returns the current action label.

func (*CommentEditor) Open

func (c *CommentEditor) Open(sectionID string, existing *markdown.ReviewComment) tea.Cmd

Open opens the comment editor for a section, optionally pre-filling with existing comment.

func (*CommentEditor) OpenWithLines added in v0.6.0

func (c *CommentEditor) OpenWithLines(startLine, endLine int, side string) tea.Cmd

OpenWithLines opens the comment editor for a new line-level comment; its section follows from the lines when it is saved (see markdown.ReviewState.SaveComment). Editing an existing comment goes through Open, which restores its lines.

func (*CommentEditor) Result

func (c *CommentEditor) Result() markdown.ReviewComment

Result returns the review comment from the editor content, with the ID of the edited comment ("" for a new one).

func (*CommentEditor) SectionID

func (c *CommentEditor) SectionID() string

SectionID returns the section ID being edited.

func (*CommentEditor) SetWidth

func (c *CommentEditor) SetWidth(w int)

SetWidth sets the width of the textarea.

func (*CommentEditor) Update

func (c *CommentEditor) Update(msg tea.Msg) tea.Cmd

Update handles tea messages for the textarea.

func (*CommentEditor) View

func (c *CommentEditor) View() string

View renders the comment editor.

type CommentList

type CommentList struct {
	// contains filtered or unexported fields
}

CommentList manages the comment list view for a section.

func NewCommentList

func NewCommentList() *CommentList

NewCommentList creates a new CommentList.

func (*CommentList) Close

func (cl *CommentList) Close()

Close closes the comment list.

func (*CommentList) Cursor

func (cl *CommentList) Cursor() int

Cursor returns the current cursor position.

func (*CommentList) CursorDown

func (cl *CommentList) CursorDown()

CursorDown moves the cursor down.

func (*CommentList) CursorUp

func (cl *CommentList) CursorUp()

CursorUp moves the cursor up.

func (*CommentList) Open

func (cl *CommentList) Open(sectionID string, comments []*markdown.ReviewComment)

Open opens the comment list for a section.

func (*CommentList) Render

func (cl *CommentList) Render(width, height int, styles Styles) string

Render renders the comment list.

func (*CommentList) SectionID

func (cl *CommentList) SectionID() string

SectionID returns the section ID.

type DetailPane

type DetailPane struct {
	// contains filtered or unexported fields
}

DetailPane manages the right pane that shows section details.

func NewDetailPane

func NewDetailPane(width, height int, theme string) *DetailPane

NewDetailPane creates a new DetailPane.

func (*DetailPane) ScrollToSectionID

func (d *DetailPane) ScrollToSectionID(sectionID string)

ScrollToSectionID scrolls the viewport to the given section's offset.

func (*DetailPane) SectionIDAtOffset

func (d *DetailPane) SectionIDAtOffset(yOffset int) string

SectionIDAtOffset returns the section ID visible at the given vertical offset.

func (*DetailPane) SetSize

func (d *DetailPane) SetSize(width, height int)

SetSize updates the pane size. It does not re-render current content; call ShowSection or ShowOverview after resizing to refresh the viewport.

func (*DetailPane) ShowAll

func (d *DetailPane) ShowAll(doc *markdown.Document, getComments func(string) []*markdown.ReviewComment)

ShowAll renders the entire document in a single view.

func (*DetailPane) ShowOverview

func (d *DetailPane) ShowOverview(doc *markdown.Document, comments []*markdown.ReviewComment)

ShowOverview renders and displays the document overview (preamble).

func (*DetailPane) ShowSection

func (d *DetailPane) ShowSection(section *markdown.Section, comments []*markdown.ReviewComment)

ShowSection renders and displays a section's content.

func (*DetailPane) View

func (d *DetailPane) View() string

View returns the viewport view.

func (*DetailPane) Viewport

func (d *DetailPane) Viewport() *viewport.Model

Viewport returns a pointer to the viewport for event handling.

type FilePicker added in v0.7.0

type FilePicker struct {
	// contains filtered or unexported fields
}

FilePicker is a Bubble Tea model for selecting files from a list.

func NewFilePicker added in v0.7.0

func NewFilePicker(files []string) *FilePicker

NewFilePicker creates a file picker with the given file list.

func (*FilePicker) Init added in v0.7.0

func (fp *FilePicker) Init() tea.Cmd

Init implements tea.Model.

func (*FilePicker) Result added in v0.7.0

func (fp *FilePicker) Result() FilePickerResult

Result returns the file picker result.

func (*FilePicker) Update added in v0.7.0

func (fp *FilePicker) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model.

func (*FilePicker) View added in v0.7.0

func (fp *FilePicker) View() tea.View

View implements tea.Model.

type FilePickerResult added in v0.7.0

type FilePickerResult struct {
	SelectedFiles []string
	Cancelled     bool
}

FilePickerResult is the result of the file picker interaction.

type Focus

type Focus int

Focus represents which pane has focus.

const (
	FocusLeft Focus = iota
	FocusRight
)

type KeyMap

type KeyMap struct {
	Up          key.Binding
	Down        key.Binding
	ScrollRight key.Binding
	ScrollLeft  key.Binding
	Toggle      key.Binding
	Tab         key.Binding
	Comment     key.Binding
	CommentList key.Binding
	Viewed      key.Binding
	Search      key.Binding
	Submit      key.Binding
	Quit        key.Binding
	Help        key.Binding
	Save        key.Binding
	Cancel      key.Binding

	// View mode
	FullView key.Binding

	// Right pane specific
	ScrollToStart key.Binding
	ScrollToEnd   key.Binding

	// Pane resizing
	PaneGrow   key.Binding
	PaneShrink key.Binding

	// Page scrolling
	HalfPageDown key.Binding
	HalfPageUp   key.Binding
	PageDown     key.Binding
	PageUp       key.Binding

	// Comment list specific
	Edit   key.Binding
	Delete key.Binding

	// Comment editor specific
	CommentLabelNext key.Binding
	CommentLabelPrev key.Binding
	CommentCycleDeco key.Binding

	// Line mode
	RawView      key.Binding
	Reload       key.Binding
	VisualSelect key.Binding

	// Search mode: only arrow keys navigate so that letters (including j/k)
	// reach the query input.
	SearchUp   key.Binding
	SearchDown key.Binding
}

KeyMap defines all key bindings for the TUI.

func DefaultKeyMap

func DefaultKeyMap() KeyMap

DefaultKeyMap returns the default key bindings.

type LinePane added in v0.6.0

type LinePane struct {
	// contains filtered or unexported fields
}

LinePane renders raw source with line numbers for line-level commenting.

func NewLinePane added in v0.6.0

func NewLinePane(lines []string, width, height int, styles Styles, lineSections []string) *LinePane

NewLinePane creates a new LinePane. lineSections holds the section ID of each line (see markdown.Document.LineSections and DiffLineSections).

func (*LinePane) AtRangeBottom added in v0.6.0

func (lp *LinePane) AtRangeBottom() bool

AtRangeBottom returns true if the cursor is at the bottom of the visible range.

func (*LinePane) AtRangeTop added in v0.6.0

func (lp *LinePane) AtRangeTop() bool

AtRangeTop returns true if the cursor is at the top of the visible range.

func (*LinePane) CanComment added in v0.7.0

func (lp *LinePane) CanComment() bool

CanComment returns whether the current cursor position allows commenting. All lines in the diff are commentable (added, removed, and context).

func (*LinePane) CancelVisualSelect added in v0.6.0

func (lp *LinePane) CancelVisualSelect()

CancelVisualSelect cancels visual line selection.

func (*LinePane) ClearViewRange added in v0.6.0

func (lp *LinePane) ClearViewRange()

ClearViewRange shows all lines.

func (*LinePane) Cursor added in v0.6.0

func (lp *LinePane) Cursor() int

Cursor returns the current 0-based cursor position.

func (*LinePane) CursorBottom added in v0.6.0

func (lp *LinePane) CursorBottom()

CursorBottom moves the cursor to the last visible line.

func (*LinePane) CursorDown added in v0.6.0

func (lp *LinePane) CursorDown()

CursorDown moves the cursor down one line.

func (*LinePane) CursorSide added in v0.7.0

func (lp *LinePane) CursorSide() string

CursorSide returns the diff side ("RIGHT" or "LEFT") at the cursor position. Returns "" in non-diff mode.

func (*LinePane) CursorTop added in v0.6.0

func (lp *LinePane) CursorTop()

CursorTop moves the cursor to the first visible line.

func (*LinePane) CursorUp added in v0.6.0

func (lp *LinePane) CursorUp()

CursorUp moves the cursor up one line.

func (*LinePane) HalfPageDown added in v0.6.0

func (lp *LinePane) HalfPageDown()

HalfPageDown moves the cursor down by half the viewport height.

func (*LinePane) HalfPageUp added in v0.6.0

func (lp *LinePane) HalfPageUp()

HalfPageUp moves the cursor up by half the viewport height.

func (*LinePane) IsVisualSelect added in v0.6.0

func (lp *LinePane) IsVisualSelect() bool

IsVisualSelect returns true if visual selection is active.

func (*LinePane) LineCount added in v0.6.0

func (lp *LinePane) LineCount() int

LineCount returns the total number of source lines.

func (*LinePane) PageDown added in v0.6.0

func (lp *LinePane) PageDown()

PageDown moves the cursor down by a full viewport height.

func (*LinePane) PageUp added in v0.6.0

func (lp *LinePane) PageUp()

PageUp moves the cursor up by a full viewport height.

func (*LinePane) ScrollToLine added in v0.6.0

func (lp *LinePane) ScrollToLine(line int)

ScrollToLine scrolls the viewport so the given 1-based file line is visible, centered if possible.

func (*LinePane) SectionIDAtCursor added in v0.8.2

func (lp *LinePane) SectionIDAtCursor() string

SectionIDAtCursor returns the section ID of the line under the cursor, or "" when there is no such line.

func (*LinePane) SelectedRange added in v0.6.0

func (lp *LinePane) SelectedRange() (startLine, endLine int)

SelectedRange returns the 1-based line range for commenting. Without visual selection: returns (cursor+1, 0) for single line. With visual selection: returns (min+1, max+1) for range. In diff mode, maps display indices to actual file line numbers. Returns (0, 0) if the selected line is not commentable in diff mode.

func (*LinePane) SetComments added in v0.6.0

func (lp *LinePane) SetComments(comments []*markdown.ReviewComment)

SetComments sets the comments for inline display.

func (*LinePane) SetSize added in v0.6.0

func (lp *LinePane) SetSize(width, height int)

SetSize updates the pane dimensions and keeps the cursor on screen, so a terminal that shrinks (or a comment editor that takes rows away) never leaves the cursor below the visible area until the next move.

func (*LinePane) SetViewSection added in v0.12.0

func (lp *LinePane) SetViewSection(sectionID string)

SetViewSection shows only the lines of the given section, which are contiguous (see markdown.Document.LineSections and DiffLineSections). A section without diff lines shows an empty range.

func (*LinePane) StartVisualSelect added in v0.6.0

func (lp *LinePane) StartVisualSelect()

StartVisualSelect begins visual line selection from the current cursor position. It is a no-op while the pane shows an empty diff range, since there is no line to select.

func (*LinePane) View added in v0.6.0

func (lp *LinePane) View() string

View renders the line pane content.

type ReviewAction added in v0.7.0

type ReviewAction int

ReviewAction represents the user's chosen action in the review dialog.

const (
	ReviewActionExit    ReviewAction = iota // do nothing
	ReviewActionApprove                     // approve the PR
	ReviewActionComment                     // submit as comment
)

type ReviewDialog added in v0.7.0

type ReviewDialog struct {
	// contains filtered or unexported fields
}

ReviewDialog is a Bubble Tea model for the post-review action selection.

func NewReviewDialog added in v0.7.0

func NewReviewDialog(fileSummary []string, hasComments bool) *ReviewDialog

NewReviewDialog creates a review dialog. fileSummary contains "file.md: N comment(s)" lines for display.

func (*ReviewDialog) Init added in v0.7.0

func (d *ReviewDialog) Init() tea.Cmd

Init implements tea.Model.

func (*ReviewDialog) Result added in v0.7.0

func (d *ReviewDialog) Result() ReviewDialogResult

Result returns the dialog result.

func (*ReviewDialog) Update added in v0.7.0

func (d *ReviewDialog) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model.

func (*ReviewDialog) View added in v0.7.0

func (d *ReviewDialog) View() tea.View

View implements tea.Model.

type ReviewDialogResult added in v0.7.0

type ReviewDialogResult struct {
	Action ReviewAction
	Body   string // optional PR-level comment
}

ReviewDialogResult holds the outcome of the review dialog.

type SearchBar struct {
	// contains filtered or unexported fields
}

SearchBar wraps a textinput for section searching.

func NewSearchBar

func NewSearchBar() *SearchBar

NewSearchBar creates a new SearchBar.

func (*SearchBar) Close

func (s *SearchBar) Close()

Close deactivates the search bar.

func (*SearchBar) Open

func (s *SearchBar) Open() tea.Cmd

Open activates the search bar.

func (*SearchBar) Query

func (s *SearchBar) Query() string

Query returns the current search query.

func (*SearchBar) Update

func (s *SearchBar) Update(msg tea.Msg) tea.Cmd

Update handles tea messages for the textinput.

func (*SearchBar) View

func (s *SearchBar) View() string

View renders the search bar.

type SectionList

type SectionList struct {
	// contains filtered or unexported fields
}

SectionList manages the left pane section tree.

func NewSectionList

func NewSectionList(review *markdown.ReviewState) *SectionList

NewSectionList creates a new SectionList for the document under review.

func (*SectionList) ClearFilter

func (sl *SectionList) ClearFilter()

ClearFilter resets visibility to respect only expansion state.

func (*SectionList) CursorBottom

func (sl *SectionList) CursorBottom()

CursorBottom moves the cursor to the last visible item.

func (*SectionList) CursorDown

func (sl *SectionList) CursorDown()

CursorDown moves the cursor down to the next visible item.

func (*SectionList) CursorHalfPageDown added in v0.5.0

func (sl *SectionList) CursorHalfPageDown(pageHeight int)

CursorHalfPageDown moves the cursor down by half the visible page height.

func (*SectionList) CursorHalfPageUp added in v0.5.0

func (sl *SectionList) CursorHalfPageUp(pageHeight int)

CursorHalfPageUp moves the cursor up by half the visible page height.

func (*SectionList) CursorPageDown added in v0.5.0

func (sl *SectionList) CursorPageDown(pageHeight int)

CursorPageDown moves the cursor down by the visible page height.

func (*SectionList) CursorPageUp added in v0.5.0

func (sl *SectionList) CursorPageUp(pageHeight int)

CursorPageUp moves the cursor up by the visible page height.

func (*SectionList) CursorTop

func (sl *SectionList) CursorTop()

CursorTop moves the cursor to the first visible item.

func (*SectionList) CursorUp

func (sl *SectionList) CursorUp()

CursorUp moves the cursor up to the previous visible item.

func (*SectionList) FilterByQuery

func (sl *SectionList) FilterByQuery(query string)

FilterByQuery filters the section list to show only sections matching the query. Matching is case-insensitive against section ID, Title, and Body. If a child matches, its ancestors are shown. If a parent matches, its children are shown.

func (*SectionList) IsOverviewSelected

func (sl *SectionList) IsOverviewSelected() bool

IsOverviewSelected returns true if the overview entry is selected.

func (*SectionList) Render

func (sl *SectionList) Render(width, height int, styles Styles) string

Render renders the section list for display within the given height.

func (*SectionList) SelectBySectionID

func (sl *SectionList) SelectBySectionID(sectionID string)

SelectBySectionID moves the cursor to the item with the given section ID. OverviewSectionID selects the overview entry. A section hidden under a collapsed parent cannot be selected, so its nearest visible ancestor is selected instead; the highlight then still tracks the line cursor at the granularity the list shows.

func (*SectionList) Selected

func (sl *SectionList) Selected() *markdown.Section

Selected returns the currently selected section (or nil for overview).

func (*SectionList) ToggleExpand

func (sl *SectionList) ToggleExpand()

ToggleExpand toggles the expand/collapse state of the current section.

func (*SectionList) TotalSectionCount

func (sl *SectionList) TotalSectionCount() int

TotalSectionCount returns the number of sections (excluding overview).

type SectionListItem

type SectionListItem struct {
	Section    *markdown.Section
	Depth      int
	Expanded   bool
	Visible    bool
	IsOverview bool // true for the overview (preamble) entry
}

SectionListItem is a flattened section for display in the section list.

type Styles

type Styles struct {
	ActiveBorder   lipgloss.Style
	InactiveBorder lipgloss.Style

	// Section list
	Title           lipgloss.Style
	SelectedSection lipgloss.Style
	NormalSection   lipgloss.Style
	SectionBadge    lipgloss.Style
	ViewedBadge     lipgloss.Style

	// Status bar
	StatusBar lipgloss.Style
	StatusKey lipgloss.Style

	// Comment
	CommentBorder lipgloss.Style

	// Line mode
	LineGutter   lipgloss.Style
	LineCursor   lipgloss.Style
	LineSelected lipgloss.Style

	// Diff mode
	DiffAdded   lipgloss.Style
	DiffRemoved lipgloss.Style
}

Styles holds all the lipgloss styles for the TUI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL