summary refs log tree commit diff stats
path: root/config
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-03-21 17:36:42 -0400
committerDrew DeVault <sir@cmpwn.com>2019-03-21 17:37:19 -0400
commitf5bf4a93243c62b5b30ed0f1d15c124739444c79 (patch)
tree68edf4ecdd4d979ead71f712860d2bd2101c53c2 /config
parent79b459ecb0da7759de617d164cb1cafc4a6be1c8 (diff)
downloadaerc-f5bf4a93243c62b5b30ed0f1d15c124739444c79.tar.gz
Add context-specific keybindings
Diffstat (limited to 'config')
-rw-r--r--config/bindings.go10
-rw-r--r--config/binds.conf32
-rw-r--r--config/config.go84
3 files changed, 114 insertions, 12 deletions
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 <key sequence> = <command to run>
+# To use '=' in a key sequence, substitute it with "Eq": "<Ctrl+Eq>"
+# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit
+q = :quit<Enter>
+L = :next-tab<Enter>
+H = :prev-tab<Enter>
+<C-t> = :term<Enter>
+
+[messages]
+j = :next-message<Enter>
+<Down> = :next-message<Enter>
+<C-d> = :next-message 50%<Enter>
+<C-f> = :next-message 100%<Enter>
+<PgDn> = :next-message -s 100%<Enter>
+
+k = :prev-message<Enter>
+<Up> = :prev-message<Enter>
+<C-u> = :prev-message 50%<Enter>
+<C-b> = :prev-message 100%<Enter>
+<PgUp> = :prev-message -s 100%<Enter>
+g = :select-message 0<Enter>
+G = :select-message -1<Enter>
+
+J = :next-folder<Enter>
+K = :prev-folder<Enter>
+
+<Enter> = :view-message<Enter>
+d = :confirm 'Really delete this message?' ':delete-message<Enter>'<Enter>
+D = :delete-message<Enter>
+
+c = :cf<space>
+$ = :term<space>
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
 }
52c5fdb'>^
3ae7e543 ^
7da71d03 ^
7a9b05fa ^
6d6b656f ^

d9cd13ad ^
82ac0b7e ^
0edc9471 ^
80b781cc ^
82ac0b7e ^

80b781cc ^


82ac0b7e ^
198ad741 ^
a8007cc4 ^
80b781cc ^
3ae7e543 ^
7da71d03 ^
6d6b656f ^

d9cd13ad ^
80b781cc ^


72cc3ae1 ^
80b781cc ^
82ac0b7e ^

80b781cc ^



fc55fea0 ^
2fb94e3c ^
82ac0b7e ^






a3d9828c ^



db5c9550 ^
a3d9828c ^



db5c9550 ^



a3d9828c ^
db5c9550 ^
a3d9828c ^


198ad741 ^






88be3dbc ^
fc55fea0 ^





ad68bbce ^
198ad741 ^
88be3dbc ^
ad68bbce ^
3ae7e543 ^
ad68bbce ^

3ae7e543 ^
a3d9828c ^
198ad741 ^
88be3dbc ^
198ad741 ^




7284d503 ^
caec3c16 ^
db5c9550 ^
a3d9828c ^


88be3dbc ^
a3d9828c ^



db5c9550 ^

72cc3ae1 ^
06b3eb96 ^
db5c9550 ^
06b3eb96 ^



66b97b4d ^
06b3eb96 ^

db5c9550 ^
caec3c16 ^


06b3eb96 ^

72cc3ae1 ^
8c9e97ae ^
88be3dbc ^
72cc3ae1 ^





caec3c16 ^
7284d503 ^
caec3c16 ^

88be3dbc ^
caec3c16 ^




















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200