about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJeffas <dev@jeffas.io>2019-07-19 18:12:57 +0100
committerDrew DeVault <sir@cmpwn.com>2019-07-23 10:27:59 -0400
commite42b95a617399b2736df96ae6469309e6b306d71 (patch)
tree65bd6f78faa0607a3d73a35b7c59a713472adbea
parentd526786c9358bc92a5ffc3233e0ba4491aff07ba (diff)
downloadaerc-e42b95a617399b2736df96ae6469309e6b306d71.tar.gz
Add change tab command
This command allows the user to change tab by giving the tab name. This
can be tab completed too. The previous tab is stored in the tabs module
so that when a new tab is created it is still possible to go to the
previous one.

Normal invocation is :ct folder
Previous tab is :ct -
-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)