~rjarry/aerc-devel

aerc: query: add completions for notmuch search-terms v3 APPLIED

Bence Ferdinandy: 2
 query: add completions for notmuch search-terms
 notmuch: add completions for :cf, :filter and :search

 4 files changed, 78 insertions(+), 6 deletions(-)
#1195039 alpine-edge.yml success
#1195040 openbsd.yml success
Works as expected for all of :{query,cf,filter,search} commands.
The 'tag:' completion is really useful!

The only thing i found interesting is this:
If you type for example  folder:Inbox/<TAB> then aerc completes
  folder:Inbox/{cur,tmp,new}
but the notmuch command in bash shell completes just
  folder:Inbox/
so cur,tmp and new are not expanded. But i don't think that this is an
issue at all.
Tested-by: Julio B <julio.bacel@gmail.com>
aerc/patches: SUCCESS in 1m57s

[query: add completions for notmuch search-terms][0] v3 from [Bence Ferdinandy][1]

[0]: https://lists.sr.ht/~rjarry/aerc-devel/patches/50991
[1]: mailto:bence@ferdinandy.com

✓ #1195040 SUCCESS aerc/patches/openbsd.yml     https://builds.sr.ht/~rjarry/job/1195040
✓ #1195039 SUCCESS aerc/patches/alpine-edge.yml https://builds.sr.ht/~rjarry/job/1195039
2024. ápr. 14. 5:35:22 Julio B <julio.bacel@gmail.com>:
Next
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~rjarry/aerc-devel/patches/50991/mbox | git am -3
Learn more about email & git

[PATCH aerc v3 1/2] query: add completions for notmuch search-terms Export this patch

Add completions to :query for the notmuch search terms. Most search
terms that seemed valid for interactive use in aerc are listed as
options. Some of them (from, to, tag, path, and folder) get actual
completions. The function was designed, so later patches can reuse it to
add completions to :cf, :filter and :search for notmuch accounts.

References: https://todo.sr.ht/~rjarry/aerc/244
Changelog-added: Added notmuch search-term completions to query.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
---

Notes:
    v2:
     - moved list of search-terms to a variable for reference in other
       commands
 commands/account/query.go      | 47 +++++++++++++++++++++++++++++++++-
 commands/completion_helpers.go |  2 +-
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/commands/account/query.go b/commands/account/query.go
index fccdc756..daa292b2 100644
--- a/commands/account/query.go
+++ b/commands/account/query.go
@@ -3,6 +3,7 @@ package account
import (
	"errors"
	"reflect"
	"strings"
	"time"

	"git.sr.ht/~rjarry/aerc/app"
@@ -14,7 +15,7 @@ import (
type Query struct {
	Account string `opt:"-a" complete:"CompleteAccount"`
	Name    string `opt:"-n"`
	Query   string `opt:"..."`
	Query   string `opt:"..." complete:"CompleteNotmuch"`
}

func init() {
@@ -65,3 +66,47 @@ func (q Query) Execute([]string) error {
	acct.Directories().Open(name, q.Query, 0*time.Second, finalize)
	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)
}
diff --git a/commands/completion_helpers.go b/commands/completion_helpers.go
index 02c13526..7f046630 100644
--- a/commands/completion_helpers.go
+++ b/commands/completion_helpers.go
@@ -29,7 +29,7 @@ func GetAddress(search string) []string {
		log.Warnf("could not complete header: %v", err)
	})

	if len(search) > config.Ui.CompletionMinChars && cmpl != nil {
	if cmpl != nil {
		addrList, _ := cmpl.ForHeader("to")(search)
		for _, full := range addrList {
			addr, err := mail.ParseAddress(full)
-- 
2.43.2
Bence Ferdinandy <bence@ferdinandy.com> wrote:

[PATCH aerc v3 2/2] notmuch: add completions for :cf, :filter and :search Export this patch

Add completion of notmuch search-terms for cf, filter and search.

Implements: https://todo.sr.ht/~rjarry/aerc/244
Changelog-added: Add notmuch completions for cf, filter and search.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
---

Notes:
    v3:
        - fixed cf not triggering

 commands/account/cf.go     | 19 ++++++++++++++++---
 commands/account/search.go | 16 +++++++++++++++-
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/commands/account/cf.go b/commands/account/cf.go
index e96ab2d6..c6993a23 100644
--- a/commands/account/cf.go
+++ b/commands/account/cf.go
@@ -3,6 +3,7 @@ package account
import (
	"errors"
	"reflect"
	"strings"
	"time"

	"git.sr.ht/~rjarry/aerc/app"
@@ -18,7 +19,7 @@ var history map[string]string

type ChangeFolder struct {
	Account bool   `opt:"-a"`
	Folder  string `opt:"..." complete:"CompleteFolder"`
	Folder  string `opt:"..." complete:"CompleteFolderAndNotmuch"`
}

func init() {
@@ -34,7 +35,7 @@ func (ChangeFolder) Aliases() []string {
	return []string{"cf"}
}

func (c *ChangeFolder) CompleteFolder(arg string) []string {
func (c *ChangeFolder) CompleteFolderAndNotmuch(arg string) []string {
	var acct *app.AccountView

	args := opt.LexArgs(c.Folder)
@@ -51,7 +52,7 @@ func (c *ChangeFolder) CompleteFolder(arg string) []string {
	if acct == nil {
		return nil
	}
	return commands.FilterList(
	retval := commands.FilterList(
		acct.Directories().List(), arg,
		func(s string) string {
			dir := acct.Directories().Directory(s)
@@ -61,6 +62,18 @@ func (c *ChangeFolder) CompleteFolder(arg string) []string {
			return s
		},
	)
	notmuch, _ := handlers.GetHandlerForScheme("notmuch", new(types.Worker))
	if reflect.TypeOf(notmuch) == reflect.TypeOf(acct.Worker().Backend) {
		notmuchcomps := handleNotmuchComplete(arg)
		for _, prefix := range notmuch_search_terms {
			if strings.HasPrefix(arg, prefix) {
				return notmuchcomps
			}
		}
		retval = append(retval, notmuchcomps...)

	}
	return retval
}

func (c ChangeFolder) Execute([]string) error {
diff --git a/commands/account/search.go b/commands/account/search.go
index e64e8154..f37e094d 100644
--- a/commands/account/search.go
+++ b/commands/account/search.go
@@ -4,6 +4,7 @@ import (
	"errors"
	"fmt"
	"net/textproto"
	"reflect"
	"strings"
	"time"

@@ -14,6 +15,7 @@ import (
	"git.sr.ht/~rjarry/aerc/lib/state"
	"git.sr.ht/~rjarry/aerc/lib/ui"
	"git.sr.ht/~rjarry/aerc/models"
	"git.sr.ht/~rjarry/aerc/worker/handlers"
	"git.sr.ht/~rjarry/aerc/worker/types"
)

@@ -30,7 +32,7 @@ type SearchFilter struct {
	Cc           []string             `opt:"-c" action:"ParseCc" complete:"CompleteAddress"`
	StartDate    time.Time            `opt:"-d" action:"ParseDate" complete:"CompleteDate"`
	EndDate      time.Time
	Terms        string `opt:"..." required:"false"`
	Terms        string `opt:"..." required:"false" complete:"CompleteNotmuch"`
}

func init() {
@@ -57,6 +59,18 @@ func (*SearchFilter) CompleteDate(arg string) []string {
	return commands.FilterList(commands.GetDateList(), arg, commands.QuoteSpace)
}

func (*SearchFilter) CompleteNotmuch(arg string) []string {
	acct := app.SelectedAccount()
	if acct == nil {
		return nil
	}
	notmuch, _ := handlers.GetHandlerForScheme("notmuch", new(types.Worker))
	if reflect.TypeOf(notmuch) != reflect.TypeOf(acct.Worker().Backend) {
		return nil
	}
	return handleNotmuchComplete(arg)
}

func (s *SearchFilter) ParseRead(arg string) error {
	s.WithFlags |= models.SeenFlag
	s.WithoutFlags &^= models.SeenFlag
-- 
2.43.2
Works as expected for all of :{query,cf,filter,search} commands.
The 'tag:' completion is really useful!

The only thing i found interesting is this:
If you type for example  folder:Inbox/<TAB> then aerc completes
  folder:Inbox/{cur,tmp,new}
but the notmuch command in bash shell completes just
  folder:Inbox/
so cur,tmp and new are not expanded. But i don't think that this is an
issue at all.

Tested-by: Julio B <julio.bacel@gmail.com>
aerc/patches: SUCCESS in 1m57s

[query: add completions for notmuch search-terms][0] v3 from [Bence Ferdinandy][1]

[0]: https://lists.sr.ht/~rjarry/aerc-devel/patches/50991
[1]: mailto:bence@ferdinandy.com

✓ #1195040 SUCCESS aerc/patches/openbsd.yml     https://builds.sr.ht/~rjarry/job/1195040
✓ #1195039 SUCCESS aerc/patches/alpine-edge.yml https://builds.sr.ht/~rjarry/job/1195039