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:
parent
4bc43d2741
commit
74366d895d
6 changed files with 91 additions and 24 deletions
35
commands/msgview/toggle-key-passthrough.go
Normal file
35
commands/msgview/toggle-key-passthrough.go
Normal 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
|
||||||
|
}
|
|
@ -56,6 +56,7 @@ N = :prev-result<Enter>
|
||||||
<Esc> = :clear<Enter>
|
<Esc> = :clear<Enter>
|
||||||
|
|
||||||
[view]
|
[view]
|
||||||
|
/ = :toggle-key-passthrough<Enter>/
|
||||||
q = :close<Enter>
|
q = :close<Enter>
|
||||||
| = :pipe<space>
|
| = :pipe<space>
|
||||||
D = :delete<Enter>
|
D = :delete<Enter>
|
||||||
|
@ -74,6 +75,11 @@ H = :toggle-headers<Enter>
|
||||||
J = :next<Enter>
|
J = :next<Enter>
|
||||||
K = :prev<Enter>
|
K = :prev<Enter>
|
||||||
|
|
||||||
|
[view::passthrough]
|
||||||
|
$noinherit = true
|
||||||
|
$ex = <C-x>
|
||||||
|
<Esc> = :toggle-key-passthrough<Enter>
|
||||||
|
|
||||||
[compose]
|
[compose]
|
||||||
# Keybindings used when the embedded terminal is not selected in the compose
|
# Keybindings used when the embedded terminal is not selected in the compose
|
||||||
# view
|
# view
|
||||||
|
|
|
@ -112,6 +112,7 @@ type BindingConfig struct {
|
||||||
ComposeReview *KeyBindings
|
ComposeReview *KeyBindings
|
||||||
MessageList *KeyBindings
|
MessageList *KeyBindings
|
||||||
MessageView *KeyBindings
|
MessageView *KeyBindings
|
||||||
|
MessageViewPassthrough *KeyBindings
|
||||||
Terminal *KeyBindings
|
Terminal *KeyBindings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +144,7 @@ type ViewerConfig struct {
|
||||||
ShowHeaders bool `ini:"show-headers"`
|
ShowHeaders bool `ini:"show-headers"`
|
||||||
AlwaysShowMime bool `ini:"always-show-mime"`
|
AlwaysShowMime bool `ini:"always-show-mime"`
|
||||||
HeaderLayout [][]string `ini:"-"`
|
HeaderLayout [][]string `ini:"-"`
|
||||||
|
KeyPassthrough bool `ini:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TriggersConfig struct {
|
type TriggersConfig struct {
|
||||||
|
@ -598,6 +600,7 @@ func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) {
|
||||||
ComposeReview: NewKeyBindings(),
|
ComposeReview: NewKeyBindings(),
|
||||||
MessageList: NewKeyBindings(),
|
MessageList: NewKeyBindings(),
|
||||||
MessageView: NewKeyBindings(),
|
MessageView: NewKeyBindings(),
|
||||||
|
MessageViewPassthrough: NewKeyBindings(),
|
||||||
Terminal: NewKeyBindings(),
|
Terminal: NewKeyBindings(),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -708,6 +711,7 @@ func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) {
|
||||||
"messages": &config.Bindings.MessageList,
|
"messages": &config.Bindings.MessageList,
|
||||||
"terminal": &config.Bindings.Terminal,
|
"terminal": &config.Bindings.Terminal,
|
||||||
"view": &config.Bindings.MessageView,
|
"view": &config.Bindings.MessageView,
|
||||||
|
"view::passthrough": &config.Bindings.MessageViewPassthrough,
|
||||||
"compose::editor": &config.Bindings.ComposeEditor,
|
"compose::editor": &config.Bindings.ComposeEditor,
|
||||||
"compose::review": &config.Bindings.ComposeReview,
|
"compose::review": &config.Bindings.ComposeReview,
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,6 +564,10 @@ are:
|
||||||
*[view]*
|
*[view]*
|
||||||
keybindings for the message viewer
|
keybindings for the message viewer
|
||||||
|
|
||||||
|
*[view::passthrough]*
|
||||||
|
keybindings for the viewer, when in key passthrough mode
|
||||||
|
(toggled with :toggle-key-passthrough)
|
||||||
|
|
||||||
*[compose]*
|
*[compose]*
|
||||||
keybindings for the message composer
|
keybindings for the message composer
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,12 @@ func (aerc *Aerc) getBindings() *config.KeyBindings {
|
||||||
return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.Compose, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose")
|
return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.Compose, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose")
|
||||||
}
|
}
|
||||||
case *MessageViewer:
|
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")
|
return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageView, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "view")
|
||||||
|
}
|
||||||
case *Terminal:
|
case *Terminal:
|
||||||
return aerc.conf.Bindings.Terminal
|
return aerc.conf.Bindings.Terminal
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -286,6 +286,11 @@ func (mv *MessageViewer) ToggleHeaders() {
|
||||||
switcher.Invalidate()
|
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 {
|
func (mv *MessageViewer) SelectedMessagePart() *PartInfo {
|
||||||
switcher := mv.switcher
|
switcher := mv.switcher
|
||||||
part := switcher.parts[switcher.selected]
|
part := switcher.parts[switcher.selected]
|
||||||
|
@ -325,6 +330,14 @@ func (mv *MessageViewer) NextPart() {
|
||||||
mv.Invalidate()
|
mv.Invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mv *MessageViewer) Bindings() string {
|
||||||
|
if mv.conf.Viewer.KeyPassthrough {
|
||||||
|
return "view::passthrough"
|
||||||
|
} else {
|
||||||
|
return "view"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (mv *MessageViewer) Close() error {
|
func (mv *MessageViewer) Close() error {
|
||||||
mv.switcher.Cleanup()
|
mv.switcher.Cleanup()
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in a new issue