mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-23 12:18:51 +02:00
In d5b4f7bb3e and 58a83b0862 we introduced a combined mechanism for rerendering views when either their width changes (needed for the branches view which truncates long branch names), or the screen mode (needed for those views that display more information in half or full screen mode, e.g. the commits view). This was a bad idea, because it unnecessarily rerenders too many views when just their width changes, which causes a noticable lag. This is a problem, for example, when selecting a file in the files panel that has only unstaged changes, and then going to one that has both staged and unstaged changes; this splits the main view, causing the side panels to become a bit narrower, and rerendering all those views took almost 500ms on my machine. Another similar example is entering or leaving staging mode. Fix this by being more specific about which views need rerendering under what conditions; this improves the time it takes to rerender in the above scenarios from 450-500s down to about 20ms. This reintroduces the code that was removed in 58a83b0862, but in a slightly different way.
81 lines
2.0 KiB
Go
81 lines
2.0 KiB
Go
package controllers
|
|
|
|
import (
|
|
"github.com/jesseduffield/gocui"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
)
|
|
|
|
type ScreenModeActions struct {
|
|
c *ControllerCommon
|
|
}
|
|
|
|
func (self *ScreenModeActions) Next() error {
|
|
self.c.State().GetRepoState().SetScreenMode(
|
|
nextIntInCycle(
|
|
[]types.WindowMaximisation{types.SCREEN_NORMAL, types.SCREEN_HALF, types.SCREEN_FULL},
|
|
self.c.State().GetRepoState().GetScreenMode(),
|
|
),
|
|
)
|
|
|
|
return self.rerenderViewsWithScreenModeDependentContent()
|
|
}
|
|
|
|
func (self *ScreenModeActions) Prev() error {
|
|
self.c.State().GetRepoState().SetScreenMode(
|
|
prevIntInCycle(
|
|
[]types.WindowMaximisation{types.SCREEN_NORMAL, types.SCREEN_HALF, types.SCREEN_FULL},
|
|
self.c.State().GetRepoState().GetScreenMode(),
|
|
),
|
|
)
|
|
|
|
return self.rerenderViewsWithScreenModeDependentContent()
|
|
}
|
|
|
|
// 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 (self *ScreenModeActions) rerenderViewsWithScreenModeDependentContent() error {
|
|
for _, context := range self.c.Context().AllList() {
|
|
if context.NeedsRerenderOnWidthChange() == types.NEEDS_RERENDER_ON_WIDTH_CHANGE_WHEN_SCREEN_MODE_CHANGES {
|
|
if err := self.rerenderView(context.GetView()); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (self *ScreenModeActions) rerenderView(view *gocui.View) error {
|
|
context, ok := self.c.Helpers().View.ContextForView(view.Name())
|
|
if !ok {
|
|
self.c.Log.Errorf("no context found for view %s", view.Name())
|
|
return nil
|
|
}
|
|
|
|
return context.HandleRender()
|
|
}
|
|
|
|
func nextIntInCycle(sl []types.WindowMaximisation, current types.WindowMaximisation) types.WindowMaximisation {
|
|
for i, val := range sl {
|
|
if val == current {
|
|
if i == len(sl)-1 {
|
|
return sl[0]
|
|
}
|
|
return sl[i+1]
|
|
}
|
|
}
|
|
return sl[0]
|
|
}
|
|
|
|
func prevIntInCycle(sl []types.WindowMaximisation, current types.WindowMaximisation) types.WindowMaximisation {
|
|
for i, val := range sl {
|
|
if val == current {
|
|
if i > 0 {
|
|
return sl[i-1]
|
|
}
|
|
return sl[len(sl)-1]
|
|
}
|
|
}
|
|
return sl[len(sl)-1]
|
|
}
|