1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-17 00:18:05 +02:00

better handling of cursor and origin positionings

This commit is contained in:
Jesse Duffield
2018-09-10 20:17:39 +10:00
parent 7f4371ad71
commit 52b132fe01
4 changed files with 60 additions and 22 deletions

View File

@ -275,22 +275,23 @@ func (gui *Gui) updateHasMergeConflictStatus() error {
return nil return nil
} }
func (gui *Gui) renderFile(file commands.File, filesView *gocui.View) { func (gui *Gui) renderFile(file commands.File) string {
// potentially inefficient to be instantiating these color // potentially inefficient to be instantiating these color
// objects with each render // objects with each render
red := color.New(color.FgRed) red := color.New(color.FgRed)
green := color.New(color.FgGreen) green := color.New(color.FgGreen)
if !file.Tracked && !file.HasStagedChanges { if !file.Tracked && !file.HasStagedChanges {
red.Fprintln(filesView, file.DisplayString) return red.Sprint(file.DisplayString)
return
} }
green.Fprint(filesView, file.DisplayString[0:1])
red.Fprint(filesView, file.DisplayString[1:3]) output := green.Sprint(file.DisplayString[0:1])
output += red.Sprint(file.DisplayString[1:3])
if file.HasUnstagedChanges { if file.HasUnstagedChanges {
red.Fprintln(filesView, file.Name) output += red.Sprint(file.Name)
} else { } else {
green.Fprintln(filesView, file.Name) output += green.Sprint(file.Name)
} }
return output
} }
func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) { func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) {
@ -319,8 +320,14 @@ func (gui *Gui) refreshFiles(g *gocui.Gui) error {
} }
gui.refreshStateFiles() gui.refreshStateFiles()
filesView.Clear() filesView.Clear()
for _, file := range gui.State.Files { for i, file := range gui.State.Files {
gui.renderFile(file, filesView) str := gui.renderFile(file)
if i < len(gui.State.Files)-1 {
str += "\n"
}
if _, err := filesView.Write([]byte(str)); err != nil {
return err
}
} }
gui.correctCursor(filesView) gui.correctCursor(filesView)
if filesView == g.CurrentView() { if filesView == g.CurrentView() {

View File

@ -8,6 +8,12 @@ import (
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
// I need to store the handler function in state and it will take an interface and do something with it
// I need to have another function describing how to display one of the structs
// perhaps this calls for an interface where the struct is Binding and the interface has the methods Display and Execute
// but this means that for the one struct I can only have one possible display/execute function, but I want to use whatever I want.
// Would I ever need to use different handlers for different things? Maybe I should assume not given that I can cross that bridge when I come to it
func (gui *Gui) handleMenuPress(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleMenuPress(g *gocui.Gui, v *gocui.View) error {
lineNumber := gui.getItemPosition(v) lineNumber := gui.getItemPosition(v)
if gui.State.Keys[lineNumber].Key == nil { if gui.State.Keys[lineNumber].Key == nil {
@ -106,11 +112,11 @@ func (gui *Gui) handleMenu(g *gocui.Gui, v *gocui.View) error {
content := append(contentPanel, contentGlobal...) content := append(contentPanel, contentGlobal...)
gui.State.Keys = append(bindingsPanel, bindingsGlobal...) gui.State.Keys = append(bindingsPanel, bindingsGlobal...)
// append newline at the end so the last line would be selectable // append newline at the end so the last line would be selectable
contentJoined := strings.Join(content, "\n") + "\n" contentJoined := strings.Join(content, "\n")
// y1-1 so there will not be an extra space at the end of panel // y1-1 so there will not be an extra space at the end of panel
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, contentJoined) x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, contentJoined)
menuView, _ := g.SetView("menu", x0, y0, x1, y1-1, 0) menuView, _ := g.SetView("menu", x0, y0, x1, y1, 0)
menuView.Title = strings.Title(gui.Tr.SLocalize("menu")) menuView.Title = strings.Title(gui.Tr.SLocalize("menu"))
menuView.FgColor = gocui.ColorWhite menuView.FgColor = gocui.ColorWhite

View File

@ -160,7 +160,6 @@ func (gui *Gui) getItemPosition(v *gocui.View) int {
func (gui *Gui) cursorUp(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) cursorUp(g *gocui.Gui, v *gocui.View) error {
// swallowing cursor movements in main // swallowing cursor movements in main
// TODO: pull this out
if v == nil || v.Name() == "main" { if v == nil || v.Name() == "main" {
return nil return nil
} }
@ -179,19 +178,28 @@ func (gui *Gui) cursorUp(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) cursorDown(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) cursorDown(g *gocui.Gui, v *gocui.View) error {
// swallowing cursor movements in main // swallowing cursor movements in main
// TODO: pull this out
if v == nil || v.Name() == "main" { if v == nil || v.Name() == "main" {
return nil return nil
} }
cx, cy := v.Cursor() cx, cy := v.Cursor()
ox, oy := v.Origin() ox, oy := v.Origin()
if cy+oy >= len(v.BufferLines())-2 { ly := len(v.BufferLines()) - 1
_, height := v.Size()
maxY := height - 1
// if we are at the end we just return
if cy+oy == ly {
return nil return nil
} }
if err := v.SetCursor(cx, cy+1); err != nil {
if err := v.SetOrigin(ox, oy+1); err != nil { var err error
return err if cy < maxY {
err = v.SetCursor(cx, cy+1)
} else {
err = v.SetOrigin(ox, oy+1)
} }
if err != nil {
return err
} }
gui.newLineFocused(g, v) gui.newLineFocused(g, v)
@ -208,10 +216,19 @@ func (gui *Gui) resetOrigin(v *gocui.View) error {
// if the cursor down past the last item, move it to the last line // if the cursor down past the last item, move it to the last line
func (gui *Gui) correctCursor(v *gocui.View) error { func (gui *Gui) correctCursor(v *gocui.View) error {
cx, cy := v.Cursor() cx, cy := v.Cursor()
_, oy := v.Origin() ox, oy := v.Origin()
lineCount := len(v.BufferLines()) - 2 _, height := v.Size()
if cy >= lineCount-oy { maxY := height - 1
return v.SetCursor(cx, lineCount-oy) ly := len(v.BufferLines()) - 1
if oy+cy <= ly {
return nil
}
newCy := utils.Min(ly, maxY)
if err := v.SetCursor(cx, newCy); err != nil {
return err
}
if err := v.SetOrigin(ox, ly-newCy); err != nil {
return err
} }
return nil return nil
} }

View File

@ -99,3 +99,11 @@ func ResolvePlaceholderString(str string, arguments map[string]string) string {
} }
return str return str
} }
// Min returns the minimum of two integers
func Min(x, y int) int {
if x < y {
return x
}
return y
}