keymap

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package keymap turns key events into named actions.

Keeping key knowledge out of the UI has two payoffs: the whole mapping can be tested without a terminal, and the bindings become data the user can override in configuration rather than constants only a rebuild can change.

Index

Constants

View Source
const DefaultPreset = PresetVim

DefaultPreset is what a user who has said nothing gets.

It is the modal one. That is a strong default, so the interface says which mode it is in at all times, the empty editor says how to start typing, and the help screen says how to leave — see the vim reference and the escape hatch there.

Variables

This section is empty.

Functions

func GhosttySnippet

func GhosttySnippet(m *Map) string

GhosttySnippet returns configuration that makes Ghostty forward the ⌘ bindings to the application.

macOS terminals keep Cmd for their own menus, so the combinations have to be sent explicitly. The escape sequences are the kitty keyboard protocol's CSI-u form: CSI <key> ; <modifiers> u, where the modifier value is 1 + (shift 1, alt 2, ctrl 4, super 8).

func ITerm2Advice

func ITerm2Advice() string

ITerm2Advice explains the equivalent setup for iTerm2, which is done in the user interface rather than a configuration file.

func LabelWidth

func LabelWidth(label string) int

LabelWidth is how many terminal cells a key label occupies.

Glyphs such as ⌘ and ⇥ are wider than one cell in most fonts, so counting runes would leave the description column ragged.

func PadLabel

func PadLabel(label string, width int) string

PadLabel right-pads a label to the given display width.

func SupportsExtendedKeys

func SupportsExtendedKeys(term string) bool

SupportsExtendedKeys reports whether the terminal named by TERM can report modified keys such as Ctrl+Enter.

tcell enables the extended keyboard protocols only for terminals its terminfo marks XTermLike. The common trap is tmux, whose default TERM of "screen-256color" is not — so Ctrl+Enter silently degrades there while the very same tmux running as "tmux-256color" handles it.

func TerminalAdvice

func TerminalAdvice(term string, m *Map) string

TerminalAdvice returns a one-line hint when the current terminal cannot deliver the primary bindings, or "" when everything works.

func TmuxSnippet

func TmuxSnippet() string

TmuxSnippet returns the two settings that let tmux carry modified keys.

Types

type Action

type Action int

Action is something the user asked for, independent of how they asked.

const (
	// ActionNone means the event is not a command; the widget should handle
	// it as ordinary input.
	ActionNone Action = iota

	// Running.
	ActionRun
	ActionRunAll
	ActionCancel
	// ActionCopyOrCancel is Ctrl+C, whose meaning depends on whether text is
	// selected. The keymap cannot see that state, so it names the ambiguity
	// instead of guessing.
	ActionCopyOrCancel

	// Cursor movement. These are the one place ⌘ and Ctrl differ: on macOS
	// ⌘← goes to the start of a line while Ctrl← moves by word.
	ActionWordLeft
	ActionWordRight
	ActionSelectWordLeft
	ActionSelectWordRight
	ActionLineStart
	ActionLineEnd
	ActionSelectLineStart
	ActionSelectLineEnd
	ActionDeleteWordLeft
	ActionDeleteToLineStart

	// Editing.
	ActionCopy
	ActionCut
	ActionPaste
	ActionSelectAll
	ActionToggleComment
	ActionDuplicateLine
	ActionDeleteLine

	// Navigation and panes.
	ActionNextPane
	ActionPrevPane
	ActionToggleSidebar
	ActionRefreshSchema
	ActionUseSchema

	ActionComplete
	ActionFind
	ActionCommandPalette
	ActionGoToTable
	// ActionCycleTab moves through the tabs of whichever pane has focus.
	ActionCycleTab
	// ActionInspect shows the definition of the selected table.
	ActionInspect

	// Application.
	ActionHelp
	ActionQuit
)

func AllActions

func AllActions() []Action

AllActions lists every bindable action in help-screen order.

func (Action) Describe

func (a Action) Describe() string

Describe returns the help-screen text for the action.

func (Action) Reserved

func (a Action) Reserved() bool

