You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aerc/commands/reload.go

195 lines
3.6 KiB
Go

package commands
import (
"os"
"git.sr.ht/~rjarry/aerc/app"
"git.sr.ht/~rjarry/aerc/config"
"git.sr.ht/~rjarry/aerc/lib/log"
"git.sr.ht/~rjarry/aerc/lib/ui"
)
type Reload struct {
Binds bool `opt:"-B" desc:"Reload binds.conf."`
Conf bool `opt:"-C" desc:"Reload aerc.conf."`
Style string `opt:"-s" complete:"CompleteStyle" desc:"Reload the specified styleset."`
}
func init() {
Register(Reload{})
}
func (Reload) Description() string {
return "Hot-reload configuration files."
}
func (r *Reload) CompleteStyle(s string) []string {
var files []string
for _, dir := range config.Ui.StyleSetDirs {
entries, err := os.ReadDir(dir)
if err != nil {
log.Debugf("could not read directory '%s': %v", dir,
err)
continue
}
for _, e := range entries {
if e.IsDir() {
continue
}
files = append(files, e.Name())
}
}
return FilterList(files, s, nil)
}
func (Reload) Context() CommandContext {
return GLOBAL
}
func (Reload) Aliases() []string {
return []string{"reload"}
}
func (r Reload) Execute(args []string) error {
if !r.Binds && !r.Conf && r.Style == "" {
r.Binds = true
r.Conf = true
r.Style = config.Ui.StyleSetName
}
reconfigure := false
if r.Binds {
f, err := config.ReloadBinds()
if err != nil {
return err
}
app.PushSuccess("Binds reloaded: " + f)
}
if r.Conf {
f, err := config.ReloadConf()
if err != nil {
return err
}
app.PushSuccess("Conf reloaded: " + f)
reconfigure = true
}
if r.Style != "" {
config.Ui.ClearCache()
config.Ui.StyleSetName = r.Style
err := config.Ui.LoadStyle()
if err != nil {
return err
}
app.PushSuccess("Styleset: " + r.Style)
reconfigure = true
}
if !reconfigure {
return nil
}
// reload account views and message stores
for _, name := range app.AccountNames() {
// rebuild account view
view, err := app.Account(name)
if err != nil {
continue
}
dirlist := view.Directories()
if dirlist == nil {
continue
}
wantTree := config.Ui.ForAccount(name).DirListTree
dirlist = adjustDirlist(dirlist, wantTree)
view.SetDirectories(dirlist)
// now rebuild grid with correct dirlist
view.Configure()
// reconfigure the message stores
for _, dir := range dirlist.List() {
store, ok := dirlist.MsgStore(dir)
if !ok {
continue
}
uiConf := dirlist.UiConfig(dir)
store.Configure(view.SortCriteria(uiConf))
}
ui.Invalidate()
}
// reload message viewers
doTabs(func(tab *ui.Tab) {
mv, ok := tab.Content.(*app.MessageViewer)
if !ok {
return
}
reloaded, err := app.NewMessageViewer(
mv.SelectedAccount(),
mv.MessageView(),
)
if err != nil {
app.PushError(err.Error())
return
}
app.ReplaceTab(mv, reloaded, tab.Name, false)
})
// reload composers
doTabs(func(tab *ui.Tab) {
c, ok := tab.Content.(*app.Composer)
if !ok {
return
}
_ = c.SwitchAccount(c.Account())
})
return nil
}
func adjustDirlist(d app.DirectoryLister, wantTree bool) app.DirectoryLister {
switch d := d.(type) {
case *app.DirectoryList:
if wantTree {
log.Tracef("dirlist: build tree")
tree := app.NewDirectoryTree(d)
tree.SelectedMsgStore()
return tree
}
log.Tracef("dirlist: already dirlist")
return d
case *app.DirectoryTree:
if !wantTree {
log.Tracef("dirtree: get dirlist")
return d.DirectoryList
}
log.Tracef("dirtree: already tree")
return d
default:
return d
}
}
func doTabs(do func(*ui.Tab)) {
var tabname string
if t := app.SelectedTab(); t != nil {
tabname = t.Name
}
for i := range app.TabNames() {
tab := app.GetTab(i)
if tab == nil {
continue
}
do(tab)
}
if tabname != "" {
app.SelectTab(tabname)
}
}