1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-04 03:48:07 +02:00

update view cursor when selecting new line in patch explorer view

This commit is contained in:
Jesse Duffield 2023-02-16 21:31:10 +11:00
parent 8cad8cda8f
commit c517d1e0a2
8 changed files with 82 additions and 45 deletions

View File

@ -20,6 +20,7 @@ type BaseContext struct {
focusable bool
transient bool
hasControlledBounds bool
highlightOnFocus bool
*ParentContextMgr
}
@ -34,6 +35,7 @@ type NewBaseContextOpts struct {
Focusable bool
Transient bool
HasUncontrolledBounds bool // negating for the sake of making false the default
HighlightOnFocus bool
OnGetOptionsMap func() map[string]string
}
@ -52,6 +54,7 @@ func NewBaseContext(opts NewBaseContextOpts) *BaseContext {
focusable: opts.Focusable,
transient: opts.Transient,
hasControlledBounds: hasControlledBounds,
highlightOnFocus: opts.HighlightOnFocus,
ParentContextMgr: &ParentContextMgr{},
viewTrait: viewTrait,
}

View File

@ -42,12 +42,13 @@ func NewMergeConflictsContext(
mutex: &deadlock.Mutex{},
Context: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: view,
WindowName: "main",
Key: MERGE_CONFLICTS_CONTEXT_KEY,
OnGetOptionsMap: getOptionsMap,
Focusable: true,
Kind: types.MAIN_CONTEXT,
View: view,
WindowName: "main",
Key: MERGE_CONFLICTS_CONTEXT_KEY,
OnGetOptionsMap: getOptionsMap,
Focusable: true,
HighlightOnFocus: true,
}),
opts,
),
@ -77,7 +78,7 @@ func (self *MergeConflictsContext) IsUserScrolling() bool {
func (self *MergeConflictsContext) RenderAndFocus(isFocused bool) error {
self.setContent(isFocused)
self.focusSelection()
self.FocusSelection()
self.c.Render()
@ -104,9 +105,9 @@ func (self *MergeConflictsContext) setContent(isFocused bool) {
self.GetView().SetContent(self.GetContentToRender(isFocused))
}
func (self *MergeConflictsContext) focusSelection() {
func (self *MergeConflictsContext) FocusSelection() {
if !self.IsUserScrolling() {
_ = self.GetView().SetOrigin(self.GetView().OriginX(), self.GetOriginY())
_ = self.GetView().SetOriginY(self.GetOriginY())
}
}

View File

@ -37,11 +37,12 @@ func NewPatchExplorerContext(
mutex: &deadlock.Mutex{},
getIncludedLineIndices: getIncludedLineIndices,
SimpleContext: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
View: view,
WindowName: windowName,
Key: key,
Kind: types.MAIN_CONTEXT,
Focusable: true,
View: view,
WindowName: windowName,
Key: key,
Kind: types.MAIN_CONTEXT,
Focusable: true,
HighlightOnFocus: true,
}), ContextCallbackOpts{
OnFocus: onFocus,
OnFocusLost: onFocusLost,
@ -68,7 +69,7 @@ func (self *PatchExplorerContext) GetIncludedLineIndices() []int {
func (self *PatchExplorerContext) RenderAndFocus(isFocused bool) error {
self.setContent(isFocused)
self.focusSelection()
self.FocusSelection()
self.c.Render()
return nil
@ -83,7 +84,7 @@ func (self *PatchExplorerContext) Render(isFocused bool) error {
}
func (self *PatchExplorerContext) Focus() error {
self.focusSelection()
self.FocusSelection()
self.c.Render()
return nil
@ -93,16 +94,18 @@ func (self *PatchExplorerContext) setContent(isFocused bool) {
self.GetView().SetContent(self.GetContentToRender(isFocused))
}
func (self *PatchExplorerContext) focusSelection() {
func (self *PatchExplorerContext) FocusSelection() {
view := self.GetView()
state := self.GetState()
_, viewHeight := view.Size()
bufferHeight := viewHeight - 1
_, origin := view.Origin()
newOrigin := state.CalculateOrigin(origin, bufferHeight)
newOriginY := state.CalculateOrigin(origin, bufferHeight)
_ = view.SetOriginY(newOrigin)
_ = view.SetOriginY(newOriginY)
view.SetCursorY(state.GetSelectedLineIdx() - newOriginY)
}
func (self *PatchExplorerContext) GetContentToRender(isFocused bool) string {

View File

@ -50,6 +50,10 @@ func NewDisplayContext(key types.ContextKey, view *gocui.View, windowName string
}
func (self *SimpleContext) HandleFocus(opts types.OnFocusOpts) error {
if self.highlightOnFocus {
self.GetViewTrait().SetHighlight(true)
}
if self.OnFocus != nil {
if err := self.OnFocus(opts); err != nil {
return err

View File

@ -618,6 +618,12 @@ func (gui *Gui) refreshStagingPanel(focusOpts types.OnFocusOpts) error {
return gui.c.PushContext(mainContext, focusOpts)
}
if secondaryFocused {
gui.State.Contexts.StagingSecondary.FocusSelection()
} else {
gui.State.Contexts.Staging.FocusSelection()
}
return gui.c.RenderToMainViews(types.RefreshMainOpts{
Pair: gui.c.MainViewPairs().Staging,
Main: &types.ViewUpdateOpts{
@ -679,6 +685,8 @@ func (gui *Gui) refreshPatchBuildingPanel(opts types.OnFocusOpts) error {
return gui.helpers.PatchBuilding.Escape()
}
gui.State.Contexts.CustomPatchBuilder.FocusSelection()
mainContent := context.GetContentToRender(true)
return gui.c.RenderToMainViews(types.RefreshMainOpts{

View File

@ -5,7 +5,6 @@ import (
"strings"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/samber/lo"
)
@ -89,9 +88,6 @@ func (self *ViewDriver) Content(matcher *matcher) *ViewDriver {
func (self *ViewDriver) SelectedLine(matcher *matcher) *ViewDriver {
self.t.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context),
func() string {
if idx, ok := self.selectedLineIdxInPatchExplorer(); ok {
return self.getView().BufferLines()[idx]
}
return self.getView().SelectedLine()
},
)
@ -102,25 +98,13 @@ func (self *ViewDriver) SelectedLine(matcher *matcher) *ViewDriver {
// asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view.
func (self *ViewDriver) SelectedLineIdx(expected int) *ViewDriver {
self.t.assertWithRetries(func() (bool, string) {
actual, ok := self.selectedLineIdxInPatchExplorer()
if !ok {
actual = self.getView().SelectedLineIdx()
}
actual := self.getView().SelectedLineIdx()
return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual)
})
return self
}
func (self *ViewDriver) selectedLineIdxInPatchExplorer() (int, bool) {
context := self.t.gui.ContextForView(self.getView().Name())
patchExplorerContext, ok := context.(types.IPatchExplorerContext)
if ok && patchExplorerContext.GetState() != nil {
return patchExplorerContext.GetState().GetSelectedLineIdx(), true
}
return 0, false
}
// focus the view (assumes the view is a side-view)
func (self *ViewDriver) Focus() *ViewDriver {
viewName := self.getView().Name()

View File

@ -1226,8 +1226,10 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
newCx = lastCharForLine
}
}
if err := v.SetCursor(newCx, newCy); err != nil {
return err
if !IsMouseScrollKey(ev.Key) {
if err := v.SetCursor(newCx, newCy); err != nil {
return err
}
}
if IsMouseKey(ev.Key) {
@ -1289,6 +1291,19 @@ func IsMouseKey(key interface{}) bool {
}
}
func IsMouseScrollKey(key interface{}) bool {
switch key {
case
MouseWheelUp,
MouseWheelDown,
MouseWheelLeft,
MouseWheelRight:
return true
default:
return false
}
}
// execKeybindings executes the keybinding handlers that match the passed view
// and event. The value of matched is true if there is a match and no errors.
func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) (matched bool, err error) {

View File

@ -418,9 +418,10 @@ func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) error {
if err != nil {
return err
}
_, rcy, err = v.realPosition(v.cx, v.cy)
if err != nil {
return err
_, rrcy, err := v.realPosition(v.cx, v.cy)
// if error is not nil, then the cursor is out of bounds, which is fine
if err == nil {
rcy = rrcy
}
}
@ -460,6 +461,22 @@ func (v *View) SetCursor(x, y int) error {
return nil
}
func (v *View) SetCursorX(x int) {
maxX, _ := v.Size()
if x < 0 || x >= maxX {
return
}
v.cx = x
}
func (v *View) SetCursorY(y int) {
_, maxY := v.Size()
if y < 0 || y >= maxY {
return
}
v.cy = y
}
// Cursor returns the cursor position of the view.
func (v *View) Cursor() (x, y int) {
return v.cx, v.cy
@ -1349,11 +1366,12 @@ func (v *View) OverwriteLines(y int, content string) {
}
func (v *View) ScrollUp(amount int) {
newOy := v.oy - amount
if newOy < 0 {
newOy = 0
if amount > v.oy {
amount = v.oy
}
v.oy = newOy
v.oy -= amount
v.cy += amount
}
// ensures we don't scroll past the end of the view's content
@ -1361,6 +1379,7 @@ func (v *View) ScrollDown(amount int) {
adjustedAmount := v.adjustDownwardScrollAmount(amount)
if adjustedAmount > 0 {
v.oy += adjustedAmount
v.cy -= adjustedAmount
}
}