From a8163ad4ebd8580bed05ad1e261b1a0f0c6fd878 Mon Sep 17 00:00:00 2001 From: Graham Clark Date: Thu, 19 Aug 2021 23:26:30 -0400 Subject: [PATCH] A cleaner command-line The minibuffer can be opened with ":". Some commands take arguments, and if it's possible to present a selection of arguments that match a prefix, the minibuffer displays them, vertically, above the partially typed command. Prior to this commit, if the number of selections was large, the list would exceed the space in the viewport and be cut off uncleanly at the top of the terminal. This also had the unwanted side-effect of having the minibuffer's list widget compute *all* selections only to throw away (by trimming the rendered canvas of) the selections that didn't fit on the screen. This change tracks the number of currently available selections and stores that value in the widget itself. At the same time, it adjusts the height argument, in units, of the overlay used to contain the widget structure of the minibuffer, including the list. When the minibuffer is rendered, it's in a box context (columns and rows both specified). The list of selections will ultimately be rendered in a box context, but with a small gowid change too, the list's vertical space will be determined by the minimum of (a) the computed number of selections and (b) the rows left in the viewport. So all selections will be shows if they fit, and if there are too many, the list itself will handle the cutoff. This means the cmdline frame will render correctly too. --- go.mod | 2 +- go.sum | 8 ++------ ui/ui.go | 2 +- widgets/minibuffer/minibuffer.go | 19 +++++++++++++------ 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 74f24e8..69189ed 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/blang/semver v3.5.1+incompatible github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/gcla/deep v1.0.2 - github.com/gcla/gowid v1.2.1-0.20210817042717-048ae42d28f3 + github.com/gcla/gowid v1.2.1-0.20210820032031-cfd3f37ca741 github.com/gcla/tail v1.0.1-0.20190505190527-650e90873359 github.com/gdamore/tcell v1.3.1-0.20200115030318-bff4943f9a29 github.com/go-test/deep v1.0.2 // indirect diff --git a/go.sum b/go.sum index 64dd834..cbd9cf6 100644 --- a/go.sum +++ b/go.sum @@ -57,12 +57,8 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gcla/deep v1.0.2 h1:qBOx6eepcOSRYnHJ+f2ih4hP4Vca1YnLtXxp73n5KWI= github.com/gcla/deep v1.0.2/go.mod h1:evE9pbpSGhItmFoBIk8hPOIC/keKTGYhFl6Le1Av+GE= -github.com/gcla/gowid v1.2.1-0.20210730201604-e21cc1dff36b h1:mIGVx3Kq19ln5E25pwQtxCNmKi6rbrUhOgAtA1Vx+BE= -github.com/gcla/gowid v1.2.1-0.20210730201604-e21cc1dff36b/go.mod h1:jQwZ6fAAnaylA+MkfgXLzjG0mTMStYixffw2jY0qG4k= -github.com/gcla/gowid v1.2.1-0.20210806031049-f60cd69d4bd7 h1:4v2rkKvFsirRgM3C2UMPoxWxwM7Q9hlL/P31oB0YfIQ= -github.com/gcla/gowid v1.2.1-0.20210806031049-f60cd69d4bd7/go.mod h1:jQwZ6fAAnaylA+MkfgXLzjG0mTMStYixffw2jY0qG4k= -github.com/gcla/gowid v1.2.1-0.20210817042717-048ae42d28f3 h1:dWk9qzXXFwkWVP3UM+kJQ52FztZqof5cWx3Af6DG4t8= -github.com/gcla/gowid v1.2.1-0.20210817042717-048ae42d28f3/go.mod h1:jQwZ6fAAnaylA+MkfgXLzjG0mTMStYixffw2jY0qG4k= +github.com/gcla/gowid v1.2.1-0.20210820032031-cfd3f37ca741 h1:eeOU9lh9s7imJI/DMUxEwJS6vma8dC+d9ZKcxn8Nos4= +github.com/gcla/gowid v1.2.1-0.20210820032031-cfd3f37ca741/go.mod h1:jQwZ6fAAnaylA+MkfgXLzjG0mTMStYixffw2jY0qG4k= github.com/gcla/tail v1.0.1-0.20190505190527-650e90873359 h1:3xEhacR7pIJV8daurdBygptxhzTJeYFqJp1V6SDl+pE= github.com/gcla/tail v1.0.1-0.20190505190527-650e90873359/go.mod h1:Wn+pZpM98JHSOYkPDtmdvlqmc0OzQGHWOsHB2d28WtQ= github.com/gcla/tcell v1.1.2-0.20200927150251-decc2045f510 h1:TlEZ0DHOvn0P79nHtkfemw7XFn2h8Lacd6AZpXrPU/o= diff --git a/ui/ui.go b/ui/ui.go index 4483b63..393ae55 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -1441,7 +1441,7 @@ func lastLineMode(app gowid.IApp) { MiniBuffer.Register("unmap", unmapCommand{w: keyMapper}) MiniBuffer.Register("help", helpCommand{}) - minibuffer.Open(MiniBuffer, mbView, ratio(1.0), fixed, app) + minibuffer.Open(MiniBuffer, mbView, ratio(1.0), app) } //====================================================================== diff --git a/widgets/minibuffer/minibuffer.go b/widgets/minibuffer/minibuffer.go index 4166352..56fe335 100644 --- a/widgets/minibuffer/minibuffer.go +++ b/widgets/minibuffer/minibuffer.go @@ -38,6 +38,7 @@ type Widget struct { selections *list.Widget ed *edit.Widget pl *pile.Widget + ov *overlay.Widget showAll bool // true if the user hits tab with nothing in the minibuffer. I don't // want to display all completions if the buffer is empty because it fills the screen // and looks ugly. So this is a hack to allow the completions to be displayed @@ -146,11 +147,11 @@ func New() *Widget { []gowid.IContainerWidget{ &gowid.ContainerWidget{ IWidget: top, - D: gowid.RenderFlow{}, + D: gowid.RenderWithWeight{W: 1}, }, &gowid.ContainerWidget{ IWidget: bottom, - D: gowid.RenderFlow{}, + D: gowid.RenderWithUnits{U: 1}, }, }, pile.Options{ @@ -175,6 +176,7 @@ func New() *Widget { BackgroundStyle: gowid.MakePaletteRef("cmdline"), ButtonStyle: gowid.MakePaletteRef("cmdline-button"), BorderStyle: gowid.MakePaletteRef("cmdline-border"), + Modal: true, }, ), compl: top, @@ -433,10 +435,13 @@ func (w *Widget) updateCompletions(app gowid.IApp) { } + w.ov.SetHeight(gowid.RenderWithUnits{U: 3 + len(complWidgets)}, app) + walker := list.NewSimpleListWalker(complWidgets) if len(complWidgets) > 0 { walker.SetFocus(walker.Last(), app) selections := list.New(walker) + selections.GoToBottom(app) sl2 := keepselected.New(selections) w.compl.SetSubWidget(sl2, app) w.selections = selections @@ -447,9 +452,11 @@ func (w *Widget) updateCompletions(app gowid.IApp) { } } -func Open(w dialog.IOpenExt, container gowid.ISettableComposite, width gowid.IWidgetDimension, height gowid.IWidgetDimension, app gowid.IApp) { - ov := overlay.New(w, container.SubWidget(), - gowid.VAlignBottom{}, height, // Intended to mean use as much vertical space as you need +// w is minibuffer +// container is main view +func Open(w *Widget, container gowid.ISettableComposite, width gowid.IWidgetDimension, app gowid.IApp) { + w.ov = overlay.New(w, container.SubWidget(), + gowid.VAlignBottom{}, gowid.RenderWithUnits{U: 3}, // Intended to mean use as much vertical space as you need gowid.HAlignLeft{Margin: 5, MarginRight: 5}, width) if _, ok := width.(gowid.IRenderFixed); ok { @@ -459,7 +466,7 @@ func Open(w dialog.IOpenExt, container gowid.ISettableComposite, width gowid.IWi } w.SetSavedSubWidget(container.SubWidget(), app) w.SetSavedContainer(container, app) - container.SetSubWidget(ov, app) + container.SetSubWidget(w.ov, app) w.SetOpen(true, app) }