1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-12 11:15:00 +02:00
lazygit/pkg/gui/view_helpers.go

151 lines
3.7 KiB
Go
Raw Normal View History

2018-08-14 11:05:26 +02:00
package gui
2018-05-26 05:23:39 +02:00
import (
"time"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/tasks"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/spkg/bom"
2018-05-26 05:23:39 +02:00
)
func (gui *Gui) resetViewOrigin(v *gocui.View) {
if err := v.SetCursor(0, 0); err != nil {
gui.Log.Error(err)
}
if err := v.SetOrigin(0, 0); err != nil {
gui.Log.Error(err)
}
2018-06-09 11:06:33 +02:00
}
// Returns the number of lines that we should read initially from a cmd task so
// that the scrollbar has the correct size, along with the number of lines after
// which the view is filled and we can do a first refresh.
func (gui *Gui) linesToReadFromCmdTask(v *gocui.View) tasks.LinesToRead {
_, height := v.Size()
_, oy := v.Origin()
linesForFirstRefresh := height + oy + 10
// We want to read as many lines initially as necessary to let the
// scrollbar go to its minimum height, so that the scrollbar thumb doesn't
// change size as you scroll down.
minScrollbarHeight := 2
linesToReadForAccurateScrollbar := height*(height-1)/minScrollbarHeight + oy
// However, cap it at some arbitrary max limit, so that we don't get
// performance problems for huge monitors or tiny font sizes
if linesToReadForAccurateScrollbar > 5000 {
linesToReadForAccurateScrollbar = 5000
}
return tasks.LinesToRead{
Total: linesToReadForAccurateScrollbar,
InitialRefreshAfter: linesForFirstRefresh,
}
}
func (gui *Gui) cleanString(s string) string {
output := string(bom.Clean([]byte(s)))
return utils.NormalizeLinefeeds(output)
}
2021-04-11 02:05:19 +02:00
func (gui *Gui) setViewContent(v *gocui.View, s string) {
2022-01-15 03:04:00 +02:00
v.SetContent(gui.cleanString(s))
2021-04-11 02:05:19 +02:00
}
2019-02-25 13:11:35 +02:00
func (gui *Gui) currentViewName() string {
currentView := gui.g.CurrentView()
2020-05-16 04:35:19 +02:00
if currentView == nil {
return ""
}
2018-08-14 11:05:26 +02:00
return currentView.Name()
}
2018-09-05 11:07:46 +02:00
func (gui *Gui) onViewTabClick(windowName string, tabIndex int) error {
tabs := gui.viewTabMap()[windowName]
if len(tabs) == 0 {
return nil
}
2020-08-17 13:58:30 +02:00
viewName := tabs[tabIndex].ViewName
context, ok := gui.helpers.View.ContextForView(viewName)
if !ok {
return nil
}
2020-08-19 11:31:58 +02:00
return gui.c.PushContext(context)
2020-08-19 11:31:58 +02:00
}
func (gui *Gui) handleNextTab() error {
view := getTabbedView(gui)
if view == nil {
return nil
}
for _, context := range gui.State.Contexts.Flatten() {
if context.GetViewName() == view.Name() {
return gui.onViewTabClick(
context.GetWindowName(),
utils.ModuloWithWrap(view.TabIndex+1, len(view.Tabs)),
)
}
}
return nil
2020-08-19 11:31:58 +02:00
}
func (gui *Gui) handlePrevTab() error {
view := getTabbedView(gui)
if view == nil {
return nil
}
for _, context := range gui.State.Contexts.Flatten() {
if context.GetViewName() == view.Name() {
return gui.onViewTabClick(
context.GetWindowName(),
utils.ModuloWithWrap(view.TabIndex-1, len(view.Tabs)),
)
}
}
return nil
}
2021-06-06 12:41:55 +02:00
func getTabbedView(gui *Gui) *gocui.View {
2021-06-15 19:58:43 +02:00
// It safe assumption that only static contexts have tabs
context := gui.c.CurrentStaticContext()
2021-06-15 19:58:43 +02:00
view, _ := gui.g.View(context.GetViewName())
return view
2021-06-06 12:41:55 +02:00
}
func (gui *Gui) render() {
gui.c.OnUIThread(func() error { return nil })
}
// postRefreshUpdate is to be called on a context after the state that it depends on has been refreshed
// if the context's view is set to another context we do nothing.
// if the context's view is the current view we trigger a focus; re-selecting the current item.
func (gui *Gui) postRefreshUpdate(c types.Context) error {
t := time.Now()
defer func() {
gui.Log.Infof("postRefreshUpdate for %s took %s", c.GetKey(), time.Since(t))
}()
if err := c.HandleRender(); err != nil {
return err
}
if gui.currentViewName() == c.GetViewName() {
if err := c.HandleFocus(types.OnFocusOpts{}); err != nil {
return err
}
}
return nil
}