aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkt programs <ktprograms@gmail.com>2022-03-14 11:03:34 +0800
committerRobin Jarry <robin@jarry.cc>2022-03-14 22:55:19 +0100
commit74366d895d5c5cce5c14424926bb5de229894884 (patch)
treea7f79c483abec9240d31fa1d54c7adfa506de254
parent4bc43d2741fa4904e51fc5da71d15b804c556c43 (diff)
downloadaerc-74366d895d5c5cce5c14424926bb5de229894884.tar.gz
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>
-rw-r--r--commands/msgview/toggle-key-passthrough.go35
-rw-r--r--config/binds.conf6
-rw-r--r--config/config.go50
-rw-r--r--doc/aerc-config.5.scd4
-rw-r--r--widgets/aerc.go7
-rw-r--r--widgets/msgviewer.go13
6 files changed, 91 insertions, 24 deletions
diff --git a/commands/msgview/toggle-key-passthrough.go b/commands/msgview/toggle-key-passthrough.go
new file mode 100644
index 00000000..6cd575bf
--- /dev/null
+++ b/commands/msgview/toggle-key-passthrough.go
@@ -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
+}
diff --git a/config/binds.conf b/config/binds.conf
index 538f9a35..d53a99f8 100644
--- a/config/binds.conf
+++ b/config/binds.conf
@@ -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
diff --git a/config/config.go b/config/config.go
index 8a01f503..24ec1b00 100644
--- a/config/config.go
+++ b/config/config.go
@@ -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
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index e172328a..885c4f80 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -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
diff --git a/widgets/aerc.go b/widgets/aerc.go
index 8061f388..cfc42919 100644
--- a/widgets/aerc.go
+++ b/widgets/aerc.go
@@ -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:
diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go
index da81ec95..9771a905 100644
--- a/widgets/msgviewer.go
+++ b/widgets/msgviewer.go
@@ -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