Reserved reports whether the action names a feature that is not built yet.

func (Action) String

func (a Action) String() string

type Binding

type Binding struct {
	Key  tcell.Key
	Rune rune // only meaningful when Key is tcell.KeyRune
	Mods tcell.ModMask
}

Binding is one key combination in a canonical form.

Canonical means: a combination that can be written as a rune is stored as KeyRune plus a lower-case rune, never as one of tcell's control-code constants. Terminals disagree about which form they send — an extended terminal reports Ctrl+A as KeyRune 'a' with ModCtrl, a legacy one as KeyCtrlA — and folding both into one shape is what lets a single registration serve every terminal.

func ParseBinding

func ParseBinding(spec string) (Binding, error)

ParseBinding reads a specification such as "ctrl+shift+enter".

func (Binding) Event

func (b Binding) Event() *tcell.EventKey

Event renders the binding as an event, which is how tests and the round trip from configuration reach Lookup.

func (Binding) Label

func (b Binding) Label(mac bool) string

Label renders the binding for display. On macOS the familiar glyphs are used, since that is what DataGrip and every other Mac application shows.

type Map

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

Map resolves key events to actions.

func Default

func Default() *Map

Default returns the key map for the default preset.

func ForPreset

func ForPreset(p Preset) (*Map, error)

ForPreset builds the key map for a preset.

Every preset starts from the same base and then rebinds what it disagrees with. Sharing the base is what keeps the presets from drifting apart on the hundred keys nobody has an opinion about.

func FromConfig

func FromConfig(preset string, overrides map[string][]string) (*Map, error)

FromConfig builds the effective key map from configuration.

An empty preset name means the default. Overrides are applied on top, so a user can take a whole keyboard and still disagree with it about one key.

It takes plain values rather than a config type so that the dependency runs one way: configuration carries strings, this package decides what they mean.

func (*Map) Apply

func (m *Map) Apply(overrides map[string][]string) error

Apply replaces the bindings of the named actions.

It is all-or-nothing: a map with one bad entry changes nothing, so a typo in configuration cannot leave the user with a half-rebound keyboard.

func (*Map) Bindings

func (m *Map) Bindings(a Action) []Binding

Bindings returns the bindings for an action, most idiomatic first.

func (*Map) DisplayBindings

func (m *Map) DisplayBindings(a Action) []Binding

DisplayBindings returns an action's bindings with duplicates collapsed, for the help screen and `dv keys`.

Some bindings exist only so a key keeps working on terminals that cannot report it properly — Ctrl+J standing in for Ctrl+Enter, for instance. They render identically to the binding they stand for, and listing both makes the table look broken. They stay bound; they just stop being advertised.

func (*Map) Lookup

func (m *Map) Lookup(ev *tcell.EventKey) Action

Lookup returns the action bound to the event, or ActionNone.

func (*Map) Modal

func (m *Map) Modal() bool

Modal reports whether the editor uses a modal input model.

This is the one thing a preset changes that a binding table cannot express, so it is carried on the map rather than inferred by comparing keys.

func (*Map) Preset

func (m *Map) Preset() Preset

Preset reports which preset the map was built from.

type Preset

type Preset string

Preset is a named starting point for the key map.

Muscle memory is the whole reason this exists: someone who spends the day in vim and someone who spends it in DataGrip both want their fingers to keep working, and neither wants to write out a keymap section to get it.

const (
	// PresetVim gives the editor a modal input model. The application keys
	// are unchanged — only what happens inside the editor differs.
	PresetVim Preset = "vim"
	// PresetDataGrip is DataGrip's SQL-tool keyboard.
	PresetDataGrip Preset = "datagrip"
	// PresetVSCode swaps in VS Code's spelling of the few keys where the two
	// tools genuinely disagree.
	PresetVSCode Preset = "vscode"
)

func ParsePreset

func ParsePreset(name string) (Preset, error)

ParsePreset resolves a configured name.

func Presets

func Presets() []Preset

Presets lists the presets, most preferred first.

Jump to

Keyboard shortcuts

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