Implement key bindings subsystem
Which is not yet rigged up
This commit is contained in:
parent
d274bf926c
commit
8d20e9218e
7 changed files with 400 additions and 34 deletions
|
@ -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
|
||||
# Binds are of the form <input keys> = <output keys>
|
||||
# Pressing <input keys> in sequence will then simulate pressing <output keys>
|
||||
#
|
||||
# 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>
|
||||
# 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>
|
||||
<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>
|
||||
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>
|
||||
<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>
|
||||
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>
|
||||
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]
|
||||
#
|
||||
|
|
284
config/bindings.go
Normal file
284
config/bindings.go
Normal file
|
@ -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
|
||||
}
|
61
config/bindings_test.go
Normal file
61
config/bindings_test.go
Normal file
|
@ -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")
|
||||
}
|
|
@ -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
|
||||
|
|
3
go.mod
3
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
|
||||
)
|
||||
|
|
9
go.sum
9
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=
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue