diff --git a/commands/ct.go b/commands/ct.go new file mode 100644 index 0000000..ab2993d --- /dev/null +++ b/commands/ct.go @@ -0,0 +1,48 @@ +package commands + +import ( + "errors" + "fmt" + "strings" + + "git.sr.ht/~sircmpwn/aerc/widgets" +) + +type ChangeTab struct{} + +func init() { + register(ChangeTab{}) +} + +func (_ ChangeTab) Aliases() []string { + return []string{"ct", "change-tab"} +} + +func (_ ChangeTab) Complete(aerc *widgets.Aerc, args []string) []string { + out := make([]string, 0) + for _, tab := range aerc.TabNames() { + if strings.HasPrefix(tab, args[0]) { + out = append(out, tab) + } + } + return out +} + +func (_ ChangeTab) Execute(aerc *widgets.Aerc, args []string) error { + if len(args) != 2 { + return errors.New(fmt.Sprintf("Usage: %s ", args[0])) + } + + if args[1] == "-" { + ok := aerc.SelectPreviousTab() + if !ok { + return errors.New("No previous tab to return to") + } + } else { + ok := aerc.SelectTab(args[1]) + if !ok { + return errors.New("No tab with that name") + } + } + return nil +} diff --git a/lib/ui/tab.go b/lib/ui/tab.go index 0061472..7808db4 100644 --- a/lib/ui/tab.go +++ b/lib/ui/tab.go @@ -29,7 +29,7 @@ func NewTabs() *Tabs { tabs := &Tabs{} tabs.TabStrip = (*TabStrip)(tabs) tabs.TabContent = (*TabContent)(tabs) - tabs.history = []int{0} + tabs.history = []int{} return tabs } @@ -64,7 +64,10 @@ func (tabs *Tabs) Remove(content Drawable) { break } } - tabs.Select(tabs.popHistory()) + index, ok := tabs.popHistory() + if ok { + tabs.Select(index) + } tabs.TabStrip.Invalidate() } @@ -90,22 +93,34 @@ func (tabs *Tabs) Select(index int) { } if tabs.Selected != index { + tabs.pushHistory(tabs.Selected) tabs.Selected = index - tabs.pushHistory(index) tabs.TabStrip.Invalidate() tabs.TabContent.Invalidate() } } +func (tabs *Tabs) SelectPrevious() bool { + index, ok := tabs.popHistory() + if !ok { + return false + } + tabs.Select(index) + return true +} + func (tabs *Tabs) pushHistory(index int) { tabs.history = append(tabs.history, index) } -func (tabs *Tabs) popHistory() int { +func (tabs *Tabs) popHistory() (int, bool) { lastIdx := len(tabs.history) - 1 + if lastIdx < 0 { + return 0, false + } item := tabs.history[lastIdx] tabs.history = tabs.history[:lastIdx] - return item + return item, true } func (tabs *Tabs) removeHistory(index int) { diff --git a/widgets/aerc.go b/widgets/aerc.go index 14cf3c4..079d442 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -252,6 +252,28 @@ func (aerc *Aerc) PrevTab() { aerc.tabs.Select(next) } +func (aerc *Aerc) SelectTab(name string) bool { + for i, tab := range aerc.tabs.Tabs { + if tab.Name == name { + aerc.tabs.Select(i) + return true + } + } + return false +} + +func (aerc *Aerc) TabNames() []string { + var names []string + for _, tab := range aerc.tabs.Tabs { + names = append(names, tab.Name) + } + return names +} + +func (aerc *Aerc) SelectPreviousTab() bool { + return aerc.tabs.SelectPrevious() +} + // TODO: Use per-account status lines, but a global ex line func (aerc *Aerc) SetStatus(status string) *StatusMessage { return aerc.statusline.Set(status)