v0.9.1 ece7682

history_policy.go RawHistoryFolder

1package daemon
2
3import (
4	"context"
5	"time"
6
7	vt "github.com/bnema/vev-vt"
8	"github.com/bnema/vev/internal/domain"
9)
10
11func historyConfigFor(policy domain.ScrollbackConfig) vt.HistoryConfig {
12	if policy.Megabytes == 0 {
13		return vt.HistoryConfig{}
14	}
15	return vt.HistoryConfig{MaxBytes: policy.Megabytes * 1_000_000, MaxRows: policy.Lines}
16}
17
18func (d *Daemon) currentHistoryConfig() vt.HistoryConfig {
19	return historyConfigFor(d.currentRuntimeConfig().scrollback)
20}
21
22// historyPanes gathers references without holding a session/tab lock while
23// touching history. Include hidden floating panes; deduplicate a pane that moves
24// between tabs while the separate session snapshots are being collected.
25func (d *Daemon) historyPanes() []*pane {
26	var panes []*pane
27	seen := make(map[*pane]struct{})
28	for _, sess := range d.sessionsSnapshot() {
29		sess.mu.Lock()
30		tabs := append([]*tab(nil), sess.tabs...)
31		sess.mu.Unlock()
32		for _, tb := range tabs {
33			if tb == nil {
34				continue
35			}
36			tb.mu.Lock()
37			current := tb.panesSnapshot()
38			if tb.floating.pane != nil {
39				current = append(current, tb.floating.pane)
40			}
41			tb.mu.Unlock()
42			for _, p := range current {
43				if p == nil {
44					continue
45				}
46				if _, exists := seen[p]; exists {
47					continue
48				}
49				seen[p] = struct{}{}
50				panes = append(panes, p)
51			}
52		}
53	}
54	return panes
55}
56
57func (d *Daemon) applyHistoryLimitsToPane(p *pane) {
58	p.mu.Lock()
59	var err error
60	if p.history != nil {
61		// Load inside the pane lock so an older concurrent reload cannot install
62		// a stale policy after a newer reload has already published its value.
63		err = p.history.SetLimits(d.currentHistoryConfig())
64	}
65	p.mu.Unlock()
66	if err != nil {
67		d.log.Warn("cannot apply scrollback limits", "err", err)
68	}
69}
70
71func (d *Daemon) applyHistoryLimits() {
72	for _, p := range d.historyPanes() {
73		d.applyHistoryLimitsToPane(p)
74	}
75}
76
77// Keep background compression infrequent and bounded; it must not compete
78// with interactive output when many panes retain history.
79const historyMaintenanceInterval = 5 * time.Second
80
81// historyMaintenance is application scheduling, not a VT-owned worker. It
82// visits one history page per pane per interval and skips busy/resizing panes.
83func (d *Daemon) historyMaintenance(ctx context.Context) {
84	timer := d.clock.NewTimer(historyMaintenanceInterval)
85	defer timer.Stop()
86	for {
87		select {
88		case <-ctx.Done():
89			return
90		case <-timer.C():
91			d.compressIdleHistories()
92			timer.Reset(historyMaintenanceInterval)
93		}
94	}
95}
96
97func (d *Daemon) compressIdleHistories() {
98	for _, p := range d.historyPanes() {
99		if !p.mu.TryLock() {
100			continue
101		}
102		var err error
103		if p.history != nil && !p.resizeApplying {
104			_, err = p.history.CompressIdle(1)
105		}
106		p.mu.Unlock()
107		if err != nil {
108			d.log.Warn("cannot compress idle scrollback", "err", err)
109		}
110	}
111}

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