lint: homogenize operations and minor fixes (gocritic)
Apply GoDoc comment policy (comments for humans should have a space after the //; machine-readable comments shouldn't) Use strings.ReplaceAll instead of strings.Replace when appropriate Remove if/else chains by replacing them with switches Use short assignment/increment notation Replace single case switches with if statements Combine else and if when appropriate Signed-off-by: Moritz Poldrack <moritz@poldrack.dev> Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
parent
c882cf9960
commit
978d35d356
52 changed files with 231 additions and 256 deletions
27
aerc.go
27
aerc.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -59,19 +60,20 @@ func execCommand(aerc *widgets.Aerc, ui *libui.UI, cmd []string) error {
|
||||||
cmds := getCommands(aerc.SelectedTabContent())
|
cmds := getCommands(aerc.SelectedTabContent())
|
||||||
for i, set := range cmds {
|
for i, set := range cmds {
|
||||||
err := set.ExecuteCommand(aerc, cmd)
|
err := set.ExecuteCommand(aerc, cmd)
|
||||||
if _, ok := err.(commands.NoSuchCommand); ok {
|
if err != nil {
|
||||||
if i == len(cmds)-1 {
|
if errors.As(err, new(commands.NoSuchCommand)) {
|
||||||
return err
|
if i == len(cmds)-1 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if errors.As(err, new(commands.ErrorExit)) {
|
||||||
|
ui.Exit()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
} else if _, ok := err.(commands.ErrorExit); ok {
|
|
||||||
ui.Exit()
|
|
||||||
return nil
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -123,8 +125,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'v' {
|
||||||
case 'v':
|
|
||||||
fmt.Println("aerc " + Version)
|
fmt.Println("aerc " + Version)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -153,7 +154,7 @@ func main() {
|
||||||
conf, err := config.LoadConfigFromFile(nil)
|
conf, err := config.LoadConfigFromFile(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1) //nolint:gocritic // PanicHandler does not need to run as it's not a panic
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -39,8 +39,7 @@ func (Clear) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 's' {
|
||||||
case 's':
|
|
||||||
clearSelected = true
|
clearSelected = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,8 +135,7 @@ func (ImportMbox) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
func(option string, err error) {
|
func(option string, err error) {
|
||||||
aerc.CloseDialog()
|
aerc.CloseDialog()
|
||||||
aerc.Invalidate()
|
aerc.Invalidate()
|
||||||
switch option {
|
if option == "Yes" {
|
||||||
case "Yes":
|
|
||||||
go importFolder()
|
go importFolder()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,9 +36,10 @@ func (Recover) Complete(aerc *widgets.Aerc, args []string) []string {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
if args[0] == "-" {
|
switch args[0] {
|
||||||
|
case "-":
|
||||||
return []string{"-f"}
|
return []string{"-f"}
|
||||||
} else if args[0] == "-f" {
|
case "-f":
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
for i, file := range files {
|
for i, file := range files {
|
||||||
files[i] = args[0] + " " + file
|
files[i] = args[0] + " " + file
|
||||||
|
@ -49,7 +50,7 @@ func (Recover) Complete(aerc *widgets.Aerc, args []string) []string {
|
||||||
return commands.FilterList(files, args[1], args[0]+" ",
|
return commands.FilterList(files, args[1], args[0]+" ",
|
||||||
aerc.SelectedAccountUiConfig().FuzzyComplete)
|
aerc.SelectedAccountUiConfig().FuzzyComplete)
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
// only accepts one file to recover
|
// only accepts one file to recover
|
||||||
return commands.FilterList(files, args[0], "", aerc.SelectedAccountUiConfig().FuzzyComplete)
|
return commands.FilterList(files, args[0], "", aerc.SelectedAccountUiConfig().FuzzyComplete)
|
||||||
}
|
}
|
||||||
|
@ -68,8 +69,7 @@ func (Recover) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'f' {
|
||||||
case 'f':
|
|
||||||
force = true
|
force = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,7 @@ func (RemoveDir) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'f' {
|
||||||
case 'f':
|
|
||||||
force = true
|
force = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,7 @@ func (Header) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
|
|
||||||
var force bool = false
|
var force bool = false
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'f' {
|
||||||
case 'f':
|
|
||||||
force = true
|
force = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,12 +250,13 @@ func parseScheme(uri *url.URL) (scheme string, auth string, err error) {
|
||||||
auth = "plain"
|
auth = "plain"
|
||||||
if uri.Scheme != "" {
|
if uri.Scheme != "" {
|
||||||
parts := strings.Split(uri.Scheme, "+")
|
parts := strings.Split(uri.Scheme, "+")
|
||||||
if len(parts) == 1 {
|
switch len(parts) {
|
||||||
|
case 1:
|
||||||
scheme = parts[0]
|
scheme = parts[0]
|
||||||
} else if len(parts) == 2 {
|
case 2:
|
||||||
scheme = parts[0]
|
scheme = parts[0]
|
||||||
auth = parts[1]
|
auth = parts[1]
|
||||||
} else {
|
default:
|
||||||
return "", "", fmt.Errorf("Unknown transfer protocol %s", uri.Scheme)
|
return "", "", fmt.Errorf("Unknown transfer protocol %s", uri.Scheme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,7 +381,7 @@ func newSmtpSender(ctx sendCtx) (io.WriteCloser, error) {
|
||||||
func connectSmtp(starttls bool, host string) (*smtp.Client, error) {
|
func connectSmtp(starttls bool, host string) (*smtp.Client, error) {
|
||||||
serverName := host
|
serverName := host
|
||||||
if !strings.ContainsRune(host, ':') {
|
if !strings.ContainsRune(host, ':') {
|
||||||
host = host + ":587" // Default to submission port
|
host += ":587" // Default to submission port
|
||||||
} else {
|
} else {
|
||||||
serverName = host[:strings.IndexRune(host, ':')]
|
serverName = host[:strings.IndexRune(host, ':')]
|
||||||
}
|
}
|
||||||
|
@ -402,14 +403,12 @@ func connectSmtp(starttls bool, host string) (*smtp.Client, error) {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, errors.Wrap(err, "StartTLS")
|
return nil, errors.Wrap(err, "StartTLS")
|
||||||
}
|
}
|
||||||
} else {
|
} else if starttls {
|
||||||
if starttls {
|
err := errors.New("STARTTLS requested, but not supported " +
|
||||||
err := errors.New("STARTTLS requested, but not supported " +
|
"by this SMTP server. Is someone tampering with your " +
|
||||||
"by this SMTP server. Is someone tampering with your " +
|
"connection?")
|
||||||
"connection?")
|
conn.Close()
|
||||||
conn.Close()
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
@ -417,7 +416,7 @@ func connectSmtp(starttls bool, host string) (*smtp.Client, error) {
|
||||||
func connectSmtps(host string) (*smtp.Client, error) {
|
func connectSmtps(host string) (*smtp.Client, error) {
|
||||||
serverName := host
|
serverName := host
|
||||||
if !strings.ContainsRune(host, ':') {
|
if !strings.ContainsRune(host, ':') {
|
||||||
host = host + ":465" // Default to smtps port
|
host += ":465" // Default to smtps port
|
||||||
} else {
|
} else {
|
||||||
serverName = host[:strings.IndexRune(host, ':')]
|
serverName = host[:strings.IndexRune(host, ':')]
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,15 +40,16 @@ func (ChangeTab) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
} else {
|
} else {
|
||||||
n, err := strconv.Atoi(joinedArgs)
|
n, err := strconv.Atoi(joinedArgs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if strings.HasPrefix(joinedArgs, "+") {
|
switch {
|
||||||
|
case strings.HasPrefix(joinedArgs, "+"):
|
||||||
for ; n > 0; n-- {
|
for ; n > 0; n-- {
|
||||||
aerc.NextTab()
|
aerc.NextTab()
|
||||||
}
|
}
|
||||||
} else if strings.HasPrefix(joinedArgs, "-") {
|
case strings.HasPrefix(joinedArgs, "-"):
|
||||||
for ; n < 0; n++ {
|
for ; n < 0; n++ {
|
||||||
aerc.PrevTab()
|
aerc.PrevTab()
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
ok := aerc.SelectTabIndex(n)
|
ok := aerc.SelectTabIndex(n)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New(
|
return errors.New(
|
||||||
|
|
|
@ -36,8 +36,7 @@ func (Copy) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
}
|
}
|
||||||
var createParents bool
|
var createParents bool
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'p' {
|
||||||
case 'p':
|
|
||||||
createParents = true
|
createParents = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,16 +61,17 @@ func (Mark) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
} else {
|
} else {
|
||||||
modFunc = store.Mark
|
modFunc = store.Mark
|
||||||
}
|
}
|
||||||
if all {
|
switch {
|
||||||
|
case all:
|
||||||
uids := store.Uids()
|
uids := store.Uids()
|
||||||
for _, uid := range uids {
|
for _, uid := range uids {
|
||||||
modFunc(uid)
|
modFunc(uid)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if visual {
|
case visual:
|
||||||
store.ToggleVisualMark()
|
store.ToggleVisualMark()
|
||||||
return nil
|
return nil
|
||||||
} else {
|
default:
|
||||||
modFunc(selected.Uid)
|
modFunc(selected.Uid)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -80,16 +81,17 @@ func (Mark) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return fmt.Errorf("visual mode not supported for this command")
|
return fmt.Errorf("visual mode not supported for this command")
|
||||||
}
|
}
|
||||||
|
|
||||||
if all && toggle {
|
switch {
|
||||||
|
case all && toggle:
|
||||||
uids := store.Uids()
|
uids := store.Uids()
|
||||||
for _, uid := range uids {
|
for _, uid := range uids {
|
||||||
store.ToggleMark(uid)
|
store.ToggleMark(uid)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if all && !toggle {
|
case all && !toggle:
|
||||||
store.ClearVisualMark()
|
store.ClearVisualMark()
|
||||||
return nil
|
return nil
|
||||||
} else {
|
default:
|
||||||
store.Unmark(selected.Uid)
|
store.Unmark(selected.Uid)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,7 @@ func (Move) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
}
|
}
|
||||||
var createParents bool
|
var createParents bool
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'p' {
|
||||||
case 'p':
|
|
||||||
createParents = true
|
createParents = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,11 +102,12 @@ func (FlagMsg) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
flagChosen = true
|
flagChosen = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if toggle {
|
switch {
|
||||||
|
case toggle:
|
||||||
actionName = "Toggling"
|
actionName = "Toggling"
|
||||||
} else if enable {
|
case enable:
|
||||||
actionName = "Setting"
|
actionName = "Setting"
|
||||||
} else {
|
default:
|
||||||
actionName = "Unsetting"
|
actionName = "Unsetting"
|
||||||
}
|
}
|
||||||
if optind != len(args) {
|
if optind != len(args) {
|
||||||
|
|
|
@ -42,8 +42,7 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'f' {
|
||||||
case 'f':
|
|
||||||
force = true
|
force = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,7 @@ func (NewAccount) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
}
|
}
|
||||||
wizard := widgets.NewAccountWizard(aerc.Config(), aerc)
|
wizard := widgets.NewAccountWizard(aerc.Config(), aerc)
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 't' {
|
||||||
case 't':
|
|
||||||
wizard.ConfigureTemporaryAccount(true)
|
wizard.ConfigureTemporaryAccount(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,7 @@ func (Quit) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
switch opt.Option {
|
if opt.Option == 'f' {
|
||||||
case 'f':
|
|
||||||
force = true
|
force = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (c *Completer) getAddressCmd(s string) (*exec.Cmd, error) {
|
||||||
if strings.TrimSpace(c.AddressBookCmd) == "" {
|
if strings.TrimSpace(c.AddressBookCmd) == "" {
|
||||||
return nil, fmt.Errorf("no command configured")
|
return nil, fmt.Errorf("no command configured")
|
||||||
}
|
}
|
||||||
queryCmd := strings.Replace(c.AddressBookCmd, "%s", s, -1)
|
queryCmd := strings.ReplaceAll(c.AddressBookCmd, "%s", s)
|
||||||
parts, err := shlex.Split(queryCmd)
|
parts, err := shlex.Split(queryCmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not lex command")
|
return nil, fmt.Errorf("could not lex command")
|
||||||
|
|
|
@ -182,11 +182,12 @@ func ParseKeyStrokes(keystrokes string) ([]KeyStroke, error) {
|
||||||
switch tok {
|
switch tok {
|
||||||
case '<':
|
case '<':
|
||||||
name, err := buf.ReadString(byte('>'))
|
name, err := buf.ReadString(byte('>'))
|
||||||
if err == io.EOF {
|
switch {
|
||||||
|
case err == io.EOF:
|
||||||
return nil, errors.New("Expecting '>'")
|
return nil, errors.New("Expecting '>'")
|
||||||
} else if err != nil {
|
case err != nil:
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if name == ">" {
|
case name == ">":
|
||||||
return nil, errors.New("Expected a key name")
|
return nil, errors.New("Expected a key name")
|
||||||
}
|
}
|
||||||
name = name[:len(name)-1]
|
name = name[:len(name)-1]
|
||||||
|
|
|
@ -294,42 +294,45 @@ func loadAccountConfig(path string) ([]AccountConfig, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for key, val := range sec.KeysHash() {
|
for key, val := range sec.KeysHash() {
|
||||||
if key == "folders" {
|
switch key {
|
||||||
|
case "folders":
|
||||||
folders := strings.Split(val, ",")
|
folders := strings.Split(val, ",")
|
||||||
sort.Strings(folders)
|
sort.Strings(folders)
|
||||||
account.Folders = folders
|
account.Folders = folders
|
||||||
} else if key == "folders-exclude" {
|
case "folders-exclude":
|
||||||
folders := strings.Split(val, ",")
|
folders := strings.Split(val, ",")
|
||||||
sort.Strings(folders)
|
sort.Strings(folders)
|
||||||
account.FoldersExclude = folders
|
account.FoldersExclude = folders
|
||||||
} else if key == "source" {
|
case "source":
|
||||||
sourceRemoteConfig.Value = val
|
sourceRemoteConfig.Value = val
|
||||||
} else if key == "source-cred-cmd" {
|
case "source-cred-cmd":
|
||||||
sourceRemoteConfig.PasswordCmd = val
|
sourceRemoteConfig.PasswordCmd = val
|
||||||
} else if key == "outgoing" {
|
case "outgoing":
|
||||||
account.Outgoing.Value = val
|
account.Outgoing.Value = val
|
||||||
} else if key == "outgoing-cred-cmd" {
|
case "outgoing-cred-cmd":
|
||||||
account.Outgoing.PasswordCmd = val
|
account.Outgoing.PasswordCmd = val
|
||||||
} else if key == "from" {
|
case "from":
|
||||||
account.From = val
|
account.From = val
|
||||||
} else if key == "aliases" {
|
case "aliases":
|
||||||
account.Aliases = val
|
account.Aliases = val
|
||||||
} else if key == "copy-to" {
|
case "copy-to":
|
||||||
account.CopyTo = val
|
account.CopyTo = val
|
||||||
} else if key == "archive" {
|
case "archive":
|
||||||
account.Archive = val
|
account.Archive = val
|
||||||
} else if key == "enable-folders-sort" {
|
case "enable-folders-sort":
|
||||||
account.EnableFoldersSort, _ = strconv.ParseBool(val)
|
account.EnableFoldersSort, _ = strconv.ParseBool(val)
|
||||||
} else if key == "pgp-key-id" {
|
case "pgp-key-id":
|
||||||
account.PgpKeyId = val
|
account.PgpKeyId = val
|
||||||
} else if key == "pgp-auto-sign" {
|
case "pgp-auto-sign":
|
||||||
account.PgpAutoSign, _ = strconv.ParseBool(val)
|
account.PgpAutoSign, _ = strconv.ParseBool(val)
|
||||||
} else if key == "pgp-opportunistic-encrypt" {
|
case "pgp-opportunistic-encrypt":
|
||||||
account.PgpOpportunisticEncrypt, _ = strconv.ParseBool(val)
|
account.PgpOpportunisticEncrypt, _ = strconv.ParseBool(val)
|
||||||
} else if key == "address-book-cmd" {
|
case "address-book-cmd":
|
||||||
account.AddressBookCmd = val
|
account.AddressBookCmd = val
|
||||||
} else if key != "name" {
|
default:
|
||||||
account.Params[key] = val
|
if key != "name" {
|
||||||
|
account.Params[key] = val
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if account.Source == "" {
|
if account.Source == "" {
|
||||||
|
@ -428,25 +431,26 @@ func (config *AercConfig) LoadConfig(file *ini.File) error {
|
||||||
Command: cmd,
|
Command: cmd,
|
||||||
Filter: match,
|
Filter: match,
|
||||||
}
|
}
|
||||||
if strings.Contains(match, ",~") {
|
switch {
|
||||||
|
case strings.Contains(match, ",~"):
|
||||||
filter.FilterType = FILTER_HEADER
|
filter.FilterType = FILTER_HEADER
|
||||||
header := filter.Filter[:strings.Index(filter.Filter, ",")]
|
header := filter.Filter[:strings.Index(filter.Filter, ",")] //nolint:gocritic // guarded by strings.Contains
|
||||||
regex := filter.Filter[strings.Index(filter.Filter, "~")+1:]
|
regex := filter.Filter[strings.Index(filter.Filter, "~")+1:]
|
||||||
filter.Header = strings.ToLower(header)
|
filter.Header = strings.ToLower(header)
|
||||||
filter.Regex, err = regexp.Compile(regex)
|
filter.Regex, err = regexp.Compile(regex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if strings.ContainsRune(match, ',') {
|
case strings.ContainsRune(match, ','):
|
||||||
filter.FilterType = FILTER_HEADER
|
filter.FilterType = FILTER_HEADER
|
||||||
header := filter.Filter[:strings.Index(filter.Filter, ",")]
|
header := filter.Filter[:strings.Index(filter.Filter, ",")] //nolint:gocritic // guarded by strings.Contains
|
||||||
value := filter.Filter[strings.Index(filter.Filter, ",")+1:]
|
value := filter.Filter[strings.Index(filter.Filter, ",")+1:]
|
||||||
filter.Header = strings.ToLower(header)
|
filter.Header = strings.ToLower(header)
|
||||||
filter.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
|
filter.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
filter.FilterType = FILTER_MIMETYPE
|
filter.FilterType = FILTER_MIMETYPE
|
||||||
}
|
}
|
||||||
config.Filters = append(config.Filters, filter)
|
config.Filters = append(config.Filters, filter)
|
||||||
|
@ -475,8 +479,7 @@ func (config *AercConfig) LoadConfig(file *ini.File) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for key, val := range compose.KeysHash() {
|
for key, val := range compose.KeysHash() {
|
||||||
switch key {
|
if key == "header-layout" {
|
||||||
case "header-layout":
|
|
||||||
config.Compose.HeaderLayout = parseLayout(val)
|
config.Compose.HeaderLayout = parseLayout(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,21 +534,22 @@ func (config *AercConfig) LoadConfig(file *ini.File) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var index int
|
var index int
|
||||||
if strings.Contains(sectionName, "~") {
|
switch {
|
||||||
|
case strings.Contains(sectionName, "~"):
|
||||||
index = strings.Index(sectionName, "~")
|
index = strings.Index(sectionName, "~")
|
||||||
regex := string(sectionName[index+1:])
|
regex := string(sectionName[index+1:])
|
||||||
contextualUi.Regex, err = regexp.Compile(regex)
|
contextualUi.Regex, err = regexp.Compile(regex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if strings.Contains(sectionName, "=") {
|
case strings.Contains(sectionName, "="):
|
||||||
index = strings.Index(sectionName, "=")
|
index = strings.Index(sectionName, "=")
|
||||||
value := string(sectionName[index+1:])
|
value := string(sectionName[index+1:])
|
||||||
contextualUi.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
|
contextualUi.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
return fmt.Errorf("Invalid Ui Context regex in %s", sectionName)
|
return fmt.Errorf("Invalid Ui Context regex in %s", sectionName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,8 +654,7 @@ func validatePgpProvider(section *ini.Section) error {
|
||||||
"internal": true,
|
"internal": true,
|
||||||
}
|
}
|
||||||
for key, val := range section.KeysHash() {
|
for key, val := range section.KeysHash() {
|
||||||
switch key {
|
if key == "pgp-provider" {
|
||||||
case "pgp-provider":
|
|
||||||
if !m[strings.ToLower(val)] {
|
if !m[strings.ToLower(val)] {
|
||||||
return fmt.Errorf("%v must be either 'gpg' or 'internal'", key)
|
return fmt.Errorf("%v must be either 'gpg' or 'internal'", key)
|
||||||
}
|
}
|
||||||
|
@ -857,10 +860,10 @@ func LoadConfigFromFile(root *string) (*AercConfig, error) {
|
||||||
// Base Bindings
|
// Base Bindings
|
||||||
for _, sectionName := range binds.SectionStrings() {
|
for _, sectionName := range binds.SectionStrings() {
|
||||||
// Handle :: delimeter
|
// Handle :: delimeter
|
||||||
baseSectionName := strings.Replace(sectionName, "::", "////", -1)
|
baseSectionName := strings.ReplaceAll(sectionName, "::", "////")
|
||||||
sections := strings.Split(baseSectionName, ":")
|
sections := strings.Split(baseSectionName, ":")
|
||||||
baseOnly := len(sections) == 1
|
baseOnly := len(sections) == 1
|
||||||
baseSectionName = strings.Replace(sections[0], "////", "::", -1)
|
baseSectionName = strings.ReplaceAll(sections[0], "////", "::")
|
||||||
|
|
||||||
group, ok := baseGroups[strings.ToLower(baseSectionName)]
|
group, ok := baseGroups[strings.ToLower(baseSectionName)]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -82,14 +82,16 @@ func CreateParser(m Method) func(*mail.Header, []string) (*Details, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
identifier, results, err := authres.Parse(headerText)
|
identifier, results, err := authres.Parse(headerText)
|
||||||
if err != nil && err.Error() == "msgauth: unsupported version" {
|
// TODO: refactor to use errors.Is
|
||||||
|
switch {
|
||||||
|
case err != nil && err.Error() == "msgauth: unsupported version":
|
||||||
// Some MTA write their authres header without an identifier
|
// Some MTA write their authres header without an identifier
|
||||||
// which does not conform to RFC but still exists in the wild
|
// which does not conform to RFC but still exists in the wild
|
||||||
identifier, results, err = authres.Parse("unknown;" + headerText)
|
identifier, results, err = authres.Parse("unknown;" + headerText)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if err != nil && err.Error() == "msgauth: malformed authentication method and value" {
|
case err != nil && err.Error() == "msgauth: malformed authentication method and value":
|
||||||
// the go-msgauth parser doesn't like semi-colons in the comments
|
// the go-msgauth parser doesn't like semi-colons in the comments
|
||||||
// as a work-around we remove those
|
// as a work-around we remove those
|
||||||
cleanHeader := cleaner.ReplaceAllString(headerText, "${1}${2}")
|
cleanHeader := cleaner.ReplaceAllString(headerText, "${1}${2}")
|
||||||
|
@ -97,7 +99,7 @@ func CreateParser(m Method) func(*mail.Header, []string) (*Details, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if err != nil {
|
case err != nil:
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,11 +298,12 @@ func ParseMessageFormat(format string, timeFmt string, thisDayTimeFmt string,
|
||||||
recent := false
|
recent := false
|
||||||
answered := false
|
answered := false
|
||||||
for _, flag := range ctx.MsgInfo.Flags {
|
for _, flag := range ctx.MsgInfo.Flags {
|
||||||
if flag == models.SeenFlag {
|
switch flag {
|
||||||
|
case models.SeenFlag:
|
||||||
seen = true
|
seen = true
|
||||||
} else if flag == models.RecentFlag {
|
case models.RecentFlag:
|
||||||
recent = true
|
recent = true
|
||||||
} else if flag == models.AnsweredFlag {
|
case models.AnsweredFlag:
|
||||||
answered = true
|
answered = true
|
||||||
}
|
}
|
||||||
if flag == models.DeletedFlag {
|
if flag == models.DeletedFlag {
|
||||||
|
|
|
@ -121,8 +121,7 @@ func (store *MessageStore) FetchHeaders(uids []uint32,
|
||||||
}
|
}
|
||||||
if len(toFetch) > 0 {
|
if len(toFetch) > 0 {
|
||||||
store.worker.PostAction(&types.FetchMessageHeaders{Uids: toFetch}, func(msg types.WorkerMessage) {
|
store.worker.PostAction(&types.FetchMessageHeaders{Uids: toFetch}, func(msg types.WorkerMessage) {
|
||||||
switch msg.(type) {
|
if _, ok := msg.(*types.Error); ok {
|
||||||
case *types.Error:
|
|
||||||
for _, uid := range toFetch {
|
for _, uid := range toFetch {
|
||||||
delete(store.pendingHeaders, uid)
|
delete(store.pendingHeaders, uid)
|
||||||
delete(store.headerCallbacks, uid)
|
delete(store.headerCallbacks, uid)
|
||||||
|
@ -153,8 +152,7 @@ func (store *MessageStore) FetchFull(uids []uint32, cb func(*types.FullMessage))
|
||||||
store.worker.PostAction(&types.FetchFullMessages{
|
store.worker.PostAction(&types.FetchFullMessages{
|
||||||
Uids: toFetch,
|
Uids: toFetch,
|
||||||
}, func(msg types.WorkerMessage) {
|
}, func(msg types.WorkerMessage) {
|
||||||
switch msg.(type) {
|
if _, ok := msg.(*types.Error); ok {
|
||||||
case *types.Error:
|
|
||||||
for _, uid := range toFetch {
|
for _, uid := range toFetch {
|
||||||
delete(store.pendingBodies, uid)
|
delete(store.pendingBodies, uid)
|
||||||
delete(store.bodyCallbacks, uid)
|
delete(store.bodyCallbacks, uid)
|
||||||
|
@ -244,10 +242,8 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
|
||||||
case *types.MessageInfo:
|
case *types.MessageInfo:
|
||||||
if existing, ok := store.Messages[msg.Info.Uid]; ok && existing != nil {
|
if existing, ok := store.Messages[msg.Info.Uid]; ok && existing != nil {
|
||||||
merge(existing, msg.Info)
|
merge(existing, msg.Info)
|
||||||
} else {
|
} else if msg.Info.Envelope != nil {
|
||||||
if msg.Info.Envelope != nil {
|
store.Messages[msg.Info.Uid] = msg.Info
|
||||||
store.Messages[msg.Info.Uid] = msg.Info
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
seen := false
|
seen := false
|
||||||
recent := false
|
recent := false
|
||||||
|
@ -441,8 +437,7 @@ func (store *MessageStore) Delete(uids []uint32,
|
||||||
|
|
||||||
store.worker.PostAction(&types.DeleteMessages{Uids: uids},
|
store.worker.PostAction(&types.DeleteMessages{Uids: uids},
|
||||||
func(msg types.WorkerMessage) {
|
func(msg types.WorkerMessage) {
|
||||||
switch msg.(type) {
|
if _, ok := msg.(*types.Error); ok {
|
||||||
case *types.Error:
|
|
||||||
store.revertDeleted(uids)
|
store.revertDeleted(uids)
|
||||||
}
|
}
|
||||||
cb(msg)
|
cb(msg)
|
||||||
|
@ -726,8 +721,7 @@ func (store *MessageStore) Search(args []string, cb func([]uint32)) {
|
||||||
store.worker.PostAction(&types.SearchDirectory{
|
store.worker.PostAction(&types.SearchDirectory{
|
||||||
Argv: args,
|
Argv: args,
|
||||||
}, func(msg types.WorkerMessage) {
|
}, func(msg types.WorkerMessage) {
|
||||||
switch msg := msg.(type) {
|
if msg, ok := msg.(*types.SearchResults); ok {
|
||||||
case *types.SearchResults:
|
|
||||||
allowedUids := store.Uids()
|
allowedUids := store.Uids()
|
||||||
uids := make([]uint32, 0, len(msg.Uids))
|
uids := make([]uint32, 0, len(msg.Uids))
|
||||||
for _, uid := range msg.Uids {
|
for _, uid := range msg.Uids {
|
||||||
|
|
|
@ -35,7 +35,7 @@ func NewXDGOpen(filename string) *xdgOpen {
|
||||||
func (xdg *xdgOpen) SetArgs(args []string) {
|
func (xdg *xdgOpen) SetArgs(args []string) {
|
||||||
args = append([]string{}, args...) // don't overwrite array of caller
|
args = append([]string{}, args...) // don't overwrite array of caller
|
||||||
filename := xdg.args[len(xdg.args)-1]
|
filename := xdg.args[len(xdg.args)-1]
|
||||||
xdg.args = append(args, filename)
|
xdg.args = append(args, filename) //nolint:gocritic // intentional append to different slice
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the open handler.
|
// Start the open handler.
|
||||||
|
|
|
@ -69,10 +69,8 @@ func contentInfo(acct *accountState, fldr *folderState, texter Texter) []string
|
||||||
var status []string
|
var status []string
|
||||||
if fldr.FilterActivity != "" {
|
if fldr.FilterActivity != "" {
|
||||||
status = append(status, fldr.FilterActivity)
|
status = append(status, fldr.FilterActivity)
|
||||||
} else {
|
} else if fldr.Filter != "" {
|
||||||
if fldr.Filter != "" {
|
status = append(status, texter.FormatFilter(fldr.Filter))
|
||||||
status = append(status, texter.FormatFilter(fldr.Filter))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if fldr.Search != "" {
|
if fldr.Search != "" {
|
||||||
status = append(status, texter.FormatSearch(fldr.Search))
|
status = append(status, texter.FormatSearch(fldr.Search))
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
func FindPlaintext(bs *models.BodyStructure, path []int) []int {
|
func FindPlaintext(bs *models.BodyStructure, path []int) []int {
|
||||||
for i, part := range bs.Parts {
|
for i, part := range bs.Parts {
|
||||||
cur := append(path, i+1)
|
cur := append(path, i+1) //nolint:gocritic // intentional append to different slice
|
||||||
if strings.ToLower(part.MIMEType) == "text" &&
|
if strings.ToLower(part.MIMEType) == "text" &&
|
||||||
strings.ToLower(part.MIMESubType) == "plain" {
|
strings.ToLower(part.MIMESubType) == "plain" {
|
||||||
return cur
|
return cur
|
||||||
|
@ -24,7 +24,7 @@ func FindPlaintext(bs *models.BodyStructure, path []int) []int {
|
||||||
|
|
||||||
func FindCalendartext(bs *models.BodyStructure, path []int) []int {
|
func FindCalendartext(bs *models.BodyStructure, path []int) []int {
|
||||||
for i, part := range bs.Parts {
|
for i, part := range bs.Parts {
|
||||||
cur := append(path, i+1)
|
cur := append(path, i+1) //nolint:gocritic // intentional append to different slice
|
||||||
if strings.ToLower(part.MIMEType) == "text" &&
|
if strings.ToLower(part.MIMEType) == "text" &&
|
||||||
strings.ToLower(part.MIMESubType) == "calendar" {
|
strings.ToLower(part.MIMESubType) == "calendar" {
|
||||||
return cur
|
return cur
|
||||||
|
@ -40,7 +40,7 @@ func FindCalendartext(bs *models.BodyStructure, path []int) []int {
|
||||||
|
|
||||||
func FindFirstNonMultipart(bs *models.BodyStructure, path []int) []int {
|
func FindFirstNonMultipart(bs *models.BodyStructure, path []int) []int {
|
||||||
for i, part := range bs.Parts {
|
for i, part := range bs.Parts {
|
||||||
cur := append(path, i+1)
|
cur := append(path, i+1) //nolint:gocritic // intentional append to different slice
|
||||||
mimetype := strings.ToLower(part.MIMEType)
|
mimetype := strings.ToLower(part.MIMEType)
|
||||||
if mimetype != "multipart" {
|
if mimetype != "multipart" {
|
||||||
return cur
|
return cur
|
||||||
|
@ -55,7 +55,7 @@ func FindFirstNonMultipart(bs *models.BodyStructure, path []int) []int {
|
||||||
|
|
||||||
func FindAllNonMultipart(bs *models.BodyStructure, path []int, pathlist [][]int) [][]int {
|
func FindAllNonMultipart(bs *models.BodyStructure, path []int, pathlist [][]int) [][]int {
|
||||||
for i, part := range bs.Parts {
|
for i, part := range bs.Parts {
|
||||||
cur := append(path, i+1)
|
cur := append(path, i+1) //nolint:gocritic // intentional append to different slice
|
||||||
mimetype := strings.ToLower(part.MIMEType)
|
mimetype := strings.ToLower(part.MIMEType)
|
||||||
if mimetype != "multipart" {
|
if mimetype != "multipart" {
|
||||||
tmp := make([]int, len(cur))
|
tmp := make([]int, len(cur))
|
||||||
|
|
|
@ -76,8 +76,7 @@ func (bordered *Bordered) Draw(ctx *Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bordered *Bordered) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (bordered *Bordered) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch content := bordered.content.(type) {
|
if content, ok := bordered.content.(Mouseable); ok {
|
||||||
case Mouseable:
|
|
||||||
content.MouseEvent(localX, localY, event)
|
content.MouseEvent(localX, localY, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,8 +150,7 @@ func (grid *Grid) Draw(ctx *Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (grid *Grid) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (grid *Grid) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
|
||||||
invalid := grid.invalid
|
invalid := grid.invalid
|
||||||
|
|
||||||
grid.mutex.RLock()
|
grid.mutex.RLock()
|
||||||
|
|
|
@ -16,13 +16,14 @@ func (p *Popover) Draw(ctx *Context) {
|
||||||
width = ctx.Width() - p.x
|
width = ctx.Width() - p.x
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.y+p.height+1 < ctx.Height() {
|
switch {
|
||||||
|
case p.y+p.height+1 < ctx.Height():
|
||||||
// draw below
|
// draw below
|
||||||
subcontext = ctx.Subcontext(p.x, p.y+1, width, p.height)
|
subcontext = ctx.Subcontext(p.x, p.y+1, width, p.height)
|
||||||
} else if p.y-p.height >= 0 {
|
case p.y-p.height >= 0:
|
||||||
// draw above
|
// draw above
|
||||||
subcontext = ctx.Subcontext(p.x, p.y-p.height, width, p.height)
|
subcontext = ctx.Subcontext(p.x, p.y-p.height, width, p.height)
|
||||||
} else {
|
default:
|
||||||
// can't fit entirely above or below, so find the largest available
|
// can't fit entirely above or below, so find the largest available
|
||||||
// vertical space and shrink to fit
|
// vertical space and shrink to fit
|
||||||
if p.y > ctx.Height()-p.y {
|
if p.y > ctx.Height()-p.y {
|
||||||
|
|
|
@ -43,8 +43,7 @@ func (stack *Stack) Draw(ctx *Context) {
|
||||||
|
|
||||||
func (stack *Stack) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (stack *Stack) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
if len(stack.children) > 0 {
|
if len(stack.children) > 0 {
|
||||||
switch element := stack.Peek().(type) {
|
if element, ok := stack.Peek().(Mouseable); ok {
|
||||||
case Mouseable:
|
|
||||||
element.MouseEvent(localX, localY, event)
|
element.MouseEvent(localX, localY, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,27 +219,28 @@ func (tabs *Tabs) moveTabPriv(to int, relative bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tab := tabs.tabs[from]
|
tab := tabs.tabs[from]
|
||||||
if to > from {
|
switch {
|
||||||
|
case to > from:
|
||||||
copy(tabs.tabs[from:to], tabs.tabs[from+1:to+1])
|
copy(tabs.tabs[from:to], tabs.tabs[from+1:to+1])
|
||||||
for i, h := range tabs.history {
|
for i, h := range tabs.history {
|
||||||
if h == from {
|
if h == from {
|
||||||
tabs.history[i] = to
|
tabs.history[i] = to
|
||||||
}
|
}
|
||||||
if h > from && h <= to {
|
if h > from && h <= to {
|
||||||
tabs.history[i] -= 1
|
tabs.history[i]--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if from > to {
|
case from > to:
|
||||||
copy(tabs.tabs[to+1:from+1], tabs.tabs[to:from])
|
copy(tabs.tabs[to+1:from+1], tabs.tabs[to:from])
|
||||||
for i, h := range tabs.history {
|
for i, h := range tabs.history {
|
||||||
if h == from {
|
if h == from {
|
||||||
tabs.history[i] = to
|
tabs.history[i] = to
|
||||||
}
|
}
|
||||||
if h >= to && h < from {
|
if h >= to && h < from {
|
||||||
tabs.history[i] += 1
|
tabs.history[i]++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +340,7 @@ func (tabs *Tabs) removeHistory(index int) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if item > index {
|
if item > index {
|
||||||
item = item - 1
|
item--
|
||||||
}
|
}
|
||||||
// dedup
|
// dedup
|
||||||
if i > 0 && len(newHist) > 0 && item == newHist[len(newHist)-1] {
|
if i > 0 && len(newHist) > 0 && item == newHist[len(newHist)-1] {
|
||||||
|
@ -399,8 +400,7 @@ func (strip *TabStrip) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
}
|
}
|
||||||
unfocus := func() { changeFocus(false) }
|
unfocus := func() { changeFocus(false) }
|
||||||
refocus := func() { changeFocus(true) }
|
refocus := func() { changeFocus(true) }
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
|
||||||
switch event.Buttons() {
|
switch event.Buttons() {
|
||||||
case tcell.Button1:
|
case tcell.Button1:
|
||||||
selectedTab, ok := strip.clicked(localX, localY)
|
selectedTab, ok := strip.clicked(localX, localY)
|
||||||
|
@ -484,8 +484,7 @@ func (content *TabContent) MouseEvent(localX int, localY int, event tcell.Event)
|
||||||
content.parent.m.Lock()
|
content.parent.m.Lock()
|
||||||
tab := content.tabs[content.curIndex]
|
tab := content.tabs[content.curIndex]
|
||||||
content.parent.m.Unlock()
|
content.parent.m.Unlock()
|
||||||
switch tabContent := tab.Content.(type) {
|
if tabContent, ok := tab.Content.(Mouseable); ok {
|
||||||
case Mouseable:
|
|
||||||
tabContent.MouseEvent(localX, localY, event)
|
tabContent.MouseEvent(localX, localY, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,10 +148,8 @@ func (ti *TextInput) drawPopover(ctx *Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ti *TextInput) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (ti *TextInput) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
if event.Buttons() == tcell.Button1 {
|
||||||
switch event.Buttons() {
|
|
||||||
case tcell.Button1:
|
|
||||||
if localX >= len(ti.prompt)+1 && localX <= len(ti.text[ti.scroll:])+len(ti.prompt)+1 {
|
if localX >= len(ti.prompt)+1 && localX <= len(ti.text[ti.scroll:])+len(ti.prompt)+1 {
|
||||||
ti.index = localX - len(ti.prompt) - 1
|
ti.index = localX - len(ti.prompt) - 1
|
||||||
ti.ensureScroll()
|
ti.ensureScroll()
|
||||||
|
@ -190,7 +188,7 @@ func (ti *TextInput) ensureScroll() {
|
||||||
func (ti *TextInput) insert(ch rune) {
|
func (ti *TextInput) insert(ch rune) {
|
||||||
left := ti.text[:ti.index]
|
left := ti.text[:ti.index]
|
||||||
right := ti.text[ti.index:]
|
right := ti.text[ti.index:]
|
||||||
ti.text = append(left, append([]rune{ch}, right...)...)
|
ti.text = append(left, append([]rune{ch}, right...)...) //nolint:gocritic // intentional append to different slice
|
||||||
ti.index++
|
ti.index++
|
||||||
ti.ensureScroll()
|
ti.ensureScroll()
|
||||||
ti.Invalidate()
|
ti.Invalidate()
|
||||||
|
@ -323,8 +321,7 @@ func (ti *TextInput) OnFocusLost(onFocusLost func(ti *TextInput)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ti *TextInput) Event(event tcell.Event) bool {
|
func (ti *TextInput) Event(event tcell.Event) bool {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventKey); ok {
|
||||||
case *tcell.EventKey:
|
|
||||||
switch event.Key() {
|
switch event.Key() {
|
||||||
case tcell.KeyBackspace, tcell.KeyBackspace2:
|
case tcell.KeyBackspace, tcell.KeyBackspace2:
|
||||||
ti.invalidateCompletions()
|
ti.invalidateCompletions()
|
||||||
|
@ -464,8 +461,7 @@ func (c *completions) prev() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *completions) Event(e tcell.Event) bool {
|
func (c *completions) Event(e tcell.Event) bool {
|
||||||
switch e := e.(type) {
|
if e, ok := e.(*tcell.EventKey); ok {
|
||||||
case *tcell.EventKey:
|
|
||||||
switch e.Key() {
|
switch e.Key() {
|
||||||
case tcell.KeyTab:
|
case tcell.KeyTab:
|
||||||
if len(c.options) == 1 && c.idx >= 0 {
|
if len(c.options) == 1 && c.idx >= 0 {
|
||||||
|
@ -496,7 +492,7 @@ func (c *completions) Event(e tcell.Event) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func findStem(words []string) string {
|
func findStem(words []string) string {
|
||||||
if len(words) <= 0 {
|
if len(words) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if len(words) == 1 {
|
if len(words) == 1 {
|
||||||
|
@ -519,7 +515,7 @@ func findStem(words []string) string {
|
||||||
return stem
|
return stem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stem = stem + string(r)
|
stem += string(r)
|
||||||
stemLen++
|
stemLen++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,7 @@ func (state *UI) Tick() bool {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case event := <-state.tcEvents:
|
case event := <-state.tcEvents:
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventResize); ok {
|
||||||
case *tcell.EventResize:
|
|
||||||
state.screen.Clear()
|
state.screen.Clear()
|
||||||
width, height := event.Size()
|
width, height := event.Size()
|
||||||
state.ctx = NewContext(width, height, state.screen, state.onPopover)
|
state.ctx = NewContext(width, height, state.screen, state.onPopover)
|
||||||
|
|
|
@ -689,8 +689,7 @@ func (wizard *AccountWizard) Focus(focus bool) {
|
||||||
|
|
||||||
func (wizard *AccountWizard) Event(event tcell.Event) bool {
|
func (wizard *AccountWizard) Event(event tcell.Event) bool {
|
||||||
interactive := wizard.getInteractive()
|
interactive := wizard.getInteractive()
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventKey); ok {
|
||||||
case *tcell.EventKey:
|
|
||||||
switch event.Key() {
|
switch event.Key() {
|
||||||
case tcell.KeyUp:
|
case tcell.KeyUp:
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
|
@ -362,11 +362,11 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
|
||||||
seen = true
|
seen = true
|
||||||
}
|
}
|
||||||
if flag == models.RecentFlag {
|
if flag == models.RecentFlag {
|
||||||
recent = recent + 1
|
recent++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !seen {
|
if !seen {
|
||||||
unseen = unseen + 1
|
unseen++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if accurate {
|
if accurate {
|
||||||
|
@ -415,7 +415,7 @@ func (acct *AccountView) CheckMail() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Exclude selected mailbox, per IMAP specification
|
// Exclude selected mailbox, per IMAP specification
|
||||||
exclude := append(acct.AccountConfig().CheckMailExclude, acct.dirlist.Selected())
|
exclude := append(acct.AccountConfig().CheckMailExclude, acct.dirlist.Selected()) //nolint:gocritic // intentional append to different slice
|
||||||
dirs := acct.dirlist.List()
|
dirs := acct.dirlist.List()
|
||||||
dirs = acct.dirlist.FilterDirs(dirs, acct.AccountConfig().CheckMailInclude, false)
|
dirs = acct.dirlist.FilterDirs(dirs, acct.AccountConfig().CheckMailInclude, false)
|
||||||
dirs = acct.dirlist.FilterDirs(dirs, exclude, true)
|
dirs = acct.dirlist.FilterDirs(dirs, exclude, true)
|
||||||
|
|
|
@ -456,10 +456,8 @@ func (aerc *Aerc) focus(item ui.Interactive) {
|
||||||
if ok {
|
if ok {
|
||||||
interactive.Focus(false)
|
interactive.Focus(false)
|
||||||
}
|
}
|
||||||
} else {
|
} else if ok {
|
||||||
if ok {
|
interactive.Focus(true)
|
||||||
interactive.Focus(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,20 +25,17 @@ func (a *AuthInfo) Draw(ctx *ui.Context) {
|
||||||
defaultStyle := a.uiConfig.GetStyle(config.STYLE_DEFAULT)
|
defaultStyle := a.uiConfig.GetStyle(config.STYLE_DEFAULT)
|
||||||
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', defaultStyle)
|
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', defaultStyle)
|
||||||
var text string
|
var text string
|
||||||
if a.authdetails == nil {
|
switch {
|
||||||
|
case a.authdetails == nil:
|
||||||
text = "(no header)"
|
text = "(no header)"
|
||||||
ctx.Printf(0, 0, defaultStyle, text)
|
ctx.Printf(0, 0, defaultStyle, text)
|
||||||
} else if a.authdetails.Err != nil {
|
case a.authdetails.Err != nil:
|
||||||
style := a.uiConfig.GetStyle(config.STYLE_ERROR)
|
style := a.uiConfig.GetStyle(config.STYLE_ERROR)
|
||||||
text = a.authdetails.Err.Error()
|
text = a.authdetails.Err.Error()
|
||||||
ctx.Printf(0, 0, style, text)
|
ctx.Printf(0, 0, style, text)
|
||||||
} else {
|
default:
|
||||||
checkBounds := func(x int) bool {
|
checkBounds := func(x int) bool {
|
||||||
if x < ctx.Width() {
|
return x < ctx.Width()
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setResult := func(result auth.Result) (string, tcell.Style) {
|
setResult := func(result auth.Result) (string, tcell.Style) {
|
||||||
switch result {
|
switch result {
|
||||||
|
|
|
@ -527,11 +527,12 @@ func (c *Composer) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Composer) Bindings() string {
|
func (c *Composer) Bindings() string {
|
||||||
if c.editor == nil {
|
switch c.editor {
|
||||||
|
case nil:
|
||||||
return "compose::review"
|
return "compose::review"
|
||||||
} else if c.editor == c.focusable[c.focused] {
|
case c.focusable[c.focused]:
|
||||||
return "compose::editor"
|
return "compose::editor"
|
||||||
} else {
|
default:
|
||||||
return "compose"
|
return "compose"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -798,10 +799,8 @@ func (c *Composer) resetReview() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Composer) termEvent(event tcell.Event) bool {
|
func (c *Composer) termEvent(event tcell.Event) bool {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
if event.Buttons() == tcell.Button1 {
|
||||||
switch event.Buttons() {
|
|
||||||
case tcell.Button1:
|
|
||||||
c.FocusTerminal()
|
c.FocusTerminal()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1041,10 +1040,8 @@ func (he *headerEditor) Draw(ctx *ui.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (he *headerEditor) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (he *headerEditor) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
if event.Buttons() == tcell.Button1 {
|
||||||
switch event.Buttons() {
|
|
||||||
case tcell.Button1:
|
|
||||||
he.focused = true
|
he.focused = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1117,7 @@ func newReviewMessage(composer *Composer, err error) *reviewMessage {
|
||||||
inputs = append(inputs, config.FormatKeyStrokes(input))
|
inputs = append(inputs, config.FormatKeyStrokes(input))
|
||||||
}
|
}
|
||||||
actions = append(actions, fmt.Sprintf(" %-6s %-40s %s",
|
actions = append(actions, fmt.Sprintf(" %-6s %-40s %s",
|
||||||
strings.Join(inputs[:], ", "), name, cmd))
|
strings.Join(inputs, ", "), name, cmd))
|
||||||
}
|
}
|
||||||
|
|
||||||
spec := []ui.GridSpec{
|
spec := []ui.GridSpec{
|
||||||
|
|
|
@ -270,11 +270,12 @@ func (dirlist *DirectoryList) getRUEString(name string) string {
|
||||||
}
|
}
|
||||||
di := msgStore.DirInfo
|
di := msgStore.DirInfo
|
||||||
rueString := ""
|
rueString := ""
|
||||||
if di.Recent > 0 {
|
switch {
|
||||||
|
case di.Recent > 0:
|
||||||
rueString = fmt.Sprintf("%d/%d/%d", di.Recent, di.Unseen, di.Exists)
|
rueString = fmt.Sprintf("%d/%d/%d", di.Recent, di.Unseen, di.Exists)
|
||||||
} else if di.Unseen > 0 {
|
case di.Unseen > 0:
|
||||||
rueString = fmt.Sprintf("%d/%d", di.Unseen, di.Exists)
|
rueString = fmt.Sprintf("%d/%d", di.Unseen, di.Exists)
|
||||||
} else if di.Exists > 0 {
|
case di.Exists > 0:
|
||||||
rueString = fmt.Sprintf("%d", di.Exists)
|
rueString = fmt.Sprintf("%d", di.Exists)
|
||||||
}
|
}
|
||||||
return rueString
|
return rueString
|
||||||
|
@ -358,8 +359,7 @@ func (dirlist *DirectoryList) drawScrollbar(ctx *ui.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dirlist *DirectoryList) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (dirlist *DirectoryList) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
|
||||||
switch event.Buttons() {
|
switch event.Buttons() {
|
||||||
case tcell.Button1:
|
case tcell.Button1:
|
||||||
clickedDir, ok := dirlist.Clicked(localX, localY)
|
clickedDir, ok := dirlist.Clicked(localX, localY)
|
||||||
|
|
|
@ -129,8 +129,7 @@ func (dt *DirectoryTree) Draw(ctx *ui.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dt *DirectoryTree) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (dt *DirectoryTree) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
|
||||||
switch event.Buttons() {
|
switch event.Buttons() {
|
||||||
case tcell.Button1:
|
case tcell.Button1:
|
||||||
clickedDir, ok := dt.Clicked(localX, localY)
|
clickedDir, ok := dt.Clicked(localX, localY)
|
||||||
|
@ -194,7 +193,7 @@ func (dt *DirectoryTree) NextPrev(delta int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < delta; {
|
for i := 0; i < delta; {
|
||||||
newIdx = newIdx + step
|
newIdx += step
|
||||||
if newIdx < 0 {
|
if newIdx < 0 {
|
||||||
newIdx = ndirs - 1
|
newIdx = ndirs - 1
|
||||||
} else if newIdx >= ndirs {
|
} else if newIdx >= ndirs {
|
||||||
|
@ -378,7 +377,7 @@ func buildTree(node *types.Thread, stree [][]string, defaultUid uint32) {
|
||||||
m := make(map[string][][]string)
|
m := make(map[string][][]string)
|
||||||
for _, branch := range stree {
|
for _, branch := range stree {
|
||||||
if len(branch) > 1 {
|
if len(branch) > 1 {
|
||||||
next := append(m[branch[0]], branch[1:])
|
next := append(m[branch[0]], branch[1:]) //nolint:gocritic // intentional append to different slice
|
||||||
m[branch[0]] = next
|
m[branch[0]] = next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,8 +72,7 @@ func (ex *ExLine) Focus(focus bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ex *ExLine) Event(event tcell.Event) bool {
|
func (ex *ExLine) Event(event tcell.Event) bool {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventKey); ok {
|
||||||
case *tcell.EventKey:
|
|
||||||
switch event.Key() {
|
switch event.Key() {
|
||||||
case tcell.KeyEnter, tcell.KeyCtrlJ:
|
case tcell.KeyEnter, tcell.KeyCtrlJ:
|
||||||
cmd := ex.input.String()
|
cmd := ex.input.String()
|
||||||
|
|
|
@ -288,8 +288,7 @@ func (ml *MessageList) drawScrollbar(ctx *ui.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *MessageList) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (ml *MessageList) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
|
||||||
switch event.Buttons() {
|
switch event.Buttons() {
|
||||||
case tcell.Button1:
|
case tcell.Button1:
|
||||||
if ml.aerc == nil {
|
if ml.aerc == nil {
|
||||||
|
|
|
@ -182,7 +182,7 @@ func enumerateParts(acct *AccountView, conf *config.AercConfig,
|
||||||
) ([]*PartViewer, error) {
|
) ([]*PartViewer, error) {
|
||||||
var parts []*PartViewer
|
var parts []*PartViewer
|
||||||
for i, part := range body.Parts {
|
for i, part := range body.Parts {
|
||||||
curindex := append(index, i+1)
|
curindex := append(index, i+1) //nolint:gocritic // intentional append to different slice
|
||||||
if part.MIMEType == "multipart" {
|
if part.MIMEType == "multipart" {
|
||||||
// Multipart meta-parts are faked
|
// Multipart meta-parts are faked
|
||||||
pv := &PartViewer{part: part}
|
pv := &PartViewer{part: part}
|
||||||
|
@ -437,8 +437,7 @@ func (ps *PartSwitcher) Draw(ctx *ui.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *PartSwitcher) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (ps *PartSwitcher) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
|
||||||
switch event.Buttons() {
|
switch event.Buttons() {
|
||||||
case tcell.Button1:
|
case tcell.Button1:
|
||||||
height := len(ps.parts)
|
height := len(ps.parts)
|
||||||
|
@ -785,7 +784,7 @@ func newNoFilterConfigured(pv *PartViewer) *ui.Grid {
|
||||||
inputs = append(inputs, config.FormatKeyStrokes(input))
|
inputs = append(inputs, config.FormatKeyStrokes(input))
|
||||||
}
|
}
|
||||||
actions = append(actions, fmt.Sprintf(" %-6s %-29s %s",
|
actions = append(actions, fmt.Sprintf(" %-6s %-29s %s",
|
||||||
strings.Join(inputs[:], ", "), name, cmd))
|
strings.Join(inputs, ", "), name, cmd))
|
||||||
}
|
}
|
||||||
|
|
||||||
spec := []ui.GridSpec{
|
spec := []ui.GridSpec{
|
||||||
|
|
|
@ -132,8 +132,7 @@ func (sel *Selector) Focus(focus bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sel *Selector) Event(event tcell.Event) bool {
|
func (sel *Selector) Event(event tcell.Event) bool {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventKey); ok {
|
||||||
case *tcell.EventKey:
|
|
||||||
switch event.Key() {
|
switch event.Key() {
|
||||||
case tcell.KeyCtrlH:
|
case tcell.KeyCtrlH:
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
|
@ -343,8 +343,7 @@ func (term *Terminal) Draw(ctx *ui.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) MouseEvent(localX int, localY int, event tcell.Event) {
|
func (term *Terminal) MouseEvent(localX int, localY int, event tcell.Event) {
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventMouse); ok {
|
||||||
case *tcell.EventMouse:
|
|
||||||
if term.OnEvent != nil {
|
if term.OnEvent != nil {
|
||||||
if term.OnEvent(event) {
|
if term.OnEvent(event) {
|
||||||
return
|
return
|
||||||
|
@ -399,22 +398,20 @@ func (term *Terminal) Event(event tcell.Event) bool {
|
||||||
if term.closed {
|
if term.closed {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
switch event := event.(type) {
|
if event, ok := event.(*tcell.EventKey); ok {
|
||||||
case *tcell.EventKey:
|
|
||||||
if event.Key() == tcell.KeyRune {
|
if event.Key() == tcell.KeyRune {
|
||||||
term.vterm.KeyboardUnichar(
|
term.vterm.KeyboardUnichar(
|
||||||
event.Rune(), convertMods(event.Modifiers()))
|
event.Rune(), convertMods(event.Modifiers()))
|
||||||
} else {
|
} else if key, ok := keyMap[event.Key()]; ok {
|
||||||
if key, ok := keyMap[event.Key()]; ok {
|
switch {
|
||||||
if key.Key == vterm.KeyNone {
|
case key.Key == vterm.KeyNone:
|
||||||
term.vterm.KeyboardUnichar(
|
term.vterm.KeyboardUnichar(
|
||||||
key.Rune, key.Mod)
|
key.Rune, key.Mod)
|
||||||
} else if key.Mod == vterm.ModNone {
|
case key.Mod == vterm.ModNone:
|
||||||
term.vterm.KeyboardKey(key.Key,
|
term.vterm.KeyboardKey(key.Key,
|
||||||
convertMods(event.Modifiers()))
|
convertMods(event.Modifiers()))
|
||||||
} else {
|
default:
|
||||||
term.vterm.KeyboardKey(key.Key, key.Mod)
|
term.vterm.KeyboardKey(key.Key, key.Mod)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
term.flushTerminal()
|
term.flushTerminal()
|
||||||
|
@ -432,19 +429,21 @@ func (term *Terminal) styleFromCell(cell *vterm.ScreenCell) tcell.Style {
|
||||||
bg tcell.Color
|
bg tcell.Color
|
||||||
fg tcell.Color
|
fg tcell.Color
|
||||||
)
|
)
|
||||||
if background.IsDefaultBg() {
|
switch {
|
||||||
|
case background.IsDefaultBg():
|
||||||
bg = tcell.ColorDefault
|
bg = tcell.ColorDefault
|
||||||
} else if background.IsIndexed() {
|
case background.IsIndexed():
|
||||||
bg = tcell.Color(tcell.PaletteColor(int(background.GetIndex())))
|
bg = tcell.Color(tcell.PaletteColor(int(background.GetIndex())))
|
||||||
} else if background.IsRgb() {
|
case background.IsRgb():
|
||||||
r, g, b := background.GetRGB()
|
r, g, b := background.GetRGB()
|
||||||
bg = tcell.NewRGBColor(int32(r), int32(g), int32(b))
|
bg = tcell.NewRGBColor(int32(r), int32(g), int32(b))
|
||||||
}
|
}
|
||||||
if foreground.IsDefaultFg() {
|
switch {
|
||||||
|
case foreground.IsDefaultFg():
|
||||||
fg = tcell.ColorDefault
|
fg = tcell.ColorDefault
|
||||||
} else if foreground.IsIndexed() {
|
case foreground.IsIndexed():
|
||||||
fg = tcell.Color(tcell.PaletteColor(int(foreground.GetIndex())))
|
fg = tcell.Color(tcell.PaletteColor(int(foreground.GetIndex())))
|
||||||
} else if foreground.IsRgb() {
|
case foreground.IsRgb():
|
||||||
r, g, b := foreground.GetRGB()
|
r, g, b := foreground.GetRGB()
|
||||||
fg = tcell.NewRGBColor(int32(r), int32(g), int32(b))
|
fg = tcell.NewRGBColor(int32(r), int32(g), int32(b))
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,9 +165,9 @@ func (w *IMAPWorker) cleanCache() {
|
||||||
logging.Errorf("cannot clean database %d: %v", w.selected.UidValidity, err)
|
logging.Errorf("cannot clean database %d: %v", w.selected.UidValidity, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
removed = removed + 1
|
removed++
|
||||||
}
|
}
|
||||||
scanned = scanned + 1
|
scanned++
|
||||||
}
|
}
|
||||||
iter.Release()
|
iter.Release()
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
|
|
|
@ -61,7 +61,8 @@ func (i *idler) isReady() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *idler) Start() {
|
func (i *idler) Start() {
|
||||||
if i.isReady() {
|
switch {
|
||||||
|
case i.isReady():
|
||||||
i.stop = make(chan struct{})
|
i.stop = make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -87,16 +88,17 @@ func (i *idler) Start() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
} else if i.isWaiting() {
|
case i.isWaiting():
|
||||||
i.log("not started: wait for idle to exit")
|
i.log("not started: wait for idle to exit")
|
||||||
} else {
|
default:
|
||||||
i.log("not started: client not ready")
|
i.log("not started: client not ready")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *idler) Stop() error {
|
func (i *idler) Stop() error {
|
||||||
var reterr error
|
var reterr error
|
||||||
if i.isReady() {
|
switch {
|
||||||
|
case i.isReady():
|
||||||
close(i.stop)
|
close(i.stop)
|
||||||
select {
|
select {
|
||||||
case err := <-i.done:
|
case err := <-i.done:
|
||||||
|
@ -118,10 +120,10 @@ func (i *idler) Stop() error {
|
||||||
|
|
||||||
reterr = errIdleTimeout
|
reterr = errIdleTimeout
|
||||||
}
|
}
|
||||||
} else if i.isWaiting() {
|
case i.isWaiting():
|
||||||
i.log("not stopped: still idleing/hanging")
|
i.log("not stopped: still idleing/hanging")
|
||||||
reterr = errIdleModeHangs
|
reterr = errIdleModeHangs
|
||||||
} else {
|
default:
|
||||||
i.log("not stopped: client not ready")
|
i.log("not stopped: client not ready")
|
||||||
reterr = nil
|
reterr = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,11 +49,12 @@ func parseSearch(args []string) (*imap.SearchCriteria, error) {
|
||||||
text = true
|
text = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text {
|
switch {
|
||||||
|
case text:
|
||||||
criteria.Text = args[optind:]
|
criteria.Text = args[optind:]
|
||||||
} else if body {
|
case body:
|
||||||
criteria.Body = args[optind:]
|
criteria.Body = args[optind:]
|
||||||
} else {
|
default:
|
||||||
for _, arg := range args[optind:] {
|
for _, arg := range args[optind:] {
|
||||||
criteria.Header.Add("Subject", arg)
|
criteria.Header.Add("Subject", arg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,11 +53,12 @@ func GetSearchCriteria(args []string) (*searchCriteria, error) {
|
||||||
text = true
|
text = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text {
|
switch {
|
||||||
|
case text:
|
||||||
criteria.Text = args[optind:]
|
criteria.Text = args[optind:]
|
||||||
} else if body {
|
case body:
|
||||||
criteria.Body = args[optind:]
|
criteria.Body = args[optind:]
|
||||||
} else {
|
default:
|
||||||
for _, arg := range args[optind:] {
|
for _, arg := range args[optind:] {
|
||||||
criteria.Header.Add("Subject", arg)
|
criteria.Header.Add("Subject", arg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,13 +74,7 @@ func sortAddresses(messageInfos []*models.MessageInfo, criterion *types.SortCrit
|
||||||
if len(addressJ) > 0 {
|
if len(addressJ) > 0 {
|
||||||
firstJ = addressJ[0]
|
firstJ = addressJ[0]
|
||||||
}
|
}
|
||||||
if firstI == nil && firstJ == nil {
|
if firstI != nil && firstJ != nil {
|
||||||
return false
|
|
||||||
} else if firstI == nil && firstJ != nil {
|
|
||||||
return false
|
|
||||||
} else if firstI != nil && firstJ == nil {
|
|
||||||
return true
|
|
||||||
} else /* firstI != nil && firstJ != nil */ {
|
|
||||||
getName := func(addr *mail.Address) string {
|
getName := func(addr *mail.Address) string {
|
||||||
if addr.Name != "" {
|
if addr.Name != "" {
|
||||||
return addr.Name
|
return addr.Name
|
||||||
|
@ -89,6 +83,8 @@ func sortAddresses(messageInfos []*models.MessageInfo, criterion *types.SortCrit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getName(firstI) < getName(firstJ)
|
return getName(firstI) < getName(firstJ)
|
||||||
|
} else {
|
||||||
|
return firstI != nil && firstJ == nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func (c *Container) ListFolders() ([]string, error) {
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
}
|
}
|
||||||
dirPath = strings.TrimPrefix(dirPath, ".")
|
dirPath = strings.TrimPrefix(dirPath, ".")
|
||||||
dirPath = strings.Replace(dirPath, ".", "/", -1)
|
dirPath = strings.ReplaceAll(dirPath, ".", "/")
|
||||||
folders = append(folders, dirPath)
|
folders = append(folders, dirPath)
|
||||||
|
|
||||||
// Since all mailboxes are stored in a single directory, don't
|
// Since all mailboxes are stored in a single directory, don't
|
||||||
|
@ -124,7 +124,7 @@ func (c *Container) Dir(name string) maildir.Dir {
|
||||||
if name == "INBOX" {
|
if name == "INBOX" {
|
||||||
return maildir.Dir(c.dir)
|
return maildir.Dir(c.dir)
|
||||||
}
|
}
|
||||||
return maildir.Dir(filepath.Join(c.dir, "."+strings.Replace(name, "/", ".", -1)))
|
return maildir.Dir(filepath.Join(c.dir, "."+strings.ReplaceAll(name, "/", ".")))
|
||||||
}
|
}
|
||||||
return maildir.Dir(filepath.Join(c.dir, name))
|
return maildir.Dir(filepath.Join(c.dir, name))
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,11 +61,12 @@ func parseSearch(args []string) (*searchCriteria, error) {
|
||||||
text = true
|
text = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text {
|
switch {
|
||||||
|
case text:
|
||||||
criteria.Text = args[optind:]
|
criteria.Text = args[optind:]
|
||||||
} else if body {
|
case body:
|
||||||
criteria.Body = args[optind:]
|
criteria.Body = args[optind:]
|
||||||
} else {
|
default:
|
||||||
for _, arg := range args[optind:] {
|
for _, arg := range args[optind:] {
|
||||||
criteria.Header.Add("Subject", arg)
|
criteria.Header.Add("Subject", arg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,16 +81,18 @@ func (w *Worker) handleAction(action types.WorkerMessage) {
|
||||||
go w.handleCheckMail(msg)
|
go w.handleCheckMail(msg)
|
||||||
default:
|
default:
|
||||||
// Default handling, will be performed synchronously
|
// Default handling, will be performed synchronously
|
||||||
if err := w.handleMessage(msg); err == errUnsupported {
|
err := w.handleMessage(msg)
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, errUnsupported):
|
||||||
w.worker.PostMessage(&types.Unsupported{
|
w.worker.PostMessage(&types.Unsupported{
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
}, nil)
|
}, nil)
|
||||||
} else if err != nil {
|
case err != nil:
|
||||||
w.worker.PostMessage(&types.Error{
|
w.worker.PostMessage(&types.Error{
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
Error: err,
|
Error: err,
|
||||||
}, nil)
|
}, nil)
|
||||||
} else {
|
default:
|
||||||
w.done(msg)
|
w.done(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,11 +351,12 @@ func (db *DB) makeThread(parent *types.Thread, msgs *notmuch.Messages,
|
||||||
|
|
||||||
// We want to return the root node
|
// We want to return the root node
|
||||||
var root *types.Thread
|
var root *types.Thread
|
||||||
if parent != nil {
|
switch {
|
||||||
|
case parent != nil:
|
||||||
root = parent
|
root = parent
|
||||||
} else if lastSibling != nil {
|
case lastSibling != nil:
|
||||||
root = lastSibling // first iteration has no parent
|
root = lastSibling // first iteration has no parent
|
||||||
} else {
|
default:
|
||||||
return nil // we don't have any messages at all
|
return nil // we don't have any messages at all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue