command.go RawHistoryFolder

1package command
2
3import (
4	"errors"
5	"strconv"
6)
7
8// ErrInvalidArguments reports arguments that do not have the exact command format.
9var ErrInvalidArguments = errors.New("invalid command arguments")
10
11// ParsePositiveUint64 accepts exactly one base-10 positive decimal value.
12// It deliberately rejects signs, whitespace, zero, and non-canonical forms.
13func ParsePositiveUint64(args []string) (uint64, error) {
14	if len(args) != 1 || args[0] == "" || (len(args[0]) > 1 && args[0][0] == '0') {
15		return 0, ErrInvalidArguments
16	}
17	for _, r := range args[0] {
18		if r < '0' || r > '9' {
19			return 0, ErrInvalidArguments
20		}
21	}
22	n, err := strconv.ParseUint(args[0], 10, 64)
23	if err != nil || n < 1 {
24		return 0, ErrInvalidArguments
25	}
26	return n, nil
27}
28
29// ParsePositiveDecimal parses a positive decimal that must fit the platform int.
30func ParsePositiveDecimal(args []string) (int, error) {
31	n, err := ParsePositiveUint64(args)
32	if err != nil || n > uint64(^uint(0)>>1) {
33		return 0, ErrInvalidArguments
34	}
35	return int(n), nil
36}
37
38// Context is the set of application actions available to commands.
39type Context interface {
40	CreateTab() error
41	CreateSession() error
42	CreateSessionNamed(name string) error
43	CreateEphemeralSession() error
44	CloseTab() error
45	SplitRight() error
46	SplitLeft() error
47	SplitUp() error
48	SplitDown() error
49	ConsumeOrExpelPaneLeft() error
50	ConsumeOrExpelPaneRight() error
51	StackPane() error
52	ToggleStack() error
53	ToggleFloatingPane() error
54	ClosePane() error
55	OpenMovePanePicker() error
56	OpenMoveTabPicker() error
57	FocusPaneLeft() error
58	FocusPaneRight() error
59	FocusPaneUp() error
60	FocusPaneDown() error
61	EnterResizeMode() error
62	GrowPaneWidth() error
63	ShrinkPaneWidth() error
64	GrowPaneHeight() error
65	ShrinkPaneHeight() error
66	EqualizePanes() error
67	NextTab() error
68	PrevTab() error
69	BackSession() error
70	Detach() error
71	EnterVisualMode() error
72	RenameSession() error
73	RenameSessionTo(name string) error
74	RenameTab() error
75	RenameTabTo(name string) error
76	OpenSessionPicker() error
77	OpenNotifications() error
78	YankLastNotification() error
79	JumpRecentSession(rank int) error
80}
81
82// Arguments declares whether a command accepts palette arguments.
83type Arguments uint8
84
85const (
86	ArgumentsNone Arguments = iota
87	ArgumentsOptional
88	ArgumentsRequired
89)
90
91// ContextHint describes optional contextual data needed to execute a command.
92type ContextHint uint8
93
94const (
95	ContextHintNone ContextHint = iota
96	ContextHintRecentSessions
97)
98
99// TargetKind declares which resolved target a control command needs.
100type TargetKind uint8
101
102const (
103	TargetNone TargetKind = iota
104	TargetSession
105	TargetTab
106	TargetPane
107)
108
109// CommandScope declares the serialization boundary needed by a command.
110type CommandScope uint8
111
112const (
113	CommandScopeSession CommandScope = iota
114	// CommandScopeCrossSession requires dispatch to defer locking to the
115	// mutation, which resolves and locks both source and destination sessions.
116	CommandScopeCrossSession
117)
118
119// ControlOptions carries per-invocation output preferences.
120type ControlOptions struct {
121	JSON bool
122}
123
124// ControlResult carries a control command's output.
125type ControlResult struct {
126	Output string
127}
128
129// ControlContext exposes prompt-free daemon actions to control commands.
130type ControlContext interface {
131	CreateTab() error
132	CreateSessionNamed(name string) error
133	CloseTab() error
134	ClosePane() error
135	MovePane(destinationSession, destinationTabID string) error
136	MoveTab(destinationSession string) error
137	SplitRight() error
138	SplitLeft() error
139	SplitUp() error
140	SplitDown() error
141	ConsumeOrExpelPaneLeft() error
142	ConsumeOrExpelPaneRight() error
143	StackPane() error
144	ToggleStack() error
145	GrowPaneWidth() error
146	ShrinkPaneWidth() error
147	GrowPaneHeight() error
148	ShrinkPaneHeight() error
149	EqualizePanes() error
150	FocusPaneLeft() error
151	FocusPaneRight() error
152	FocusPaneUp() error
153	FocusPaneDown() error
154	NextTab() error
155	PrevTab() error
156	RenameSessionTo(name string) error
157	RenameTabTo(name string) error
158	Toast(severity, message string) error
159	SessionRecovery(action string) (string, error)
160	ListSessions(json bool) (string, error)
161	ListTabs(json bool) (string, error)
162	ListPanes(json bool) (string, error)
163	SessionEnvironment(json bool) (string, error)
164	RemoteCatalog(json bool) (string, error)
165}
166
167// Command describes an executable command.
168type Command struct {
169	Slug, Code, Name, Desc string
170	Usage                  string
171	Arguments              Arguments
172	// Preview describes the selected palette command while its exact token is
173	// being entered. hasArgument is true after whitespace following the token.
174	Preview        func(args []string, hasArgument bool) string
175	ContextHint    ContextHint
176	Scriptable     bool
177	PaletteVisible bool
178	Target         TargetKind
179	Scope          CommandScope
180	Run            func(Context, []string) error
181	Control        func(ControlContext, []string, ControlOptions) (ControlResult, error)
182}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close