viewer

package
v1.3.7 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: AGPL-3.0 Imports: 26 Imported by: 0

Documentation

Overview

Package viewer is the main markdown viewer/editor TUI component.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckConflicts

func CheckConflicts(km KeyMap, appKeys config.Keys) []string

CheckConflicts inspects km for two classes of problem and returns a human-readable warning for each one found:

  1. Intra-mode conflicts same handler group (view / normal / visual). Cross-mode reuse of the same key by different bindings (e.g. "d" for DeletePrefix in normal and Cut in visual) is intentional and is NOT flagged.

  2. Viewer-vs-app conflicts that is intercepted before the viewer sees input.

func KeysFromString

func KeysFromString(raw string) []string

KeysFromString parses a comma-separated key string into a trimmed slice (public).

Types

type Direction

type Direction int

Direction for pane navigation.

const (
	DirLeft Direction = iota
	DirRight
	DirUp
	DirDown
)

Pane navigation directions.

type KeyMap

type KeyMap struct {
	// Movement (shared across Normal, Visual, View modes)
	MoveDown     key.Binding
	MoveUp       key.Binding
	MoveLeft     key.Binding
	MoveRight    key.Binding
	WordForward  key.Binding
	WordBackward key.Binding
	LineStart    key.Binding
	LineEnd      key.Binding
	HalfPageDown key.Binding
	HalfPageUp   key.Binding
	GotoPrefix   key.Binding // initiates gg / gf
	GotoEnd      key.Binding

	// Normal mode
	Undo           key.Binding
	Redo           key.Binding
	InsertMode     key.Binding
	AppendAfter    key.Binding
	InsertAtStart  key.Binding
	ReplaceMode    key.Binding
	AppendEnd      key.Binding
	NewLineBelow   key.Binding
	NewLineAbove   key.Binding
	ToggleCheckbox key.Binding
	InsertCheckbox key.Binding
	VisualMode     key.Binding
	VisualLineMode key.Binding
	Paste          key.Binding
	ReplacePrefix  key.Binding // initiates r{char}
	DeleteChar     key.Binding
	DeletePrefix   key.Binding // initiates dd / dw

	Indent key.Binding // > indent current line / selection
	Dedent key.Binding // < dedent current line / selection

	// Visual mode actions
	Yank            key.Binding
	Cut             key.Binding
	Change          key.Binding
	SearchSelection key.Binding

	// View mode
	FoldExpand   key.Binding
	FoldCollapse key.Binding

	// In-buffer search navigation (after :/pattern command)
	SearchNext key.Binding // n – jump to next match
	SearchPrev key.Binding // N – jump to previous match

	// Universal
	Escape key.Binding
}

KeyMap holds all key bindings for the viewer component. Each binding is a key.Binding that can be remapped by the user.

func DefaultKeyMap

func DefaultKeyMap() KeyMap

DefaultKeyMap returns the default vim-style key bindings for the viewer.

func (*KeyMap) ApplyConfigKeys

func (km *KeyMap) ApplyConfigKeys(vk config.ViewerKeys)

ApplyConfigKeys overlays user-configured key strings onto km, skipping any empty string (meaning "keep the default").

type Model

type Model struct {
	KeyMap KeyMap
	// contains filtered or unexported fields
}

Model is the viewer component model.

func New

func New() Model

New creates a new viewer Model with default key bindings and a single empty pane.

func (*Model) ActiveContent

func (v *Model) ActiveContent() string

ActiveContent returns the raw content of the active tab, or "" if no tabs.

func (*Model) ActiveFilePath

func (v *Model) ActiveFilePath() string

ActiveFilePath returns the file path of the active tab, or "" if no tabs.

func (*Model) ActiveMode

func (v *Model) ActiveMode() common.Mode

ActiveMode returns the current mode of the active tab (ModeView if no tabs).

func (*Model) ActivePaneIndex

func (v *Model) ActivePaneIndex() int

ActivePaneIndex returns the index of the currently focused pane.

func (*Model) ActiveTabDiskChanged

func (v *Model) ActiveTabDiskChanged() bool

ActiveTabDiskChanged returns true if the active tab's file changed on disk since last load/save.

func (*Model) ActiveTabHasRecovery

func (v *Model) ActiveTabHasRecovery() bool

ActiveTabHasRecovery returns true if the active tab has a pending swap recovery.

func (*Model) ActiveTabIndex

func (v *Model) ActiveTabIndex() int

ActiveTabIndex returns the index of the currently active tab in the active pane.

func (*Model) ActiveTabSwapPath

func (v *Model) ActiveTabSwapPath() string

ActiveTabSwapPath returns the swap file path for the active tab.

func (*Model) ActiveTabWarning

func (v *Model) ActiveTabWarning() (hasRecovery, diskChanged, modified bool, filePath string)

ActiveTabWarning returns the swap/disk-change state of the active tab for displaying a cmdbar warning. modified is true when the tab has unsaved edits (relevant when diskChanged is true to distinguish a conflict from a clean change).

func (*Model) ClearSearch added in v1.2.0

func (v *Model) ClearSearch()

ClearSearch clears the search state for the active tab.

func (*Model) ClearTabs

func (v *Model) ClearTabs()

ClearTabs removes all open tabs and resets to a single empty pane.

func (*Model) CloseActivePane

func (v *Model) CloseActivePane()

CloseActivePane closes the active pane. If the pane has tabs, the active tab is closed first; the pane then collapses if it is empty and not the last pane. If the pane is already empty and not the last pane, it collapses immediately.

func (*Model) CloseAllCleanTabs

func (v *Model) CloseAllCleanTabs() bool

CloseAllCleanTabs removes tabs with no unsaved changes across all panes. Returns true if any tabs with unsaved changes remain.

func (*Model) CloseTab

func (v *Model) CloseTab()

CloseTab closes the active tab (public wrapper for tui use).

func (*Model) CloseTabByPath

func (v *Model) CloseTabByPath(path string)

CloseTabByPath closes the tab for the given path (public wrapper for tui use).

func (*Model) ConvertTabsToSpaces added in v0.9.0

func (v *Model) ConvertTabsToSpaces(tabWidth int)

ConvertTabsToSpaces replaces every \t in the active file's content with tabWidth spaces, marks the file modified, and reloads the textarea.

func (*Model) EnterInsertMode added in v1.2.0

func (v *Model) EnterInsertMode()

EnterInsertMode switches the active tab to insert mode (public wrapper).

func (*Model) EnterNormalMode

func (v *Model) EnterNormalMode()

EnterNormalMode switches the active tab to normal mode (public wrapper).

func (*Model) ExitInsertMode

func (v *Model) ExitInsertMode()

ExitInsertMode switches from insert to normal mode (public wrapper).

func (*Model) ExitNormalMode

func (v *Model) ExitNormalMode()

ExitNormalMode switches the active tab back to view mode (public wrapper).

func (*Model) ExitVisualMode

func (v *Model) ExitVisualMode()

ExitVisualMode switches from visual to normal mode (public wrapper).

func (*Model) FocusNeighbor

func (v *Model) FocusNeighbor(dir Direction) bool

FocusNeighbor moves focus to the neighboring pane in the given direction. Returns false if no neighbor exists.

func (*Model) GetKeyMap

func (v *Model) GetKeyMap() KeyMap

GetKeyMap returns the current key map.

func (*Model) GotoLine added in v0.9.0

func (v *Model) GotoLine(lineNum int)

GotoLine jumps the active tab's cursor to the given 1-based line number. Values < 1 clamp to line 1; values > totalLines clamp to the last line. Works in both View mode (t.cursor) and edit modes (textarea navigation).

func (*Model) HasPendingInput

func (v *Model) HasPendingInput() bool

HasPendingInput returns true if the viewer is waiting for a second key in a multi-key sequence (d, g, r prefixes).

func (*Model) HasSearch added in v1.2.0

func (v *Model) HasSearch() bool

HasSearch returns true when the active tab has a non-empty search query.

func (*Model) HasTabs

func (v *Model) HasTabs() bool

HasTabs returns true if the active pane has any open tabs.

func (*Model) HasUnsavedChanges

func (v *Model) HasUnsavedChanges() bool

HasUnsavedChanges returns true if any open tab has unsaved changes.

func (*Model) InsertAtCursor

func (v *Model) InsertAtCursor(text string)

InsertAtCursor inserts text at the current cursor position in the textarea. Works in both Normal and Insert modes.

func (*Model) IsActiveModified

func (v *Model) IsActiveModified() bool

IsActiveModified returns true if the active tab has unsaved changes.

func (*Model) IsEditing

func (v *Model) IsEditing() bool

IsEditing returns whether the active tab is in insert or replace mode.

func (*Model) IsNormal

func (v *Model) IsNormal() bool

IsNormal returns whether the active tab is in normal mode.

func (*Model) IsVisual

func (v *Model) IsVisual() bool

IsVisual returns whether the active tab is in visual or visual-line mode.

func (*Model) LoadFile

func (v *Model) LoadFile(path string)

LoadFile opens a file in the viewer using the stored width.

func (*Model) ModeInfo

func (v *Model) ModeInfo() (common.Mode, int, int)

ModeInfo returns the current mode and line, column numbers for display in the cmdbar.

func (*Model) MoveTabLeft

func (v *Model) MoveTabLeft()

MoveTabLeft moves the active tab one position to the left (stops at index 0).

func (*Model) MoveTabRight

func (v *Model) MoveTabRight()

MoveTabRight moves the active tab one position to the right (stops at last index).

func (*Model) MoveTabToNeighbor

func (v *Model) MoveTabToNeighbor(dir Direction) bool

MoveTabToNeighbor moves the active tab to the neighboring pane in the given direction. Returns false if no neighbor exists or the active pane has no tabs.

func (*Model) NextTab

func (v *Model) NextTab()

NextTab switches to the next tab (public wrapper).

func (*Model) PaneCount

func (v *Model) PaneCount() int

PaneCount returns the number of open panes.

func (*Model) PrevTab

func (v *Model) PrevTab()

PrevTab switches to the previous tab (public wrapper).

func (*Model) RecoverActiveTab

func (v *Model) RecoverActiveTab(content []byte) bool

RecoverActiveTab loads swap content into the active tab. Returns false if the tab has no pending recovery.

func (*Model) RefreshAllTabs

func (v *Model) RefreshAllTabs()

RefreshAllTabs re-renders glamour content and re-highlights all open tabs with the current theme. Call this after a theme change.

func (*Model) ReloadActiveTab

func (v *Model) ReloadActiveTab(data []byte, mtime time.Time)

ReloadActiveTab replaces the active tab's content with data from disk.

func (*Model) SaveFile

func (v *Model) SaveFile() (string, bool)

SaveFile saves the active tab's content to disk.

func (*Model) SearchMatchCount added in v1.2.0

func (v *Model) SearchMatchCount() int

SearchMatchCount returns the total number of matches in the active tab.

func (*Model) SearchNext added in v1.2.0

func (v *Model) SearchNext() (found, wrapped bool)

SearchNext advances to the next match (wrapping around at the end). Returns (found, wrapped): found is false when there are no matches; wrapped is true when the search cycled back to the beginning.

func (*Model) SearchPrev added in v1.2.0

func (v *Model) SearchPrev() (found, wrapped bool)

SearchPrev moves to the previous match (wrapping around at the top). Returns (found, wrapped): found is false when there are no matches; wrapped is true when the search cycled back to the end.

func (*Model) SearchStatus added in v1.2.0

func (v *Model) SearchStatus() string

SearchStatus returns a short status string such as "/foo 2/5".

func (*Model) SelectionInfo

func (v *Model) SelectionInfo() string

SelectionInfo returns a human-readable description of the current visual selection, or "" when not in a visual mode.

func (*Model) SetActiveFilePath

func (v *Model) SetActiveFilePath(path string)

SetActiveFilePath updates the file path of the active tab.

func (*Model) SetActiveTabModified

func (v *Model) SetActiveTabModified(modified bool)

SetActiveTabModified marks the active tab as modified or clean. Intended for use in tests to simulate unsaved changes.

func (*Model) SetActiveTabRecovery

func (v *Model) SetActiveTabRecovery(hasRecovery bool)

SetActiveTabRecovery sets the hasRecovery flag on the active tab.

func (*Model) SetCheckboxStates

func (v *Model) SetCheckboxStates(states []string)

SetCheckboxStates sets the ordered list of bracket characters used when cycling checkbox state with the toggle action. Pass nil to use the built-in default ([ ] >> [x]).

func (*Model) SetCustomTheme

func (v *Model) SetCustomTheme(t *theme.CustomTheme)

SetCustomTheme sets the custom theme and resets the renderer.

func (*Model) SetDefaultMode

