aboutsummaryrefslogblamecommitdiffstats
path: root/commands/account/query.go
blob: 65b5e06384d28fc4fa2604c9d53cffffc4c63aea (plain) (tree)
1
2
3
4
5
6
7
8
9



                
                 



                                         





                                                            
                                 
                                                             






                                                
                                    

























                                                                                
                                                      










                                                                                  
                                                                                

                  
























































                                                                                                        
package account

import (
	"errors"
	"strings"
	"time"

	"git.sr.ht/~rjarry/aerc/app"
	"git.sr.ht/~rjarry/aerc/commands"
	"git.sr.ht/~rjarry/aerc/worker/types"
)

type Query struct {
	Account string `opt:"-a" complete:"CompleteAccount"`
	Name    string `opt:"-n"`
	Force   bool   `opt:"-f"`
	Query   string `opt:"..." complete:"CompleteNotmuch"`
}

func init() {
	commands.Register(Query{})
}

func (Query) Context() commands.CommandContext {
	return commands.MESSAGE_LIST
}

func (Query) Aliases() []string {
	return []string{"query"}
}

func (Query) CompleteAccount(arg string) []string {
	return commands.FilterList(app.AccountNames(), arg, commands.QuoteSpace)
}

func (q Query) Execute([]string) error {
	var acct *app.AccountView

	if q.Account == "" {
		acct = app.SelectedAccount()
		if acct == nil {
			return errors.New("No account selected")
		}
	} else {
		var err error
		acct, err = app.Account(q.Account)
		if err != nil {
			return err
		}
	}

	if acct.AccountConfig().Backend != "notmuch" {
		return errors.New(":query is only available for notmuch accounts")
	}

	finalize := func(msg types.WorkerMessage) {
		handleDirOpenResponse(acct, msg)
	}

	name := q.Name
	if name == "" {
		name = q.Query
	}
	acct.Directories().Open(name, q.Query, 0*time.Second, finalize, q.Force)
	return nil
}

func (*Query) CompleteNotmuch(arg string) []string {
	return handleNotmuchComplete(arg)
}

var notmuch_search_terms = []string{
	"from:",
	"to:",
	"tag:",
	"date:",
	"attachment:",
	"mimetype:",
	"subject:",
	"body:",
	"id:",
	"thread:",
	"folder:",
	"path:",
}

func handleNotmuchComplete(arg string) []string {
	prefixes := []string{"from:", "to:"}
	for _, prefix := range prefixes {
		if strings.HasPrefix(arg, prefix) {
			arg = strings.TrimPrefix(arg, prefix)
			return commands.FilterList(
				commands.GetAddress(arg), arg,
				func(v string) string { return prefix + v },
			)
		}
	}

	prefixes = []string{"tag:"}
	for _, prefix := range prefixes {
		if strings.HasPrefix(arg, prefix) {
			arg = strings.TrimPrefix(arg, prefix)
			return commands.FilterList(
				commands.GetLabels(arg), arg,
				func(v string) string { return prefix + v },
			)
		}
	}

	prefixes = []string{"path:", "folder:"}
	dbPath := strings.TrimPrefix(app.SelectedAccount().AccountConfig().Source, "notmuch://")
	for _, prefix := range prefixes {
		if strings.HasPrefix(arg, prefix) {
			arg = strings.TrimPrefix(arg, prefix)
			return commands.FilterList(
				commands.CompletePath(dbPath+arg, true), arg,
				func(v string) string { return prefix + strings.TrimPrefix(v, dbPath) },
			)
		}
	}

	return commands.FilterList(notmuch_search_terms, arg, nil)
}