1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-03-21 21:47:32 +02:00

begin refactor of menu panel

This commit is contained in:
Jesse Duffield 2020-02-14 22:07:56 +11:00
parent 71e018a3dd
commit 814a0ea36f
4 changed files with 134 additions and 70 deletions

View File

@ -0,0 +1,42 @@
package gui
import (
"github.com/jesseduffield/gocui"
)
func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error {
file, err := gui.getSelectedFile(g)
if err != nil {
if err != gui.Errors.ErrNoFiles {
return err
}
return nil
}
menuItems := []*menuItem{
{
displayStrings: []string{gui.Tr.SLocalize("discardAllChanges")},
onPress: func() error {
if err := gui.GitCommand.DiscardAllFileChanges(file); err != nil {
return err
}
return gui.refreshFiles()
},
},
}
if file.HasStagedChanges && file.HasUnstagedChanges {
menuItems = append(menuItems, &menuItem{
displayStrings: []string{gui.Tr.SLocalize("discardUnstagedChanges")},
onPress: func() error {
if err := gui.GitCommand.DiscardUnstagedFileChanges(file); err != nil {
return err
}
return gui.refreshFiles()
},
})
}
return gui.createMenuNew(file.Name, menuItems, createMenuOptions{showCancel: true})
}

View File

@ -540,67 +540,6 @@ func (gui *Gui) anyFilesWithMergeConflicts() bool {
return false
}
type discardOption struct {
handler func(fileName *commands.File) error
description string
}
// GetDisplayStrings is a function.
func (r *discardOption) GetDisplayStrings(isFocused bool) []string {
return []string{r.description}
}
func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error {
file, err := gui.getSelectedFile(g)
if err != nil {
if err != gui.Errors.ErrNoFiles {
return err
}
return nil
}
options := []*discardOption{
{
description: gui.Tr.SLocalize("discardAllChanges"),
handler: func(file *commands.File) error {
return gui.GitCommand.DiscardAllFileChanges(file)
},
},
{
description: gui.Tr.SLocalize("cancel"),
handler: func(file *commands.File) error {
return nil
},
},
}
if file.HasStagedChanges && file.HasUnstagedChanges {
discardUnstagedChanges := &discardOption{
description: gui.Tr.SLocalize("discardUnstagedChanges"),
handler: func(file *commands.File) error {
return gui.GitCommand.DiscardUnstagedFileChanges(file)
},
}
options = append(options[:1], append([]*discardOption{discardUnstagedChanges}, options[1:]...)...)
}
handleMenuPress := func(index int) error {
file, err := gui.getSelectedFile(g)
if err != nil {
return err
}
if err := options[index].handler(file); err != nil {
return err
}
return gui.refreshFiles()
}
return gui.createMenu(file.Name, options, len(options), handleMenuPress)
}
func (gui *Gui) handleCustomCommand(g *gocui.Gui, v *gocui.View) error {
return gui.createPromptPanel(g, v, gui.Tr.SLocalize("CustomCommand"), "", func(g *gocui.Gui, v *gocui.View) error {
command := gui.trimmedContent(v)

View File

@ -8,6 +8,11 @@ import (
"github.com/jesseduffield/lazygit/pkg/utils"
)
type menuItem struct {
displayStrings []string
onPress func() error
}
// list panel functions
func (gui *Gui) handleMenuSelect(g *gocui.Gui, v *gocui.View) error {
@ -38,6 +43,75 @@ func (gui *Gui) handleMenuClose(g *gocui.Gui, v *gocui.View) error {
return gui.returnFocus(g, v)
}
type createMenuOptions struct {
showCancel bool
}
func (gui *Gui) createMenuNew(title string, items []*menuItem, createMenuOptions createMenuOptions) error {
if createMenuOptions.showCancel {
// this is mutative but I'm okay with that for now
items = append(items, &menuItem{
displayStrings: []string{gui.Tr.SLocalize("cancel")},
onPress: func() error {
return nil
},
})
}
gui.State.MenuItemCount = len(items)
stringArrays := make([][]string, len(items))
for i, item := range items {
stringArrays[i] = item.displayStrings
}
list := utils.RenderDisplayStrings(stringArrays)
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(gui.g, false, list)
menuView, _ := gui.g.SetView("menu", x0, y0, x1, y1, 0)
menuView.Title = title
menuView.FgColor = theme.GocuiDefaultTextColor
menuView.Clear()
fmt.Fprint(menuView, list)
gui.State.Panels.Menu.SelectedLine = 0
wrappedHandlePress := func(g *gocui.Gui, v *gocui.View) error {
selectedLine := gui.State.Panels.Menu.SelectedLine
if err := items[selectedLine].onPress(); err != nil {
return err
}
if _, err := gui.g.View("menu"); err == nil {
if _, err := gui.g.SetViewOnBottom("menu"); err != nil {
return err
}
}
return gui.returnFocus(gui.g, menuView)
}
gui.State.Panels.Menu.OnPress = wrappedHandlePress
for _, key := range []gocui.Key{gocui.KeySpace, gocui.KeyEnter, 'y'} {
_ = gui.g.DeleteKeybinding("menu", key, gocui.ModNone)
if err := gui.g.SetKeybinding("menu", nil, key, gocui.ModNone, wrappedHandlePress); err != nil {
return err
}
}
gui.g.Update(func(g *gocui.Gui) error {
if _, err := gui.g.View("menu"); err == nil {
if _, err := g.SetViewOnTop("menu"); err != nil {
return err
}
}
currentView := gui.g.CurrentView()
return gui.switchFocus(gui.g, currentView, menuView)
})
return nil
}
func (gui *Gui) createMenu(title string, items interface{}, itemCount int, handlePress func(int) error) error {
isFocused := gui.g.CurrentView().Name() == "menu"
gui.State.MenuItemCount = itemCount

View File

@ -151,14 +151,14 @@ func renderDisplayableList(items []Displayable, isFocused bool) (string, error)
stringArrays := getDisplayStringArrays(items, isFocused)
if !displayArraysAligned(stringArrays) {
return "", errors.New("Each item must return the same number of strings to display")
}
return RenderDisplayStrings(stringArrays), nil
}
padWidths := getPadWidths(stringArrays)
paddedDisplayStrings := getPaddedDisplayStrings(stringArrays, padWidths)
func RenderDisplayStrings(displayStringsArr [][]string) string {
padWidths := getPadWidths(displayStringsArr)
paddedDisplayStrings := getPaddedDisplayStrings(displayStringsArr, padWidths)
return strings.Join(paddedDisplayStrings, "\n"), nil
return strings.Join(paddedDisplayStrings, "\n")
}
// Decolorise strips a string of color
@ -168,10 +168,13 @@ func Decolorise(str string) string {
}
func getPadWidths(stringArrays [][]string) []int {
if len(stringArrays[0]) <= 1 {
return []int{}
maxWidth := 0
for _, stringArray := range stringArrays {
if len(stringArray) > maxWidth {
maxWidth = len(stringArray)
}
}
padWidths := make([]int, len(stringArrays[0])-1)
padWidths := make([]int, maxWidth-1)
for i := range padWidths {
for _, strings := range stringArrays {
uncoloredString := Decolorise(strings[i])
@ -190,8 +193,14 @@ func getPaddedDisplayStrings(stringArrays [][]string, padWidths []int) []string
continue
}
for j, padWidth := range padWidths {
if len(stringArray)-1 < j {
continue
}
paddedDisplayStrings[i] += WithPadding(stringArray[j], padWidth) + " "
}
if len(stringArray)-1 < len(padWidths) {
continue
}
paddedDisplayStrings[i] += stringArray[len(padWidths)]
}
return paddedDisplayStrings