main ece7682

action.go RawHistoryFolder

1package palette
2
3import (
4	"strings"
5	"unicode"
6
7	"github.com/bnema/vev/internal/usecase/command"
8)
9
10// Action is the exact command token and its unmodified, whitespace-delimited
11// arguments. It is deliberately independent of palette state.
12type Action struct {
13	Command command.Command
14	Args    []string
15}
16
17// ParseAction recognizes an exact effective command result token. It accepts
18// outer and repeated whitespace but never treats a prefix or concatenated token
19// as a command. Commands with optional arguments accept zero or more arguments.
20func ParseAction(results []Result, input string) (Action, bool) {
21	fields := strings.Fields(input)
22	if len(fields) == 0 {
23		return Action{}, false
24	}
25	for _, result := range results {
26		cmd, ok := result.Command()
27		if !ok || !strings.EqualFold(fields[0], cmd.Code) {
28			continue
29		}
30		args := append([]string(nil), fields[1:]...)
31		switch cmd.Arguments {
32		case command.ArgumentsNone:
33			if len(args) != 0 {
34				return Action{}, false
35			}
36		case command.ArgumentsRequired:
37			if len(args) == 0 {
38				return Action{}, false
39			}
40		}
41		return Action{Command: cmd, Args: args}, true
42	}
43	return Action{}, false
44}
45
46// ExactCommandResult returns a command whose code exactly matches input.
47func ExactCommandResult(results []Result, input string) (Result, bool) {
48	if strings.Fields(input) == nil || strings.ContainsAny(strings.TrimSpace(input), " \t\n\r") {
49		return Result{}, false
50	}
51	for _, result := range results {
52		cmd, ok := result.Command()
53		if ok && strings.EqualFold(strings.TrimSpace(input), cmd.Code) {
54			return result, true
55		}
56	}
57	return Result{}, false
58}
59
60// ArgumentCommand returns the exact argument-capable command whose token is
61// being typed, including the whitespace-before-argument state.
62func ArgumentCommand(results []Result, input string) (command.Command, bool) {
63	_, cmd, ok := argumentResult(results, input)
64	return cmd, ok
65}
66
67// Preview returns the pure preview text for an exact argument-capable command.
68// It never consults mutable daemon state.
69func Preview(cmd command.Command, input string) string {
70	if cmd.Preview == nil {
71		return ""
72	}
73	fields := strings.Fields(input)
74	hasArgument := len(fields) > 1 || strings.TrimRightFunc(input, unicode.IsSpace) != input
75	return cmd.Preview(append([]string(nil), fields[1:]...), hasArgument)
76}
77
78// argumentResult finds the exact argument-taking command and its source row in
79// one pass so callers can reuse the immutable result without another scan.
80func argumentResult(results []Result, input string) (Result, command.Command, bool) {
81	fields := strings.Fields(input)
82	if len(fields) == 0 {
83		return Result{}, command.Command{}, false
84	}
85	for _, result := range results {
86		cmd, ok := result.Command()
87		if ok && cmd.Arguments != command.ArgumentsNone && strings.EqualFold(fields[0], cmd.Code) {
88			return result, cmd, true
89		}
90	}
91	return Result{}, command.Command{}, false
92}

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