diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2021-11-02 20:35:53 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2021-11-05 07:58:21 +1100 |
commit | 37be9dbea18f52a544a1dd134657c02c1ee61aef (patch) | |
tree | a18a51d7f998e41a76a2268c897d34133241229b /pkg | |
parent | f6ec7babf55c4a43bc8048e8a84970a8de8250b9 (diff) |
support scrolling left and right
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/config/user_config.go | 4 | ||||
-rw-r--r-- | pkg/gui/context.go | 2 | ||||
-rw-r--r-- | pkg/gui/global_handlers.go | 27 | ||||
-rw-r--r-- | pkg/gui/gui.go | 8 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 14 | ||||
-rw-r--r-- | pkg/gui/line_by_line_panel.go | 2 | ||||
-rw-r--r-- | pkg/gui/list_context.go | 51 | ||||
-rw-r--r-- | pkg/gui/list_context_config.go | 2 | ||||
-rw-r--r-- | pkg/gui/merge_panel.go | 4 | ||||
-rw-r--r-- | pkg/gui/view_helpers.go | 1 | ||||
-rw-r--r-- | pkg/i18n/english.go | 6 |
11 files changed, 109 insertions, 12 deletions
diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 4ded99304..2d391b5fb 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -125,6 +125,8 @@ type KeybindingUniversalConfig struct { NextItemAlt string `yaml:"nextItem-alt"` PrevPage string `yaml:"prevPage"` NextPage string `yaml:"nextPage"` + ScrollLeft string `yaml:"scrollLeft"` + ScrollRight string `yaml:"scrollRight"` GotoTop string `yaml:"gotoTop"` GotoBottom string `yaml:"gotoBottom"` PrevBlock string `yaml:"prevBlock"` @@ -382,6 +384,8 @@ func GetDefaultConfig() *UserConfig { NextItemAlt: "j", PrevPage: ",", NextPage: ".", + ScrollLeft: "H", + ScrollRight: "L", GotoTop: "<", GotoBottom: ">", PrevBlock: "<left>", diff --git a/pkg/gui/context.go b/pkg/gui/context.go index 79db5dc26..66e28fc35 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -399,6 +399,8 @@ func (gui *Gui) onViewFocusLost(oldView *gocui.View, newView *gocui.View) error return nil } + _ = oldView.SetOriginX(0) + if oldView == gui.Views.CommitFiles && newView != gui.Views.Main && newView != gui.Views.Secondary && newView != gui.Views.Search { gui.resetWindowForView(gui.Views.CommitFiles) if err := gui.deactivateContext(gui.State.Contexts.CommitFiles); err != nil { diff --git a/pkg/gui/global_handlers.go b/pkg/gui/global_handlers.go index b55d6e3a8..c104c1664 100644 --- a/pkg/gui/global_handlers.go +++ b/pkg/gui/global_handlers.go @@ -10,6 +10,8 @@ import ( "github.com/jesseduffield/lazygit/pkg/utils" ) +const HORIZONTAL_SCROLL_FACTOR = 3 + // these views need to be re-rendered when the screen mode changes. The commits view, // for example, will show authorship information in half and full screen mode. func (gui *Gui) rerenderViewsWithScreenModeDependentContent() error { @@ -114,7 +116,7 @@ func (gui *Gui) linesToScrollDown(view *gocui.View) int { func (gui *Gui) scrollUpMain() error { if gui.canScrollMergePanel() { - gui.State.Panels.Merging.UserScrolling = true + gui.State.Panels.Merging.UserVerticalScrolling = true } return gui.scrollUpView(gui.Views.Main) @@ -122,12 +124,33 @@ func (gui *Gui) scrollUpMain() error { func (gui *Gui) scrollDownMain() error { if gui.canScrollMergePanel() { - gui.State.Panels.Merging.UserScrolling = true + gui.State.Panels.Merging.UserVerticalScrolling = true } return gui.scrollDownView(gui.Views.Main) } +func (gui *Gui) scrollLeftMain() error { + gui.scrollLeft(gui.Views.Main) + + return nil +} + +func (gui *Gui) scrollRightMain() error { + gui.scrollRight(gui.Views.Main) + + return nil +} + +func (gui *Gui) scrollLeft(view *gocui.View) { + newOriginX := utils.Max(view.OriginX()-view.InnerWidth()/HORIZONTAL_SCROLL_FACTOR, 0) + _ = view.SetOriginX(newOriginX) +} + +func (gui *Gui) scrollRight(view *gocui.View) { + _ = view.SetOriginX(view.OriginX() + view.InnerWidth()/HORIZONTAL_SCROLL_FACTOR) +} + func (gui *Gui) scrollUpSecondary() error { return gui.scrollUpView(gui.Views.Secondary) } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 76df52959..496ded841 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -145,9 +145,9 @@ type LblPanelState struct { type MergingPanelState struct { *mergeconflicts.State - // UserScrolling tells us if the user has started scrolling through the file themselves + // UserVerticalScrolling tells us if the user has started scrolling through the file themselves // in which case we won't auto-scroll to a conflict. - UserScrolling bool + UserVerticalScrolling bool } type filePanelState struct { @@ -403,8 +403,8 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) { Menu: &menuPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, OnPress: nil}, Suggestions: &suggestionsPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}}, Merging: &MergingPanelState{ - State: mergeconflicts.NewState(), - UserScrolling: false, + State: mergeconflicts.NewState(), + UserVerticalScrolling: false, }, }, Ptmx: nil, diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index d441c496c..8dbcfee7e 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -1428,6 +1428,20 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { }, { ViewName: "main", + Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY), string(MAIN_MERGING_CONTEXT_KEY)}, + Key: gui.getKey(config.Universal.ScrollLeft), + Handler: gui.scrollLeftMain, + Description: gui.Tr.LcScrollLeft, + }, + { + ViewName: "main", + Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY), string(MAIN_MERGING_CONTEXT_KEY)}, + Key: gui.getKey(config.Universal.ScrollRight), + Handler: gui.scrollRightMain, + Description: gui.Tr.LcScrollRight, + }, + { + ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Files.CommitChanges), Handler: gui.handleCommitPress, diff --git a/pkg/gui/line_by_line_panel.go b/pkg/gui/line_by_line_panel.go index 8c793375b..809416451 100644 --- a/pkg/gui/line_by_line_panel.go +++ b/pkg/gui/line_by_line_panel.go @@ -174,7 +174,7 @@ func (gui *Gui) focusSelection(state *LblPanelState) error { newOrigin := state.CalculateOrigin(origin, bufferHeight) gui.g.Update(func(*gocui.Gui) error { - if err := stagingView.SetOrigin(0, newOrigin); err != nil { + if err := stagingView.SetOriginY(newOrigin); err != nil { return err } diff --git a/pkg/gui/list_context.go b/pkg/gui/list_context.go index 290ac3a37..56e229273 100644 --- a/pkg/gui/list_context.go +++ b/pkg/gui/list_context.go @@ -30,6 +30,8 @@ type IListContext interface { OnRender() error handlePrevLine() error handleNextLine() error + handleScrollLeft() error + handleScrollRight() error handleLineChange(change int) error handleNextPage() error handleGotoTop() error @@ -69,7 +71,7 @@ func (self *ListContext) FocusLine() { } // we need a way of knowing whether we've rendered to the view yet. - view.FocusPoint(0, self.GetPanelState().GetSelectedLineIdx()) + view.FocusPoint(view.OriginX(), self.GetPanelState().GetSelectedLineIdx()) if self.RenderSelection { _, originY := view.Origin() displayStrings := self.GetDisplayStrings(originY, view.InnerHeight()) @@ -117,6 +119,13 @@ func (self *ListContext) HandleFocusLost() error { return self.OnFocusLost() } + view, err := self.Gui.g.View(self.ViewName) + if err != nil { + return nil + } + + _ = view.SetOriginX(0) + return nil } @@ -150,8 +159,44 @@ func (self *ListContext) handleNextLine() error { return self.handleLineChange(1) } +func (self *ListContext) handleScrollLeft() error { + if self.ignoreKeybinding() { + return nil + } + + // get the view, move the origin + view, err := self.Gui.g.View(self.ViewName) + if err != nil { + return nil + } + + self.Gui.scrollLeft(view) + + return self.HandleFocus() +} + +func (self *ListContext) handleScrollRight() error { + if self.ignoreKeybinding() { + return nil + } + + // get the view, move the origin + view, err := self.Gui.g.View(self.ViewName) + if err != nil { + return nil + } + + self.Gui.scrollRight(view) + + return self.HandleFocus() +} + +func (self *ListContext) ignoreKeybinding() bool { + return !self.Gui.isPopupPanel(self.ViewName) && self.Gui.popupPanelFocused() +} + func (self *ListContext) handleLineChange(change int) error { - if !self.Gui.isPopupPanel(self.ViewName) && self.Gui.popupPanelFocused() { + if self.ignoreKeybinding() { return nil } @@ -195,7 +240,7 @@ func (self *ListContext) handlePrevPage() error { } func (self *ListContext) handleClick() error { - if !self.Gui.isPopupPanel(self.ViewName) && self.Gui.popupPanelFocused() { + if self.ignoreKeybinding() { return nil } diff --git a/pkg/gui/list_context_config.go b/pkg/gui/list_context_config.go index 3e19eaf75..814e4677d 100644 --- a/pkg/gui/list_context_config.go +++ b/pkg/gui/list_context_config.go @@ -402,6 +402,8 @@ func (gui *Gui) getListContextKeyBindings() []*Binding { {ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.GotoTop), Modifier: gocui.ModNone, Handler: listContext.handleGotoTop, Description: gui.Tr.LcGotoTop}, {ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: listContext.handleNextLine}, {ViewName: listContext.GetViewName(), Contexts: []string{string(listContext.GetKey())}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: listContext.handleClick}, + {ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.ScrollLeft), Modifier: gocui.ModNone, Handler: listContext.handleScrollLeft}, + {ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.ScrollRight), Modifier: gocui.ModNone, Handler: listContext.handleScrollRight}, }...) // the commits panel needs to lazyload things so it has a couple of its own handlers diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go index c0c55de6c..f9e2de55c 100644 --- a/pkg/gui/merge_panel.go +++ b/pkg/gui/merge_panel.go @@ -203,7 +203,7 @@ func (gui *Gui) catSelectedFile() (string, error) { } func (gui *Gui) scrollToConflict() error { - if gui.State.Panels.Merging.UserScrolling { + if gui.State.Panels.Merging.UserVerticalScrolling { return nil } @@ -315,5 +315,5 @@ func (gui *Gui) withMergeConflictLock(f func() error) error { } func (gui *Gui) takeOverMergeConflictScrolling() { - gui.State.Panels.Merging.UserScrolling = false + gui.State.Panels.Merging.UserVerticalScrolling = false } diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index f853f2942..e77fbf751 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -323,6 +323,7 @@ func (gui *Gui) globalOptionsMap() map[string]string { gui.getKeyDisplay(keybindingConfig.Universal.Quit): gui.Tr.LcQuit, gui.getKeyDisplay(keybindingConfig.Universal.OptionMenu): gui.Tr.LcMenu, fmt.Sprintf("%s-%s", gui.getKeyDisplay(keybindingConfig.Universal.JumpToBlock[0]), gui.getKeyDisplay(keybindingConfig.Universal.JumpToBlock[len(keybindingConfig.Universal.JumpToBlock)-1])): gui.Tr.LcJump, + fmt.Sprintf("%s/%s", gui.getKeyDisplay(keybindingConfig.Universal.ScrollLeft), gui.getKeyDisplay(keybindingConfig.Universal.ScrollRight)): gui.Tr.LcScrollLeftRight, } } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 8f39948a0..b7c38d7ac 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -271,6 +271,9 @@ type TranslationSet struct { LcStashOptions string NotARepository string LcJump string + LcScrollLeftRight string + LcScrollLeft string + LcScrollRight string DiscardPatch string DiscardPatchConfirm string CantPatchWhileRebasingError string @@ -802,6 +805,9 @@ func englishTranslationSet() TranslationSet { LcStashOptions: "Stash options", NotARepository: "Error: must be run inside a git repository", LcJump: "jump to panel", + LcScrollLeftRight: "scroll left/right", + LcScrollLeft: "scroll left", + LcScrollRight: "scroll right", DiscardPatch: "Discard Patch", DiscardPatchConfirm: "You can only build a patch from one commit/stash-entry at a time. Discard current patch?", CantPatchWhileRebasingError: "You cannot build a patch or run patch commands while in a merging or rebasing state", |