identity.go RawHistoryFolder

1package daemon
2
3import (
4	"crypto/rand"
5	"encoding/base32"
6	"fmt"
7	"io"
8	"strings"
9	"sync/atomic"
10	"time"
11)
12
13var fallbackStableIDCounter atomic.Uint64
14
15func newStableID(prefix string) (string, error) {
16	var b [16]byte
17	if _, err := io.ReadFull(rand.Reader, b[:]); err != nil {
18		return "", fmt.Errorf("generate stable id: %w", err)
19	}
20	enc := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(b[:])
21	return prefix + "_" + strings.ToLower(enc), nil
22}
23
24func (d *Daemon) newTabPaneStableIDs() (string, string, error) {
25	tabStableID, err := newStableID("t")
26	if err != nil {
27		return "", "", fmt.Errorf("daemon: generating tab identity: %w", err)
28	}
29	paneStableID, err := newStableID("p")
30	if err != nil {
31		return "", "", fmt.Errorf("daemon: generating pane identity: %w", err)
32	}
33	return tabStableID, paneStableID, nil
34}
35
36func fallbackStableID(prefix string) string {
37	id, err := newStableID(prefix)
38	if err != nil {
39		return fmt.Sprintf("%s_fallback_%x_%x", prefix, time.Now().UnixNano(), fallbackStableIDCounter.Add(1))
40	}
41	return id
42}
43
44func escapeVEVComponent(s string) string {
45	var b strings.Builder
46	for i := 0; i < len(s); i++ {
47		c := s[i]
48		if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-' {
49			b.WriteByte(c)
50			continue
51		}
52		b.WriteByte('%')
53		const hex = "0123456789ABCDEF"
54		b.WriteByte(hex[c>>4])
55		b.WriteByte(hex[c&0x0f])
56	}
57	return b.String()
58}

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