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

@ -105,14 +105,15 @@ type AccountConfig struct {
}
type BindingConfig struct {
Global *KeyBindings
AccountWizard *KeyBindings
Compose *KeyBindings
ComposeEditor *KeyBindings
ComposeReview *KeyBindings
MessageList *KeyBindings
MessageView *KeyBindings
Terminal *KeyBindings
Global *KeyBindings
AccountWizard *KeyBindings
Compose *KeyBindings
ComposeEditor *KeyBindings
ComposeReview *KeyBindings
MessageList *KeyBindings
MessageView *KeyBindings
MessageViewPassthrough *KeyBindings
Terminal *KeyBindings
}
type BindingConfigContext struct {
@ -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 {
@ -591,14 +593,15 @@ func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) {
file.NameMapper = mapName
config := &AercConfig{
Bindings: BindingConfig{
Global: NewKeyBindings(),
AccountWizard: NewKeyBindings(),
Compose: NewKeyBindings(),
ComposeEditor: NewKeyBindings(),
ComposeReview: NewKeyBindings(),
MessageList: NewKeyBindings(),
MessageView: NewKeyBindings(),
Terminal: NewKeyBindings(),
Global: NewKeyBindings(),
AccountWizard: NewKeyBindings(),
Compose: NewKeyBindings(),
ComposeEditor: NewKeyBindings(),
ComposeReview: NewKeyBindings(),
MessageList: NewKeyBindings(),
MessageView: NewKeyBindings(),
MessageViewPassthrough: NewKeyBindings(),
Terminal: NewKeyBindings(),
},
ContextualBinds: []BindingConfigContext{},
@ -703,13 +706,14 @@ func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) {
}
baseGroups := map[string]**KeyBindings{
"default": &config.Bindings.Global,
"compose": &config.Bindings.Compose,
"messages": &config.Bindings.MessageList,
"terminal": &config.Bindings.Terminal,
"view": &config.Bindings.MessageView,
"compose::editor": &config.Bindings.ComposeEditor,
"compose::review": &config.Bindings.ComposeReview,
"default": &config.Bindings.Global,
"compose": &config.Bindings.Compose,
"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,
}
// Base Bindings

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:
return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageView, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "view")
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