func (v *Model) SetDefaultMode(m common.Mode)

SetDefaultMode sets the mode new tabs open in.

func (*Model) SetFoldLevel

func (v *Model) SetFoldLevel(n int)

SetFoldLevel sets the default fold level.

func (*Model) SetKeyMap

func (v *Model) SetKeyMap(km KeyMap)

SetKeyMap sets the key map.

func (*Model) SetSearch added in v1.2.0

func (v *Model) SetSearch(query string) int

SetSearch sets the search query for the active tab, computes all matches, and jumps to the first match. Returns the number of matches found.

func (*Model) SetSize

func (v *Model) SetSize(w, h int)

SetSize updates width and height, then refreshes all open tabs.

func (*Model) SetStyles

func (v *Model) SetStyles(s Styles)

SetStyles updates the lipgloss styles used for rendering.

func (*Model) SetTabSpaces

func (v *Model) SetTabSpaces(s string)

SetTabSpaces sets the string inserted for a tab key press in insert mode.

func (*Model) SetTabWidth added in v0.9.0

func (v *Model) SetTabWidth(n int)

SetTabWidth sets the visual column width used to expand \t characters in view/normal mode display. Has no effect when tabWidth <= 0.

func (*Model) SetTheme

func (v *Model) SetTheme(s string)

SetTheme sets the theme name and resets the renderer so it rebuilds next render.

func (*Model) SetupFileTracking

func (v *Model) SetupFileTracking(swapPath string, mtime time.Time)

SetupFileTracking initialises swap and disk-mtime tracking for the active tab.

func (*Model) SplitPane added in v1.2.0

func (v *Model) SplitPane(direction splitDir)

SplitPane is a helper function for SplitPaneVert & SplitPanHoriz. It handles the split logic, given some splitDir direction.

func (*Model) SplitPaneHoriz

func (v *Model) SplitPaneHoriz() bool

SplitPaneHoriz splits the active pane horizontally (top / bottom). Returns false if the pane is too short (min 10 lines per half). The current file is opened in the new pane so both halves show the same file.

func (*Model) SplitPaneVert

func (v *Model) SplitPaneVert() bool

SplitPaneVert splits the active pane vertically (left | right). Returns false if the pane is too narrow (min 40 chars per half). The current file is opened in the new pane so both halves show the same file.

func (*Model) TabCount

func (v *Model) TabCount() int

TabCount returns the number of open tabs in the active pane.

func (*Model) Tick

func (v *Model) Tick(writeSwapFn func(swapPath, filePath string, content []byte) error) (changedPath string, hasConflict bool)

Tick writes swap files for modified tabs and checks for on-disk mtime changes. writeSwapFn is called for each modified tab; errors are its responsibility to log. Returns the path of the active file if a disk change was newly detected, and whether that file has unsaved edits (conflict). Both are empty/false if no change.

func (*Model) ToggleAllFolds added in v1.2.0

func (v *Model) ToggleAllFolds(folded bool)

ToggleAllFolds sets every fold on the active tab to folded=true (collapse) or folded=false (expand), then re-renders the tab.

func (*Model) ToggleCheckbox

func (v *Model) ToggleCheckbox()

ToggleCheckbox toggles the checkbox on the current line (public wrapper).

func (Model) Update

func (v Model) Update(msg tea.Msg) (Model, tea.Cmd)

Update handles incoming messages for the viewer.

func (Model) View

func (v Model) View(focused bool) string

View renders the viewer panel. focused determines which border style is used.

func (*Model) Width

func (v *Model) Width() int

Width returns the current width of the viewer.

type OpenLinkMsg

type OpenLinkMsg struct{ Target string }

OpenLinkMsg is sent when gf detects a link to open.

type SearchMsg

type SearchMsg struct{ Query string }

SearchMsg is sent when the user triggers a search from a visual selection.

type StatusMsg

type StatusMsg struct{ Text string }

StatusMsg carries a status string from the viewer to the app for display.

type Styles

type Styles struct {
	Gutter, CursorGutter                lipgloss.Style
	Cursor                              lipgloss.Style
	ActiveBorder, InactiveBorder, Title lipgloss.Style
	Dim, ActiveTab, InactiveTab         lipgloss.Style
}

Styles holds all lipgloss styles used by the viewer for rendering. These are set from the tui package after each theme change.

Jump to

Keyboard shortcuts

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