Help us shape the future of Go! Take the 2026 Go Developer Survey

app

package
v0.7.3 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ZoomMin = -3
	ZoomMax = +1
)

ZoomMin / ZoomMax — 5 levels total, all clamped here.

View Source
const (
	BgCork        = "cork"
	BgTransparent = "transparent"
	BgSolid       = "solid"
)

Legacy background-mode strings from an earlier single-"mode" design. Read on load and migrated into Cork/Color; never written.

View Source
const (
	AttrBold   = 1 << 0
	AttrFaint  = 1 << 1
	AttrItalic = 1 << 2
	AttrUnder  = 1 << 3
	AttrStrike = 1 << 4
)

Attr bits for a cell.

Variables

View Source
var BackgroundColors = []BackgroundColor{
	{"terminal (transparent)", ""},
	{"true black", "#000000"},
	{"github dark", "#0d1117"},
	{"tokyo night", "#1a1b26"},
	{"catppuccin", "#1e1e2e"},
	{"one dark", "#282c34"},
	{"dracula", "#282a36"},
	{"gruvbox", "#282828"},
	{"nord", "#2e3440"},
	{"solarized", "#002b36"},
	{"paper", "#faf8f3"},
	{"github light", "#ffffff"},
	{"solarized light", "#fdf6e3"},
	{"latte", "#eff1f5"},
	{"gruvbox light", "#fbf1c7"},
}

BackgroundColors — the fill colors offered in the background menu, in order. "terminal" keeps today's transparency; the rest are the background colors of the editor/terminal themes developers actually use, so the picker feels familiar. Dark themes first, then light ones. The menu appends a "custom hex" entry after these. Cork is an independent toggle, not a list entry.

View Source
var Bayer4x4 = [4][4]int{
	{0, 8, 2, 10},
	{12, 4, 14, 6},
	{3, 11, 1, 9},
	{15, 7, 13, 5},
}

Bayer 4x4 ordered-dither matrix (0..15).

View Source
var BlotchChars = []rune{'░', '▒'}

Extremely rare cork blotches (imperfections).

View Source
var CorkShades []RGB

CorkShades — weighted shade pool for the cork texture. Duplicates bias the random pick toward common mid tones, with occasional brighter or rustier accents. Rebuilt by ApplyTheme.

View Source
var FiberChars = []rune{'.', '·', ',', '\'', '˙'}

Chars used for the note's own paper-fiber flecks.

View Source
var PoreChars = []rune{'∘', '°', '◦', '○'}

Rare bigger cork pores / pinholes.

View Source
var SelBorderChoices []BorderChoice

SelBorderChoices — the 9 border colors available for notes. Keys 1-9 map to these in order; `c` cycles through them. Set by ApplyTheme; the names are identical in both palettes so a saved highlightColor index keeps meaning the same thing when the theme changes.

View Source
var StarChars = []rune{
	'.', ',', '·', '\'', ':', ';', '`', '~', '˙',
	'ˏ', 'ˎ', '‚', '„', '•',
}

Chars used to texture the cork surface — main pool. More variety gives the cork a busier, more ASCII-art feel.

View Source
var TintOrder = []string{
	"yellow", "pink", "blue", "green", "purple",
	"orange", "teal", "cream", "coral",
}

TintOrder — 1-9 in order.

View Source
var Tints map[string]Tint

Tints — the active tint set, swapped by ApplyTheme. Both palettes use the same nine keys so a note's saved tint name always resolves.

Functions

func ApplyTheme

func ApplyTheme(light bool)

ApplyTheme installs a palette into the package-level color vars that every draw site reads. Call it once at startup, before the first render.

func BackupDir

func BackupDir() (string, error)

BackupDir returns the directory holding rotated copies of notes.json, creating it on demand.

func DataPath

func DataPath() (string, error)

func DitherShade

func DitherShade(x, y int, density float32) rune

DitherShade returns a halftone char for a given (x,y) and density 0..1.

func ModeAttr

