detached 661ba07

refactor(copy): keep document ownership in mode

commit
661ba078d75b63dfe64f0ceb19a276028c888131
author
brice · · 2026-07-15 07:21 UTC
committer
brice · · 2026-07-15 09:45 UTC
parent
e769ef3
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +7 -7
M internal/usecase/daemon/overlay_runtime.go +0 -2
@@ -158,7 +158,6 @@ type overlayRenderSnapshot struct {
158158
159159 copyActive bool
160160 copyMode *scopy.Mode
161- copyDocument *scopy.Document
162161 copyPane *pane
163162 copySearchModel *visualsearch.Model
164163 copyFeedback string
@@ -195,7 +194,6 @@ func (rt *overlayRuntime) SnapshotForRender() *overlayRenderSnapshot {
195194 rt.copyMu.Lock()
196195 snap.copyActive = rt.copyMode != nil
197196 snap.copyPane = rt.copyPane
198- snap.copyDocument = rt.copyDocument
199197 if rt.copyMode != nil {
200198 copyModeValue := *rt.copyMode
201199 copyModeValue.Searches = append([]scopy.SearchMatch(nil), rt.copyMode.Searches...)
@@ -158,7 +158,6 @@ type overlayRenderSnapshot struct {
158 158
159 copyActive bool159 copyActive bool
160 copyMode *scopy.Mode160 copyMode *scopy.Mode
161- copyDocument *scopy.Document
162 copyPane *pane161 copyPane *pane
163 copySearchModel *visualsearch.Model162 copySearchModel *visualsearch.Model
164 copyFeedback string163 copyFeedback string
@@ -195,7 +194,6 @@ func (rt *overlayRuntime) SnapshotForRender() *overlayRenderSnapshot {
195 rt.copyMu.Lock()194 rt.copyMu.Lock()
196 snap.copyActive = rt.copyMode != nil195 snap.copyActive = rt.copyMode != nil
197 snap.copyPane = rt.copyPane196 snap.copyPane = rt.copyPane
198- snap.copyDocument = rt.copyDocument
199 if rt.copyMode != nil {197 if rt.copyMode != nil {
200 copyModeValue := *rt.copyMode198 copyModeValue := *rt.copyMode
201 copyModeValue.Searches = append([]scopy.SearchMatch(nil), rt.copyMode.Searches...)199 copyModeValue.Searches = append([]scopy.SearchMatch(nil), rt.copyMode.Searches...)
M internal/usecase/daemon/overlay_runtime_test.go +7 -5
@@ -145,7 +145,7 @@ func TestOverlayRuntimeHandleInputInactive(t *testing.T) {
145145 require.False(t, ac.overlays.HandleInput(&Daemon{}, []byte("x")))
146146 }
147147
148-func TestOverlayRuntimeSnapshotCarriesCopyDocumentAndClearReleasesIt(t *testing.T) {
148+func TestOverlayRuntimeSnapshotCarriesCopyModeDocumentAndClearReleasesIt(t *testing.T) {
149149 ac := &attachedClient{}
150150 ac.initOverlays()
151151 p := newPane("floating", nil, domain.Size{Cols: 4, Rows: 2})
@@ -159,7 +159,8 @@ func TestOverlayRuntimeSnapshotCarriesCopyDocumentAndClearReleasesIt(t *testing.
159159
160160 renderSnap := ac.overlays.SnapshotForRender()
161161 require.Same(t, p, renderSnap.copyPane)
162- require.Same(t, document, renderSnap.copyDocument)
162+ require.NotNil(t, renderSnap.copyMode)
163+ require.Same(t, document, renderSnap.copyMode.Document())
163164 renderSnap.Unlock()
164165
165166 ac.overlays.copyMu.Lock()
@@ -170,7 +171,7 @@ func TestOverlayRuntimeSnapshotCarriesCopyDocumentAndClearReleasesIt(t *testing.
170171 ac.overlays.copyMu.Unlock()
171172 }
172173
173-func TestOverlayRuntimeCopyDocumentSurvivesRingOverwrite(t *testing.T) {
174+func TestOverlayRuntimeCopyModeDocumentSurvivesRingOverwrite(t *testing.T) {
174175 ac := &attachedClient{}
175176 ac.initOverlays()
176177 history := newTestHistory(1)
@@ -185,6 +186,7 @@ func TestOverlayRuntimeCopyDocumentSurvivesRingOverwrite(t *testing.T) {
185186 history.Append(testRow("after"))
186187 renderSnap := ac.overlays.SnapshotForRender()
187188 defer renderSnap.Unlock()
188- require.Same(t, document, renderSnap.copyDocument)
189- require.Equal(t, "before", rowText(renderSnap.copyDocument.Snapshot().Row(0)))
189+ require.NotNil(t, renderSnap.copyMode)
190+ require.Same(t, document, renderSnap.copyMode.Document())
191+ require.Equal(t, "before", rowText(renderSnap.copyMode.Document().Snapshot().Row(0)))
190192 }
@@ -145,7 +145,7 @@ func TestOverlayRuntimeHandleInputInactive(t *testing.T) {
145 require.False(t, ac.overlays.HandleInput(&Daemon{}, []byte("x")))145 require.False(t, ac.overlays.HandleInput(&Daemon{}, []byte("x")))
146 }146 }
147 147
148-func TestOverlayRuntimeSnapshotCarriesCopyDocumentAndClearReleasesIt(t *testing.T) {148+func TestOverlayRuntimeSnapshotCarriesCopyModeDocumentAndClearReleasesIt(t *testing.T) {
149 ac := &attachedClient{}149 ac := &attachedClient{}
150 ac.initOverlays()150 ac.initOverlays()
151 p := newPane("floating", nil, domain.Size{Cols: 4, Rows: 2})151 p := newPane("floating", nil, domain.Size{Cols: 4, Rows: 2})
@@ -159,7 +159,8 @@ func TestOverlayRuntimeSnapshotCarriesCopyDocumentAndClearReleasesIt(t *testing.
159 159
160 renderSnap := ac.overlays.SnapshotForRender()160 renderSnap := ac.overlays.SnapshotForRender()
161 require.Same(t, p, renderSnap.copyPane)161 require.Same(t, p, renderSnap.copyPane)
162- require.Same(t, document, renderSnap.copyDocument)162+ require.NotNil(t, renderSnap.copyMode)
163+ require.Same(t, document, renderSnap.copyMode.Document())
163 renderSnap.Unlock()164 renderSnap.Unlock()
164 165
165 ac.overlays.copyMu.Lock()166 ac.overlays.copyMu.Lock()
@@ -170,7 +171,7 @@ func TestOverlayRuntimeSnapshotCarriesCopyDocumentAndClearReleasesIt(t *testing.
170 ac.overlays.copyMu.Unlock()171 ac.overlays.copyMu.Unlock()
171 }172 }
172 173
173-func TestOverlayRuntimeCopyDocumentSurvivesRingOverwrite(t *testing.T) {174+func TestOverlayRuntimeCopyModeDocumentSurvivesRingOverwrite(t *testing.T) {
174 ac := &attachedClient{}175 ac := &attachedClient{}
175 ac.initOverlays()176 ac.initOverlays()
176 history := newTestHistory(1)177 history := newTestHistory(1)
@@ -185,6 +186,7 @@ func TestOverlayRuntimeCopyDocumentSurvivesRingOverwrite(t *testing.T) {
185 history.Append(testRow("after"))186 history.Append(testRow("after"))
186 renderSnap := ac.overlays.SnapshotForRender()187 renderSnap := ac.overlays.SnapshotForRender()
187 defer renderSnap.Unlock()188 defer renderSnap.Unlock()
188- require.Same(t, document, renderSnap.copyDocument)189+ require.NotNil(t, renderSnap.copyMode)
189- require.Equal(t, "before", rowText(renderSnap.copyDocument.Snapshot().Row(0)))190+ require.Same(t, document, renderSnap.copyMode.Document())
191+ require.Equal(t, "before", rowText(renderSnap.copyMode.Document().Snapshot().Row(0)))
190 }192 }

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