From 24dfc4712647008a89d930b269b085c6c3f2fb2d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 15 Mar 2019 01:46:14 -0400 Subject: Rig up key bindings --- widgets/account.go | 80 ++++++++++++++++++++++++++++++++++++------------------ widgets/aerc.go | 2 +- widgets/exline.go | 8 ++++-- widgets/msglist.go | 4 +-- 4 files changed, 62 insertions(+), 32 deletions(-) (limited to 'widgets') 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() -- cgit 1.4.1-2-gfad0