move.go RawHistoryFolder

1package daemon
2
3import (
4	"reflect"
5
6	"github.com/bnema/vev/internal/domain"
7)
8
9// movePaneRequest identifies both lifecycles and both topology objects by
10// immutable identity. Session names are advisory; the ID and incarnation are
11// the commit-time authority.
12type movePaneRequest struct {
13	Follow               bool
14	BeforeFollow         func() error
15	AfterFollow          func(*attachmentEffect)
16	Attachment           *attachedClient
17	AttachmentCapability attachmentCapability
18	Source               moveSessionLocator
19	SourceTabID          domain.TabStableID
20	SourcePaneID         domain.PaneStableID
21	Destination          moveSessionLocator
22	DestinationTabID     domain.TabStableID
23}
24
25type moveTabRequest struct {
26	Follow               bool
27	BeforeFollow         func() error
28	AfterFollow          func(*attachmentEffect)
29	Attachment           *attachedClient
30	AttachmentCapability attachmentCapability
31	Source               moveSessionLocator
32	SourceTabID          domain.TabStableID
33	Destination          moveSessionLocator
34}
35
36func (d *Daemon) movePane(req movePaneRequest) error {
37	return d.executeMove(&movePaneTopology{req: req})
38}
39
40// moveSessionForLocatorLocked resolves only live sessions. The name is
41// intentionally ignored after the stable ID/incarnation pair is checked.
42func moveSessionForLocatorLocked(d *Daemon, locator moveSessionLocator) *session {
43	if d == nil {
44		return nil
45	}
46	sess := d.sessions[locator.ID]
47	if sess == nil || sess.incarnation != locator.Incarnation {
48		return nil
49	}
50	return sess
51}
52
53func moveSessionLocatorCurrentLocked(sess *session, locator moveSessionLocator) bool {
54	return sess != nil && sess.id == locator.ID && sess.incarnation == locator.Incarnation
55}
56
57func findMoveTabLocked(sess *session, stableID domain.TabStableID) *tab {
58	if sess == nil {
59		return nil
60	}
61	for _, tb := range sess.tabs {
62		if tb != nil && tb.stableID == string(stableID) {
63			return tb
64		}
65	}
66	return nil
67}
68
69func indexMoveTabLocked(sess *session, target *tab) int {
70	for i, tb := range sess.tabs {
71		if tb == target {
72			return i
73		}
74	}
75	return -1
76}
77
78func moveTabMemberLocked(sess *session, target *tab) bool {
79	return indexMoveTabLocked(sess, target) >= 0
80}
81
82func lockMoveTabs(a, b *tab) func() {
83	if a == nil && b == nil {
84		return func() {}
85	}
86	if a == nil {
87		b.mu.Lock()
88		return b.mu.Unlock
89	}
90	if b == nil {
91		a.mu.Lock()
92		return a.mu.Unlock
93	}
94	if a == b {
95		a.mu.Lock()
96		return a.mu.Unlock
97	}
98	first, second := a, b
99	if first.stableID > second.stableID ||
100		(first.stableID == second.stableID && reflect.ValueOf(first).Pointer() > reflect.ValueOf(second).Pointer()) {
101		first, second = second, first
102	}
103	first.mu.Lock()
104	second.mu.Lock()
105	return func() {
106		second.mu.Unlock()
107		first.mu.Unlock()
108	}
109}
110
111func lockMoveDispatch(a, b *session) func() {
112	if a == b {
113		a.dispatchMu.Lock()
114		return a.dispatchMu.Unlock
115	}
116	first, second := a, b
117	if first.id > second.id {
118		first, second = second, first
119	}
120	first.dispatchMu.Lock()
121	second.dispatchMu.Lock()
122	return func() {
123		second.dispatchMu.Unlock()
124		first.dispatchMu.Unlock()
125	}
126}

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