aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-03-15 01:12:06 -0400
committerDrew DeVault <sir@cmpwn.com>2019-03-15 01:31:23 -0400
commit8d20e9218ece5927d786d6e2fac5c50572fb9c81 (patch)
treee4cdf0ba821dccbb510f169c7731ae78ce987830
parentd274bf926c79ec834afcac00dab3f95f8bd5325f (diff)
Implement key bindings subsystem
Which is not yet rigged up
-rw-r--r--config/aerc.conf63
-rw-r--r--config/bindings.go284
-rw-r--r--config/bindings_test.go61
-rw-r--r--config/config.go16
-rw-r--r--go.mod3
-rw-r--r--go.sum9
-rw-r--r--widgets/exline.go6
7 files changed, 404 insertions, 38 deletions
diff --git a/config/aerc.conf b/config/aerc.conf
index 76b0310..3b29a77 100644
--- a/config/aerc.conf
+++ b/config/aerc.conf
@@ -91,43 +91,44 @@ alternatives=text/plain,text/html
[lbinds]
#
-# 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
-#
-# lbinds are bindings that take effect in the list view
-# mbinds are bindings that take effect in the message view
-q=:quit<Enter>
-<Ctrl+c>=:quit<Enter>
-
-j=:next-message<Enter>
-<Down>=:next-message<Enter>
-<Ctrl+d>=:next-message --scroll 50%<Enter>
-<Ctrl+f>=:next-message --scroll 100%<Enter>
-<PageDown>=:next-message --scroll 100%<Enter>
-<WheelDown>=:next-message --scroll 1<Enter>
-
-k=:previous-message<Enter>
-<Up>=:previous-message<Enter>
-<Ctrl+u>=:previous-message --scroll 50%<Enter>
-<Ctrl+b>=:previous-message --scroll 100%<Enter>
-<PageUp>=:previous-message --scroll 100%<Enter>
-<WheelUp>=:previous-message --scroll 1<Enter>
-g=:select-message 0<Enter>
-G=:select-message -1<Enter>
-
-J=:next-folder<Enter>
-K=:previous-folder<Enter>
+# Binds are of the form <input keys> = <output keys>
+# Pressing <input keys> in sequence will then simulate pressing <output keys>
+#
+# Use <C-*> to refer to control+something.
+#
+# lbinds are effective in the list view
+# mbinds are effective in the message view
+q = :quit<Enter>
+<C-c> = :quit<Enter>
+
+j = :next-message<Enter>
+<Down> = :next-message<Enter>
+<C-d> = :next-message --scroll 50%<Enter>
+<C-f> = :next-message --scroll 100%<Enter>
+<PageDown> = :next-message --scroll 100%<Enter>
+<WheelDown> = :next-message --scroll 1<Enter>
+
+k = :previous-message<Enter>
+<Up> = :previous-message<Enter>
+<C-u> = :previous-message --scroll 50%<Enter>
+<C-b> = :previous-message --scroll 100%<Enter>
+<PageUp> = :previous-message --scroll 100%<Enter>
+<WheelUp> = :previous-message --scroll 1<Enter>
+g = :select-message 0<Enter>
+G = :select-message -1<Enter>
+
+J = :next-folder<Enter>
+K = :previous-folder<Enter>
l = :next-account<Enter>
<Right> = :next-account<Enter>
h = :previous-account<Enter>
<Left> = :previous-account<Enter>
-<Enter>=:view-message<Enter>
-d=:confirm 'Really delete this message?' ':delete-message<Enter>'<Enter>
+<Enter> = :view-message<Enter>
+d = :confirm 'Really delete this message?' ':delete-message<Enter>'<Enter>
-c=:cd
-$=:term-exec
+c = :cd
+$ = :term-exec
[mbinds]
#
diff --git a/config/bindings.go b/config/bindings.go
new file mode 100644
index 0000000..c10b68f
--- /dev/null
+++ b/config/bindings.go
@@ -0,0 +1,284 @@
+package config
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/gdamore/tcell"
+)
+
+type KeyStroke struct {
+ Key tcell.Key
+ Rune rune
+}
+
+type Binding struct {
+ Output []KeyStroke
+ Input []KeyStroke
+}
+
+type KeyBindings []*Binding
+
+const (
+ BINDING_FOUND = iota
+ BINDING_INCOMPLETE
+ BINDING_NOT_FOUND
+)
+
+type BindingSearchResult int
+
+func NewKeyBindings() *KeyBindings {
+ return &KeyBindings{}
+}
+
+func (bindings *KeyBindings) Add(binding *Binding) {
+ // TODO: Search for conflicts?
+ *bindings = append(*bindings, binding)
+}
+
+func (bindings *KeyBindings) GetBinding(
+ input []KeyStroke) (BindingSearchResult, []KeyStroke) {
+
+ incomplete := false
+ // TODO: This could probably be a sorted list to speed things up
+ // TODO: Deal with bindings that share a prefix
+ for _, binding := range *bindings {
+ if len(binding.Input) < len(input) {
+ continue
+ }
+ for i, stroke := range input {
+ if stroke != binding.Input[i] {
+ goto next
+ }
+ }
+ if len(binding.Input) != len(input) {
+ incomplete = true
+ } else {
+ return BINDING_FOUND, binding.Output
+ }
+ next:
+ }
+ if incomplete {
+ return BINDING_INCOMPLETE, nil
+ }
+ return BINDING_NOT_FOUND, nil
+}
+
+var (
+ keyNames map[string]tcell.Key
+)
+
+func ParseKeyStrokes(keystrokes string) ([]KeyStroke, error) {
+ var strokes []KeyStroke
+ buf := bytes.NewBufferString(keystrokes)
+ for {
+ tok, _, err := buf.ReadRune()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return nil, err
+ }
+ // TODO: make it possible to bind to < or > themselves (and default to
+ // switching accounts)
+ switch tok {
+ case '<':
+ name, err := buf.ReadString(byte('>'))
+ if err == io.EOF {
+ return nil, errors.New("Expecting '>'")
+ } else if err != nil {
+ return nil, err
+ } else if name == ">" {
+ return nil, errors.New("Expected a key name")
+ }
+ name = name[:len(name)-1]
+ if key, ok := keyNames[strings.ToLower(name)]; ok {
+ strokes = append(strokes, KeyStroke{
+ Key: key,
+ })
+ } else {
+ return nil, errors.New(fmt.Sprintf("Unknown key '%s'", name))
+ }
+ case '>':
+ return nil, errors.New("Found '>' without '<'")
+ default:
+ strokes = append(strokes, KeyStroke{
+ Key: tcell.KeyRune,
+ Rune: tok,
+ })
+ }
+ }
+ return strokes, nil
+}
+
+func ParseBinding(input, output string) (*Binding, error) {
+ in, err := ParseKeyStrokes(input)
+ if err != nil {
+ return nil, err
+ }
+ out, err := ParseKeyStrokes(output)
+ if err != nil {
+ return nil, err
+ }
+ return &Binding{
+ Input: in,
+ Output: out,
+ }, nil
+}
+
+func init() {
+ keyNames = make(map[string]tcell.Key)
+ keyNames["up"] = tcell.KeyUp
+ keyNames["down"] = tcell.KeyDown
+ keyNames["right"] = tcell.KeyRight
+ keyNames["left"] = tcell.KeyLeft
+ keyNames["upleft"] = tcell.KeyUpLeft
+ keyNames["upright"] = tcell.KeyUpRight
+ keyNames["downleft"] = tcell.KeyDownLeft
+ keyNames["downright"] = tcell.KeyDownRight
+ keyNames["center"] = tcell.KeyCenter
+ keyNames["pgup"] = tcell.KeyPgUp
+ keyNames["pgdn"] = tcell.KeyPgDn
+ keyNames["home"] = tcell.KeyHome
+ keyNames["end"] = tcell.KeyEnd
+ keyNames["insert"] = tcell.KeyInsert
+ keyNames["delete"] = tcell.KeyDelete
+ keyNames["help"] = tcell.KeyHelp
+ keyNames["exit"] = tcell.KeyExit
+ keyNames["clear"] = tcell.KeyClear
+ keyNames["cancel"] = tcell.KeyCancel
+ keyNames["print"] = tcell.KeyPrint
+ keyNames["pause"] = tcell.KeyPause
+ keyNames["backtab"] = tcell.KeyBacktab
+ keyNames["f1"] = tcell.KeyF1
+ keyNames["f2"] = tcell.KeyF2
+ keyNames["f3"] = tcell.KeyF3
+ keyNames["f4"] = tcell.KeyF4
+ keyNames["f5"] = tcell.KeyF5
+ keyNames["f6"] = tcell.KeyF6
+ keyNames["f7"] = tcell.KeyF7
+ keyNames["f8"] = tcell.KeyF8
+ keyNames["f9"] = tcell.KeyF9
+ keyNames["f10"] = tcell.KeyF10
+ keyNames["f11"] = tcell.KeyF11
+ keyNames["f12"] = tcell.KeyF12
+ keyNames["f13"] = tcell.KeyF13
+ keyNames["f14"] = tcell.KeyF14
+ keyNames["f15"] = tcell.KeyF15
+ keyNames["f16"] = tcell.KeyF16
+ keyNames["f17"] = tcell.KeyF17
+ keyNames["f18"] = tcell.KeyF18
+ keyNames["f19"] = tcell.KeyF19
+ keyNames["f20"] = tcell.KeyF20
+ keyNames["f21"] = tcell.KeyF21
+ keyNames["f22"] = tcell.KeyF22
+ keyNames["f23"] = tcell.KeyF23
+ keyNames["f24"] = tcell.KeyF24
+ keyNames["f25"] = tcell.KeyF25
+ keyNames["f26"] = tcell.KeyF26
+ keyNames["f27"] = tcell.KeyF27
+ keyNames["f28"] = tcell.KeyF28
+ keyNames["f29"] = tcell.KeyF29
+ keyNames["f30"] = tcell.KeyF30
+ keyNames["f31"] = tcell.KeyF31
+ keyNames["f32"] = tcell.KeyF32
+ keyNames["f33"] = tcell.KeyF33
+ keyNames["f34"] = tcell.KeyF34
+ keyNames["f35"] = tcell.KeyF35
+ keyNames["f36"] = tcell.KeyF36
+ keyNames["f37"] = tcell.KeyF37
+ keyNames["f38"] = tcell.KeyF38
+ keyNames["f39"] = tcell.KeyF39
+ keyNames["f40"] = tcell.KeyF40
+ keyNames["f41"] = tcell.KeyF41
+ keyNames["f42"] = tcell.KeyF42
+ keyNames["f43"] = tcell.KeyF43
+ keyNames["f44"] = tcell.KeyF44
+ keyNames["f45"] = tcell.KeyF45
+ keyNames["f46"] = tcell.KeyF46
+ keyNames["f47"] = tcell.KeyF47
+ keyNames["f48"] = tcell.KeyF48
+ keyNames["f49"] = tcell.KeyF49
+ keyNames["f50"] = tcell.KeyF50
+ keyNames["f51"] = tcell.KeyF51
+ keyNames["f52"] = tcell.KeyF52
+ keyNames["f53"] = tcell.KeyF53
+ keyNames["f54"] = tcell.KeyF54
+ keyNames["f55"] = tcell.KeyF55
+ keyNames["f56"] = tcell.KeyF56
+ keyNames["f57"] = tcell.KeyF57
+ keyNames["f58"] = tcell.KeyF58
+ keyNames["f59"] = tcell.KeyF59
+ keyNames["f60"] = tcell.KeyF60
+ keyNames["f61"] = tcell.KeyF61
+ keyNames["f62"] = tcell.KeyF62
+ keyNames["f63"] = tcell.KeyF63
+ keyNames["f64"] = tcell.KeyF64
+ keyNames["c-space"] = tcell.KeyCtrlSpace
+ keyNames["c-a"] = tcell.KeyCtrlA
+ keyNames["c-b"] = tcell.KeyCtrlB
+ keyNames["c-c"] = tcell.KeyCtrlC
+ keyNames["c-d"] = tcell.KeyCtrlD
+ keyNames["c-e"] = tcell.KeyCtrlE
+ keyNames["c-f"] = tcell.KeyCtrlF
+ keyNames["c-g"] = tcell.KeyCtrlG
+ keyNames["c-h"] = tcell.KeyCtrlH
+ keyNames["c-i"] = tcell.KeyCtrlI
+ keyNames["c-j"] = tcell.KeyCtrlJ
+ keyNames["c-k"] = tcell.KeyCtrlK
+ keyNames["c-l"] = tcell.KeyCtrlL
+ keyNames["c-m"] = tcell.KeyCtrlM
+ keyNames["c-n"] = tcell.KeyCtrlN
+ keyNames["c-o"] = tcell.KeyCtrlO
+ keyNames["c-p"] = tcell.KeyCtrlP
+ keyNames["c-q"] = tcell.KeyCtrlQ
+ keyNames["c-r"] = tcell.KeyCtrlR
+ keyNames["c-s"] = tcell.KeyCtrlS
+ keyNames["c-t"] = tcell.KeyCtrlT
+ keyNames["c-u"] = tcell.KeyCtrlU
+ keyNames["c-v"] = tcell.KeyCtrlV
+ keyNames["c-w"] = tcell.KeyCtrlW
+ keyNames["c-x"] = tcell.KeyCtrlX
+ keyNames["c-y"] = tcell.KeyCtrlY
+ keyNames["c-z"] = tcell.KeyCtrlZ
+ keyNames["c-]"] = tcell.KeyCtrlLeftSq
+ keyNames["c-\\"] = tcell.KeyCtrlBackslash
+ keyNames["c-["] = tcell.KeyCtrlRightSq
+ keyNames["c-^"] = tcell.KeyCtrlCarat
+ keyNames["c-_"] = tcell.KeyCtrlUnderscore
+ keyNames["NUL"] = tcell.KeyNUL
+ keyNames["SOH"] = tcell.KeySOH
+ keyNames["STX"] = tcell.KeySTX
+ keyNames["ETX"] = tcell.KeyETX
+ keyNames["EOT"] = tcell.KeyEOT
+ keyNames["ENQ"] = tcell.KeyENQ
+ keyNames["ACK"] = tcell.KeyACK
+ keyNames["BEL"] = tcell.KeyBEL
+ keyNames["BS"] = tcell.KeyBS
+ keyNames["TAB"] = tcell.KeyTAB
+ keyNames["LF"] = tcell.KeyLF
+ keyNames["VT"] = tcell.KeyVT
+ keyNames["FF"] = tcell.KeyFF
+ keyNames["CR"] = tcell.KeyCR
+ keyNames["SO"] = tcell.KeySO
+ keyNames["SI"] = tcell.KeySI
+ keyNames["DLE"] = tcell.KeyDLE
+ keyNames["DC1"] = tcell.KeyDC1
+ keyNames["DC2"] = tcell.KeyDC2
+ keyNames["DC3"] = tcell.KeyDC3
+ keyNames["DC4"] = tcell.KeyDC4
+ keyNames["NAK"] = tcell.KeyNAK
+ keyNames["SYN"] = tcell.KeySYN
+ keyNames["ETB"] = tcell.KeyETB
+ keyNames["CAN"] = tcell.KeyCAN
+ keyNames["EM"] = tcell.KeyEM
+ keyNames["SUB"] = tcell.KeySUB
+ keyNames["ESC"] = tcell.KeyESC
+ keyNames["FS"] = tcell.KeyFS
+ keyNames["GS"] = tcell.KeyGS
+ keyNames["RS"] = tcell.KeyRS
+ keyNames["US"] = tcell.KeyUS
+ keyNames["DEL"] = tcell.KeyDEL
+}
diff --git a/config/bindings_test.go b/config/bindings_test.go
new file mode 100644
index 0000000..1d1cbfe
--- /dev/null
+++ b/config/bindings_test.go
@@ -0,0 +1,61 @@
+package config
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/gdamore/tcell"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGetBinding(t *testing.T) {
+ assert := assert.New(t)
+
+ bindings := NewKeyBindings()
+ add := func(binding, cmd string) {
+ b, _ := ParseBinding(binding, cmd)
+ bindings.Add(b)
+ }
+
+ add("abc", ":abc")
+ add("cba", ":cba")
+ add("foo", ":foo")
+ add("bar", ":bar")
+
+ test := func(input []KeyStroke, result int, output string) {
+ _output, _ := ParseKeyStrokes(output)
+ r, out := bindings.GetBinding(input)
+ assert.Equal(result, int(r), fmt.Sprintf(
+ "%s: Expected result %d, got %d", output, result, r))
+ assert.Equal(_output, out, fmt.Sprintf(
+ "%s: Expected output %v, got %v", output, _output, out))
+ }
+
+ test([]KeyStroke{
+ {tcell.KeyRune, 'a'},
+ }, BINDING_INCOMPLETE, "")
+ test([]KeyStroke{
+ {tcell.KeyRune, 'a'},
+ {tcell.KeyRune, 'b'},
+ {tcell.KeyRune, 'c'},
+ }, BINDING_FOUND, ":abc")
+ test([]KeyStroke{
+ {tcell.KeyRune, 'c'},
+ {tcell.KeyRune, 'b'},
+ {tcell.KeyRune, 'a'},
+ }, BINDING_FOUND, ":cba")
+ test([]KeyStroke{
+ {tcell.KeyRune, 'f'},
+ {tcell.KeyRune, 'o'},
+ }, BINDING_INCOMPLETE, "")
+ test([]KeyStroke{
+ {tcell.KeyRune, '4'},
+ {tcell.KeyRune, '0'},
+ {tcell.KeyRune, '4'},
+ }, BINDING_NOT_FOUND, "")
+
+ add("<C-a>", "c-a")
+ test([]KeyStroke{
+ {tcell.KeyCtrlA, 0},
+ }, BINDING_FOUND, "c-a")
+}
diff --git a/config/config.go b/config/config.go
index 142a1e0..ff0e094 100644
--- a/config/config.go
+++ b/config/config.go
@@ -29,6 +29,7 @@ type AccountConfig struct {
}
type AercConfig struct {
+ Lbinds *KeyBindings
Ini *ini.File `ini:"-"`
Accounts []AccountConfig `ini:"-"`
Ui UIConfig
@@ -94,7 +95,9 @@ func LoadConfig(root *string) (*AercConfig, error) {
}
file.NameMapper = mapName
config := &AercConfig{
- Ini: file,
+ Lbinds: NewKeyBindings(),
+ Ini: file,
+
Ui: UIConfig{
IndexFormat: "%4C %Z %D %-17.17n %s",
TimestampFormat: "%F %l:%M %p",
@@ -110,9 +113,18 @@ func LoadConfig(root *string) (*AercConfig, error) {
EmptyMessage: "(no messages)",
},
}
- if ui, err := file.GetSection("ui"); err != nil {
+ if ui, err := file.GetSection("ui"); err == nil {
ui.MapTo(config.Ui)
}
+ 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
diff --git a/go.mod b/go.mod
index 05f0880..5eae665 100644
--- a/go.mod
+++ b/go.mod
@@ -6,12 +6,13 @@ require (
github.com/emersion/go-sasl v0.0.0-20161116183048-7e096a0a6197 // indirect
github.com/gdamore/encoding v0.0.0-20151215212835-b23993cbb635
github.com/gdamore/tcell v1.0.0
- github.com/go-ini/ini v1.32.0
+ github.com/go-ini/ini v1.42.0
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
github.com/kyoh86/xdg v0.0.0-20171127140545-8db68a8ea76a
github.com/lucasb-eyer/go-colorful v0.0.0-20180531031333-d9cec903b20c
github.com/mattn/go-isatty v0.0.3
github.com/mattn/go-runewidth v0.0.2
github.com/nsf/termbox-go v0.0.0-20180129072728-88b7b944be8b
+ github.com/stretchr/testify v1.3.0
golang.org/x/text v0.3.0
)
diff --git a/go.sum b/go.sum
index be1bff1..1278e7a 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emersion/go-imap v1.0.0-beta.1 h1:bTCaVlUnb5mKoW9lEukusxguSYYZPer+q0g5t+vw5X0=
github.com/emersion/go-imap v1.0.0-beta.1/go.mod h1:oydmHwiyv92ZOiNfQY9BDax5heePWN8P2+W1B2T6qjc=
github.com/emersion/go-imap-idle v0.0.0-20180114101550-2af93776db6b h1:q4qkNe/W10qFGD3RWd4meQTkD0+Zrz0L4ekMvlptg60=
@@ -10,6 +12,8 @@ github.com/gdamore/tcell v1.0.0 h1:oaly4AkxvDT5ffKHV/n4L8iy6FxG2QkAVl0M6cjryuE=
github.com/gdamore/tcell v1.0.0/go.mod h1:tqyG50u7+Ctv1w5VX67kLzKcj9YXR/JSBZQq/+mLl1A=
github.com/go-ini/ini v1.32.0 h1:/MArBHSS0TFR28yPPDK1vPIjt4wUnPBfb81i6iiyKvA=
github.com/go-ini/ini v1.32.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
+github.com/go-ini/ini v1.42.0 h1:TWr1wGj35+UiWHlBA8er89seFXxzwFn11spilrrj+38=
+github.com/go-ini/ini v1.42.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
github.com/kyoh86/xdg v0.0.0-20171127140545-8db68a8ea76a h1:vLFQnHOnCnmlySdpHAKF+mH7MhsthJgpBbfexVhHwxY=
@@ -21,5 +25,10 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/nsf/termbox-go v0.0.0-20180129072728-88b7b944be8b/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/widgets/exline.go b/widgets/exline.go
index e0954d7..77f1414 100644
--- a/widgets/exline.go
+++ b/widgets/exline.go
@@ -126,10 +126,8 @@ func (ex *ExLine) Event(event tcell.Event) bool {
case tcell.KeyEsc, tcell.KeyCtrlC:
ex.ctx.HideCursor()
ex.cancel()
- default:
- if event.Rune() != 0 {
- ex.insert(event.Rune())
- }
+ case tcell.KeyRune:
+ ex.insert(event.Rune())
}
}
return true