summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--commands/ct.go48
-rw-r--r--lib/ui/tab.go25
-rw-r--r--widgets/aerc.go22
3 files changed, 90 insertions, 5 deletions
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 <tab>", 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)