move_pane_admission.go RawHistoryFolder

1package daemon
2
3import "github.com/bnema/vev/internal/domain/layout"
4
5// movePaneTopology is the private pane topology Implementation consumed by the
6// shared moveTransaction Module.
7type movePaneTopology struct {
8	req       movePaneRequest
9	admission movePaneAdmission
10}
11
12// movePaneAdmission is an immutable snapshot of the exact live topology and
13// generations a move may later publish. Common Session and Attachment authority
14// is snapshotted by moveTransaction.
15type movePaneAdmission struct {
16	source                *session
17	destination           *session
18	sourceTab             *tab
19	destinationTab        *tab
20	movedPane             *pane
21	sourceGeneration      uint64
22	destinationGeneration uint64
23	finalSourceTab        bool
24}
25
26func (p *movePaneTopology) transactionRequest() moveTransactionRequest {
27	req := p.req
28	return moveTransactionRequest{
29		follow:               req.Follow,
30		beforeFollow:         req.BeforeFollow,
31		afterFollow:          req.AfterFollow,
32		operation:            "pane",
33		attachment:           req.Attachment,
34		attachmentCapability: req.AttachmentCapability,
35		source:               req.Source,
36		destination:          req.Destination,
37		logAttrs: []any{
38			"source_session_id", req.Source.ID,
39			"source_tab_id", req.SourceTabID,
40			"source_pane_id", req.SourcePaneID,
41			"destination_session_id", req.Destination.ID,
42			"destination_tab_id", req.DestinationTabID,
43		},
44	}
45}
46
47func (p *movePaneTopology) validRequest() bool {
48	return p != nil && p.req.SourceTabID != "" && p.req.SourcePaneID != "" && p.req.DestinationTabID != ""
49}
50
51// admitLocked runs with daemon and ordered Session locks held. It acquires only
52// the private ordered Tab locks and performs no publication.
53func (p *movePaneTopology) admitLocked(_ *Daemon, source, destination *session) error {
54	req := p.req
55	sourceTab := findMoveTabLocked(source, req.SourceTabID)
56	destinationTab := findMoveTabLocked(destination, req.DestinationTabID)
57	if sourceTab == nil || destinationTab == nil {
58		return errMoveStaleTarget
59	}
60	if sourceTab == destinationTab {
61		return errMovePaneInvalid
62	}
63	unlockTabs := lockMoveTabs(sourceTab, destinationTab)
64	defer unlockTabs()
65
66	var movedPane *pane
67	for _, candidate := range sourceTab.panes {
68		if candidate != nil && candidate.stableID == string(req.SourcePaneID) {
69			movedPane = candidate
70			break
71		}
72	}
73	if movedPane == nil {
74		return errMoveStaleTarget
75	}
76
77	p.admission = movePaneAdmission{
78		source: source, destination: destination, sourceTab: sourceTab, destinationTab: destinationTab,
79		movedPane:        movedPane,
80		sourceGeneration: sourceTab.layoutGeneration, destinationGeneration: destinationTab.layoutGeneration,
81		finalSourceTab: len(source.tabs) == 1 && source.tabs[0] == sourceTab &&
82			sourceTab.tree != nil && sourceTab.tree.Root != nil && len(layout.LeafIDs(sourceTab.tree.Root)) == 1,
83	}
84	return nil
85}
86
87func (p *movePaneTopology) afterAdmission(d *Daemon) {
88	if d.afterMovePaneSourceSnapshot != nil {
89		d.afterMovePaneSourceSnapshot()
90	}
91}
92
93func (p *movePaneTopology) willRetireSource() bool {
94	return p != nil && p.admission.finalSourceTab && p.admission.source != p.admission.destination
95}
96
97func (p *movePaneTopology) resizeFences(source, destination *session) *moveResizeFences {
98	admission := p.admission
99	return newMovePaneResizeFences(source, destination, admission.sourceTab, admission.destinationTab, admission.movedPane)
100}
101
102func (p *movePaneTopology) publishLocked(d *Daemon, source, destination *session) (moveTopologyPublication, error) {
103	admission := p.admission
104	commit := movePaneCommit{
105		req:                   p.req,
106		source:                source,
107		destination:           destination,
108		sourceTab:             admission.sourceTab,
109		destinationTab:        admission.destinationTab,
110		movedPane:             admission.movedPane,
111		sourceGeneration:      admission.sourceGeneration,
112		destinationGeneration: admission.destinationGeneration,
113	}
114	return commit.publishTopologyLocked(d)
115}

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