From 24dfc4712647008a89d930b269b085c6c3f2fb2d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 15 Mar 2019 01:46:14 -0400 Subject: [PATCH] Rig up key bindings --- config/aerc.conf | 28 ++-- config/bindings.go | 312 ++++++++++++++++++++++----------------------- widgets/account.go | 80 ++++++++---- widgets/aerc.go | 2 +- widgets/exline.go | 8 +- widgets/msglist.go | 4 +- 6 files changed, 231 insertions(+), 203 deletions(-) diff --git a/config/aerc.conf b/config/aerc.conf index 3b29a77..f9c91b8 100644 --- a/config/aerc.conf +++ b/config/aerc.conf @@ -103,38 +103,36 @@ q = :quit j = :next-message = :next-message - = :next-message --scroll 50% - = :next-message --scroll 100% - = :next-message --scroll 100% - = :next-message --scroll 1 + = :next-message 50% + = :next-message 100% + = :next-message 100% -k = :previous-message - = :previous-message - = :previous-message --scroll 50% - = :previous-message --scroll 100% - = :previous-message --scroll 100% - = :previous-message --scroll 1 +k = :prev-message + = :prev-message + = :prev-message 50% + = :prev-message 100% + = :prev-message 100% g = :select-message 0 G = :select-message -1 J = :next-folder -K = :previous-folder +K = :prev-folder l = :next-account = :next-account -h = :previous-account - = :previous-account +h = :prev-account + = :prev-account = :view-message d = :confirm 'Really delete this message?' ':delete-message' -c = :cd +c = :cd $ = :term-exec [mbinds] # # Any key not bound is passed through to the sub-terminal. - = :previous-account + = :prev-account = :next-account [colors] diff --git a/config/bindings.go b/config/bindings.go index c10b68f..084ed58 100644 --- a/config/bindings.go +++ b/config/bindings.go @@ -68,7 +68,7 @@ func (bindings *KeyBindings) GetBinding( } var ( - keyNames map[string]tcell.Key + keyNames map[string]KeyStroke ) func ParseKeyStrokes(keystrokes string) ([]KeyStroke, error) { @@ -95,9 +95,7 @@ func ParseKeyStrokes(keystrokes string) ([]KeyStroke, error) { } name = name[:len(name)-1] if key, ok := keyNames[strings.ToLower(name)]; ok { - strokes = append(strokes, KeyStroke{ - Key: key, - }) + strokes = append(strokes, key) } else { return nil, errors.New(fmt.Sprintf("Unknown key '%s'", name)) } @@ -129,156 +127,158 @@ func ParseBinding(input, output string) (*Binding, error) { } 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 + keyNames = make(map[string]KeyStroke) + keyNames["space"] = KeyStroke{tcell.KeyRune, ' '} + keyNames["enter"] = KeyStroke{tcell.KeyEnter, 0} + keyNames["up"] = KeyStroke{tcell.KeyUp, 0} + keyNames["down"] = KeyStroke{tcell.KeyDown, 0} + keyNames["right"] = KeyStroke{tcell.KeyRight, 0} + keyNames["left"] = KeyStroke{tcell.KeyLeft, 0} + keyNames["upleft"] = KeyStroke{tcell.KeyUpLeft, 0} + keyNames["upright"] = KeyStroke{tcell.KeyUpRight, 0} + keyNames["downleft"] = KeyStroke{tcell.KeyDownLeft, 0} + keyNames["downright"] = KeyStroke{tcell.KeyDownRight, 0} + keyNames["center"] = KeyStroke{tcell.KeyCenter, 0} + keyNames["pgup"] = KeyStroke{tcell.KeyPgUp, 0} + keyNames["pgdn"] = KeyStroke{tcell.KeyPgDn, 0} + keyNames["home"] = KeyStroke{tcell.KeyHome, 0} + keyNames["end"] = KeyStroke{tcell.KeyEnd, 0} + keyNames["insert"] = KeyStroke{tcell.KeyInsert, 0} + keyNames["delete"] = KeyStroke{tcell.KeyDelete, 0} + keyNames["help"] = KeyStroke{tcell.KeyHelp, 0} + keyNames["exit"] = KeyStroke{tcell.KeyExit, 0} + keyNames["clear"] = KeyStroke{tcell.KeyClear, 0} + keyNames["cancel"] = KeyStroke{tcell.KeyCancel, 0} + keyNames["print"] = KeyStroke{tcell.KeyPrint, 0} + keyNames["pause"] = KeyStroke{tcell.KeyPause, 0} + keyNames["backtab"] = KeyStroke{tcell.KeyBacktab, 0} + keyNames["f1"] = KeyStroke{tcell.KeyF1, 0} + keyNames["f2"] = KeyStroke{tcell.KeyF2, 0} + keyNames["f3"] = KeyStroke{tcell.KeyF3, 0} + keyNames["f4"] = KeyStroke{tcell.KeyF4, 0} + keyNames["f5"] = KeyStroke{tcell.KeyF5, 0} + keyNames["f6"] = KeyStroke{tcell.KeyF6, 0} + keyNames["f7"] = KeyStroke{tcell.KeyF7, 0} + keyNames["f8"] = KeyStroke{tcell.KeyF8, 0} + keyNames["f9"] = KeyStroke{tcell.KeyF9, 0} + keyNames["f10"] = KeyStroke{tcell.KeyF10, 0} + keyNames["f11"] = KeyStroke{tcell.KeyF11, 0} + keyNames["f12"] = KeyStroke{tcell.KeyF12, 0} + keyNames["f13"] = KeyStroke{tcell.KeyF13, 0} + keyNames["f14"] = KeyStroke{tcell.KeyF14, 0} + keyNames["f15"] = KeyStroke{tcell.KeyF15, 0} + keyNames["f16"] = KeyStroke{tcell.KeyF16, 0} + keyNames["f17"] = KeyStroke{tcell.KeyF17, 0} + keyNames["f18"] = KeyStroke{tcell.KeyF18, 0} + keyNames["f19"] = KeyStroke{tcell.KeyF19, 0} + keyNames["f20"] = KeyStroke{tcell.KeyF20, 0} + keyNames["f21"] = KeyStroke{tcell.KeyF21, 0} + keyNames["f22"] = KeyStroke{tcell.KeyF22, 0} + keyNames["f23"] = KeyStroke{tcell.KeyF23, 0} + keyNames["f24"] = KeyStroke{tcell.KeyF24, 0} + keyNames["f25"] = KeyStroke{tcell.KeyF25, 0} + keyNames["f26"] = KeyStroke{tcell.KeyF26, 0} + keyNames["f27"] = KeyStroke{tcell.KeyF27, 0} + keyNames["f28"] = KeyStroke{tcell.KeyF28, 0} + keyNames["f29"] = KeyStroke{tcell.KeyF29, 0} + keyNames["f30"] = KeyStroke{tcell.KeyF30, 0} + keyNames["f31"] = KeyStroke{tcell.KeyF31, 0} + keyNames["f32"] = KeyStroke{tcell.KeyF32, 0} + keyNames["f33"] = KeyStroke{tcell.KeyF33, 0} + keyNames["f34"] = KeyStroke{tcell.KeyF34, 0} + keyNames["f35"] = KeyStroke{tcell.KeyF35, 0} + keyNames["f36"] = KeyStroke{tcell.KeyF36, 0} + keyNames["f37"] = KeyStroke{tcell.KeyF37, 0} + keyNames["f38"] = KeyStroke{tcell.KeyF38, 0} + keyNames["f39"] = KeyStroke{tcell.KeyF39, 0} + keyNames["f40"] = KeyStroke{tcell.KeyF40, 0} + keyNames["f41"] = KeyStroke{tcell.KeyF41, 0} + keyNames["f42"] = KeyStroke{tcell.KeyF42, 0} + keyNames["f43"] = KeyStroke{tcell.KeyF43, 0} + keyNames["f44"] = KeyStroke{tcell.KeyF44, 0} + keyNames["f45"] = KeyStroke{tcell.KeyF45, 0} + keyNames["f46"] = KeyStroke{tcell.KeyF46, 0} + keyNames["f47"] = KeyStroke{tcell.KeyF47, 0} + keyNames["f48"] = KeyStroke{tcell.KeyF48, 0} + keyNames["f49"] = KeyStroke{tcell.KeyF49, 0} + keyNames["f50"] = KeyStroke{tcell.KeyF50, 0} + keyNames["f51"] = KeyStroke{tcell.KeyF51, 0} + keyNames["f52"] = KeyStroke{tcell.KeyF52, 0} + keyNames["f53"] = KeyStroke{tcell.KeyF53, 0} + keyNames["f54"] = KeyStroke{tcell.KeyF54, 0} + keyNames["f55"] = KeyStroke{tcell.KeyF55, 0} + keyNames["f56"] = KeyStroke{tcell.KeyF56, 0} + keyNames["f57"] = KeyStroke{tcell.KeyF57, 0} + keyNames["f58"] = KeyStroke{tcell.KeyF58, 0} + keyNames["f59"] = KeyStroke{tcell.KeyF59, 0} + keyNames["f60"] = KeyStroke{tcell.KeyF60, 0} + keyNames["f61"] = KeyStroke{tcell.KeyF61, 0} + keyNames["f62"] = KeyStroke{tcell.KeyF62, 0} + keyNames["f63"] = KeyStroke{tcell.KeyF63, 0} + keyNames["f64"] = KeyStroke{tcell.KeyF64, 0} + keyNames["c-space"] = KeyStroke{tcell.KeyCtrlSpace, 0} + keyNames["c-a"] = KeyStroke{tcell.KeyCtrlA, 0} + keyNames["c-b"] = KeyStroke{tcell.KeyCtrlB, 0} + keyNames["c-c"] = KeyStroke{tcell.KeyCtrlC, 0} + keyNames["c-d"] = KeyStroke{tcell.KeyCtrlD, 0} + keyNames["c-e"] = KeyStroke{tcell.KeyCtrlE, 0} + keyNames["c-f"] = KeyStroke{tcell.KeyCtrlF, 0} + keyNames["c-g"] = KeyStroke{tcell.KeyCtrlG, 0} + keyNames["c-h"] = KeyStroke{tcell.KeyCtrlH, 0} + keyNames["c-i"] = KeyStroke{tcell.KeyCtrlI, 0} + keyNames["c-j"] = KeyStroke{tcell.KeyCtrlJ, 0} + keyNames["c-k"] = KeyStroke{tcell.KeyCtrlK, 0} + keyNames["c-l"] = KeyStroke{tcell.KeyCtrlL, 0} + keyNames["c-m"] = KeyStroke{tcell.KeyCtrlM, 0} + keyNames["c-n"] = KeyStroke{tcell.KeyCtrlN, 0} + keyNames["c-o"] = KeyStroke{tcell.KeyCtrlO, 0} + keyNames["c-p"] = KeyStroke{tcell.KeyCtrlP, 0} + keyNames["c-q"] = KeyStroke{tcell.KeyCtrlQ, 0} + keyNames["c-r"] = KeyStroke{tcell.KeyCtrlR, 0} + keyNames["c-s"] = KeyStroke{tcell.KeyCtrlS, 0} + keyNames["c-t"] = KeyStroke{tcell.KeyCtrlT, 0} + keyNames["c-u"] = KeyStroke{tcell.KeyCtrlU, 0} + keyNames["c-v"] = KeyStroke{tcell.KeyCtrlV, 0} + keyNames["c-w"] = KeyStroke{tcell.KeyCtrlW, 0} + keyNames["c-x"] = KeyStroke{tcell.KeyCtrlX, 0} + keyNames["c-y"] = KeyStroke{tcell.KeyCtrlY, 0} + keyNames["c-z"] = KeyStroke{tcell.KeyCtrlZ, 0} + keyNames["c-]"] = KeyStroke{tcell.KeyCtrlLeftSq, 0} + keyNames["c-\\"] = KeyStroke{tcell.KeyCtrlBackslash, 0} + keyNames["c-["] = KeyStroke{tcell.KeyCtrlRightSq, 0} + keyNames["c-^"] = KeyStroke{tcell.KeyCtrlCarat, 0} + keyNames["c-_"] = KeyStroke{tcell.KeyCtrlUnderscore, 0} + keyNames["NUL"] = KeyStroke{tcell.KeyNUL, 0} + keyNames["SOH"] = KeyStroke{tcell.KeySOH, 0} + keyNames["STX"] = KeyStroke{tcell.KeySTX, 0} + keyNames["ETX"] = KeyStroke{tcell.KeyETX, 0} + keyNames["EOT"] = KeyStroke{tcell.KeyEOT, 0} + keyNames["ENQ"] = KeyStroke{tcell.KeyENQ, 0} + keyNames["ACK"] = KeyStroke{tcell.KeyACK, 0} + keyNames["BEL"] = KeyStroke{tcell.KeyBEL, 0} + keyNames["BS"] = KeyStroke{tcell.KeyBS, 0} + keyNames["TAB"] = KeyStroke{tcell.KeyTAB, 0} + keyNames["LF"] = KeyStroke{tcell.KeyLF, 0} + keyNames["VT"] = KeyStroke{tcell.KeyVT, 0} + keyNames["FF"] = KeyStroke{tcell.KeyFF, 0} + keyNames["CR"] = KeyStroke{tcell.KeyCR, 0} + keyNames["SO"] = KeyStroke{tcell.KeySO, 0} + keyNames["SI"] = KeyStroke{tcell.KeySI, 0} + keyNames["DLE"] = KeyStroke{tcell.KeyDLE, 0} + keyNames["DC1"] = KeyStroke{tcell.KeyDC1, 0} + keyNames["DC2"] = KeyStroke{tcell.KeyDC2, 0} + keyNames["DC3"] = KeyStroke{tcell.KeyDC3, 0} + keyNames["DC4"] = KeyStroke{tcell.KeyDC4, 0} + keyNames["NAK"] = KeyStroke{tcell.KeyNAK, 0} + keyNames["SYN"] = KeyStroke{tcell.KeySYN, 0} + keyNames["ETB"] = KeyStroke{tcell.KeyETB, 0} + keyNames["CAN"] = KeyStroke{tcell.KeyCAN, 0} + keyNames["EM"] = KeyStroke{tcell.KeyEM, 0} + keyNames["SUB"] = KeyStroke{tcell.KeySUB, 0} + keyNames["ESC"] = KeyStroke{tcell.KeyESC, 0} + keyNames["FS"] = KeyStroke{tcell.KeyFS, 0} + keyNames["GS"] = KeyStroke{tcell.KeyGS, 0} + keyNames["RS"] = KeyStroke{tcell.KeyRS, 0} + keyNames["US"] = KeyStroke{tcell.KeyUS, 0} + keyNames["DEL"] = KeyStroke{tcell.KeyDEL, 0} } diff --git a/widgets/account.go b/widgets/account.go index f5e24d2..f7b9f69 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -14,7 +14,8 @@ import ( ) type AccountView struct { - conf *config.AccountConfig + acct *config.AccountConfig + conf *config.AercConfig dirlist *DirectoryList grid *ui.Grid logger *log.Logger @@ -23,12 +24,13 @@ type AccountView struct { runCmd func(cmd string) error msglist *MessageList msgStores map[string]*MessageStore + pendingKeys []config.KeyStroke statusline *StatusLine statusbar *ui.Stack worker *types.Worker } -func NewAccountView(conf *config.AccountConfig, +func NewAccountView(conf *config.AercConfig, acct *config.AccountConfig, logger *log.Logger, runCmd func(cmd string) error) *AccountView { statusbar := ui.NewStack() @@ -44,24 +46,25 @@ func NewAccountView(conf *config.AccountConfig, }) grid.AddChild(statusbar).At(1, 1) - worker, err := worker.NewWorker(conf.Source, logger) + worker, err := worker.NewWorker(acct.Source, logger) if err != nil { statusline.Set(fmt.Sprintf("%s", err)) return &AccountView{ - conf: conf, + acct: acct, grid: grid, logger: logger, statusline: statusline, } } - dirlist := NewDirectoryList(conf, logger, worker) + dirlist := NewDirectoryList(acct, logger, worker) grid.AddChild(ui.NewBordered(dirlist, ui.BORDER_RIGHT)).Span(2, 1) msglist := NewMessageList(logger) grid.AddChild(msglist).At(0, 1) - acct := &AccountView{ + view := &AccountView{ + acct: acct, conf: conf, dirlist: dirlist, grid: grid, @@ -79,19 +82,19 @@ func NewAccountView(conf *config.AccountConfig, for { msg := <-worker.Messages msg = worker.ProcessMessage(msg) - acct.onMessage(msg) + view.onMessage(msg) } }() - worker.PostAction(&types.Configure{Config: conf}, nil) - worker.PostAction(&types.Connect{}, acct.connected) + worker.PostAction(&types.Configure{Config: acct}, nil) + worker.PostAction(&types.Connect{}, view.connected) statusline.Set("Connecting...") - return acct + return view } func (acct *AccountView) Name() string { - return acct.conf.Name + return acct.acct.Name } func (acct *AccountView) Children() []ui.Drawable { @@ -112,28 +115,51 @@ func (acct *AccountView) Draw(ctx *ui.Context) { acct.grid.Draw(ctx) } +func (acct *AccountView) beginExCommand() { + exline := NewExLine(func(command string) { + err := acct.runCmd(command) + if err != nil { + acct.statusline.Push(" "+err.Error(), 10*time.Second). + Color(tcell.ColorRed, tcell.ColorWhite) + } + acct.statusbar.Pop() + acct.interactive = nil + }, func() { + acct.statusbar.Pop() + acct.interactive = nil + }) + acct.interactive = exline + acct.statusbar.Push(exline) +} + func (acct *AccountView) Event(event tcell.Event) bool { if acct.interactive != nil { return acct.interactive.Event(event) } + switch event := event.(type) { case *tcell.EventKey: - if event.Rune() == ':' { - exline := NewExLine(func(command string) { - err := acct.runCmd(command) - if err != nil { - acct.statusline.Push(" "+err.Error(), 10*time.Second). - Color(tcell.ColorRed, tcell.ColorWhite) - } - acct.statusbar.Pop() - acct.interactive = nil - }, func() { - acct.statusbar.Pop() - acct.interactive = nil - }) - acct.interactive = exline - acct.statusbar.Push(exline) - return true + acct.pendingKeys = append(acct.pendingKeys, config.KeyStroke{ + Key: event.Key(), + Rune: event.Rune(), + }) + result, output := acct.conf.Lbinds.GetBinding(acct.pendingKeys) + switch result { + case config.BINDING_FOUND: + acct.pendingKeys = []config.KeyStroke{} + for _, stroke := range output { + simulated := tcell.NewEventKey( + stroke.Key, stroke.Rune, tcell.ModNone) + acct.Event(simulated) + } + case config.BINDING_INCOMPLETE: + return false + case config.BINDING_NOT_FOUND: + acct.pendingKeys = []config.KeyStroke{} + if event.Rune() == ':' { + acct.beginExCommand() + return true + } } } return false diff --git a/widgets/aerc.go b/widgets/aerc.go index bf545f9..e7f4583 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -45,7 +45,7 @@ func NewAerc(conf *config.AercConfig, logger *log.Logger, } for _, acct := range conf.Accounts { - view := NewAccountView(&acct, logger, cmd) + view := NewAccountView(conf, &acct, logger, cmd) aerc.accounts[acct.Name] = view tabs.Add(view, acct.Name) } diff --git a/widgets/exline.go b/widgets/exline.go index 77f1414..7eff74a 100644 --- a/widgets/exline.go +++ b/widgets/exline.go @@ -121,10 +121,14 @@ func (ex *ExLine) Event(event tcell.Event) bool { case tcell.KeyCtrlW: ex.deleteWord() case tcell.KeyEnter: - ex.ctx.HideCursor() + if ex.ctx != nil { + ex.ctx.HideCursor() + } ex.commit(string(ex.command)) case tcell.KeyEsc, tcell.KeyCtrlC: - ex.ctx.HideCursor() + if ex.ctx != nil { + ex.ctx.HideCursor() + } ex.cancel() case tcell.KeyRune: ex.insert(event.Rune()) diff --git a/widgets/msglist.go b/widgets/msglist.go index 36d7f7a..5ba75a8 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -184,10 +184,10 @@ func (ml *MessageList) SetStore(store *MessageStore) { func (ml *MessageList) nextPrev(delta int) { ml.selected += delta if ml.selected < 0 { - ml.selected = len(ml.store.Uids) - 1 + ml.selected = 0 } if ml.selected >= len(ml.store.Uids) { - ml.selected = 0 + ml.selected = len(ml.store.Uids) - 1 } // TODO: scrolling ml.Invalidate()