Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArgSpec ¶
type ArgSpec int
ArgSpec describes what a command does with the text after its name.
const ( // ArgNone: the command takes no argument and rejects one rather than // silently ignoring it. Silently discarding input is how ":quit now" // becomes a bug report about a command that "sometimes does nothing". ArgNone ArgSpec = iota // ArgOptional: the argument changes behaviour but may be omitted. ArgOptional // ArgRequired: without it the command cannot run. ArgRequired )
type AuthErrorMsg ¶
type AuthErrorMsg struct {
Err error
}
AuthErrorMsg is sent when the Telegram client fails during authentication.
type AuthStateChangedMsg ¶
AuthStateChangedMsg is sent from the authorizer callback.
type AuthenticatedMsg ¶
AuthenticatedMsg signals that authentication is complete.
type ClipboardPasteFailedMsg ¶
type ClipboardPasteFailedMsg struct {
Err error
}
ClipboardPasteFailedMsg reports why a clipboard paste produced nothing.
type ClipboardPastedMsg ¶
type ClipboardPastedMsg struct {
// ChatId is the chat that was active when the paste was requested. If
// the active chat has changed by the time this message arrives, the
// paste is discarded rather than installed into the wrong chat.
ChatId int64
Path string
IsImage bool
}
ClipboardPastedMsg carries a clipboard image that has been spooled to disk and is ready to attach.
type Command ¶
type Command struct {
// Name is the command word, without the colon.
Name string
// Arg describes the argument, and Placeholder names it for display
// (e.g. "<query>"). Placeholder must be empty when Arg is ArgNone.
Arg ArgSpec
Placeholder string
// Description is one line, shown in the palette.
Description string
// Key is the equivalent key binding shown right-aligned, so the palette
// teaches the keymap rather than duplicating it. Empty when there is no
// single key for the command.
Key string
// Run performs the command. It receives the model by value and returns
// the updated model, matching how Update threads state everywhere else.
// The returned string is a notice for the user; empty means silent.
Run func(m Model, arg string) (Model, tea.Cmd, string)
}
Command is one entry in the registry.
A single typed table supplies everything about a command — its name, argument shape, description, key equivalent, and what it does — so the palette, the help card, and any future `:keymap` output all read from the same place and cannot drift apart. That is the whole reason this is a table rather than a switch in Update.
type FocusChangedMsg ¶
type FocusChangedMsg struct {
Panel FocusPanel
}
FocusChangedMsg signals a focus panel change.
type FocusPanel ¶
type FocusPanel int
FocusPanel identifies which UI panel has focus.
const ( PanelChatList FocusPanel = iota PanelChatView PanelComposer PanelSearch PanelContacts )
type InteractionMode ¶
type InteractionMode int
InteractionMode is the app-level answer to one question: will the next printable key be typed as text, or acted on as a command?
TUI 2.0 makes that question answerable at a glance (docs/tui-2.0.md, "Mode integration", resolved by decision 3). The mode is **derived**, never stored: it is computed from focus, the composer's own editing state, and which overlay owns the keyboard. There is deliberately no mode field to set, because a second source of truth beside FocusPanel could contradict what the app actually does with a keystroke — and a badge that lies about that is worse than no badge.
const ( // ModeNormal means printable keys act rather than type. It covers the // browsing panels and the overlays that navigate rather than collect // text. ModeNormal InteractionMode = iota // ModeInsert means printable keys are inserted as text: the composer // with an editor that will accept them, a text-collecting overlay, or // the auth form. ModeInsert // ModeVi means the composer is in vi editing and has returned to its // command state: the next letter runs a vi command on the draft // (decision I-12). // // It shared NORMAL with the browsing panels for a release, while // sharing none of their keys: q, r, y, e and ? are all inert there, // and i and h/l mean something else. A badge whose job is "what does // the next key do" cannot honestly say NORMAL for two keymaps that // agree on nothing. ModeVi // ModeCommand means the command palette owns input. ModeCommand )
func (InteractionMode) String ¶
func (m InteractionMode) String() string
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
func (Model) Init ¶
Init starts the chrome tick. Without it the top bar's clock would show the time of the last window resize for the rest of the session, and a transient notice would own the hint bar until something replaced it.
func (Model) Mode ¶
func (m Model) Mode() InteractionMode
Mode reports the current interaction mode.
This is the single source the mode badge, the hint bar and the palette's `:` routing must consult, so that all three agree with what Update actually does with a keystroke. It is derived from the surface (see hints.go) rather than resolved a second time beside it: two derivations of one thing is how the bar and the badge came to disagree about which keymap was live.
It is NOT a drop-in replacement for the focus checks in Update, and retrofitting it onto them would change behaviour — see the `:` and backtick gates, which consult it deliberately and differently.
func (Model) Update ¶
Update handles one message and then reconciles the frame with whatever it did.
The reconciliation is here rather than at the end of the switch because the switch has sixty-five early returns, and a step that only runs when the code happens to fall out of the bottom is a step that runs for most messages and silently not for the ones that matter.
type ScreenState ¶
type ScreenState int
ScreenState identifies the current top-level screen.
const ( ScreenAuth ScreenState = iota ScreenLoading ScreenMain )
type SendFailedMsg ¶
type SendFailedMsg struct {
Err error
ChatId int64 // chat the send was for; restore only into that composer
Attachment string
AsPhoto bool
}
SendFailedMsg reports a send that failed after the composer was already reset. It carries the attachment back so it can be restored for a retry instead of being lost with the spool file.
type Surface ¶ added in v0.0.14
type Surface int
Surface is the thing whose keymap is live right now: a panel, or the overlay that has taken the keyboard from it.
It exists because the hint bar was keyed by MODE, and a mode is a much coarser question — "does the next printable key type or act?" — than "what can I press". Three surfaces share ModeNormal and agree on almost no keys between them, so the chat-view hint set showed in the chat list, under contacts, under a confirm dialog and in a vi composer: four places where it named keys that do nothing (decision I-6).
Every hint the app draws is keyed by this, including the ones components paint themselves — the chat list footer, the dialog's own line, the media overlay's row. A hint that names an inert key is a defect, not a nit: it is how "u unread" sat in the chat list footer for a release with nothing bound to u.
const ( // The browsing panels. SurfaceChatList Surface = iota SurfaceChatView // The composer, in each of its two keymaps. They are separate surfaces // rather than one, because vi's command state shares nothing with // insert: enter still sends, but i, o, dd and : are the keys worth the // row, and ctrl+j inserts nothing there at all. SurfaceComposerInsert SurfaceComposerVi // The overlays, in the order Update consults them. SurfaceReactions SurfaceAttach SurfacePalette SurfaceMedia SurfaceHelp SurfaceDialog SurfaceSearch SurfaceContacts // The screens that are not the client: the auth form takes text, and // the loading screen takes nothing at all. SurfaceAuth SurfaceLoading )
func (Surface) Mode ¶ added in v0.0.14
func (s Surface) Mode() InteractionMode
Mode is the badge's answer for this surface: will the next printable key be typed as text, acted on, or collected into a command?
The mode is derived FROM the surface rather than beside it. Two derivations of one thing is what let the hint bar and the badge disagree about which keymap was live; there is one now, and this is the projection of it onto the coarser question the badge asks.