~sircmpwn/aerc

command/GetFolders: Add support for fuzzy matching folder names v1 PROPOSED

Clayton Craft: 1
 command/GetFolders: Add support for fuzzy matching folder names

 6 files changed, 25 insertions(+), 3 deletions(-)
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/~sircmpwn/aerc/patches/20483/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] command/GetFolders: Add support for fuzzy matching folder names Export this patch

This uses an external library that implements fuzzy matching to allow
users to fuzzy match on folder names when using the "cf" command. I have
a lot of mail folders, and using "cf" the traditional way (correctly
typing out the leading characters of the folder I want to change to) is
tedious.

I'm not sold on the fuzzy match dep here, if there's a better one that
folks know of then I can change this to use that.
---
 commands/commands.go  | 14 +++++++++++---
 config/aerc.conf.in   |  3 +++
 config/config.go      |  2 ++
 doc/aerc-config.5.scd |  6 ++++++
 go.mod                |  1 +
 go.sum                |  2 ++
 6 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/commands/commands.go b/commands/commands.go
index 0c761d1..7eca395 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -8,6 +8,7 @@ import (
	"unicode"

	"github.com/google/shlex"
	"github.com/lithammer/fuzzysearch/fuzzy"

	"git.sr.ht/~sircmpwn/aerc/widgets"
)
@@ -120,9 +121,16 @@ func GetFolders(aerc *widgets.Aerc, args []string) []string {
	if len(args) == 0 {
		return aerc.SelectedAccount().Directories().List()
	}
	for _, dir := range aerc.SelectedAccount().Directories().List() {
		if hasCaseSmartPrefix(dir, args[0]) {
			out = append(out, dir)
	if aerc.Config().Ui.FolderFuzzyMatch {
		for _, dir := range fuzzy.RankFind(args[0],
		aerc.SelectedAccount().Directories().List()) {
			out = append(out, dir.Target)
		}
	} else {
		for _, dir := range aerc.SelectedAccount().Directories().List() {
			if hasCaseSmartPrefix(dir, args[0]) {
				out = append(out, dir)
			}
		}
	}
	return out
diff --git a/config/aerc.conf.in b/config/aerc.conf.in
index b9381a8..0bec8c2 100644
--- a/config/aerc.conf.in
+++ b/config/aerc.conf.in
@@ -78,6 +78,9 @@ stylesets-dirs=@SHAREDIR@/stylesets/
# Default: default
styleset-name=default

# Use fuzzy name matching in commands that use folder names
folder-fuzzy-match=false

[viewer]
#
# Specifies the pager to use when displaying emails. Note that some filters
diff --git a/config/config.go b/config/config.go
index 8b409fe..0c518b9 100644
--- a/config/config.go
+++ b/config/config.go
@@ -47,6 +47,7 @@ type UIConfig struct {
	CompletionPopovers  bool          `ini:"completion-popovers"`
	StyleSetDirs        []string      `ini:"stylesets-dirs" delim:":"`
	StyleSetName        string        `ini:"styleset-name"`
	FolderFuzzyMatch    bool          `ini:"folder-fuzzy-match"`
	style               StyleSet
}

@@ -508,6 +509,7 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
			CompletionPopovers:  true,
			StyleSetDirs:        []string{path.Join(sharedir, "stylesets")},
			StyleSetName:        "default",
			FolderFuzzyMatch:    false,
		},

		ContextualUis: []UIConfigContext{},
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index d4de883..aab08ac 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -188,6 +188,12 @@ These options are configured in the *[ui]* section of aerc.conf.

	Have a look at *aerc-stylesets*(7) as to how a styleset looks like.

*folder-fuzzy-match*
	User fuzzy text matching for folder name when entering a folder with
	commands that use folders ('copy', 'cf', etc)

	Default: false


## Contextual UI Configuration

diff --git a/go.mod b/go.mod
index 44030e1..42735d0 100644
--- a/go.mod
+++ b/go.mod
@@ -23,6 +23,7 @@ require (
	github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect
	github.com/imdario/mergo v0.3.8
	github.com/kyoh86/xdg v1.2.0
	github.com/lithammer/fuzzysearch v1.1.1
	github.com/mattn/go-isatty v0.0.12
	github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f // indirect
	github.com/mattn/go-runewidth v0.0.8
diff --git a/go.sum b/go.sum
index 83b19ae..ec7c979 100644
--- a/go.sum
+++ b/go.sum
@@ -64,6 +64,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kyoh86/xdg v1.2.0 h1:CERuT/ShdTDj+A2UaX3hQ3mOV369+Sj+wyn2nIRIIkI=
github.com/kyoh86/xdg v1.2.0/go.mod h1:/mg8zwu1+qe76oTFUBnyS7rJzk7LLC0VGEzJyJ19DHs=
github.com/lithammer/fuzzysearch v1.1.1 h1:8F9OAV2xPuYblToVohjanztdnPjbtA0MLgMvDKQ0Z08=
github.com/lithammer/fuzzysearch v1.1.1/go.mod h1:H2bng+w5gsR7NlfIJM8ElGZI0sX6C/9uzGqicVXGU6c=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/martinlindhe/base36 v0.0.0-20190418230009-7c6542dfbb41/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
-- 
2.30.1
I tried the same thing with a different approach (no extern library):
https://lists.sr.ht/~sircmpwn/aerc/patches/15370

Glad to know there's more people interested in this functionality.

Salud,


On Tue Feb 23, 2021 at 9:25 PM CET, Clayton Craft wrote:
Hi,
Thanks for the patch.

The completion handling as we have it now is a bit of a mess.

On one hand we would have a completer package, which isn't really used for much
but the address completion.

Then we have most of the other completion stuff in the command package.

To add insult to injury the actual completion happens in the commands themselves,
and I can see why as that granularity is indeed needed sometimes (completing tags
for the notmuch backend for example).

Now, prior to introducing more functionality I'd rather see this refactored so
that it's easier to reason about.

Something like fuzzy completion should really be a global thing when enabled,
as far as that's possible (meaning fixed sized list, nothing that depends on the
previous input).

That certainly includes maildirs as well as file system paths (for :cd, :save etc.).

I also don't want to see a gazillion options for all possible places where we
want to have fuzzy completion.

We'd end up with

FolderFuzzyMatch
PathFuzzyMatch
AddressFuzzyMatch
...

and I don't think that's sensible.

What do you think?

Cheers,
Reto