func ModeAttr(_ TextStyleMode) uint8

ModeAttr returns attribute bits to OR into cell renders. Unicode-math modes provide no ANSI attributes of their own (the visual "boldness" comes from the codepoint itself), so this always returns 0.

func ResolveTheme

func ResolveTheme(mode ThemeMode) bool

ResolveTheme is resolveTheme against the real terminal.

func Run

func Run()

Run is the package's main entry point. cmd/redthread/main.go calls it.

func SaveWorkspace

func SaveWorkspace(w *Workspace) error

SaveWorkspace writes the workspace as a v4 file (workspace envelope), rotating the previous content into the backup directory first.

func ScreenDeltaToWorld

func ScreenDeltaToWorld(d, zoom int) int

ScreenDeltaToWorld converts a 1-cell screen delta into a world delta, ensuring a non-zero input always moves at least 1 world cell.

func ScreenX

func ScreenX(worldX, zoom int) int

ScreenX / ScreenY convert a world cell to screen (no bob applied).

func ScreenY

func ScreenY(worldY, zoom int) int

func SpliceOverlay

func SpliceOverlay(bg, overlay string, x, y int) string

SpliceOverlay splices `overlay` onto `bg` at visual cell position (x, y). Both strings are newline-separated; ANSI CSI escapes are preserved. Style state active at the cut point is re-emitted before the suffix so chars just past the overlay keep their original styling (otherwise they'd render in terminal default, often appearing white).

func StyleText

func StyleText(s string, mode TextStyleMode) string

StyleText maps ASCII letters/digits to the mode's Unicode variant.

func StyleViewText

func StyleViewText(s string, mode TextStyleMode) string

StyleViewText applies styleRune to a pre-rendered string while passing through ANSI CSI escape sequences untouched. Useful when post-processing the output of a third-party widget (e.g. bubbles/textarea) so the visible glyphs reflect the board's font without breaking cursor highlighting.

func WorldX

func WorldX(screenX, zoom int) int

WorldX / WorldY convert a screen cell coordinate to the equivalent world coordinate given the zoom scale.

func WorldY

func WorldY(screenY, zoom int) int

Types

type Background

type Background struct {
	Cork  bool   `json:"cork"`
	Color string `json:"color,omitempty"` // hex (e.g. "#1c2233"); "" = transparent

	// Legacy dev-only field — read on load, migrated by normalizeLegacy,
	// never written.
	Mode string `json:"mode,omitempty"`
}

Background is the workspace-wide board background. The two axes are independent: Cork toggles the ASCII texture overlay, and Color is the fill drawn behind it ("" = transparent, i.e. the terminal background shows through). Any combination is valid — cork on over a solid color, cork off over transparent for a clean terminal, etc.

type BackgroundColor

type BackgroundColor struct {
	Name string
	Hex  string
}

BackgroundColor is one fill option in the background picker. Hex "" means transparent — the terminal/tmux background shows through (the default).

type BackgroundMenu

type BackgroundMenu struct {
	Cursor int
	Saved  Background // background at open time; restored on esc

	Cork  bool   // working cork toggle
	Color string // working fill color (hex, or "" for transparent)
	Hex   string // custom-hex buffer, e.g. "#1c2233"
}

BackgroundMenu is the stateful background picker. nil on model = closed. Two independent axes: a cork on/off toggle (row 0) and the fill color (the BackgroundColors rows, then a custom-hex row). Row layout:

0                     → cork toggle
1 .. len(colors)      → color rows (color index = cursor-1)
len(colors)+1         → custom hex

func NewBackgroundMenu

func NewBackgroundMenu(current Background) *BackgroundMenu

func (*BackgroundMenu) HexBackspace

func (m *BackgroundMenu) HexBackspace()

func (*BackgroundMenu) HexInput

func (m *BackgroundMenu) HexInput(runes []rune)

HexInput appends valid hex characters to the custom buffer (single leading '#'), capping at "#rrggbb", and live-previews the result.

func (*BackgroundMenu) Label

func (m *BackgroundMenu) Label() string

Label returns a human-readable summary for the toast.

func (*BackgroundMenu) Move

func (m *BackgroundMenu) Move(delta int)

func (*BackgroundMenu) OnCork

func (m *BackgroundMenu) OnCork() bool

OnCork / OnCustom report which special row the cursor is on.

func (*BackgroundMenu) OnCustom

func (m *BackgroundMenu) OnCustom() bool

func (*BackgroundMenu) Selected

func (m *BackgroundMenu) Selected() Background

Selected returns the Background described by the working state.

func (*BackgroundMenu) ToggleCork

func (m *BackgroundMenu) ToggleCork()

ToggleCork flips the cork overlay (used by left/right/space on the cork row).

type Board

type Board struct {
	Name           string        `json:"name"`
	GrainSeed      int64         `json:"grainSeed,omitempty"`
	Notes          []*Note       `json:"notes"`
	Strings        []*StringConn `json:"strings,omitempty"`
	Selected       string        `json:"-"`
	TextMode       TextStyleMode `json:"textMode,omitempty"`
	Zoom           int           `json:"zoom,omitempty"`
	HighlightColor int           `json:"highlightColor,omitempty"`
}

func (*Board) ApplyGlobalBorder

func (b *Board) ApplyGlobalBorder()

ApplyGlobalBorder syncs the package-level SelBorder with this board's HighlightColor. Call on load and whenever HighlightColor changes.

func (*Board) Connect

func (b *Board) Connect(fromID, toID string) *StringConn

func (*Board) ConnectToWall

func (b *Board) ConnectToWall(fromID string, worldX, worldY int) *StringConn

ConnectToWall creates a string from a note to a WORLD-coord wall-pin. The caller is responsible for converting a mouse click (screen) to world before calling this.

func (*Board) Cycle

func (b *Board) Cycle(direction int)

func (*Board) Delete

func (b *Board) Delete(id string)

func (*Board) DeleteStringAt

func (b *Board) DeleteStringAt(i int) bool

func (*Board) DeleteStringsTouching

func (b *Board) DeleteStringsTouching(id string) int

func (*Board) FindNote

func (b *Board) FindNote(id string) *Note

func (*Board) HitTopmost

func (b *Board) HitTopmost(cx, cy int) int

func (*Board) NewNote

func (b *Board) NewNote(screenW, screenH int) *Note

NewNote places a note at screen-centre converted to world coords, so it appears centred at whatever zoom level the user is on.

func (*Board) Raise

func (b *Board) Raise(i int)

func (*Board) Select

func (b *Board) Select(id string)

func (*Board) Selection

func (b *Board) Selection() *Note

func (*Board) StringsTouching

func (b *Board) StringsTouching(id string) []int

type BorderChoice

type BorderChoice struct {
	Name  string
	Color RGB
}

BorderChoice pairs a display name with an RGB for the border palette.

type Canvas

type Canvas struct {
	W, H int

	// DefaultBg, when non-nil, is the background color emitted for every
	// cell that has no fill of its own — i.e. a solid board background.
	// nil keeps the original fully-transparent behavior (tmux shows through).
	DefaultBg *RGB
	// contains filtered or unexported fields
}

func NewCanvas

func NewCanvas(w, h int) *Canvas

func (*Canvas) BlankRect

func (c *Canvas) BlankRect(x, y, w, h int)

BlankRect clears a rectangle back to transparent.

func (*Canvas) BlitAt

func (c *Canvas) BlitAt(src *Canvas, dx, dy int)

BlitAt copies every cell from `src` into this canvas at offset (dx, dy). Cells that fall outside this canvas are clipped. Source-empty cells (Rune == 0 && Fg == nil) overwrite the destination just the same — the caller is expected to pass a freshly-allocated dst canvas if it wants the off-screen area to read as terminal default.

func (*Canvas) Dim

func (c *Canvas) Dim(f float32)

Dim applies a multiplier to every cell's foreground color, preserving transparency on bare cells. Used for blurring the backdrop during edit.

func (*Canvas) Get

func (c *Canvas) Get(x, y int) Cell

func (*Canvas) Inside

func (c *Canvas) Inside(x, y int) bool

func (*Canvas) Serialize

func (c *Canvas) Serialize() string

Serialize walks the grid, coalescing adjacent cells that share style. Returns a string containing ANSI SGR + text, suitable for Bubble Tea's View() return value.

func (*Canvas) SetBlank

func (c *Canvas) SetBlank(x, y int)

SetBlank clears a cell back to transparent (erases cork stars etc).

func (*Canvas) SetRune

func (c *Canvas) SetRune(x, y int, r rune, fg RGB, attr uint8)

SetRune writes just rune+fg+attr without allocation.

func (*Canvas) WriteText

func (c *Canvas) WriteText(x, y int, s string, fg RGB, attr uint8)

WriteText writes a single-line string cell-by-cell starting at (x, y), wrapping handled by the caller.

type Cell

type Cell struct {
	Rune rune
	Fg   *RGB  // nil = terminal default fg (so a space is fully transparent)
	Attr uint8 // Attr* bits
}

type Editor

type Editor struct {
	Ta     textarea.Model
	NoteID string

	// Vim is non-nil when modal editing is on. It owns the buffer in
	// normal and visual mode; the textarea takes over for insert.
	Vim *VimState
}

func NewEditor

func NewEditor(n *Note, w, h int) Editor

func NewVimEditor

func NewVimEditor(n *Note, w, h int) Editor

NewVimEditor is NewEditor with modal editing enabled, starting in normal mode as vim does.

func (*Editor) Resize

func (e *Editor) Resize(w, h int)

func (*Editor) Split

func (e *Editor) Split() (string, string)

Split returns the live (title, body) from the textarea content. First non-empty line is the title; the rest (skipping one separator blank) is the body.

func (*Editor) SyncFromTextarea

func (e *Editor) SyncFromTextarea()

SyncFromTextarea pulls edits made in insert mode back into the vim buffer, so normal mode sees what was typed.

func (*Editor) SyncToTextarea

func (e *Editor) SyncToTextarea()

SyncToTextarea pushes the vim buffer into the textarea, for entering insert mode. The textarea's own cursor cannot be placed across wrapped lines, so this positions it as closely as the widget allows: the right row when lines are short, and the right column within that row.

func (*Editor) Update

func (e *Editor) Update(msg tea.Msg) tea.Cmd

func (Editor) View

func (e Editor) View(w, h int, n *Note, stars []Star, textMode TextStyleMode, board *Board, bgColor *RGB) string

View composes: blurred backdrop → ornate canvas frame at target rect → textarea spliced inside the frame → footer.

type FontMenu

type FontMenu struct {
	Cursor    int           // index into TextModes
	SavedMode TextStyleMode // mode at time of opening; restored on Esc
}

FontMenu is the stateful popup. nil on model = closed.

func NewFontMenu

func NewFontMenu(current TextStyleMode) *FontMenu

func (*FontMenu) Move

func (m *FontMenu) Move(delta int)

func (*FontMenu) Selected

func (m *FontMenu) Selected() TextStyleMode

type History

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

History is a bounded undo stack with a redo branch. Entries are whole *workspace* states as they were before a mutation, so Undo restores the previous state and stashes the current one for Redo.

Workspace rather than Board because deleting a board (`D`) destroys far more than deleting a note, and a board-level snapshot could not bring it back.

func NewHistory

func NewHistory(limit int) *History

func (*History) CanRedo

func (h *History) CanRedo() bool

func (*History) CanUndo

func (h *History) CanUndo() bool

func (*History) Clear

func (h *History) Clear()

Clear drops both stacks.

func (*History) Len

func (h *History) Len() int

func (*History) Push

func (h *History) Push(ws *Workspace, label string)

Push records the workspace's current state, to be restored by a later Undo. Call it *before* applying a mutation. label describes the mutation and is surfaced in the toast ("undo: paste into note").

func (*History) Redo

func (h *History) Redo(current *Workspace) (*Workspace, string, bool)

Redo re-applies the most recently undone mutation.

func (*History) Undo

func (h *History) Undo(current *Workspace) (*Workspace, string, bool)

Undo restores the state before the most recent mutation. current is the workspace as it stands now; it is stashed so Redo can return to it. Returns the restored workspace, the label of the undone mutation, and false when there is nothing to undo.

type Mode

type Mode int
const (
	ModeBoard Mode = iota
	ModeEdit
)

type Note

type Note struct {
	ID      string    `json:"id"`
	Title   string    `json:"title"`
	Body    string    `json:"body"`
	X       int       `json:"x"` // WORLD coord
	Y       int       `json:"y"` // WORLD coord
	Tint    string    `json:"tint"`
	W       int       `json:"w,omitempty"` // WORLD size; 0 = default
	H       int       `json:"h,omitempty"`
	Created time.Time `json:"created"`
	Updated time.Time `json:"updated"`

	// Runtime-only:
	Bob    float32 `json:"-"` // SCREEN-cell vertical bob
	BobX   float32 `json:"-"` // SCREEN-cell lateral wobble
	Lifted bool    `json:"-"`
	Flash  float32 `json:"-"`
}

func (*Note) Dims

func (n *Note) Dims(zoom int) NoteDims

Dims returns the note's rendered size at a zoom level.

func (*Note) EffectiveX

func (n *Note) EffectiveX(zoom int) int

EffectiveX: SCREEN X = world→screen projection + bob.

func (*Note) EffectiveY

func (n *Note) EffectiveY(zoom int) int

EffectiveY: SCREEN Y = world→screen projection + bob.

func (*Note) Hit

func (n *Note) Hit(cx, cy, zoom int) bool

Hit tests a screen-cell (cx, cy) against the note's current screen rect.

func (*Note) OnResizeHandle

func (n *Note) OnResizeHandle(cx, cy, zoom int) bool

OnResizeHandle reports whether screen cell (cx, cy) is on the note's bottom-right corner grip.

func (*Note) PinPos

func (n *Note) PinPos(zoom int) (int, int)

PinPos — screen position of the pin (top-center) including bob.

func (*Note) ScreenRect

func (n *Note) ScreenRect(zoom int) Rect

ScreenRect — drawing rect (no bob, stable for shadow/hit-test).

func (*Note) SetWorldSize

func (n *Note) SetWorldSize(w, h int)

SetWorldSize clamps and stores a new world size.

func (*Note) WorldSize

func (n *Note) WorldSize() (int, int)

WorldSize returns the note's size in world cells (default if unset).

type NoteDims

type NoteDims struct{ W, H int }

func DimsFor

func DimsFor(zoom int) NoteDims

DimsFor returns rendered note size at a zoom level.

type Palette

type Palette struct {
	// Cork texture, scattered directly over the terminal background.
	CorkDark    RGB
	CorkMid     RGB
	CorkLight   RGB
	CorkRust    RGB
	CorkWarm    RGB
	CorkPore    RGB
	CorkBlotch  RGB
	CorkPatchFg RGB

	// Pins and strings.
	PinRed   RGB
	PinHi    RGB
	PinDark  RGB
	StringRd RGB
	StringHi RGB

	// Drop shadow under notes.
	ShadowBG RGB
	ShadowMi RGB

	// Chrome: footer text, dimmed labels, the bright highlight, and the
	// tint used by the darken/vignette passes.
	Footer   RGB
	DimText  RGB
	Flash    RGB
	DarkTint RGB

	Tints            map[string]Tint
	SelBorderChoices []BorderChoice
}

Palette is a complete set of board colors. darkPalette() reproduces the colors redthread has always shipped; lightPalette() is its counterpart for a pale terminal background.

type PinOverride

type PinOverride struct {
	NoteID string
	X, Y   int
}

PinOverride lets callers substitute the screen position used for a specific note's string endpoints — used during the zoom-to-edit transition so strings follow the morphing rect instead of the original pin location.

type PullState

type PullState struct {
	Active bool
	FromID string // note ID the string starts at

	TargetX int
	TargetY int

	VX float32
	VY float32
}

func (*PullState) SetTarget

func (p *PullState) SetTarget(x, y int)

func (*PullState) Start

func (p *PullState) Start(fromID string, fromX, fromY int)

func (*PullState) Stop

func (p *PullState) Stop()

func (*PullState) Tick

func (p *PullState) Tick()

type RGB

type RGB struct{ R, G, B uint8 }

RGB is a 24-bit color.

var (
	CorkDark    RGB
	CorkMid     RGB
	CorkLight   RGB
	CorkRust    RGB // warmer reddish-brown
	CorkWarm    RGB // honey highlight
	CorkPore    RGB // rare pores / holes
	CorkBlotch  RGB // cork blotches
	CorkPatchFg RGB // bigger brown "patch" fg (with `▒` density)

	PinRed   RGB
	PinHi    RGB
	PinDark  RGB
	StringRd RGB
	StringHi RGB // brighter accent for the pulled-end tip
	ShadowBG RGB
	ShadowMi RGB
	Footer   RGB
	DimText  RGB
	Flash    RGB
	DarkTint RGB // for darken/vignette passes

	// SelBorder — legacy default (first entry of SelBorderChoices).
	// Per-note colors are preferred: Note.BorderColor picks an index.
	SelBorder RGB
)

func Lerp

func Lerp(a, b RGB, t float32) RGB

Lerp blends two colors linearly (0 → a, 1 → b).

func ParseHexColor

func ParseHexColor(s string) (RGB, bool)

ParseHexColor parses "#rrggbb" or "rrggbb" (case-insensitive) into an RGB. Returns ok=false for any malformed input.

func (RGB) BgSGR

func (c RGB) BgSGR() string

BgSGR emits the background-color SGR for this color. The renderer is otherwise foreground-only; this is used for the optional solid board background.

func (RGB) Brightness

func (c RGB) Brightness() float32

Brightness — Rec 601 luma, used by the monochrome dither pass.

func (RGB) Dimmed

func (c RGB) Dimmed(f float32) RGB

func (RGB) Hex

func (c RGB) Hex() string

func (RGB) SGR

func (c RGB) SGR() string

type Rect

type Rect struct{ X, Y, W, H int }

func BackgroundMenuRect

func BackgroundMenuRect(w, h int) Rect

func FontMenuRect

func FontMenuRect(w, h int) Rect

func RectFromNote

func RectFromNote(n *Note, zoom int) Rect

RectFromNote builds the source rect for a note at the board's zoom (SCREEN coords, no bob — transitions should start from the stable resting position, not mid-bounce).

func TargetRect

func TargetRect(w, h int) Rect

TargetRect returns the centered edit-card rect for a given canvas size.

type Saver

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

Saver debounces writes. Touch snapshots the workspace on the caller's goroutine and hands the copy to a timer, so the timer never reads the live workspace that the update loop keeps mutating (that was a data race, and with backups a torn marshal could be rotated into the ring). A generation counter lets a stale timer step aside when a newer Touch, Flush or Cancel has happened, and writeMu keeps writes in order.

func NewSaver

func NewSaver(w *Workspace, delay time.Duration) *Saver

func (*Saver) Cancel

func (s *Saver) Cancel()

Cancel drops a pending write without performing it.

func (*Saver) Flush

func (s *Saver) Flush() error

Flush writes the live workspace now and invalidates any pending timer.

func (*Saver) Touch

func (s *Saver) Touch()

Touch schedules a save of the workspace as it is right now.

type Star

type Star struct {
	X, Y  int
	R     rune
	Color RGB
}

func GenStarsForBoard

func GenStarsForBoard(w, h int, grainSeed int64) []Star

GenStarsForBoard returns a cork-texture stable across resizes-of-equal-size AND distinct per `grainSeed`. Row 0 is reserved for the tab bar — no stars are placed there.

type StringConn

type StringConn struct {
	A       StringEnd `json:"a"`
	B       StringEnd `json:"b"`
	Tight   bool      `json:"tight"`
	InFront bool      `json:"front,omitempty"`

	// legacy v2 fields (loaded, never written)
	FromID string `json:"from,omitempty"`
	ToID   string `json:"to,omitempty"`
}

func (*StringConn) InvolvesNote

func (s *StringConn) InvolvesNote(id string) bool

type StringEnd

type StringEnd struct {
	NoteID string `json:"note,omitempty"`
	X      int    `json:"x,omitempty"` // WORLD coord (for wall pins)
	Y      int    `json:"y,omitempty"`
}

func (*StringEnd) Pos

func (e *StringEnd) Pos(b *Board) (int, int, bool)

Pos returns an endpoint's SCREEN position (for drawing).

type TextStyleMode

type TextStyleMode int
const (
	TextPlain   TextStyleMode = iota // plain
	TextBold                         // 𝗕𝗼𝗹𝗱 — math sans-serif bold
	TextItalic                       // 𝘐𝘵𝘢𝘭𝘪𝘤 — math sans-serif italic
	TextBoldIt                       // 𝘽𝙤𝙡𝙙 𝙄𝙩 — math sans-serif bold italic
	TextScript                       // 𝓢𝓬𝓻𝓲𝓹𝓽 — math bold script
	TextFraktur                      // 𝕱𝖗𝖆𝖐𝖙𝖚𝖗 — math bold fraktur
	TextDouble                       // 𝔻𝕠𝕦𝕓𝕝𝕖 — math double-struck
	TextMono                         // 𝙼𝚘𝚗𝚘 — math monospace
)

func (TextStyleMode) Name

func (m TextStyleMode) Name() string

func (TextStyleMode) Sample

func (m TextStyleMode) Sample() string

type ThemeMode

type ThemeMode int

ThemeMode is the user's stated preference for palette selection.

const (
	ThemeAuto  ThemeMode = iota // probe the terminal
	ThemeDark                   // force the dark palette
	ThemeLight                  // force the light palette
)

func ParseThemeMode

func ParseThemeMode(s string) (ThemeMode, error)

ParseThemeMode reads "auto" / "light" / "dark", case-insensitively. The empty string means auto.

func (ThemeMode) String

func (m ThemeMode) String() string

type Tint

type Tint struct {
	Name  string
	Paper RGB // main ink / border color
	Ink   RGB // body text color (slightly lighter or darker for contrast)
	Fiber RGB // paper-fiber dot color
	Tape  RGB // tape strip color (tape on top of the note)
	Edge  RGB // edge highlight when selected
}

A Tint is a named color set for a sticky-note look.

func GetTint

func GetTint(name string) Tint

type Transition

type Transition struct {
	Mode     TransitionMode
	Start    time.Time
	Source   Rect
	NoteID   string
	Duration time.Duration
}

func NewTransitionIn

func NewTransitionIn(n *Note, zoom int) *Transition

func NewTransitionOut

func NewTransitionOut(n *Note, zoom int) *Transition

func (*Transition) Done

func (t *Transition) Done(now time.Time) bool

func (*Transition) Progress

func (t *Transition) Progress(now time.Time) float32

Progress: 0 = at source, 1 = at target. In runs 0→1; Out runs 1→0.

type TransitionMode

type TransitionMode int
const (
	TransitionIn TransitionMode = iota
	TransitionOut
)

type VimMode

type VimMode int
const (
	VimNormal VimMode = iota
	VimInsert
	VimVisual
)

func (VimMode) String

func (m VimMode) String() string

type VimState

type VimState struct {
	Row  int
	Col  int
	Mode VimMode
	// contains filtered or unexported fields
}

VimState is the buffer plus everything the key handler needs to interpret the next keystroke.

func NewVimState

func NewVimState(text string) *VimState

func (*VimState) Insert

func (v *VimState) Insert(s string)

Insert types text at the cursor (insert mode only).

func (*VimState) Key

func (v *VimState) Key(key string)

Key feeds one key to the state machine. Keys are bubbletea's names ("a", "esc", "backspace", "enter", …).

func (*VimState) Line

func (v *VimState) Line(i int) string

Line returns row i as a string (for rendering).

func (*VimState) LineCount

func (v *VimState) LineCount() int

LineCount is the number of lines in the buffer.

func (*VimState) SetText

func (v *VimState) SetText(text string)

SetText replaces the buffer, clamping the cursor into the new content.

func (*VimState) Text

func (v *VimState) Text() string

Text renders the buffer back to a string.

type Workspace

type Workspace struct {
	Boards     []*Board   `json:"boards"`
	ActiveIdx  int        `json:"activeIdx,omitempty"`
	Background Background `json:"background,omitempty"`

	// Theme is the saved palette preference: "light", "dark", or "" for
	// auto-detect. Omitted from the file when empty, so a workspace that
	// has never expressed a preference keeps getting detection.
	Theme string `json:"theme,omitempty"`

	// Vim enables modal editing in the note card. Off by default and
	// omitted when off, so nobody's muscle memory changes without asking.
	Vim bool `json:"vim,omitempty"`
}

Workspace is a list of named cork boards the user can cycle between. One is "active"; everything in the running model points at that one.

func LoadWorkspace

func LoadWorkspace() (*Workspace, error)

LoadWorkspace reads notes.json, migrating older schemas on the way in. Returns (nil, nil) when the file simply doesn't exist yet.

func (*Workspace) ActiveBoard

func (w *Workspace) ActiveBoard() *Board

ActiveBoard returns the currently-focused board, never nil while the workspace has at least one board.

func (*Workspace) AddBoard

func (w *Workspace) AddBoard(name string) *Board

AddBoard appends a fresh board with a unique grain seed and makes it active. Returns the new board.

func (*Workspace) BgColor

func (w *Workspace) BgColor() (*RGB, bool)

BgColor returns the solid fill color when one is set and parses; otherwise (nil, false) — meaning transparent (terminal shows through).

func (*Workspace) CanMoveActive

func (w *Workspace) CanMoveActive(delta int) bool

MoveActive shifts the active board by `delta` positions in the workspace order (negative = move left, positive = move right). Wraps around. The active index follows the moved board so the tab bar's `●` stays on it. Returns true if a swap happened. CanMoveActive reports whether MoveActive(delta) would actually reorder anything. Callers snapshot for undo before mutating, so they need to know in advance rather than from the return value.

func (*Workspace) CorkOn

func (w *Workspace) CorkOn() bool

CorkOn reports whether the cork texture overlay should be drawn.

func (*Workspace) CycleActive

func (w *Workspace) CycleActive(delta int)

CycleActive moves the active index by `delta`, wrapping around.

func (*Workspace) DeleteBoard

func (w *Workspace) DeleteBoard(i int) bool

DeleteBoard removes the board at index i. Refuses to delete the last remaining board.

func (*Workspace) MoveActive

func (w *Workspace) MoveActive(delta int) bool

func (*Workspace) SetThemeMode

func (w *Workspace) SetThemeMode(m ThemeMode)

SetThemeMode records a palette preference. Auto clears the field rather than writing "auto", keeping the key out of the file entirely.

func (*Workspace) ThemeMode

func (w *Workspace) ThemeMode() ThemeMode

ThemeMode returns the saved palette preference, defaulting to auto for an absent or unrecognized value.

func (*Workspace) ToggleTheme

func (w *Workspace) ToggleTheme() ThemeMode

ToggleTheme flips between the light and dark palettes, applies the new one immediately, and records the choice. A workspace still on auto resolves to whatever is currently rendered before flipping, so the first toggle always visibly changes something.

Jump to

Keyboard shortcuts

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