aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/aerc.go18
-rw-r--r--app/app.go3
-rw-r--r--app/exline.go9
-rw-r--r--app/msgviewer.go2
-rw-r--r--commands/account/cf.go2
-rw-r--r--commands/account/mkdir.go2
-rw-r--r--commands/account/rmdir.go2
-rw-r--r--commands/commands.go4
-rw-r--r--commands/completion_helpers.go2
-rw-r--r--commands/compose/send.go10
-rw-r--r--commands/menu.go2
-rw-r--r--commands/patch/find.go2
-rw-r--r--commands/patch/list.go2
-rw-r--r--commands/patch/patch.go8
-rw-r--r--commands/prompt.go2
-rw-r--r--commands/util.go2
-rw-r--r--completer/completer.go18
-rw-r--r--config/style.go12
-rw-r--r--doc/aerc-stylesets.7.scd6
-rw-r--r--go.mod2
-rw-r--r--go.sum7
-rw-r--r--lib/open.go2
-rw-r--r--lib/send/sendmail.go2
-rw-r--r--lib/ui/textinput.go69
-rw-r--r--main.go24
-rw-r--r--stylesets/blue3
-rw-r--r--stylesets/default4
-rw-r--r--stylesets/monochrome1
-rw-r--r--stylesets/nord1
-rw-r--r--stylesets/pink3
-rw-r--r--stylesets/solarized1
-rw-r--r--worker/imap/search.go2
-rw-r--r--worker/lib/search.go2
-rw-r--r--worker/notmuch/search.go2
34 files changed, 145 insertions, 88 deletions
diff --git a/app/aerc.go b/app/aerc.go
index 107fc1f3..72a60562 100644
--- a/app/aerc.go
+++ b/app/aerc.go
@@ -11,7 +11,7 @@ import (
"time"
"unicode"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rockorager/vaxis"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/emersion/go-message/mail"
@@ -29,7 +29,7 @@ type Aerc struct {
accounts map[string]*AccountView
cmd func(string, *config.AccountConfig, *models.MessageInfo) error
cmdHistory lib.History
- complete func(cmd string) ([]string, string)
+ complete func(cmd string) ([]opt.Completion, string)
focused ui.Interactive
grid *ui.Grid
simulating int
@@ -54,7 +54,7 @@ type Choice struct {
func (aerc *Aerc) Init(
crypto crypto.Provider,
cmd func(string, *config.AccountConfig, *models.MessageInfo) error,
- complete func(cmd string) ([]string, string), cmdHistory lib.History,
+ complete func(cmd string) ([]opt.Completion, string), cmdHistory lib.History,
deferLoop chan struct{},
) {
tabs := ui.NewTabs(func(d ui.Drawable) *config.UIConfig {
@@ -317,7 +317,7 @@ func (aerc *Aerc) simulate(strokes []config.KeyStroke) {
aerc.simulating -= 1
if exline, ok := aerc.focused.(*ExLine); ok {
// we are still focused on the exline, turn on tab complete
- exline.TabComplete(func(cmd string) ([]string, string) {
+ exline.TabComplete(func(cmd string) ([]opt.Completion, string) {
return aerc.complete(cmd)
})
if complete {
@@ -633,14 +633,12 @@ func (aerc *Aerc) focus(item ui.Interactive) {
func (aerc *Aerc) BeginExCommand(cmd string) {
previous := aerc.focused
- var tabComplete func(string) ([]string, string)
+ var tabComplete func(string) ([]opt.Completion, string)
if aerc.simulating != 0 {
// Don't try to draw completions for simulated events
tabComplete = nil
} else {
- tabComplete = func(cmd string) ([]string, string) {
- return aerc.complete(cmd)
- }
+ tabComplete = aerc.complete
}
exline := NewExLine(cmd, func(cmd string) {
err := aerc.cmd(cmd, nil, nil)
@@ -673,7 +671,7 @@ func (aerc *Aerc) RegisterPrompt(prompt string, cmd string) {
if err != nil {
aerc.PushError(err.Error())
}
- }, func(cmd string) ([]string, string) {
+ }, func(cmd string) ([]opt.Completion, string) {
return nil, "" // TODO: completions
})
aerc.prompts.Push(p)
@@ -700,7 +698,7 @@ func (aerc *Aerc) RegisterChoices(choices []Choice) {
if err != nil {
aerc.PushError(err.Error())
}
- }, func(cmd string) ([]string, string) {
+ }, func(cmd string) ([]opt.Completion, string) {
return nil, "" // TODO: completions
})
aerc.prompts.Push(p)
diff --git a/app/app.go b/app/app.go
index 37444c8b..071aac74 100644
--- a/app/app.go
+++ b/app/app.go
@@ -10,6 +10,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
+ "git.sr.ht/~rjarry/go-opt/v2"
"github.com/ProtonMail/go-crypto/openpgp"
)
@@ -18,7 +19,7 @@ var aerc Aerc
func Init(
crypto crypto.Provider,
cmd func(string, *config.AccountConfig, *models.MessageInfo) error,
- complete func(cmd string) ([]string, string), history lib.History,
+ complete func(cmd string) ([]opt.Completion, string), history lib.History,
deferLoop chan struct{},
) {
aerc.Init(crypto, cmd, complete, history, deferLoop)
diff --git a/app/exline.go b/app/exline.go
index e8b0069e..5f8e4280 100644
--- a/app/exline.go
+++ b/app/exline.go
@@ -4,19 +4,20 @@ import (
"git.sr.ht/~rjarry/aerc/config"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/lib/ui"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rockorager/vaxis"
)
type ExLine struct {
commit func(cmd string)
finish func()
- tabcomplete func(cmd string) ([]string, string)
+ tabcomplete func(cmd string) ([]opt.Completion, string)
cmdHistory lib.History
input *ui.TextInput
}
func NewExLine(cmd string, commit func(cmd string), finish func(),
- tabcomplete func(cmd string) ([]string, string),
+ tabcomplete func(cmd string) ([]opt.Completion, string),
cmdHistory lib.History,
) *ExLine {
input := ui.NewTextInput("", config.Ui).Prompt(":").Set(cmd)
@@ -38,7 +39,7 @@ func NewExLine(cmd string, commit func(cmd string), finish func(),
return exline
}
-func (x *ExLine) TabComplete(tabComplete func(string) ([]string, string)) {
+func (x *ExLine) TabComplete(tabComplete func(string) ([]opt.Completion, string)) {
x.input.TabComplete(
tabComplete,
config.Ui.CompletionDelay,
@@ -48,7 +49,7 @@ func (x *ExLine) TabComplete(tabComplete func(string) ([]string, string)) {
}
func NewPrompt(prompt string, commit func(text string),
- tabcomplete func(cmd string) ([]string, string),
+ tabcomplete func(cmd string) ([]opt.Completion, string),
) *ExLine {
input := ui.NewTextInput("", config.Ui).Prompt(prompt)
if config.Ui.CompletionPopovers {
diff --git a/app/msgviewer.go b/app/msgviewer.go
index 0af87e5e..0c2c1bef 100644
--- a/app/msgviewer.go
+++ b/app/msgviewer.go
@@ -23,7 +23,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/parse"
"git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/models"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rockorager/vaxis"
"git.sr.ht/~rockorager/vaxis/widgets/align"
diff --git a/commands/account/cf.go b/commands/account/cf.go
index 8d7d27ae..2c2cee53 100644
--- a/commands/account/cf.go
+++ b/commands/account/cf.go
@@ -10,7 +10,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/state"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
type ChangeFolder struct {
diff --git a/commands/account/mkdir.go b/commands/account/mkdir.go
index 13310665..d6a6f9f3 100644
--- a/commands/account/mkdir.go
+++ b/commands/account/mkdir.go
@@ -7,7 +7,7 @@ import (
"git.sr.ht/~rjarry/aerc/app"
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/aerc/worker/types"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
type MakeDir struct {
diff --git a/commands/account/rmdir.go b/commands/account/rmdir.go
index ff1463b6..3c5b24d7 100644
--- a/commands/account/rmdir.go
+++ b/commands/account/rmdir.go
@@ -9,7 +9,7 @@ import (
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
type RemoveDir struct {
diff --git a/commands/commands.go b/commands/commands.go
index 27e50bcf..e87cd802 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -9,7 +9,7 @@ import (
"strings"
"unicode"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rjarry/aerc/app"
"git.sr.ht/~rjarry/aerc/config"
@@ -272,7 +272,7 @@ func GetTemplateCompletion(
// GetCompletions returns the completion options and the command prefix
func GetCompletions(
cmd Command, args *opt.Args,
-) (options []string, prefix string) {
+) (options []opt.Completion, prefix string) {
// copy zeroed struct
tmp := reflect.New(reflect.TypeOf(cmd)).Interface().(Command)
s, err := args.ArgSafe(0)
diff --git a/commands/completion_helpers.go b/commands/completion_helpers.go
index 92c33bea..8d293a32 100644
--- a/commands/completion_helpers.go
+++ b/commands/completion_helpers.go
@@ -32,7 +32,7 @@ func GetAddress(search string) []string {
if cmpl != nil {
addrList, _ := cmpl.ForHeader("to")(search)
for _, full := range addrList {
- addr, err := mail.ParseAddress(full)
+ addr, err := mail.ParseAddress(full.Value)
if err != nil {
continue
}
diff --git a/commands/compose/send.go b/commands/compose/send.go
index aefeaa3c..1e30bd0e 100644
--- a/commands/compose/send.go
+++ b/commands/compose/send.go
@@ -19,6 +19,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/send"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
+ "git.sr.ht/~rjarry/go-opt/v2"
"github.com/emersion/go-message/mail"
)
@@ -142,12 +143,13 @@ func (s Send) Execute(args []string) error {
from, rcpts, tab.Name, s.CopyTo,
s.Archive, copyToReplied)
}
- }, func(cmd string) ([]string, string) {
+ }, func(cmd string) ([]opt.Completion, string) {
+ var comps []opt.Completion
if cmd == "" {
- return []string{"y", "n"}, ""
+ comps = append(comps, opt.Completion{Value: "y"})
+ comps = append(comps, opt.Completion{Value: "n"})
}
-
- return nil, ""
+ return comps, ""
},
)
diff --git a/commands/menu.go b/commands/menu.go
index 6ebba81f..08eec9cb 100644
--- a/commands/menu.go
+++ b/commands/menu.go
@@ -12,7 +12,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/log"
"git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/models"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
type Menu struct {
diff --git a/commands/patch/find.go b/commands/patch/find.go
index a508551d..10b96ef2 100644
--- a/commands/patch/find.go
+++ b/commands/patch/find.go
@@ -11,7 +11,7 @@ import (
"git.sr.ht/~rjarry/aerc/commands/account"
"git.sr.ht/~rjarry/aerc/lib/pama"
"git.sr.ht/~rjarry/aerc/lib/pama/models"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
type Find struct {
diff --git a/commands/patch/list.go b/commands/patch/list.go
index 0451605b..b05a9bf3 100644
--- a/commands/patch/list.go
+++ b/commands/patch/list.go
@@ -13,7 +13,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/pama"
"git.sr.ht/~rjarry/aerc/lib/pama/models"
"git.sr.ht/~rjarry/aerc/lib/ui"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rockorager/vaxis"
)
diff --git a/commands/patch/patch.go b/commands/patch/patch.go
index 25d7850a..15fb35f4 100644
--- a/commands/patch/patch.go
+++ b/commands/patch/patch.go
@@ -5,7 +5,7 @@ import (
"fmt"
"git.sr.ht/~rjarry/aerc/commands"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
var subCommands map[string]commands.Command
@@ -68,7 +68,11 @@ func (p *Patch) CompleteSubArgs(arg string) []string {
}
// prepend arbitrary string to arg to work with sub-commands
options, _ := commands.GetCompletions(p.SubCmd, opt.LexArgs("a "+arg))
- return options
+ completions := make([]string, 0, len(options))
+ for _, o := range options {
+ completions = append(completions, o.Value)
+ }
+ return completions
}
func (p Patch) Execute(args []string) error {
diff --git a/commands/prompt.go b/commands/prompt.go
index 9ab2aac1..fe6632e9 100644
--- a/commands/prompt.go
+++ b/commands/prompt.go
@@ -1,7 +1,7 @@
package commands
import (
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rjarry/aerc/app"
)
diff --git a/commands/util.go b/commands/util.go
index bb20a204..8c1e497d 100644
--- a/commands/util.go
+++ b/commands/util.go
@@ -18,7 +18,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/xdg"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rockorager/vaxis"
)
diff --git a/completer/completer.go b/completer/completer.go
index 5a5dea10..c5b61528 100644
--- a/completer/completer.go
+++ b/completer/completer.go
@@ -13,7 +13,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/format"
"git.sr.ht/~rjarry/aerc/lib/log"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
// A Completer is used to autocomplete text inputs based on the configured
@@ -31,7 +31,7 @@ type Completer struct {
// A CompleteFunc accepts a string to be completed and returns a slice of
// completions candidates with a prefix to prepend to the chosen candidate
-type CompleteFunc func(string) ([]string, string)
+type CompleteFunc func(string) ([]opt.Completion, string)
// New creates a new Completer with the specified address book command.
func New(addressBookCmd string, errHandler func(error)) *Completer {
@@ -51,11 +51,11 @@ func (c *Completer) ForHeader(h string) CompleteFunc {
return nil
}
// wrap completeAddress in an error handler
- return func(s string) ([]string, string) {
+ return func(s string) ([]opt.Completion, string) {
completions, prefix, err := c.completeAddress(s)
if err != nil {
c.handleErr(err)
- return []string{}, ""
+ return []opt.Completion{}, ""
}
return completions, prefix
}
@@ -80,7 +80,7 @@ var tooManyLines = fmt.Errorf("returned more than %d lines", maxCompletionLines)
// completeAddress uses the configured address book completion command to fetch
// completions for the specified string, returning a slice of completions and
// a prefix to be prepended to the selected completion, or an error.
-func (c *Completer) completeAddress(s string) ([]string, string, error) {
+func (c *Completer) completeAddress(s string) ([]opt.Completion, string, error) {
prefix, candidate := c.parseAddress(s)
cmd, err := c.getAddressCmd(candidate)
if err != nil {
@@ -156,9 +156,9 @@ func (c *Completer) getAddressCmd(s string) (*exec.Cmd, error) {
// must consist of tab-delimited fields. Only the first field (the email
// address field) is required, the second field (the contact name) is optional,
// and subsequent fields are ignored.
-func readCompletions(r io.Reader) ([]string, error) {
+func readCompletions(r io.Reader) ([]opt.Completion, error) {
buf := bufio.NewReader(r)
- completions := []string{}
+ var completions []opt.Completion
for i := 0; i < maxCompletionLines; i++ {
line, err := buf.ReadString('\n')
if errors.Is(err, io.EOF) {
@@ -180,7 +180,9 @@ func readCompletions(r io.Reader) ([]string, error) {
if len(parts) > 1 {
addr.Name = strings.TrimSpace(parts[1])
}
- completions = append(completions, format.AddressForHumans(addr))
+ completions = append(completions, opt.Completion{
+ Value: format.AddressForHumans(addr),
+ })
}
return completions, tooManyLines
}
diff --git a/config/style.go b/config/style.go
index a8f17e8d..c81e7204 100644
--- a/config/style.go
+++ b/config/style.go
@@ -54,6 +54,7 @@ const (
STYLE_PART_MIMETYPE
STYLE_COMPLETION_DEFAULT
+ STYLE_COMPLETION_DESCRIPTION
STYLE_COMPLETION_GUTTER
STYLE_COMPLETION_PILL
@@ -105,9 +106,10 @@ var StyleNames = map[string]StyleObject{
"part_filename": STYLE_PART_FILENAME,
"part_mimetype": STYLE_PART_MIMETYPE,
- "completion_default": STYLE_COMPLETION_DEFAULT,
- "completion_gutter": STYLE_COMPLETION_GUTTER,
- "completion_pill": STYLE_COMPLETION_PILL,
+ "completion_default": STYLE_COMPLETION_DEFAULT,
+ "completion_description": STYLE_COMPLETION_DESCRIPTION,
+ "completion_gutter": STYLE_COMPLETION_GUTTER,
+ "completion_pill": STYLE_COMPLETION_PILL,
"tab": STYLE_TAB,
"stack": STYLE_STACK,
@@ -337,9 +339,11 @@ selector_chooser.bold = true
selector_focused.bold = true
selector_focused.bg = 12
selector_focused.fg = 15
+completion_*.bg = 8
completion_pill.bg = 12
-completion_default.bg = 8
completion_default.fg = 15
+completion_description.fg = 15
+completion_description.dim = true
`
func NewStyleSet() StyleSet {
diff --git a/doc/aerc-stylesets.7.scd b/doc/aerc-stylesets.7.scd
index ad05d69c..2a311db2 100644
--- a/doc/aerc-stylesets.7.scd
+++ b/doc/aerc-stylesets.7.scd
@@ -135,6 +135,8 @@ styling.
: Attachment/part MIME type in the part switcher.
| *completion_default*
: The default style for the completion engine.
+| *completion_description*
+: Completion item descriptions.
| *completion_gutter*
: The completion gutter.
| *completion_pill*
@@ -384,9 +386,11 @@ selector_chooser.bold = true
selector_focused.bold = true
selector_focused.bg = 12
selector_focused.fg = 15
+completion_*.bg = 8
completion_pill.bg = 12
-completion_default.bg = 8
completion_default.fg = 15
+completion_description.fg = 15
+completion_description.dim = true
[viewer]
url.underline = true
diff --git a/go.mod b/go.mod
index d34a80ca..9f82c8e3 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module git.sr.ht/~rjarry/aerc
go 1.21
require (
- git.sr.ht/~rjarry/go-opt v1.4.0
+ git.sr.ht/~rjarry/go-opt/v2 v2.0.1
git.sr.ht/~rockorager/go-jmap v0.5.0
git.sr.ht/~rockorager/vaxis v0.10.3
github.com/ProtonMail/go-crypto v1.0.0
diff --git a/go.sum b/go.sum
index 607f91b7..6b6ca806 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-git.sr.ht/~rjarry/go-opt v1.4.0 h1:YHUKRXOuoy6d57Jt2b0DRSLbxq0mz5biq+6P/npFK5s=
-git.sr.ht/~rjarry/go-opt v1.4.0/go.mod h1:oEPZUTJKGn1FVye0znaLoeskE/QTuyoJw5q+fjusdM4=
+git.sr.ht/~rjarry/go-opt/v2 v2.0.1 h1:rNag0btxzpPN9FOPEqJfmFY70R9Zqf7M1lbNdy6+jvM=
+git.sr.ht/~rjarry/go-opt/v2 v2.0.1/go.mod h1:ZIcXh1fUrJEE5bdfaOpx5Uk9YURsimePQ7JJpitDZq4=
git.sr.ht/~rockorager/go-jmap v0.5.0 h1:Xs8NeqpA631HUz4uIe6V+0CpWt6b+nnHF7S14U2BVPA=
git.sr.ht/~rockorager/go-jmap v0.5.0/go.mod h1:aOTCtwpZSINpDDSOkLGpHU0Kbbm5lcSDMcobX3ZtOjY=
git.sr.ht/~rockorager/vaxis v0.10.3 h1:r9oHYKPfItWh05SQE/UJ4wDrmWRY9MDJKtA9HEl5nBI=
@@ -77,6 +77,7 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
@@ -167,6 +168,7 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
+golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -174,6 +176,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/lib/open.go b/lib/open.go
index 5ca819e0..edbc7ff6 100644
--- a/lib/open.go
+++ b/lib/open.go
@@ -6,7 +6,7 @@ import (
"runtime"
"strings"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"github.com/danwakefield/fnmatch"
"git.sr.ht/~rjarry/aerc/config"
diff --git a/lib/send/sendmail.go b/lib/send/sendmail.go
index b267721e..9d98cf8f 100644
--- a/lib/send/sendmail.go
+++ b/lib/send/sendmail.go
@@ -6,7 +6,7 @@ import (
"net/url"
"os/exec"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"github.com/emersion/go-message/mail"
"github.com/pkg/errors"
)
diff --git a/lib/ui/textinput.go b/lib/ui/textinput.go
index 6c4551b3..d52859b7 100644
--- a/lib/ui/textinput.go
+++ b/lib/ui/textinput.go
@@ -10,6 +10,7 @@ import (
"git.sr.ht/~rjarry/aerc/config"
"git.sr.ht/~rjarry/aerc/lib/log"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rockorager/vaxis"
)
@@ -27,8 +28,8 @@ type TextInput struct {
text []vaxis.Character
change []func(ti *TextInput)
focusLost []func(ti *TextInput)
- tabcomplete func(s string) ([]string, string)
- completions []string
+ tabcomplete func(s string) ([]opt.Completion, string)
+ completions []opt.Completion
prefix string
completeIndex int
completeDelay time.Duration
@@ -62,7 +63,7 @@ func (ti *TextInput) Prompt(prompt string) *TextInput {
}
func (ti *TextInput) TabComplete(
- tabcomplete func(s string) ([]string, string),
+ tabcomplete func(s string) ([]opt.Completion, string),
d time.Duration, minChars int, key *config.KeyStroke,
) *TextInput {
ti.tabcomplete = tabcomplete
@@ -142,8 +143,24 @@ func (ti *TextInput) drawPopover(ctx *Context) {
if len(ti.completions) == 0 {
return
}
- cmp := &completions{ti: ti}
- width := maxLen(ti.completions) + 3
+
+ valWidth := 0
+ descWidth := 0
+ for _, c := range ti.completions {
+ valWidth = max(valWidth, runewidth.StringWidth(unquote(c.Value)))
+ descWidth = max(descWidth, runewidth.StringWidth(c.Description))
+ }
+ descWidth = min(descWidth, 80)
+ // one space padding
+ width := 1 + valWidth
+ if descWidth != 0 {
+ // two spaces padding + parentheses
+ width += 2 + descWidth + 2
+ }
+ // one space padding + gutter
+ width += 2
+
+ cmp := &completions{ti: ti, valWidth: valWidth, descWidth: descWidth}
height := len(ti.completions)
pos := len(ti.prefix) - ti.scroll
@@ -275,7 +292,7 @@ func (ti *TextInput) backspace() {
func (ti *TextInput) executeCompletion() {
if len(ti.completions) > 0 {
- ti.Set(ti.prefix + ti.completions[ti.completeIndex] + ti.StringRight())
+ ti.Set(ti.prefix + ti.completions[ti.completeIndex].Value + ti.StringRight())
}
}
@@ -402,7 +419,9 @@ func (ti *TextInput) Event(event vaxis.Event) bool {
}
type completions struct {
- ti *TextInput
+ ti *TextInput
+ valWidth int
+ descWidth int
}
func unquote(s string) string {
@@ -412,22 +431,13 @@ func unquote(s string) string {
return s
}
-func maxLen(ss []string) int {
- max := 0
- for _, s := range ss {
- l := runewidth.StringWidth(unquote(s))
- if l > max {
- max = l
- }
- }
- return max
-}
-
func (c *completions) Draw(ctx *Context) {
bg := c.ti.uiConfig.GetStyle(config.STYLE_COMPLETION_DEFAULT)
+ bgDesc := c.ti.uiConfig.GetStyle(config.STYLE_COMPLETION_DESCRIPTION)
gutter := c.ti.uiConfig.GetStyle(config.STYLE_COMPLETION_GUTTER)
pill := c.ti.uiConfig.GetStyle(config.STYLE_COMPLETION_PILL)
sel := c.ti.uiConfig.GetStyleSelected(config.STYLE_COMPLETION_DEFAULT)
+ selDesc := c.ti.uiConfig.GetStyleSelected(config.STYLE_COMPLETION_DESCRIPTION)
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', bg)
@@ -445,11 +455,20 @@ func (c *completions) Draw(ctx *Context) {
if idx > endIdx {
continue
}
+ val := runewidth.FillRight(unquote(opt.Value), c.valWidth)
+ desc := opt.Description
+ if desc != "" {
+ if runewidth.StringWidth(desc) > c.descWidth {
+ desc = runewidth.Truncate(desc, c.descWidth, "…")
+ }
+ desc = " " + runewidth.FillRight("("+desc+")", c.descWidth+2)
+ }
if c.index() == idx {
- ctx.Fill(0, idx-startIdx, ctx.Width(), 1, ' ', sel)
- ctx.Printf(0, idx-startIdx, sel, " %s ", unquote(opt))
+ n := ctx.Printf(0, idx-startIdx, sel, " %s", val)
+ ctx.Printf(n, idx-startIdx, selDesc, "%s ", desc)
} else {
- ctx.Printf(0, idx-startIdx, bg, " %s ", unquote(opt))
+ n := ctx.Printf(0, idx-startIdx, bg, " %s", val)
+ ctx.Printf(n, idx-startIdx, bgDesc, "%s ", desc)
}
}
@@ -548,23 +567,23 @@ func (c *completions) stem(stem string) {
c.ti.index = len(vaxis.Characters(c.ti.prefix + stem))
}
-func findStem(words []string) string {
+func findStem(words []opt.Completion) string {
if len(words) == 0 {
return ""
}
if len(words) == 1 {
- return words[0]
+ return words[0].Value
}
var stem string
stemLen := 1
- firstWord := []rune(words[0])
+ firstWord := []rune(words[0].Value)
for {
if len(firstWord) < stemLen {
return stem
}
var r rune = firstWord[stemLen-1]
for _, word := range words[1:] {
- runes := []rune(word)
+ runes := []rune(word.Value)
if len(runes) < stemLen {
return stem
}
diff --git a/main.go b/main.go
index 66c2ed1a..0d2bb0e4 100644
--- a/main.go
+++ b/main.go
@@ -11,7 +11,7 @@ import (
"sync"
"time"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
"git.sr.ht/~rjarry/aerc/app"
"git.sr.ht/~rjarry/aerc/commands"
@@ -50,24 +50,36 @@ func execCommand(
return err
}
-func getCompletions(cmdline string) ([]string, string) {
+func getCompletions(cmdline string) ([]opt.Completion, string) {
// complete template terms
if options, prefix, ok := commands.GetTemplateCompletion(cmdline); ok {
sort.Strings(options)
- return options, prefix
+ completions := make([]opt.Completion, 0, len(options))
+ for _, o := range options {
+ completions = append(completions, opt.Completion{
+ Value: o,
+ Description: "Template",
+ })
+ }
+ return completions, prefix
}
args := opt.LexArgs(cmdline)
if args.Count() < 2 && args.TrailingSpace() == "" {
// complete command names
- var completions []string
+ var completions []opt.Completion
for _, name := range commands.ActiveCommandNames() {
if strings.HasPrefix(name, cmdline) {
- completions = append(completions, name+" ")
+ completions = append(completions, opt.Completion{
+ Value: name + " ",
+ Description: "",
+ })
}
}
- sort.Strings(completions)
+ sort.Slice(completions, func(i, j int) bool {
+ return completions[i].Value < completions[j].Value
+ })
return completions, ""
}
diff --git a/stylesets/blue b/stylesets/blue
index 4fffca0a..7c1169fb 100644
--- a/stylesets/blue
+++ b/stylesets/blue
@@ -43,7 +43,6 @@ part_*.selected.fg=#ffffff
part_*.selected.bg=#005f87
part_filename.selected.bold=true
-completion_pill.reverse=true
selector_focused.bold=true
selector_focused.bg=#005f87
selector_focused.fg=white
@@ -54,7 +53,9 @@ default.selected.bold=true
default.selected.fg=white
default.selected.bg=#005f87
+completion_pill.reverse=true
completion_default.selected.bg=#005f87
+completion_description.dim=true
[viewer]
*.default=true
diff --git a/stylesets/default b/stylesets/default
index dd5f4a8d..22ea1701 100644
--- a/stylesets/default
+++ b/stylesets/default
@@ -48,9 +48,11 @@
#selector_focused.bg = 12
#selector_focused.fg = 15
+#completion_*.bg = 8
#completion_pill.bg = 12
-#completion_default.bg = 8
#completion_default.fg = 15
+#completion_description.fg = 15
+#completion_description.dim = true
#[viewer]
# Uncomment these two lines to reset all attributes in the [viewer] section.
diff --git a/stylesets/monochrome b/stylesets/monochrome
index 42d5352d..00b7f51b 100644
--- a/stylesets/monochrome
+++ b/stylesets/monochrome
@@ -30,6 +30,7 @@ part_filename.selected.bold = true
selector_focused.reverse = true
selector_chooser.bold = true
+completion_description.dim = true
[viewer]
*.default = true
diff --git a/stylesets/nord b/stylesets/nord
index 3d1d76a3..d8388b94 100644
--- a/stylesets/nord
+++ b/stylesets/nord
@@ -18,6 +18,7 @@ statusline_default.reverse=true
statusline_error.reverse=true
completion_pill.reverse=true
+completion_description.dim=true
border.fg = #49576b
diff --git a/stylesets/pink b/stylesets/pink
index 87428874..65ef2fe2 100644
--- a/stylesets/pink
+++ b/stylesets/pink
@@ -43,7 +43,6 @@ part_*.selected.fg=#ffffff
part_*.selected.bg=#de4e85
part_filename.selected.bold=true
-completion_pill.reverse=true
selector_focused.bold=true
selector_focused.bg=#de4e85
selector_focused.fg=white
@@ -54,7 +53,9 @@ default.selected.bold=true
default.selected.fg=white
default.selected.bg=#de4e85
+completion_pill.reverse=true
completion_default.selected.bg=#de4e85
+completion_description.dim=true
[viewer]
*.default=true
diff --git a/stylesets/solarized b/stylesets/solarized
index 29717c72..9308d785 100644
--- a/stylesets/solarized
+++ b/stylesets/solarized
@@ -8,6 +8,7 @@
*error.bold=true
border.reverse=true
completion_pill.reverse=true
+completion_description.dim=true
error.fg=#dc322f # red
header.bold=true
selector_chooser.bold=true
diff --git a/worker/imap/search.go b/worker/imap/search.go
index 970d4db6..4bcff69a 100644
--- a/worker/imap/search.go
+++ b/worker/imap/search.go
@@ -6,7 +6,7 @@ import (
"github.com/emersion/go-imap"
"git.sr.ht/~rjarry/aerc/worker/types"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
func translateSearch(c *types.SearchCriteria) *imap.SearchCriteria {
diff --git a/worker/lib/search.go b/worker/lib/search.go
index b98e2bbb..9715c4a1 100644
--- a/worker/lib/search.go
+++ b/worker/lib/search.go
@@ -10,7 +10,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib/rfc822"
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
func Search(messages []rfc822.RawMessage, criteria *types.SearchCriteria) ([]models.UID, error) {
diff --git a/worker/notmuch/search.go b/worker/notmuch/search.go
index a84711eb..ddbb13cd 100644
--- a/worker/notmuch/search.go
+++ b/worker/notmuch/search.go
@@ -9,7 +9,7 @@ import (
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
- "git.sr.ht/~rjarry/go-opt"
+ "git.sr.ht/~rjarry/go-opt/v2"
)
type queryBuilder struct {