~sircmpwn/aerc

e42b95a617399b2736df96ae6469309e6b306d71 — Jeffas 2 years ago d526786
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 -
3 files changed, 90 insertions(+), 5 deletions(-)

A commands/ct.go
M lib/ui/tab.go
M widgets/aerc.go
A commands/ct.go => commands/ct.go +48 -0
@@ 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
}

M lib/ui/tab.go => lib/ui/tab.go +20 -5
@@ 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) {

M widgets/aerc.go => widgets/aerc.go +22 -0
@@ 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)