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:
parent
8cad8cda8f
commit
c517d1e0a2
@ -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,
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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()
|
||||
|
19
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
19
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@ -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) {
|
||||
|
33
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
33
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user