From f5bf4a93243c62b5b30ed0f1d15c124739444c79 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 21 Mar 2019 17:36:42 -0400 Subject: Add context-specific keybindings --- config/bindings.go | 10 +++++++ config/binds.conf | 32 +++++++++++++++++++++ config/config.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 config/binds.conf (limited to 'config') diff --git a/config/bindings.go b/config/bindings.go index 1882f74..0032d72 100644 --- a/config/bindings.go +++ b/config/bindings.go @@ -44,6 +44,16 @@ func NewKeyBindings() *KeyBindings { } } +func MergeBindings(bindings ...*KeyBindings) *KeyBindings { + merged := NewKeyBindings() + for _, b := range bindings { + merged.bindings = append(merged.bindings, b.bindings...) + } + merged.ExKey = bindings[0].ExKey + merged.Globals = bindings[0].Globals + return merged +} + func (bindings *KeyBindings) Add(binding *Binding) { // TODO: Search for conflicts? bindings.bindings = append(bindings.bindings, binding) diff --git a/config/binds.conf b/config/binds.conf new file mode 100644 index 0000000..814f9f5 --- /dev/null +++ b/config/binds.conf @@ -0,0 +1,32 @@ +# Binds are of the form = +# To use '=' in a key sequence, substitute it with "Eq": "" +# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit +q = :quit +L = :next-tab +H = :prev-tab + = :term + +[messages] +j = :next-message + = :next-message + = :next-message 50% + = :next-message 100% + = :next-message -s 100% + +k = :prev-message + = :prev-message + = :prev-message 50% + = :prev-message 100% + = :prev-message -s 100% +g = :select-message 0 +G = :select-message -1 + +J = :next-folder +K = :prev-folder + + = :view-message +d = :confirm 'Really delete this message?' ':delete-message' +D = :delete-message + +c = :cf +$ = :term diff --git a/config/config.go b/config/config.go index 537626f..7aff1ea 100644 --- a/config/config.go +++ b/config/config.go @@ -1,6 +1,7 @@ package config import ( + "errors" "fmt" "path" "strings" @@ -29,8 +30,16 @@ type AccountConfig struct { Params map[string]string } +type BindingConfig struct { + Global *KeyBindings + Compose *KeyBindings + MessageList *KeyBindings + MessageView *KeyBindings + Terminal *KeyBindings +} + type AercConfig struct { - Lbinds *KeyBindings + Bindings BindingConfig Ini *ini.File `ini:"-"` Accounts []AccountConfig `ini:"-"` Ui UIConfig @@ -98,8 +107,14 @@ func LoadConfig(root *string) (*AercConfig, error) { } file.NameMapper = mapName config := &AercConfig{ - Lbinds: NewKeyBindings(), - Ini: file, + Bindings: BindingConfig{ + Global: NewKeyBindings(), + Compose: NewKeyBindings(), + MessageList: NewKeyBindings(), + MessageView: NewKeyBindings(), + Terminal: NewKeyBindings(), + }, + Ini: file, Ui: UIConfig{ IndexFormat: "%4C %Z %D %-17.17n %s", @@ -121,20 +136,65 @@ func LoadConfig(root *string) (*AercConfig, error) { return nil, err } } - if lbinds, err := file.GetSection("lbinds"); err == nil { - for key, value := range lbinds.KeysHash() { - binding, err := ParseBinding(key, value) - if err != nil { - return nil, err - } - config.Lbinds.Add(binding) - } - } accountsPath := path.Join(*root, "accounts.conf") if accounts, err := loadAccountConfig(accountsPath); err != nil { return nil, err } else { config.Accounts = accounts } + binds, err := ini.Load(path.Join(*root, "binds.conf")) + if err != nil { + return nil, err + } + groups := map[string]**KeyBindings{ + "default": &config.Bindings.Global, + "compose": &config.Bindings.Compose, + "messages": &config.Bindings.MessageList, + "terminal": &config.Bindings.Terminal, + "view": &config.Bindings.MessageView, + } + for _, name := range binds.SectionStrings() { + sec, err := binds.GetSection(name) + if err != nil { + return nil, err + } + group, ok := groups[strings.ToLower(name)] + if !ok { + return nil, errors.New("Unknown keybinding group " + name) + } + bindings := NewKeyBindings() + for key, value := range sec.KeysHash() { + if key == "$ex" { + strokes, err := ParseKeyStrokes(value) + if err != nil { + return nil, err + } + if len(strokes) != 1 { + return nil, errors.New( + "Error: only one keystroke supported for $ex") + } + bindings.ExKey = strokes[0] + continue + } + if key == "$noinherit" { + if value == "false" { + continue + } + if value != "true" { + return nil, errors.New( + "Error: expected 'true' or 'false' for $noinherit") + } + bindings.Globals = false + } + binding, err := ParseBinding(key, value) + if err != nil { + return nil, err + } + bindings.Add(binding) + } + *group = MergeBindings(bindings, *group) + } + // Globals can't inherit from themselves + config.Bindings.Global.Globals = false return config, nil } -- cgit 1.4.1-2-gfad0