v0.2.0 80c61e3

action.go RawHistoryFolder

1package palette
2
3import (
4	"strings"
5
6	"github.com/bnema/vev/internal/usecase/command"
7)
8
9// Action is the exact command token and its unmodified, whitespace-delimited
10// arguments. It is deliberately independent of palette state.
11type Action struct {
12	Command command.Command
13	Args    []string
14}
15
16// ParseAction recognizes an exact effective command result token. It accepts
17// outer and repeated whitespace but never treats a prefix or concatenated token
18// as a command. Static commands reject arguments.
19func ParseAction(results []Result, input string) (Action, bool) {
20	fields := strings.Fields(input)
21	if len(fields) == 0 {
22		return Action{}, false
23	}
24	for _, result := range results {
25		cmd, ok := result.Command()
26		if !ok || !strings.EqualFold(fields[0], cmd.Code) {
27			continue
28		}
29		args := append([]string(nil), fields[1:]...)
30		switch cmd.Arguments {
31		case command.ArgumentsNone:
32			if len(args) != 0 {
33				return Action{}, false
34			}
35		case command.ArgumentsRequired:
36			if len(args) == 0 {
37				return Action{}, false
38			}
39		}
40		return Action{Command: cmd, Args: args}, true
41	}
42	return Action{}, false
43}
44
45// ArgumentCommand returns the exact argument-taking command whose token is
46// being typed, including the whitespace-before-argument state.
47func ArgumentCommand(results []Result, input string) (command.Command, bool) {
48	_, cmd, ok := argumentResult(results, input)
49	return cmd, ok
50}
51
52// argumentResult finds the exact argument-taking command and its source row in
53// one pass so callers can reuse the immutable result without another scan.
54func argumentResult(results []Result, input string) (Result, command.Command, bool) {
55	fields := strings.Fields(input)
56	if len(fields) == 0 {
57		return Result{}, command.Command{}, false
58	}
59	for _, result := range results {
60		cmd, ok := result.Command()
61		if ok && cmd.Arguments == command.ArgumentsRequired && strings.EqualFold(fields[0], cmd.Code) {
62			return result, cmd, true
63		}
64	}
65	return Result{}, command.Command{}, false
66}

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