exline: don't draw completions for keybinds

The exline widget works by matching actual keystrokes to a map of
keybinds, and if a match is found sending simulated keystrokes through
aerc. This has the effect of aerc thinking we are actually typing in the
expanded command, and aerc attempts to draw the completions. This
results in even basic navigation having two screen draws:

For example, pressing 'j' to select the next message (:next), draws once
for the initial key event and state change, and again after the
completion debounce timer.

Disable tab completion while aerc is simulating keystrokes. If the
exline still has focus after simulating keystrokes, restore tab
completion.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Koni Marti <koni.marti@gmail.com>
This commit is contained in:
Tim Culverhouse 2022-09-28 13:17:21 -05:00 committed by Robin Jarry
parent 75fc42e270
commit 055c6dc660
2 changed files with 20 additions and 3 deletions

View file

@ -274,6 +274,12 @@ func (aerc *Aerc) simulate(strokes []config.KeyStroke) {
aerc.Event(simulated) aerc.Event(simulated)
} }
aerc.simulating -= 1 aerc.simulating -= 1
// If we are still focused on the exline, turn on tab complete
if exline, ok := aerc.focused.(*ExLine); ok {
exline.TabComplete(func(cmd string) ([]string, string) {
return aerc.complete(cmd), ""
})
}
} }
func (aerc *Aerc) Event(event tcell.Event) bool { func (aerc *Aerc) Event(event tcell.Event) bool {
@ -571,6 +577,15 @@ func (aerc *Aerc) focus(item ui.Interactive) {
func (aerc *Aerc) BeginExCommand(cmd string) { func (aerc *Aerc) BeginExCommand(cmd string) {
previous := aerc.focused previous := aerc.focused
var tabComplete func(string) ([]string, string)
if aerc.simulating != 0 {
// Don't try to draw completions for simulated events
tabComplete = nil
} else {
tabComplete = func(cmd string) ([]string, string) {
return aerc.complete(cmd), ""
}
}
exline := NewExLine(aerc.conf, cmd, func(cmd string) { exline := NewExLine(aerc.conf, cmd, func(cmd string) {
parts, err := shlex.Split(cmd) parts, err := shlex.Split(cmd)
if err != nil { if err != nil {
@ -588,9 +603,7 @@ func (aerc *Aerc) BeginExCommand(cmd string) {
}, func() { }, func() {
aerc.statusbar.Pop() aerc.statusbar.Pop()
aerc.focus(previous) aerc.focus(previous)
}, func(cmd string) ([]string, string) { }, tabComplete, aerc.cmdHistory)
return aerc.complete(cmd), ""
}, aerc.cmdHistory)
aerc.statusbar.Push(exline) aerc.statusbar.Push(exline)
aerc.focus(exline) aerc.focus(exline)
} }

View file

@ -40,6 +40,10 @@ func NewExLine(conf *config.AercConfig, cmd string, commit func(cmd string), fin
return exline return exline
} }
func (x *ExLine) TabComplete(tabComplete func(string) ([]string, string)) {
x.input.TabComplete(tabComplete, x.conf.Ui.CompletionDelay)
}
func NewPrompt(conf *config.AercConfig, prompt string, commit func(text string), func NewPrompt(conf *config.AercConfig, prompt string, commit func(text string),
tabcomplete func(cmd string) ([]string, string), tabcomplete func(cmd string) ([]string, string),
) *ExLine { ) *ExLine {