viewer: add key passthrough mode

When trying to search in less, keys bound to viewer functions can't be
used as part of the search query, which makes the search useless.

Add a view::passthrough binding mode and a :toggle-key-passthrough
command go toggle in and out of that mode. By default, typing '/' in the
viewer is bound to enabling key passthrough and automatically inserting
'/', to easily enter "less" search mode. When in the passthrough mode,
all bindings are ignored by default. The default binds.conf only defines
a single keybinding in that mode: <Esc> to get back out. $ex is bound to
<C-x> to allow typing colons.

Signed-off-by: Kt Programs <ktprograms@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
kt programs 2022-03-14 11:03:34 +08:00 committed by Robin Jarry
parent 4bc43d2741
commit 74366d895d
6 changed files with 91 additions and 24 deletions

View file

@ -0,0 +1,35 @@
package msgview
import (
"errors"
"git.sr.ht/~rjarry/aerc/widgets"
)
type ToggleKeyPassthrough struct{}
func init() {
register(ToggleKeyPassthrough{})
}
func (ToggleKeyPassthrough) Aliases() []string {
return []string{"toggle-key-passthrough"}
}
func (ToggleKeyPassthrough) Complete(aerc *widgets.Aerc, args []string) []string {
return nil
}
func (ToggleKeyPassthrough) Execute(aerc *widgets.Aerc, args []string) error {
if len(args) != 1 {
return errors.New("Usage: toggle-key-passthrough")
}
mv, _ := aerc.SelectedTab().(*widgets.MessageViewer)
keyPassthroughEnabled := mv.ToggleKeyPassthrough()
if keyPassthroughEnabled {
aerc.SetExtraStatus("[passthrough]")
} else {
aerc.ClearExtraStatus()
}
return nil
}

View file

@ -56,6 +56,7 @@ N = :prev-result<Enter>
<Esc> = :clear<Enter>
[view]
/ = :toggle-key-passthrough<Enter>/
q = :close<Enter>
| = :pipe<space>
D = :delete<Enter>
@ -74,6 +75,11 @@ H = :toggle-headers<Enter>
J = :next<Enter>
K = :prev<Enter>
[view::passthrough]
$noinherit = true
$ex = <C-x>
<Esc> = :toggle-key-passthrough<Enter>
[compose]
# Keybindings used when the embedded terminal is not selected in the compose
# view

View file

@ -112,6 +112,7 @@ type BindingConfig struct {
ComposeReview *KeyBindings
MessageList *KeyBindings
MessageView *KeyBindings
MessageViewPassthrough *KeyBindings
Terminal *KeyBindings
}
@ -143,6 +144,7 @@ type ViewerConfig struct {
ShowHeaders bool `ini:"show-headers"`
AlwaysShowMime bool `ini:"always-show-mime"`
HeaderLayout [][]string `ini:"-"`
KeyPassthrough bool `ini:"-"`
}
type TriggersConfig struct {
@ -598,6 +600,7 @@ func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) {
ComposeReview: NewKeyBindings(),
MessageList: NewKeyBindings(),
MessageView: NewKeyBindings(),
MessageViewPassthrough: NewKeyBindings(),
Terminal: NewKeyBindings(),
},
@ -708,6 +711,7 @@ func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) {
"messages": &config.Bindings.MessageList,
"terminal": &config.Bindings.Terminal,
"view": &config.Bindings.MessageView,
"view::passthrough": &config.Bindings.MessageViewPassthrough,
"compose::editor": &config.Bindings.ComposeEditor,
"compose::review": &config.Bindings.ComposeReview,
}

View file

@ -564,6 +564,10 @@ are:
*[view]*
keybindings for the message viewer
*[view::passthrough]*
keybindings for the viewer, when in key passthrough mode
(toggled with :toggle-key-passthrough)
*[compose]*
keybindings for the message composer

View file

@ -201,7 +201,12 @@ func (aerc *Aerc) getBindings() *config.KeyBindings {
return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.Compose, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose")
}
case *MessageViewer:
switch view.Bindings() {
case "view::passthrough":
return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageViewPassthrough, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "view::passthrough")
default:
return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageView, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "view")
}
case *Terminal:
return aerc.conf.Bindings.Terminal
default:

View file

@ -286,6 +286,11 @@ func (mv *MessageViewer) ToggleHeaders() {
switcher.Invalidate()
}
func (mv *MessageViewer) ToggleKeyPassthrough() bool {
mv.conf.Viewer.KeyPassthrough = !mv.conf.Viewer.KeyPassthrough
return mv.conf.Viewer.KeyPassthrough
}
func (mv *MessageViewer) SelectedMessagePart() *PartInfo {
switcher := mv.switcher
part := switcher.parts[switcher.selected]
@ -325,6 +330,14 @@ func (mv *MessageViewer) NextPart() {
mv.Invalidate()
}
func (mv *MessageViewer) Bindings() string {
if mv.conf.Viewer.KeyPassthrough {
return "view::passthrough"
} else {
return "view"
}
}
func (mv *MessageViewer) Close() error {
mv.switcher.Cleanup()
return nil