mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-21 23:01:03 +00:00
allow searching in any list view
This commit is contained in:
parent
b6b5373999
commit
702361559f
8 changed files with 52 additions and 24 deletions
|
|
@ -52,8 +52,8 @@ func (gui *Gui) getMessageHeight(wrap bool, message string, width int) int {
|
|||
return lineCount
|
||||
}
|
||||
|
||||
func (gui *Gui) getConfirmationPanelDimensions(g *gocui.Gui, wrap bool, prompt string) (int, int, int, int) {
|
||||
width, height := g.Size()
|
||||
func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, int, int, int) {
|
||||
width, height := gui.g.Size()
|
||||
panelWidth := width / 2
|
||||
panelHeight := gui.getMessageHeight(wrap, prompt, panelWidth)
|
||||
return width/2 - panelWidth/2,
|
||||
|
|
@ -73,7 +73,7 @@ func (gui *Gui) createPromptPanel(title string, handleConfirm func(*gocui.Gui, *
|
|||
}
|
||||
|
||||
func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool) error {
|
||||
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(gui.g, true, prompt)
|
||||
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt)
|
||||
confirmationView := gui.Views.Confirmation
|
||||
_, err := gui.g.SetView("confirmation", x0, y0, x1, y1, 0)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ type guiState struct {
|
|||
|
||||
type searchingState struct {
|
||||
view *gocui.View
|
||||
panel ISideListPanel
|
||||
isSearching bool
|
||||
searchString string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -450,13 +450,6 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||
Handler: gui.handleImagesBulkCommand,
|
||||
Description: gui.Tr.ViewBulkCommands,
|
||||
},
|
||||
{
|
||||
ViewName: "images",
|
||||
Key: '/',
|
||||
Modifier: gocui.ModNone,
|
||||
Handler: wrappedHandler(gui.handleOpenImageSearch),
|
||||
Description: gui.Tr.FilterList,
|
||||
},
|
||||
{
|
||||
ViewName: "volumes",
|
||||
Key: '[',
|
||||
|
|
@ -620,6 +613,17 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||
})
|
||||
}
|
||||
|
||||
for _, panel := range gui.allListPanels() {
|
||||
bindings = append(bindings,
|
||||
&Binding{
|
||||
ViewName: panel.View().Name(),
|
||||
Key: '/',
|
||||
Modifier: gocui.ModNone,
|
||||
Handler: wrappedHandler(gui.handleOpenSearch),
|
||||
Description: gui.Tr.LcFilter,
|
||||
})
|
||||
}
|
||||
|
||||
return bindings
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ type SideListPanel[T comparable] struct {
|
|||
onClick func(T) error
|
||||
|
||||
getDisplayStrings func(T) []string
|
||||
|
||||
// function to be called after re-rendering list. Can be nil
|
||||
onRerender func() error
|
||||
}
|
||||
|
||||
type ISideListPanel interface {
|
||||
|
|
@ -80,6 +83,7 @@ type ISideListPanel interface {
|
|||
HandleSelect() error
|
||||
View() *gocui.View
|
||||
Refocus()
|
||||
RerenderList() error
|
||||
}
|
||||
|
||||
var _ ISideListPanel = &SideListPanel[int]{}
|
||||
|
|
@ -275,6 +279,12 @@ func (self *SideListPanel[T]) RerenderList() error {
|
|||
}
|
||||
fmt.Fprint(self.view, renderedTable)
|
||||
|
||||
if self.onRerender != nil {
|
||||
if err := self.onRerender(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if self.view == self.gui.CurrentView() {
|
||||
return self.HandleSelect()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ func (gui *Gui) getMenuPanel() *SideListPanel[*MenuItem] {
|
|||
getDisplayStrings: func(menuItem *MenuItem) []string {
|
||||
return menuItem.LabelColumns
|
||||
},
|
||||
onRerender: func() error {
|
||||
return gui.resizePopupPanel(gui.Views.Menu)
|
||||
},
|
||||
|
||||
// the menu panel doesn't actually have any contexts to display on the main view
|
||||
// so what follows are all dummy values
|
||||
|
|
|
|||
|
|
@ -4,13 +4,15 @@ import (
|
|||
"github.com/jesseduffield/gocui"
|
||||
)
|
||||
|
||||
func (gui *Gui) handleOpenImageSearch() error {
|
||||
return gui.handleOpenSearch(gui.Views.Images)
|
||||
}
|
||||
func (gui *Gui) handleOpenSearch() error {
|
||||
panel, ok := gui.currentListPanel()
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleOpenSearch(view *gocui.View) error {
|
||||
gui.State.Searching.isSearching = true
|
||||
gui.State.Searching.view = view
|
||||
gui.State.Searching.view = panel.View()
|
||||
gui.State.Searching.panel = panel
|
||||
|
||||
return gui.switchFocus(gui.Views.Search)
|
||||
}
|
||||
|
|
@ -18,7 +20,7 @@ func (gui *Gui) handleOpenSearch(view *gocui.View) error {
|
|||
func (gui *Gui) onNewSearchString(value string) error {
|
||||
// need to refresh the right list panel.
|
||||
gui.State.Searching.searchString = value
|
||||
return gui.Panels.Images.RerenderList()
|
||||
return gui.State.Searching.panel.RerenderList()
|
||||
}
|
||||
|
||||
func (gui *Gui) wrapEditor(f func(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) bool) func(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) bool {
|
||||
|
|
@ -44,9 +46,11 @@ func (gui *Gui) clearSearch() error {
|
|||
gui.State.Searching.searchString = ""
|
||||
gui.State.Searching.isSearching = false
|
||||
gui.State.Searching.view = nil
|
||||
panel := gui.State.Searching.panel
|
||||
gui.State.Searching.panel = nil
|
||||
gui.Views.Search.ClearTextArea()
|
||||
|
||||
return gui.Panels.Images.RerenderList()
|
||||
return panel.RerenderList()
|
||||
}
|
||||
|
||||
// returns to the list view with the filter still applied
|
||||
|
|
|
|||
|
|
@ -133,9 +133,12 @@ func (gui *Gui) returnFocus() error {
|
|||
// Not to be called directly. Use `switchFocus` instead
|
||||
func (gui *Gui) pushView(name string) {
|
||||
// No matter what view we're pushing, we first remove all popup panels from the stack
|
||||
gui.State.ViewStack = lo.Filter(gui.State.ViewStack, func(viewName string, _ int) bool {
|
||||
return !gui.isPopupPanel(viewName)
|
||||
})
|
||||
// (unless it's the search view because we may be searching the menu panel)
|
||||
if name != "search" {
|
||||
gui.State.ViewStack = lo.Filter(gui.State.ViewStack, func(viewName string, _ int) bool {
|
||||
return !gui.isPopupPanel(viewName)
|
||||
})
|
||||
}
|
||||
|
||||
// If we're pushing a side panel, we remove all other panels
|
||||
if lo.Contains(gui.sideViewNames(), name) {
|
||||
|
|
@ -318,21 +321,21 @@ func (gui *Gui) currentViewName() string {
|
|||
func (gui *Gui) resizeCurrentPopupPanel(g *gocui.Gui) error {
|
||||
v := g.CurrentView()
|
||||
if gui.isPopupPanel(v.Name()) {
|
||||
return gui.resizePopupPanel(g, v)
|
||||
return gui.resizePopupPanel(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) resizePopupPanel(g *gocui.Gui, v *gocui.View) error {
|
||||
func (gui *Gui) resizePopupPanel(v *gocui.View) error {
|
||||
// If the confirmation panel is already displayed, just resize the width,
|
||||
// otherwise continue
|
||||
content := v.Buffer()
|
||||
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, v.Wrap, content)
|
||||
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(v.Wrap, content)
|
||||
vx0, vy0, vx1, vy1 := v.Dimensions()
|
||||
if vx0 == x0 && vy0 == y0 && vx1 == x1 && vy1 == y1 {
|
||||
return nil
|
||||
}
|
||||
_, err := g.SetView(v.Name(), x0, y0, x1, y1, 0)
|
||||
_, err := gui.g.SetView(v.Name(), x0, y0, x1, y1, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -482,6 +485,7 @@ func (gui *Gui) currentSidePanel() (ISideListPanel, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
// returns the current list panel. If no list panel is focused, returns false.
|
||||
func (gui *Gui) currentListPanel() (ISideListPanel, bool) {
|
||||
viewName := gui.currentViewName()
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ type TranslationSet struct {
|
|||
Confirm string
|
||||
Return string
|
||||
FocusMain string
|
||||
LcFilter string
|
||||
StopContainer string
|
||||
RestartingStatus string
|
||||
StartingStatus string
|
||||
|
|
@ -148,6 +149,7 @@ func englishSet() TranslationSet {
|
|||
|
||||
Return: "return",
|
||||
FocusMain: "focus main panel",
|
||||
LcFilter: "filter list",
|
||||
Navigate: "navigate",
|
||||
Execute: "execute",
|
||||
Close: "close",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue