components

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package components provides reusable Bubble Tea TUI components for dispatch.

Package components provides the sub-models (session list, search bar, filter panel, preview, help overlay, shell picker, reindex) that compose the Copilot CLI Session Browser TUI.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AbbrevHome

func AbbrevHome(path string) string

AbbrevHome returns the path with the user's home directory replaced by "~". Path separators are normalised to the OS-native format for display.

func AbbrevPath

func AbbrevPath(path string) string

AbbrevPath returns the path with the user's home directory replaced by "~". If the path is not under the home directory, it is returned as-is (full absolute path). This avoids relative-looking paths like "…\code\dispatch".

func CleanSummary

func CleanSummary(s string) string

CleanSummary strips chat-style prefixes (e.g. "[user]: ", "[assistant]: ") from a session summary, collapses whitespace to a single line, and returns a display-friendly string. This prevents raw conversation fragments stored by the Copilot CLI from appearing as "chat messages" in the session list.

func FormatInt

func FormatInt(v int) string

FormatInt formats an integer as a decimal string. It delegates to strconv.Itoa which handles all edge cases including math.MinInt (where negation overflows in two's complement).

func FormatTimestamp added in v0.1.3

func FormatTimestamp(timestamp string) string

FormatTimestamp parses a timestamp string (RFC3339 or common variants) and returns a human-readable local time with timezone, e.g. "Jan 2 3:04 PM MST". On parse failure, the raw string is returned as-is.

func PadLeft

func PadLeft(s string, width int) string

PadLeft returns s padded with spaces on the left to exactly width runes.

func PadRight

func PadRight(s string, width int) string

PadRight returns s padded with spaces on the right to exactly width runes. If s is longer than width it is truncated.

NOTE: This function uses rune counting, which is NOT ANSI-aware. For strings containing ANSI escape sequences (pre-styled inline text), use PadToWidth instead.

func PadToWidth added in v0.1.3

func PadToWidth(s string, width int) string

PadToWidth pads s with trailing spaces so its visual (printed) width equals exactly width columns. Unlike PadRight, this function is ANSI-aware: it uses lipgloss.Width (which strips escape sequences before measuring) so pre-styled inline content like attention dots is measured correctly.

If the visual width already meets or exceeds width, s is returned unchanged (no truncation — callers are expected to have pre-truncated content).

func RelativeTime

func RelativeTime(timestamp string) string

RelativeTime parses a timestamp string and returns a human-friendly relative time such as "2h ago" or "3d ago".

func RenderChatBubble

func RenderChatBubble(msg, label string, contentWidth int, isUser bool) string

RenderChatBubble renders a single chat message as a styled bubble with a role label. When isUser is true, both the label and bubble are right-aligned; otherwise they are left-aligned.

func RenderConversation

func RenderConversation(turns []data.Turn, contentWidth int) string

RenderConversation renders all turns as a chat-style conversation with right-aligned user messages and left-aligned assistant messages.

func SplitDirLeaf

func SplitDirLeaf(path string) (parent, leaf string)

SplitDirLeaf splits a path into its parent directory and leaf (last component). Both are normalised to OS-native separators.

func Truncate

func Truncate(s string, width int) string

Truncate returns s trimmed to at most width runes, appending "…" when truncation occurs.

Types

type AttentionPicker added in v0.1.3

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

AttentionPicker renders a compact overlay for selecting which attention statuses to include when filtering the session list.

func NewAttentionPicker added in v0.1.3

func NewAttentionPicker() AttentionPicker

NewAttentionPicker returns a picker with no statuses selected (show all).

func (*AttentionPicker) HasSelection added in v0.1.3

func (p *AttentionPicker) HasSelection() bool

HasSelection returns true when at least one status is checked.

func (*AttentionPicker) MoveDown added in v0.1.3

func (p *AttentionPicker) MoveDown()

MoveDown moves the cursor down, wrapping to the top.

func (*AttentionPicker) MoveUp added in v0.1.3

func (p *AttentionPicker) MoveUp()

MoveUp moves the cursor up, wrapping to the bottom.

func (*AttentionPicker) Selected added in v0.1.3

func (p *AttentionPicker) Selected() map[data.AttentionStatus]struct{}

Selected returns a copy of the checked status set.

func (*AttentionPicker) SetCounts added in v0.1.3

func (p *AttentionPicker) SetCounts(counts map[data.AttentionStatus]int)

SetCounts provides the per-status session counts shown beside each row.

func (*AttentionPicker) SetSelected added in v0.1.3

func (p *AttentionPicker) SetSelected(set map[data.AttentionStatus]struct{})

SetSelected initialises the picker with a pre-existing selection.

func (*AttentionPicker) SetSize added in v0.1.3

func (p *AttentionPicker) SetSize(w, h int)

SetSize updates the overlay dimensions.

func (*AttentionPicker) Toggle added in v0.1.3

func (p *AttentionPicker) Toggle()

Toggle toggles the status at the current cursor position.

func (AttentionPicker) View added in v0.1.3

func (p AttentionPicker) View() string

View renders the attention picker overlay.

type ConfigPanel

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

ConfigPanel presents an overlay that lets users edit session-resume settings (yolo mode, agent, model, launch-in-place, terminal, shell, custom command).

func NewConfigPanel

func NewConfigPanel() ConfigPanel

NewConfigPanel returns a ConfigPanel initialised with the provided values.

func (*ConfigPanel) CancelEdit

func (c *ConfigPanel) CancelEdit()

CancelEdit discards the current text input without saving.

func (*ConfigPanel) ConfirmEdit

func (c *ConfigPanel) ConfirmEdit()

ConfirmEdit saves the current text input value to the appropriate field.

func (*ConfigPanel) HandleEnter

func (c *ConfigPanel) HandleEnter() tea.Cmd

HandleEnter toggles a boolean field, cycles a selection, or starts editing a text field. Returns a tea.Cmd when a text input needs focus.

func (*ConfigPanel) IsEditing

func (c *ConfigPanel) IsEditing() bool

IsEditing returns true when a text field is being edited.

func (*ConfigPanel) MoveDown

func (c *ConfigPanel) MoveDown()

MoveDown moves the cursor to the next field.

func (*ConfigPanel) MoveUp

func (c *ConfigPanel) MoveUp()

MoveUp moves the cursor to the previous field.

func (*ConfigPanel) SetShellOptions

func (c *ConfigPanel) SetShellOptions(shells []platform.ShellInfo)

SetShellOptions provides the list of available shells.

func (*ConfigPanel) SetSize

func (c *ConfigPanel) SetSize(w, h int)

SetSize updates the overlay dimensions.

func (*ConfigPanel) SetTerminals

func (c *ConfigPanel) SetTerminals(names []string)

SetTerminals provides the list of available terminal emulator names.

func (*ConfigPanel) SetThemeOptions

func (c *ConfigPanel) SetThemeOptions(names []string)

SetThemeOptions provides the list of available scheme names for cycling. The first entry should be "auto".

func (*ConfigPanel) SetValues

func (c *ConfigPanel) SetValues(v ConfigValues)

SetValues loads the config panel state from external values.

func (ConfigPanel) Update

func (c ConfigPanel) Update(msg tea.Msg) (ConfigPanel, tea.Cmd)

Update delegates to the underlying text input when editing.

func (*ConfigPanel) Values

func (c *ConfigPanel) Values() ConfigValues

Values returns the current state of all editable fields.

func (ConfigPanel) View

func (c ConfigPanel) View() string

View renders the config panel as a centred overlay.

type ConfigValues

type ConfigValues struct {
	YoloMode      bool
	Agent         string
	Model         string
	LaunchMode    string
	PaneDirection string
	Terminal      string
	Shell         string
	CustomCommand string
	Theme         string
}

ConfigValues bundles the editable fields exchanged between the config panel and the rest of the application.

type FilterCategory

type FilterCategory int

FilterCategory identifies the kind of filter (kept for badge compatibility).

const (
	// FilterFolder represents a directory-based filter category.
	FilterFolder FilterCategory = iota
)

type FilterPanel

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

FilterPanel is an overlay showing a hierarchical directory tree for multi-select exclusion. Users navigate with arrows, toggle with Space, apply with Enter, and cancel with Esc.

func NewFilterPanel

func NewFilterPanel() FilterPanel

NewFilterPanel returns a FilterPanel.

func (*FilterPanel) ActiveBadges

func (f *FilterPanel) ActiveBadges() []string

ActiveBadges returns a slice of short badge strings representing the currently applied exclusions.

func (*FilterPanel) Apply

func (f *FilterPanel) Apply() []string

Apply commits the pending exclusions and returns them as a string slice.

func (*FilterPanel) Cancel

func (f *FilterPanel) Cancel()

Cancel discards the pending exclusions (reverts to last applied state).

func (*FilterPanel) ClearAll

func (f *FilterPanel) ClearAll()

ClearAll removes all active filters.

func (*FilterPanel) CollapseGroup

func (f *FilterPanel) CollapseGroup()

CollapseGroup collapses the group under the cursor.

func (*FilterPanel) ExpandGroup

func (f *FilterPanel) ExpandGroup()

ExpandGroup expands the group under the cursor.

func (*FilterPanel) HasActive

func (f *FilterPanel) HasActive() bool

HasActive returns true if any exclusions are applied.

func (*FilterPanel) MoveDown

func (f *FilterPanel) MoveDown()

MoveDown moves the cursor down.

func (*FilterPanel) MoveUp

func (f *FilterPanel) MoveUp()

MoveUp moves the cursor up.

func (*FilterPanel) SetActive

func (f *FilterPanel) SetActive(_ FilterCategory, _ string)

SetActive is a no-op kept for backward compatibility with time-range quick-key calls (time ranges are now handled outside the filter panel).

func (*FilterPanel) SetFolders

func (f *FilterPanel) SetFolders(folders []string, excluded []string)

SetFolders populates the filter panel with folder paths and initialises the pending exclusion set from the given excluded dirs.

func (*FilterPanel) SetOptions

func (f *FilterPanel) SetOptions(folders, repos, branches []string)

SetOptions is a backward-compatible shim (deprecated — use SetFolders).

func (*FilterPanel) SetSize

func (f *FilterPanel) SetSize(w, h int)

SetSize updates the overlay dimensions.

func (*FilterPanel) Toggle

func (f *FilterPanel) Toggle() (FilterCategory, string, bool)

Toggle is provided for backward compatibility. It calls ToggleExclusion and returns placeholder values.

func (*FilterPanel) ToggleExclusion

func (f *FilterPanel) ToggleExclusion()

ToggleExclusion toggles the exclusion state of the item under the cursor. On a child: toggles that directory. On a parent: toggles all children.

func (FilterPanel) View

func (f FilterPanel) View() string

View renders the filter panel as a centred overlay.

type HelpOverlay

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

HelpOverlay renders a hand-crafted keyboard shortcut reference as a centred overlay panel. It replaces the bubbles/help.Model approach with a clean two-column layout grouped by category.

func NewHelpOverlay

func NewHelpOverlay() HelpOverlay

NewHelpOverlay returns a ready-to-use HelpOverlay.

func (*HelpOverlay) SetSize

func (h *HelpOverlay) SetSize(width, height int)

SetSize updates the overlay dimensions.

func (HelpOverlay) ShortView

func (h HelpOverlay) ShortView() string

ShortView renders a compact single-line help hint for the status bar.

func (HelpOverlay) View

func (h HelpOverlay) View() string

View renders the full help overlay centred on screen.

type PreviewPanel

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

PreviewPanel renders a right-side detail panel for the selected session.

func NewPreviewPanel

func NewPreviewPanel() PreviewPanel

NewPreviewPanel returns an empty PreviewPanel.

func (*PreviewPanel) HitConversationSort added in v0.1.3

func (p *PreviewPanel) HitConversationSort(contentRow int) bool

HitConversationSort reports whether contentRow (a 0-indexed line in the full rendered content) falls on the "Conversation" header label. This is used by the mouse handler to detect clicks on the sort toggle.

func (*PreviewPanel) PageDown

func (p *PreviewPanel) PageDown()

PageDown scrolls down by half the viewport height.

func (*PreviewPanel) PageUp

func (p *PreviewPanel) PageUp()

PageUp scrolls up by half the viewport height.

func (*PreviewPanel) ScrollDown

func (p *PreviewPanel) ScrollDown(n int)

ScrollDown scrolls the preview content down by n lines.

func (*PreviewPanel) ScrollOffset added in v0.1.3

func (p *PreviewPanel) ScrollOffset() int

ScrollOffset returns the current scroll position.

func (*PreviewPanel) ScrollUp

func (p *PreviewPanel) ScrollUp(n int)

ScrollUp scrolls the preview content up by n lines.

func (*PreviewPanel) SetAttentionStatus added in v0.1.3

func (p *PreviewPanel) SetAttentionStatus(status data.AttentionStatus)

SetAttentionStatus updates the attention status shown in the preview.

func (*PreviewPanel) SetConversationSort added in v0.1.3

func (p *PreviewPanel) SetConversationSort(newestFirst bool)

SetConversationSort sets the conversation turn display order. When newestFirst is true, turns are shown in descending order (newest at the top). When false, turns are shown in ascending order (oldest first).

func (*PreviewPanel) SetDetail

func (p *PreviewPanel) SetDetail(d *data.SessionDetail)

SetDetail updates the displayed session detail.

func (*PreviewPanel) SetSize

func (p *PreviewPanel) SetSize(w, h int)

SetSize updates the panel dimensions.

func (*PreviewPanel) ToggleConversationSort added in v0.1.3

func (p *PreviewPanel) ToggleConversationSort() bool

ToggleConversationSort flips the conversation sort order and returns the new value.

func (PreviewPanel) View

func (p PreviewPanel) View() string

View renders the preview panel content.

type ReindexFinishedMsg

type ReindexFinishedMsg struct {
	Err error
}

ReindexFinishedMsg is sent when a reindex completes. The model re-queries the session store database on receipt.

type ReindexHandle

type ReindexHandle struct {
	Cancel context.CancelFunc
}

ReindexHandle holds the cancel function for a running reindex so the caller can abort it from the UI.

func StartChronicleReindex

func StartChronicleReindex() (ReindexHandle, []tea.Cmd)

StartChronicleReindex launches a full chronicle reindex via the Copilot CLI in a pseudo-terminal. It returns a ReindexHandle (for cancellation) and two Cmds: one that runs the reindex (sending ReindexFinishedMsg on completion), and one that pumps log lines into ReindexLogPump messages.

Falls back to Maintain() if the copilot binary is not found.

type ReindexLogPump

type ReindexLogPump struct {
	Lines []string
	// contains filtered or unexported fields
}

ReindexLogPump carries a batch of log lines and the channel reference so the model can request the next batch.

func (ReindexLogPump) NextLogCmd

func (p ReindexLogPump) NextLogCmd() tea.Cmd

NextLogCmd returns the Cmd to wait for the next batch of log lines.

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

SearchBar wraps a bubbles textinput for FTS5 session search.

func NewSearchBar

func NewSearchBar() SearchBar

NewSearchBar returns a SearchBar ready for use.

func (*SearchBar) Blur

func (s *SearchBar) Blur()

Blur deactivates the search input.

func (*SearchBar) Focus

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

Focus activates the search input for typing.

func (*SearchBar) Focused

func (s *SearchBar) Focused() bool

Focused returns true when the search bar is capturing keystrokes.

func (*SearchBar) SetAIError

func (s *SearchBar) SetAIError(msg string)

SetAIError sets the AI error message shown when status is "error".

func (*SearchBar) SetAIResults

func (s *SearchBar) SetAIResults(n int)

SetAIResults sets the count of AI-found sessions from the last search.

func (*SearchBar) SetAISearching

func (s *SearchBar) SetAISearching(v bool)

SetAISearching sets the Copilot SDK search-in-progress indicator.

func (*SearchBar) SetAIStatus

func (s *SearchBar) SetAIStatus(status string)

SetAIStatus sets the Copilot SDK connection status. Valid values: "" (not started), "connecting", "ready", "error".

func (*SearchBar) SetResultCount

func (s *SearchBar) SetResultCount(n int)

SetResultCount updates the displayed result count.

func (*SearchBar) SetSearching

func (s *SearchBar) SetSearching(v bool)

SetSearching sets the deep-search-in-progress indicator.

func (*SearchBar) SetValue

func (s *SearchBar) SetValue(v string)

SetValue sets the search text.

func (*SearchBar) SetWidth

func (s *SearchBar) SetWidth(w int)

SetWidth sets the available width for the search bar.

func (SearchBar) Update

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

Update delegates a tea.Msg to the underlying textinput.

func (*SearchBar) Value

func (s *SearchBar) Value() string

Value returns the current search query.

func (SearchBar) View

func (s SearchBar) View() string

View renders the search bar.

type SessionList

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

SessionList renders a vertical list of sessions with optional collapsible folder tree grouping when pivoting is active.

func NewSessionList

func NewSessionList() SessionList

NewSessionList returns an empty SessionList.

func (*SessionList) AllSessions added in v0.1.3

func (s *SessionList) AllSessions() []data.Session

AllSessions returns a flat slice of all sessions in display order (skipping folder nodes). This is used for sequential navigation (e.g. jump-to-next-waiting).

func (*SessionList) Anchor added in v0.1.3

func (s *SessionList) Anchor() int

Anchor returns the anchor index for range selection.

func (*SessionList) CollapseAll

func (s *SessionList) CollapseAll()

CollapseAll sets all folder groups to collapsed state and rebuilds the visible item list. Used by the screenshot generator.

func (*SessionList) CollapseFolder

func (s *SessionList) CollapseFolder()

CollapseFolder collapses the folder under the cursor (no-op if not a folder or already collapsed).

func (*SessionList) Cursor

func (s *SessionList) Cursor() int

Cursor returns the current cursor position within visible items.

func (*SessionList) DeselectAll added in v0.1.3

func (s *SessionList) DeselectAll()

DeselectAll clears all selections.

func (*SessionList) ExpandFolder

func (s *SessionList) ExpandFolder()

ExpandFolder expands the folder under the cursor (no-op if not a folder or already expanded).

func (*SessionList) FindNextWaiting added in v0.1.3

func (s *SessionList) FindNextWaiting(attentionMap map[string]data.AttentionStatus) int

FindNextWaiting searches forward from the current cursor position for the next visible session item with AttentionWaiting status. Returns the visItems index, or -1 if none found. Wraps around to the beginning.

func (*SessionList) FolderSessions added in v0.1.3

func (s *SessionList) FolderSessions() []data.Session

FolderSessions returns all sessions under the folder at the cursor position, including children of collapsed sub-folders (it walks allItems, not visItems). Returns nil if the cursor is not on a folder.

func (*SessionList) IsFolderSelected

func (s *SessionList) IsFolderSelected() bool

IsFolderSelected returns true when the cursor is on a folder node.

func (*SessionList) IsSelected added in v0.1.3

func (s *SessionList) IsSelected(id string) bool

IsSelected returns true if the given session ID is in the selection set.

func (*SessionList) MoveDown

func (s *SessionList) MoveDown()

MoveDown moves the cursor to the next visible item.

func (*SessionList) MoveTo

func (s *SessionList) MoveTo(idx int)

MoveTo sets the cursor to a specific visible-item index, clamping to bounds.

func (*SessionList) MoveUp

func (s *SessionList) MoveUp()

MoveUp moves the cursor to the previous visible item.

func (*SessionList) ScrollBy

func (s *SessionList) ScrollBy(delta int)

ScrollBy adjusts the scroll offset by delta lines (positive = down).

func (*SessionList) ScrollOffset

func (s *SessionList) ScrollOffset() int

ScrollOffset returns the current scroll position.

func (*SessionList) SelectAll added in v0.1.3

func (s *SessionList) SelectAll()

SelectAll marks all visible non-folder sessions as selected.

func (*SessionList) SelectRange added in v0.1.3

func (s *SessionList) SelectRange(from, to int)

SelectRange selects all visible non-folder sessions between indices from and to (inclusive), clearing any previous selections first. This implements Shift+click range selection.

func (*SessionList) Selected

func (s *SessionList) Selected() (data.Session, bool)

Selected returns the currently highlighted session.

func (*SessionList) SelectedFolderPath

func (s *SessionList) SelectedFolderPath() string

SelectedFolderPath returns the path/label of the selected folder, or "".

func (*SessionList) SelectedSessions added in v0.1.3

func (s *SessionList) SelectedSessions() []data.Session

SelectedSessions returns all selected sessions in display order. If no sessions are explicitly selected, returns nil.

func (*SessionList) SelectionCount added in v0.1.3

func (s *SessionList) SelectionCount() int

SelectionCount returns the number of currently selected sessions.

func (*SessionList) SessionCount

func (s *SessionList) SessionCount() int

SessionCount returns the number of (non-folder) items across all items.

func (*SessionList) SetAISessions

func (s *SessionList) SetAISessions(set map[string]struct{})

SetAISessions updates the set of AI-found session IDs, used to render those sessions with a "✦" marker.

func (*SessionList) SetAnchor added in v0.1.3

func (s *SessionList) SetAnchor()

SetAnchor records the current cursor position as the anchor for Shift+click range selection (mirrors Windows Explorer behavior).

func (*SessionList) SetAttentionStatuses added in v0.1.3

func (s *SessionList) SetAttentionStatuses(m map[string]data.AttentionStatus)

SetAttentionStatuses updates the attention status map used to render colored dots next to each session.

func (*SessionList) SetCursor added in v0.1.3

func (s *SessionList) SetCursor(idx int)

SetCursor moves the cursor to the given visible-item index, clamping to valid bounds and adjusting the scroll offset.

func (*SessionList) SetGroups

func (s *SessionList) SetGroups(groups []data.SessionGroup)

SetGroups replaces the list content with grouped sessions (tree mode). Folders are collapsible; initial state is expanded.

func (*SessionList) SetHiddenSessions

func (s *SessionList) SetHiddenSessions(set map[string]struct{})

SetHiddenSessions updates the set of hidden session IDs, used to render hidden sessions with a dimmed style.

func (*SessionList) SetPivotField added in v0.1.3

func (s *SessionList) SetPivotField(pivot string)

SetPivotField stores the current pivot mode so that group header icons reflect the active grouping dimension (folder, repo, branch, date).

func (*SessionList) SetSessions

func (s *SessionList) SetSessions(sessions []data.Session)

SetSessions replaces the list content with a flat slice of sessions.

func (*SessionList) SetSize

func (s *SessionList) SetSize(w, h int)

SetSize updates the available rendering dimensions.

func (*SessionList) ToggleFolder

func (s *SessionList) ToggleFolder() bool

ToggleFolder expands or collapses the folder under the cursor. Returns true if the cursor was on a folder.

func (*SessionList) ToggleSelected added in v0.1.3

func (s *SessionList) ToggleSelected() bool

ToggleSelected toggles the selection state of the session under the cursor. Returns true if the cursor was on a session (not a folder).

func (SessionList) View

func (s SessionList) View() string

View renders the visible portion of the list.

func (*SessionList) VisibleCount

func (s *SessionList) VisibleCount() int

VisibleCount returns the number of currently visible items.

type ShellPicker

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

ShellPicker renders a modal list of detected shells for session launch.

func NewShellPicker

func NewShellPicker() ShellPicker

NewShellPicker returns an empty ShellPicker.

func (*ShellPicker) MoveDown

func (s *ShellPicker) MoveDown()

MoveDown moves the selection down.

func (*ShellPicker) MoveUp

func (s *ShellPicker) MoveUp()

MoveUp moves the selection up.

func (*ShellPicker) Selected

func (s *ShellPicker) Selected() (platform.ShellInfo, bool)

Selected returns the currently highlighted shell.

func (*ShellPicker) SetShells

func (s *ShellPicker) SetShells(shells []platform.ShellInfo, defaultShell string)

SetShells replaces the available shells. If defaultShell is non-empty, it is placed first in the list with a "(default)" label.

func (*ShellPicker) SetSize

func (s *ShellPicker) SetSize(w, h int)

SetSize updates the overlay dimensions.

func (ShellPicker) View

func (s ShellPicker) View() string

View renders the shell picker overlay.

Jump to

Keyboard shortcuts

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