diff --git a/pkg/gui/context/main_context.go b/pkg/gui/context/main_context.go index b3e7ab21c..1ce340b8b 100644 --- a/pkg/gui/context/main_context.go +++ b/pkg/gui/context/main_context.go @@ -9,45 +9,21 @@ type MainContext struct { *SimpleContext *SearchTrait - diffSelect DiffSelectState + diffSelect types.DiffSelectState // selectableContentRenderKey names the render whose content HasSelectableContent // was worked out from. What there is to select is a property of the content, so an // answer about the content of another render says nothing about this one. selectableContentRenderKey string } -var _ types.ISearchableContext = (*MainContext)(nil) - -// DiffSelectMode is how the focused main view's diff selection extends from the -// cursor: a single line, a range from a fixed anchor, or the change block (hunk) -// around the cursor. -type DiffSelectMode int - -const ( - DiffSelectModeLine DiffSelectMode = iota - DiffSelectModeRange - DiffSelectModeHunk +var ( + _ types.ISearchableContext = (*MainContext)(nil) + _ types.DiffPaneContext = (*MainContext)(nil) ) -// DiffSelectState holds the *mode* of the focused main view's diff selection. The -// selected line and the range anchor themselves live in the gocui view (its cursor -// and range-select start), so only the mode lives here. It's on the context rather -// than on the controller because the controller that drives the selection, the -// controller that establishes it on focus, and the pane-toggle that seeds it on the -// other pane all reach the pane through its context. -type DiffSelectState struct { - Mode DiffSelectMode - // When a range is sticky, moving the cursor without holding shift extends the - // range; otherwise it collapses the range back to a single line. - RangeIsSticky bool - // Whether hunk mode was turned on by the user rather than being the configured - // default. This decides whether escape leaves hunk mode or leaves the view. - UserEnabledHunkMode bool -} - // DiffSelectState returns the focused main view's selection mode state, for the // controllers to read and mutate directly. -func (self *MainContext) DiffSelectState() *DiffSelectState { +func (self *MainContext) DiffSelectState() *types.DiffSelectState { return &self.diffSelect } @@ -56,7 +32,7 @@ func (self *MainContext) DiffSelectState() *DiffSelectState { // view's range anchor is cleared too, so the next render highlights the cursor line // only. func (self *MainContext) ResetDiffSelectMode() { - self.diffSelect.Mode = DiffSelectModeLine + self.diffSelect.Mode = types.DiffSelectModeLine self.diffSelect.RangeIsSticky = false self.diffSelect.UserEnabledHunkMode = false self.GetView().CancelRangeSelect() diff --git a/pkg/gui/controllers/main_view_controller.go b/pkg/gui/controllers/main_view_controller.go index 53154745d..4c2c993bb 100644 --- a/pkg/gui/controllers/main_view_controller.go +++ b/pkg/gui/controllers/main_view_controller.go @@ -43,7 +43,7 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty Keys: opts.GetKeys(opts.Config.Main.ToggleSelectHunk), Handler: self.toggleSelectHunk, DescriptionFunc: self.diffSelectionDescription(func() string { - if self.diffSelectState().Mode == context.DiffSelectModeHunk { + if self.diffSelectState().Mode == types.DiffSelectModeHunk { return self.c.Tr.SelectLineByLine } return self.c.Tr.SelectHunk @@ -163,7 +163,7 @@ func (self *MainViewController) escapeDescription() string { // selectingHunkEnabledByUser reports whether we are in hunk mode because the user // asked for it, as opposed to it being the configured default. func (self *MainViewController) selectingHunkEnabledByUser() bool { - return self.diffSelectState().Mode == context.DiffSelectModeHunk && self.diffSelectState().UserEnabledHunkMode + return self.diffSelectState().Mode == types.DiffSelectModeHunk && self.diffSelectState().UserEnabledHunkMode } // isDiffView reports whether the focused main view currently shows a diff, and so @@ -189,7 +189,7 @@ func (self *MainViewController) diffMainViewType() types.DiffMainViewType { } // diffSelectState returns this pane's diff selection mode state. -func (self *MainViewController) diffSelectState() *context.DiffSelectState { +func (self *MainViewController) diffSelectState() *types.DiffSelectState { return self.context.DiffSelectState() } @@ -250,7 +250,7 @@ func (self *MainViewController) selectClickedDiffLine(viewLine int) { return } view := self.context.GetView() - if self.diffSelectState().Mode == context.DiffSelectModeHunk && + if self.diffSelectState().Mode == types.DiffSelectModeHunk && self.c.Helpers().DiffLine.IsChangeLine(view, viewLine) { self.selectHunkAround(viewLine, false) return @@ -313,7 +313,7 @@ func (self *MainViewController) selectHunkAround(changeViewLine int, scrollIntoV view := self.context.GetView() start, end, ok := self.c.Helpers().DiffLine.ChangeBlockBounds(view, changeViewLine) if !ok { - self.diffSelectState().Mode = context.DiffSelectModeLine + self.diffSelectState().Mode = types.DiffSelectModeLine view.CancelRangeSelect() showSelectionAtLine(view, changeViewLine, scrollIntoView) return @@ -370,7 +370,7 @@ func (self *MainViewController) placeNavigationTarget(target int) { v.SetOrigin(0, target) return } - if self.diffSelectState().Mode == context.DiffSelectModeHunk { + if self.diffSelectState().Mode == types.DiffSelectModeHunk { self.selectHunkAround(target, true) return } @@ -403,9 +403,9 @@ func (self *MainViewController) moveCursor(delta int) { // sticky range is kept, so the move extends it. func (self *MainViewController) collapseForLineMove() { sel := self.diffSelectState() - if sel.Mode == context.DiffSelectModeHunk || - (sel.Mode == context.DiffSelectModeRange && !sel.RangeIsSticky) { - sel.Mode = context.DiffSelectModeLine + if sel.Mode == types.DiffSelectModeHunk || + (sel.Mode == types.DiffSelectModeRange && !sel.RangeIsSticky) { + sel.Mode = types.DiffSelectModeLine self.context.GetView().CancelRangeSelect() } } @@ -419,7 +419,7 @@ func (self *MainViewController) adjustSelection(delta int) { self.handleLineChange(delta) return } - if self.diffSelectState().Mode == context.DiffSelectModeHunk && (delta == 1 || delta == -1) { + if self.diffSelectState().Mode == types.DiffSelectModeHunk && (delta == 1 || delta == -1) { self.navigate(self.c.Helpers().DiffLine.AdjacentChangeBlock, delta > 0) return } @@ -438,7 +438,7 @@ func (self *MainViewController) selectAbsoluteLine(target int) { // range mode and either it's sticky or the anchor and cursor differ, i.e. a // non-sticky range that has actually been extended. func (self *MainViewController) selectingRange() bool { - if self.diffSelectState().Mode != context.DiffSelectModeRange { + if self.diffSelectState().Mode != types.DiffSelectModeRange { return false } start, end := self.context.GetView().SelectedLineRange() @@ -453,11 +453,11 @@ func (self *MainViewController) toggleSelectHunk() error { return nil } sel := self.diffSelectState() - if sel.Mode == context.DiffSelectModeHunk { - sel.Mode = context.DiffSelectModeLine + if sel.Mode == types.DiffSelectModeHunk { + sel.Mode = types.DiffSelectModeLine v.CancelRangeSelect() } else { - sel.Mode = context.DiffSelectModeHunk + sel.Mode = types.DiffSelectModeHunk sel.UserEnabledHunkMode = true self.selectHunkAround(v.SelectedLineIdx(), true) } @@ -473,11 +473,11 @@ func (self *MainViewController) toggleRangeSelect() error { } sel := self.diffSelectState() if self.selectingRange() { - sel.Mode = context.DiffSelectModeLine + sel.Mode = types.DiffSelectModeLine sel.RangeIsSticky = false v.CancelRangeSelect() } else { - sel.Mode = context.DiffSelectModeRange + sel.Mode = types.DiffSelectModeRange sel.RangeIsSticky = true v.SetRangeSelectStart(v.SelectedLineIdx()) } @@ -493,7 +493,7 @@ func (self *MainViewController) extendRange(forward bool) error { } sel := self.diffSelectState() if !self.selectingRange() { - sel.Mode = context.DiffSelectModeRange + sel.Mode = types.DiffSelectModeRange v.SetRangeSelectStart(v.SelectedLineIdx()) } sel.RangeIsSticky = false diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index c787d7504..2201b66a8 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -211,6 +211,15 @@ const ( DiffMainViewTypePatchBuilding ) +// DiffPaneContext is one of the two panes the main section can show, as the thing +// that holds a diff with a selection in it. The panels that act on such a selection +// are handed the pane it was made in, and speak to it through this. +type DiffPaneContext interface { + Context + + DiffSelectState() *DiffSelectState +} + type IListContext interface { Context diff --git a/pkg/gui/types/diff_select.go b/pkg/gui/types/diff_select.go new file mode 100644 index 000000000..041ac5969 --- /dev/null +++ b/pkg/gui/types/diff_select.go @@ -0,0 +1,28 @@ +package types + +// DiffSelectMode is how the focused main view's diff selection extends from the +// cursor: a single line, a range from a fixed anchor, or the change block (hunk) +// around the cursor. +type DiffSelectMode int + +const ( + DiffSelectModeLine DiffSelectMode = iota + DiffSelectModeRange + DiffSelectModeHunk +) + +// DiffSelectState holds the *mode* of the focused main view's diff selection. The +// selected line and the range anchor themselves live in the gocui view (its cursor +// and range-select start), so only the mode lives here. It's on the context rather +// than on the controller because the controller that drives the selection, the +// controller that establishes it on focus, and the pane-toggle that seeds it on the +// other pane all reach the pane through its context. +type DiffSelectState struct { + Mode DiffSelectMode + // When a range is sticky, moving the cursor without holding shift extends the + // range; otherwise it collapses the range back to a single line. + RangeIsSticky bool + // Whether hunk mode was turned on by the user rather than being the configured + // default. This decides whether escape leaves hunk mode or leaves the view. + UserEnabledHunkMode bool +}