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

soft code finding of suggestions

This commit is contained in:
Jesse Duffield
2020-11-28 20:01:45 +11:00
parent be404068ff
commit f31fbc10f6
5 changed files with 53 additions and 40 deletions

View File

@ -7,6 +7,8 @@ import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
@ -209,7 +211,7 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions)
func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
return gui.prompt(promptOpts{ return gui.prompt(promptOpts{
title: gui.Tr.BranchName + ":", title: gui.Tr.BranchName + ":",
showSuggestions: true, findSuggestionsFunc: gui.findBranchNameSuggestions,
handleConfirm: func(response string) error { handleConfirm: func(response string) error {
return gui.handleCheckoutRef(response, handleCheckoutRefOptions{ return gui.handleCheckoutRef(response, handleCheckoutRefOptions{
onRefNotFound: func(ref string) error { onRefNotFound: func(ref string) error {
@ -517,3 +519,29 @@ func (gui *Gui) handleNewBranchOffCurrentItem() error {
}, },
}) })
} }
func (gui *Gui) getBranchNames() []string {
result := make([]string, len(gui.State.Branches))
for i, branch := range gui.State.Branches {
result[i] = branch.Name
}
return result
}
func (gui *Gui) findBranchNameSuggestions(input string) []*types.Suggestion {
branchNames := gui.getBranchNames()
matchingBranchNames := utils.FuzzySearch(input, branchNames)
suggestions := make([]*types.Suggestion, len(matchingBranchNames))
for i, branchName := range matchingBranchNames {
suggestions[i] = &types.Suggestion{
Value: branchName,
Label: utils.ColoredString(branchName, presentation.GetBranchColor(branchName)),
}
}
return suggestions
}

View File

@ -29,7 +29,7 @@ type createPopupPanelOpts struct {
// when handlersManageFocus is true, do not return from the confirmation context automatically. It's expected that the handlers will manage focus, whether that means switching to another context, or manually returning the context. // when handlersManageFocus is true, do not return from the confirmation context automatically. It's expected that the handlers will manage focus, whether that means switching to another context, or manually returning the context.
handlersManageFocus bool handlersManageFocus bool
showSuggestions bool findSuggestionsFunc func(string) []*types.Suggestion
} }
type askOpts struct { type askOpts struct {
@ -38,14 +38,14 @@ type askOpts struct {
handleConfirm func() error handleConfirm func() error
handleClose func() error handleClose func() error
handlersManageFocus bool handlersManageFocus bool
showSuggestions bool findSuggestionsFunc func(string) []*types.Suggestion
} }
type promptOpts struct { type promptOpts struct {
title string title string
initialContent string initialContent string
handleConfirm func(string) error handleConfirm func(string) error
showSuggestions bool findSuggestionsFunc func(string) []*types.Suggestion
} }
func (gui *Gui) ask(opts askOpts) error { func (gui *Gui) ask(opts askOpts) error {
@ -55,7 +55,7 @@ func (gui *Gui) ask(opts askOpts) error {
handleConfirm: opts.handleConfirm, handleConfirm: opts.handleConfirm,
handleClose: opts.handleClose, handleClose: opts.handleClose,
handlersManageFocus: opts.handlersManageFocus, handlersManageFocus: opts.handlersManageFocus,
showSuggestions: opts.showSuggestions, findSuggestionsFunc: opts.findSuggestionsFunc,
}) })
} }
@ -65,7 +65,7 @@ func (gui *Gui) prompt(opts promptOpts) error {
prompt: opts.initialContent, prompt: opts.initialContent,
editable: true, editable: true,
handleConfirmPrompt: opts.handleConfirm, handleConfirmPrompt: opts.handleConfirm,
showSuggestions: opts.showSuggestions, findSuggestionsFunc: opts.findSuggestionsFunc,
}) })
} }
@ -181,7 +181,7 @@ func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, i
height/2 + panelHeight/2 height/2 + panelHeight/2
} }
func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, showSuggestions bool) (*gocui.View, error) { func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, findSuggestionsFunc func(string) []*types.Suggestion) (*gocui.View, error) {
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt) x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt)
confirmationView, err := gui.g.SetView("confirmation", x0, y0, x1, y1, 0) confirmationView, err := gui.g.SetView("confirmation", x0, y0, x1, y1, 0)
if err != nil { if err != nil {
@ -197,7 +197,8 @@ func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, s
confirmationView.FgColor = theme.GocuiDefaultTextColor confirmationView.FgColor = theme.GocuiDefaultTextColor
} }
if showSuggestions { gui.findSuggestions = findSuggestionsFunc
if findSuggestionsFunc != nil {
suggestionsViewHeight := 11 suggestionsViewHeight := 11
suggestionsView, err := gui.g.SetView("suggestions", x0, y1, x1, y1+suggestionsViewHeight, 0) suggestionsView, err := gui.g.SetView("suggestions", x0, y1, x1, y1+suggestionsViewHeight, 0)
if err != nil { if err != nil {
@ -223,7 +224,7 @@ func (gui *Gui) createPopupPanel(opts createPopupPanelOpts) error {
if view, _ := g.View("confirmation"); view != nil { if view, _ := g.View("confirmation"); view != nil {
gui.deleteConfirmationView() gui.deleteConfirmationView()
} }
confirmationView, err := gui.prepareConfirmationPanel(opts.title, opts.prompt, opts.hasLoader, opts.showSuggestions) confirmationView, err := gui.prepareConfirmationPanel(opts.title, opts.prompt, opts.hasLoader, opts.findSuggestionsFunc)
if err != nil { if err != nil {
return err return err
} }

View File

@ -2,9 +2,6 @@ package gui
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
) )
// we've just copy+pasted the editor from gocui to here so that we can also re- // we've just copy+pasted the editor from gocui to here so that we can also re-
@ -77,28 +74,9 @@ func (gui *Gui) editorWithCallback(v *gocui.View, key gocui.Key, ch rune, mod go
v.EditWrite(ch) v.EditWrite(ch)
} }
if gui.findSuggestions != nil {
input := v.Buffer() input := v.Buffer()
branchNames := gui.getBranchNames() suggestions := gui.findSuggestions(input)
matchingBranchNames := utils.FuzzySearch(input, branchNames)
suggestions := make([]*types.Suggestion, len(matchingBranchNames))
for i, branchName := range matchingBranchNames {
suggestions[i] = &types.Suggestion{
Value: branchName,
Label: utils.ColoredString(branchName, presentation.GetBranchColor(branchName)),
}
}
gui.setSuggestions(suggestions) gui.setSuggestions(suggestions)
}
func (gui *Gui) getBranchNames() []string {
result := make([]string, len(gui.State.Branches))
for i, branch := range gui.State.Branches {
result[i] = branch.Name
} }
return result
} }

View File

@ -113,6 +113,10 @@ type Gui struct {
StartTime time.Time StartTime time.Time
Mutexes guiStateMutexes Mutexes guiStateMutexes
// findSuggestions will take a string that the user has typed into a prompt
// and return a slice of suggestions which match that string.
findSuggestions func(string) []*types.Suggestion
} }
type RecordedEvent struct { type RecordedEvent struct {

View File

@ -1,6 +1,8 @@
package gui package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types" import (
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
func (gui *Gui) getSelectedSuggestionValue() string { func (gui *Gui) getSelectedSuggestionValue() string {
selectedSuggestion := gui.getSelectedSuggestion() selectedSuggestion := gui.getSelectedSuggestion()