1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-24 05:36:19 +02:00
lazygit/pkg/gui/global_handlers.go
Jesse Duffield 2e05ac0c90 paging keybindings for line by line panel
support searching in line by line panel

move mutexes into their own struct

add line by line panel mutex

apply LBL panel mutex

bump gocui to prevent crashing when search item count decreases
2020-10-10 00:23:01 +11:00

196 lines
5.0 KiB
Go

package gui
import (
"math"
"strings"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/utils"
)
// 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 {
for _, viewName := range []string{"branches", "commits"} {
if err := gui.rerenderView(viewName); err != nil {
return err
}
}
return nil
}
func (gui *Gui) nextScreenMode(g *gocui.Gui, v *gocui.View) error {
gui.State.ScreenMode = utils.NextIntInCycle([]int{SCREEN_NORMAL, SCREEN_HALF, SCREEN_FULL}, gui.State.ScreenMode)
return gui.rerenderViewsWithScreenModeDependentContent()
}
func (gui *Gui) prevScreenMode(g *gocui.Gui, v *gocui.View) error {
gui.State.ScreenMode = utils.PrevIntInCycle([]int{SCREEN_NORMAL, SCREEN_HALF, SCREEN_FULL}, gui.State.ScreenMode)
return gui.rerenderViewsWithScreenModeDependentContent()
}
func (gui *Gui) scrollUpView(viewName string) error {
mainView, err := gui.g.View(viewName)
if err != nil {
return nil
}
ox, oy := mainView.Origin()
newOy := int(math.Max(0, float64(oy-gui.Config.GetUserConfig().Gui.ScrollHeight)))
return mainView.SetOrigin(ox, newOy)
}
func (gui *Gui) scrollDownView(viewName string) error {
mainView, err := gui.g.View(viewName)
if err != nil {
return nil
}
ox, oy := mainView.Origin()
y := oy
if !gui.Config.GetUserConfig().Gui.ScrollPastBottom {
_, sy := mainView.Size()
y += sy
}
scrollHeight := gui.Config.GetUserConfig().Gui.ScrollHeight
if y < mainView.LinesHeight() {
if err := mainView.SetOrigin(ox, oy+scrollHeight); err != nil {
return err
}
}
if manager, ok := gui.viewBufferManagerMap[viewName]; ok {
manager.ReadLines(scrollHeight)
}
return nil
}
func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error {
if gui.canScrollMergePanel() {
gui.State.Panels.Merging.UserScrolling = true
}
return gui.scrollUpView("main")
}
func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error {
if gui.canScrollMergePanel() {
gui.State.Panels.Merging.UserScrolling = true
}
return gui.scrollDownView("main")
}
func (gui *Gui) scrollUpSecondary(g *gocui.Gui, v *gocui.View) error {
return gui.scrollUpView("secondary")
}
func (gui *Gui) scrollDownSecondary(g *gocui.Gui, v *gocui.View) error {
return gui.scrollDownView("secondary")
}
func (gui *Gui) scrollUpConfirmationPanel(g *gocui.Gui, v *gocui.View) error {
if v.Editable {
return nil
}
return gui.scrollUpView("confirmation")
}
func (gui *Gui) scrollDownConfirmationPanel(g *gocui.Gui, v *gocui.View) error {
if v.Editable {
return nil
}
return gui.scrollDownView("confirmation")
}
func (gui *Gui) handleRefresh(g *gocui.Gui, v *gocui.View) error {
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
}
func (gui *Gui) handleMouseDownMain(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
return nil
}
switch g.CurrentView().Name() {
case "files":
// set filename, set primary/secondary selected, set line number, then switch context
// I'll need to know it was changed though.
// Could I pass something along to the context change?
return gui.enterFile(false, v.SelectedLineIdx())
case "commitFiles":
return gui.enterCommitFile(v.SelectedLineIdx())
}
return nil
}
func (gui *Gui) handleMouseDownSecondary(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
return nil
}
switch g.CurrentView().Name() {
case "files":
return gui.enterFile(true, v.SelectedLineIdx())
}
return nil
}
func (gui *Gui) handleInfoClick(g *gocui.Gui, v *gocui.View) error {
if !gui.g.Mouse {
return nil
}
cx, _ := v.Cursor()
width, _ := v.Size()
for _, mode := range gui.modeStatuses() {
if mode.isActive() {
if width-cx > len(gui.Tr.ResetInParentheses) {
return nil
}
return mode.reset()
}
}
// if we're not in an active mode we show the donate button
if cx <= len(gui.Tr.Donate)+len(INFO_SECTION_PADDING) {
return gui.OSCommand.OpenLink("https://github.com/sponsors/jesseduffield")
}
return nil
}
func (gui *Gui) fetch(canPromptForCredentials bool) (err error) {
gui.State.Mutexes.FetchMutex.Lock()
defer gui.State.Mutexes.FetchMutex.Unlock()
fetchOpts := commands.FetchOptions{}
if canPromptForCredentials {
fetchOpts.PromptUserForCredential = gui.promptUserForCredential
}
err = gui.GitCommand.Fetch(fetchOpts)
if canPromptForCredentials && err != nil && strings.Contains(err.Error(), "exit status 128") {
gui.createErrorPanel(gui.Tr.PassUnameWrong)
}
gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, COMMITS, REMOTES, TAGS}, mode: ASYNC})
return err
}
func (gui *Gui) handleCopySelectedSideContextItemToClipboard() error {
// important to note that this assumes we've selected an item in a side context
itemId := gui.getSideContextSelectedItemId()
if itemId == "" {
return nil
}
return gui.OSCommand.CopyToClipboard(itemId)
}