~sircmpwn/aerc

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
1

[PATCH v7] Account Specific Bindings

Details
Message ID
<20210521160022.121437-1-jonathan@jonnobrow.co.uk>
DKIM signature
pass
Download raw message
Patch: +198 -58
---
 config/bindings.go    |  22 +++++
 config/config.go      | 205 +++++++++++++++++++++++++++++++-----------
 doc/aerc-config.5.scd |  15 ++++
 widgets/aerc.go       |  14 +--
 4 files changed, 198 insertions(+), 58 deletions(-)

diff --git a/config/bindings.go b/config/bindings.go
index 9956b41..23a082e 100644
--- a/config/bindings.go
+++ b/config/bindings.go
@@ -54,6 +54,28 @@ func MergeBindings(bindings ...*KeyBindings) *KeyBindings {
	return merged
}

func (config AercConfig) MergeContextualBinds(baseBinds *KeyBindings,
	contextType ContextType, reg string, bindCtx string) *KeyBindings {

	bindings := baseBinds
	for _, contextualBind := range config.ContextualBinds {
		if contextualBind.ContextType != contextType {
			continue
		}

		if !contextualBind.Regex.Match([]byte(reg)) {
			continue
		}

		if contextualBind.BindContext != bindCtx {
			continue
		}

		bindings = MergeBindings(bindings, contextualBind.Bindings)
	}
	return bindings
}

func (bindings *KeyBindings) Add(binding *Binding) {
	// TODO: Search for conflicts?
	bindings.bindings = append(bindings.bindings, binding)
diff --git a/config/config.go b/config/config.go
index af9c63b..6b4a7da 100644
--- a/config/config.go
+++ b/config/config.go
@@ -56,6 +56,7 @@ const (
	UI_CONTEXT_FOLDER ContextType = iota
	UI_CONTEXT_ACCOUNT
	UI_CONTEXT_SUBJECT
	BIND_CONTEXT_ACCOUNT
)

type UIConfigContext struct {
@@ -100,6 +101,13 @@ type BindingConfig struct {
	Terminal      *KeyBindings
}

type BindingConfigContext struct {
	ContextType ContextType
	Regex       *regexp.Regexp
	Bindings    *KeyBindings
	BindContext string
}

type ComposeConfig struct {
	Editor         string     `ini:"editor"`
	HeaderLayout   [][]string `ini:"-"`
@@ -134,17 +142,18 @@ type TemplateConfig struct {
}

type AercConfig struct {
	Bindings      BindingConfig
	Compose       ComposeConfig
	Ini           *ini.File       `ini:"-"`
	Accounts      []AccountConfig `ini:"-"`
	Filters       []FilterConfig  `ini:"-"`
	Viewer        ViewerConfig    `ini:"-"`
	Triggers      TriggersConfig  `ini:"-"`
	Ui            UIConfig
	ContextualUis []UIConfigContext
	General       GeneralConfig
	Templates     TemplateConfig
	Bindings        BindingConfig
	ContextualBinds []BindingConfigContext
	Compose         ComposeConfig
	Ini             *ini.File       `ini:"-"`
	Accounts        []AccountConfig `ini:"-"`
	Filters         []FilterConfig  `ini:"-"`
	Viewer          ViewerConfig    `ini:"-"`
	Triggers        TriggersConfig  `ini:"-"`
	Ui              UIConfig
	ContextualUis   []UIConfigContext
	General         GeneralConfig
	Templates       TemplateConfig
}

// Input: TimestampFormat
@@ -345,11 +354,13 @@ func (config *AercConfig) LoadConfig(file *ini.File) error {
			}
		}
	}

	if ui, err := file.GetSection("ui"); err == nil {
		if err := ui.MapTo(&config.Ui); err != nil {
			return err
		}
	}

	for _, sectionName := range file.SectionStrings() {
		if !strings.Contains(sectionName, "ui:") {
			continue
@@ -488,6 +499,9 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
			MessageView:   NewKeyBindings(),
			Terminal:      NewKeyBindings(),
		},

		ContextualBinds: []BindingConfigContext{},

		Ini: file,

		Ui: UIConfig{
@@ -565,6 +579,7 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
	} else {
		config.Accounts = accounts
	}

	filename = path.Join(*root, "binds.conf")
	binds, err := ini.Load(filename)
	if err != nil {
@@ -575,63 +590,147 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
			return nil, err
		}
	}
	groups := map[string]**KeyBindings{
		"default":  &config.Bindings.Global,
		"compose":  &config.Bindings.Compose,
		"messages": &config.Bindings.MessageList,
		"terminal": &config.Bindings.Terminal,
		"view":     &config.Bindings.MessageView,

	baseGroups := map[string]**KeyBindings{
		"default":         &config.Bindings.Global,
		"compose":         &config.Bindings.Compose,
		"messages":        &config.Bindings.MessageList,
		"terminal":        &config.Bindings.Terminal,
		"view":            &config.Bindings.MessageView,
		"compose::editor": &config.Bindings.ComposeEditor,
		"compose::review": &config.Bindings.ComposeReview,
	}
	for _, name := range binds.SectionStrings() {
		sec, err := binds.GetSection(name)
		if err != nil {
			return nil, err
		}
		group, ok := groups[strings.ToLower(name)]

	// Base Bindings
	for _, sectionName := range binds.SectionStrings() {
		// Handle :: delimeter
		baseSectionName := strings.Replace(sectionName, "::", "////", -1)
		sections := strings.Split(baseSectionName, ":")
		baseOnly := len(sections) == 1
		baseSectionName = strings.Replace(sections[0], "////", "::", -1)

		group, ok := baseGroups[strings.ToLower(baseSectionName)]
		if !ok {
			return nil, errors.New("Unknown keybinding group " + name)
			return nil, errors.New("Unknown keybinding group " + sectionName)
		}
		bindings := NewKeyBindings()
		for key, value := range sec.KeysHash() {
			if key == "$ex" {
				strokes, err := ParseKeyStrokes(value)
				if err != nil {
					return nil, err
				}
				if len(strokes) != 1 {
					return nil, errors.New(
						"Error: only one keystroke supported for $ex")
				}
				bindings.ExKey = strokes[0]
				continue
			}
			if key == "$noinherit" {
				if value == "false" {
					continue
				}
				if value != "true" {
					return nil, errors.New(
						"Error: expected 'true' or 'false' for $noinherit")
				}
				bindings.Globals = false
				continue
			}
			binding, err := ParseBinding(key, value)

		if baseOnly {
			err = config.LoadBinds(binds, baseSectionName, group)
			if err != nil {
				return nil, err
			}
			bindings.Add(binding)
		}
		*group = MergeBindings(bindings, *group)
	}
	// Globals can't inherit from themselves

	config.Bindings.Global.Globals = false
	for _, contextBind := range config.ContextualBinds {
		if contextBind.BindContext == "default" {
			contextBind.Bindings.Globals = false
		}
	}

	return config, nil
}

func LoadBindingSection(sec *ini.Section) (*KeyBindings, error) {
	bindings := NewKeyBindings()
	for key, value := range sec.KeysHash() {
		if key == "$ex" {
			strokes, err := ParseKeyStrokes(value)
			if err != nil {
				return nil, err
			}
			if len(strokes) != 1 {
				return nil, errors.New("Invalid binding")
			}
			bindings.ExKey = strokes[0]
			continue
		}
		if key == "$noinherit" {
			if value == "false" {
				continue
			}
			if value != "true" {
				return nil, errors.New("Invalid binding")
			}
			bindings.Globals = false
			continue
		}
		binding, err := ParseBinding(key, value)
		if err != nil {
			return nil, err
		}
		bindings.Add(binding)
	}
	return bindings, nil
}

func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup **KeyBindings) error {

	if sec, err := binds.GetSection(baseName); err == nil {
		binds, err := LoadBindingSection(sec)
		if err != nil {
			return err
		}
		*baseGroup = MergeBindings(binds, *baseGroup)
	}

	for _, sectionName := range binds.SectionStrings() {
		if !strings.Contains(sectionName, baseName+":") ||
			strings.Contains(sectionName, baseName+"::") {
			continue
		}

		bindSection, err := binds.GetSection(sectionName)
		if err != nil {
			return err
		}

		binds, err := LoadBindingSection(bindSection)
		if err != nil {
			return err
		}

		contextualBind :=
			BindingConfigContext{
				Bindings:    binds,
				BindContext: baseName,
			}

		var index int
		if strings.Contains(sectionName, "=") {
			index = strings.Index(sectionName, "=")
			value := string(sectionName[index+1:])
			contextualBind.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
			if err != nil {
				return err
			}
		} else {
			return fmt.Errorf("Invalid Bind Context regex in %s", sectionName)
		}

		switch sectionName[len(baseName)+1 : index] {
		case "account":
            acctName := sectionName[index+1:]
            valid := false
            for _, acctConf := range config.Accounts {
                if acctConf.Name == acctName {
                    valid = true
                }
            }
            if !valid {
                return fmt.Errorf("Invalid Account Name: %s", acctName)
            }
			contextualBind.ContextType = BIND_CONTEXT_ACCOUNT
		default:
			return fmt.Errorf("Unknown Context Bind Section: %s", sectionName)
		}
		config.ContextualBinds = append(config.ContextualBinds, contextualBind)
	}

	return nil
}

// checkConfigPerms checks for too open permissions
// printing the fix on stdout and returning an error
func checkConfigPerms(filename string) error {
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index d4de883..c89115f 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -487,6 +487,21 @@ are:
*[terminal]*
	keybindings for terminal tabs

You may also configure account specific key bindings for each context:

*[context:account=<AccountName>]*
	keybindings for this context and account, where <AccountName> matches
	the account name you provided in *accounts.conf*.

Example:
```
[messages:account=Mailbox]
c = :cf path:mailbox/** and<space>

[compose::editor:account=Mailbox2]
...
```

You may also configure global keybindings by placing them at the beginning of
the file, before specifying any context-specific sections. For each *key=value*
option specified, the _key_ is the keystrokes pressed (in order) to invoke this
diff --git a/widgets/aerc.go b/widgets/aerc.go
index 6df0c95..5661260 100644
--- a/widgets/aerc.go
+++ b/widgets/aerc.go
@@ -182,22 +182,26 @@ func (aerc *Aerc) Draw(ctx *ui.Context) {
}

func (aerc *Aerc) getBindings() *config.KeyBindings {
	selectedAccountName := ""
	if aerc.SelectedAccount() != nil {
		selectedAccountName = aerc.SelectedAccount().acct.Name
	}
	switch view := aerc.SelectedTab().(type) {
	case *AccountView:
		return aerc.conf.Bindings.MessageList
		return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageList, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "messages")
	case *AccountWizard:
		return aerc.conf.Bindings.AccountWizard
	case *Composer:
		switch view.Bindings() {
		case "compose::editor":
			return aerc.conf.Bindings.ComposeEditor
			return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.ComposeEditor, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose::editor")
		case "compose::review":
			return aerc.conf.Bindings.ComposeReview
			return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.ComposeReview, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose::review")
		default:
			return aerc.conf.Bindings.Compose
			return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.Compose, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose")
		}
	case *MessageViewer:
		return aerc.conf.Bindings.MessageView
		return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageView, config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "view")
	case *Terminal:
		return aerc.conf.Bindings.Terminal
	default:
-- 
2.31.1
Details
Message ID
<CG9WBZ891GHG.2P9FWO597SMQ@bisio>
In-Reply-To
<20210521160022.121437-1-jonathan@jonnobrow.co.uk> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
I've tried this patch and it works fine. However, I believe there's something
that could be improved: if you define a specific binding for one account, you're
forced to define that binding for all the accounts. It'd be nicer to be able to
define a default binding for all the accounts (non contextual) and then modify
that binding for some individual accounts.

An example. I can set:

```
[messages]
d = :move Deleted Items<Enter>
a = :move Archive<Enter>

[messages:account=ACCOUNT]
d = :move Bin<Enter>
a = :move Archived Mail<Enter>
```

In that case, however, only the first bindings take effect, and aerc ignores my
account specific bindings. If I delete the general non-account-specific
bindings, it works as expected, but this forces me to declare bindings for all
the configured accounts. Wouldn't it be nice to have general defaults and
specific tuning for some accounts?

Thanks for the patch, it's really useful for multi-account settings!

Regards,

On Fri May 21, 2021 at 6:00 PM CEST, Jonathan Bartlett wrote:
> ---
> config/bindings.go | 22 +++++
> config/config.go | 205 +++++++++++++++++++++++++++++++-----------
> doc/aerc-config.5.scd | 15 ++++
> widgets/aerc.go | 14 +--
> 4 files changed, 198 insertions(+), 58 deletions(-)
>
> diff --git a/config/bindings.go b/config/bindings.go
> index 9956b41..23a082e 100644
> --- a/config/bindings.go
> +++ b/config/bindings.go
> @@ -54,6 +54,28 @@ func MergeBindings(bindings ...*KeyBindings)
> *KeyBindings {
> return merged
> }
>  
> +func (config AercConfig) MergeContextualBinds(baseBinds *KeyBindings,
> + contextType ContextType, reg string, bindCtx string) *KeyBindings {
> +
> + bindings := baseBinds
> + for _, contextualBind := range config.ContextualBinds {
> + if contextualBind.ContextType != contextType {
> + continue
> + }
> +
> + if !contextualBind.Regex.Match([]byte(reg)) {
> + continue
> + }
> +
> + if contextualBind.BindContext != bindCtx {
> + continue
> + }
> +
> + bindings = MergeBindings(bindings, contextualBind.Bindings)
> + }
> + return bindings
> +}
> +
> func (bindings *KeyBindings) Add(binding *Binding) {
> // TODO: Search for conflicts?
> bindings.bindings = append(bindings.bindings, binding)
> diff --git a/config/config.go b/config/config.go
> index af9c63b..6b4a7da 100644
> --- a/config/config.go
> +++ b/config/config.go
> @@ -56,6 +56,7 @@ const (
> UI_CONTEXT_FOLDER ContextType = iota
> UI_CONTEXT_ACCOUNT
> UI_CONTEXT_SUBJECT
> + BIND_CONTEXT_ACCOUNT
> )
>  
> type UIConfigContext struct {
> @@ -100,6 +101,13 @@ type BindingConfig struct {
> Terminal *KeyBindings
> }
>  
> +type BindingConfigContext struct {
> + ContextType ContextType
> + Regex *regexp.Regexp
> + Bindings *KeyBindings
> + BindContext string
> +}
> +
> type ComposeConfig struct {
> Editor string `ini:"editor"`
> HeaderLayout [][]string `ini:"-"`
> @@ -134,17 +142,18 @@ type TemplateConfig struct {
> }
>  
> type AercConfig struct {
> - Bindings BindingConfig
> - Compose ComposeConfig
> - Ini *ini.File `ini:"-"`
> - Accounts []AccountConfig `ini:"-"`
> - Filters []FilterConfig `ini:"-"`
> - Viewer ViewerConfig `ini:"-"`
> - Triggers TriggersConfig `ini:"-"`
> - Ui UIConfig
> - ContextualUis []UIConfigContext
> - General GeneralConfig
> - Templates TemplateConfig
> + Bindings BindingConfig
> + ContextualBinds []BindingConfigContext
> + Compose ComposeConfig
> + Ini *ini.File `ini:"-"`
> + Accounts []AccountConfig `ini:"-"`
> + Filters []FilterConfig `ini:"-"`
> + Viewer ViewerConfig `ini:"-"`
> + Triggers TriggersConfig `ini:"-"`
> + Ui UIConfig
> + ContextualUis []UIConfigContext
> + General GeneralConfig
> + Templates TemplateConfig
> }
>  
> // Input: TimestampFormat
> @@ -345,11 +354,13 @@ func (config *AercConfig) LoadConfig(file
> *ini.File) error {
> }
> }
> }
> +
> if ui, err := file.GetSection("ui"); err == nil {
> if err := ui.MapTo(&config.Ui); err != nil {
> return err
> }
> }
> +
> for _, sectionName := range file.SectionStrings() {
> if !strings.Contains(sectionName, "ui:") {
> continue
> @@ -488,6 +499,9 @@ func LoadConfigFromFile(root *string, sharedir
> string) (*AercConfig, error) {
> MessageView: NewKeyBindings(),
> Terminal: NewKeyBindings(),
> },
> +
> + ContextualBinds: []BindingConfigContext{},
> +
> Ini: file,
>  
> Ui: UIConfig{
> @@ -565,6 +579,7 @@ func LoadConfigFromFile(root *string, sharedir
> string) (*AercConfig, error) {
> } else {
> config.Accounts = accounts
> }
> +
> filename = path.Join(*root, "binds.conf")
> binds, err := ini.Load(filename)
> if err != nil {
> @@ -575,63 +590,147 @@ func LoadConfigFromFile(root *string, sharedir
> string) (*AercConfig, error) {
> return nil, err
> }
> }
> - groups := map[string]**KeyBindings{
> - "default": &config.Bindings.Global,
> - "compose": &config.Bindings.Compose,
> - "messages": &config.Bindings.MessageList,
> - "terminal": &config.Bindings.Terminal,
> - "view": &config.Bindings.MessageView,
>  
> + baseGroups := map[string]**KeyBindings{
> + "default": &config.Bindings.Global,
> + "compose": &config.Bindings.Compose,
> + "messages": &config.Bindings.MessageList,
> + "terminal": &config.Bindings.Terminal,
> + "view": &config.Bindings.MessageView,
> "compose::editor": &config.Bindings.ComposeEditor,
> "compose::review": &config.Bindings.ComposeReview,
> }
> - for _, name := range binds.SectionStrings() {
> - sec, err := binds.GetSection(name)
> - if err != nil {
> - return nil, err
> - }
> - group, ok := groups[strings.ToLower(name)]
> +
> + // Base Bindings
> + for _, sectionName := range binds.SectionStrings() {
> + // Handle :: delimeter
> + baseSectionName := strings.Replace(sectionName, "::", "////", -1)
> + sections := strings.Split(baseSectionName, ":")
> + baseOnly := len(sections) == 1
> + baseSectionName = strings.Replace(sections[0], "////", "::", -1)
> +
> + group, ok := baseGroups[strings.ToLower(baseSectionName)]
> if !ok {
> - return nil, errors.New("Unknown keybinding group " + name)
> + return nil, errors.New("Unknown keybinding group " + sectionName)
> }
> - bindings := NewKeyBindings()
> - for key, value := range sec.KeysHash() {
> - if key == "$ex" {
> - strokes, err := ParseKeyStrokes(value)
> - if err != nil {
> - return nil, err
> - }
> - if len(strokes) != 1 {
> - return nil, errors.New(
> - "Error: only one keystroke supported for $ex")
> - }
> - bindings.ExKey = strokes[0]
> - continue
> - }
> - if key == "$noinherit" {
> - if value == "false" {
> - continue
> - }
> - if value != "true" {
> - return nil, errors.New(
> - "Error: expected 'true' or 'false' for $noinherit")
> - }
> - bindings.Globals = false
> - continue
> - }
> - binding, err := ParseBinding(key, value)
> +
> + if baseOnly {
> + err = config.LoadBinds(binds, baseSectionName, group)
> if err != nil {
> return nil, err
> }
> - bindings.Add(binding)
> }
> - *group = MergeBindings(bindings, *group)
> }
> - // Globals can't inherit from themselves
> +
> config.Bindings.Global.Globals = false
> + for _, contextBind := range config.ContextualBinds {
> + if contextBind.BindContext == "default" {
> + contextBind.Bindings.Globals = false
> + }
> + }
> +
> return config, nil
> }
>  
> +func LoadBindingSection(sec *ini.Section) (*KeyBindings, error) {
> + bindings := NewKeyBindings()
> + for key, value := range sec.KeysHash() {
> + if key == "$ex" {
> + strokes, err := ParseKeyStrokes(value)
> + if err != nil {
> + return nil, err
> + }
> + if len(strokes) != 1 {
> + return nil, errors.New("Invalid binding")
> + }
> + bindings.ExKey = strokes[0]
> + continue
> + }
> + if key == "$noinherit" {
> + if value == "false" {
> + continue
> + }
> + if value != "true" {
> + return nil, errors.New("Invalid binding")
> + }
> + bindings.Globals = false
> + continue
> + }
> + binding, err := ParseBinding(key, value)
> + if err != nil {
> + return nil, err
> + }
> + bindings.Add(binding)
> + }
> + return bindings, nil
> +}
> +
> +func (config *AercConfig) LoadBinds(binds *ini.File, baseName string,
> baseGroup **KeyBindings) error {
> +
> + if sec, err := binds.GetSection(baseName); err == nil {
> + binds, err := LoadBindingSection(sec)
> + if err != nil {
> + return err
> + }
> + *baseGroup = MergeBindings(binds, *baseGroup)
> + }
> +
> + for _, sectionName := range binds.SectionStrings() {
> + if !strings.Contains(sectionName, baseName+":") ||
> + strings.Contains(sectionName, baseName+"::") {
> + continue
> + }
> +
> + bindSection, err := binds.GetSection(sectionName)
> + if err != nil {
> + return err
> + }
> +
> + binds, err := LoadBindingSection(bindSection)
> + if err != nil {
> + return err
> + }
> +
> + contextualBind :=
> + BindingConfigContext{
> + Bindings: binds,
> + BindContext: baseName,
> + }
> +
> + var index int
> + if strings.Contains(sectionName, "=") {
> + index = strings.Index(sectionName, "=")
> + value := string(sectionName[index+1:])
> + contextualBind.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
> + if err != nil {
> + return err
> + }
> + } else {
> + return fmt.Errorf("Invalid Bind Context regex in %s", sectionName)
> + }
> +
> + switch sectionName[len(baseName)+1 : index] {
> + case "account":
> + acctName := sectionName[index+1:]
> + valid := false
> + for _, acctConf := range config.Accounts {
> + if acctConf.Name == acctName {
> + valid = true
> + }
> + }
> + if !valid {
> + return fmt.Errorf("Invalid Account Name: %s", acctName)
> + }
> + contextualBind.ContextType = BIND_CONTEXT_ACCOUNT
> + default:
> + return fmt.Errorf("Unknown Context Bind Section: %s", sectionName)
> + }
> + config.ContextualBinds = append(config.ContextualBinds,
> contextualBind)
> + }
> +
> + return nil
> +}
> +
> // checkConfigPerms checks for too open permissions
> // printing the fix on stdout and returning an error
> func checkConfigPerms(filename string) error {
> diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
> index d4de883..c89115f 100644
> --- a/doc/aerc-config.5.scd
> +++ b/doc/aerc-config.5.scd
> @@ -487,6 +487,21 @@ are:
> *[terminal]*
> keybindings for terminal tabs
>  
> +You may also configure account specific key bindings for each context:
> +
> +*[context:account=<AccountName>]*
> + keybindings for this context and account, where <AccountName> matches
> + the account name you provided in *accounts.conf*.
> +
> +Example:
> +```
> +[messages:account=Mailbox]
> +c = :cf path:mailbox/** and<space>
> +
> +[compose::editor:account=Mailbox2]
> +...
> +```
> +
> You may also configure global keybindings by placing them at the
> beginning of
> the file, before specifying any context-specific sections. For each
> *key=value*
> option specified, the _key_ is the keystrokes pressed (in order) to
> invoke this
> diff --git a/widgets/aerc.go b/widgets/aerc.go
> index 6df0c95..5661260 100644
> --- a/widgets/aerc.go
> +++ b/widgets/aerc.go
> @@ -182,22 +182,26 @@ func (aerc *Aerc) Draw(ctx *ui.Context) {
> }
>  
> func (aerc *Aerc) getBindings() *config.KeyBindings {
> + selectedAccountName := ""
> + if aerc.SelectedAccount() != nil {
> + selectedAccountName = aerc.SelectedAccount().acct.Name
> + }
> switch view := aerc.SelectedTab().(type) {
> case *AccountView:
> - return aerc.conf.Bindings.MessageList
> + return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageList,
> config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "messages")
> case *AccountWizard:
> return aerc.conf.Bindings.AccountWizard
> case *Composer:
> switch view.Bindings() {
> case "compose::editor":
> - return aerc.conf.Bindings.ComposeEditor
> + return
> aerc.conf.MergeContextualBinds(aerc.conf.Bindings.ComposeEditor,
> config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose::editor")
> case "compose::review":
> - return aerc.conf.Bindings.ComposeReview
> + return
> aerc.conf.MergeContextualBinds(aerc.conf.Bindings.ComposeReview,
> config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose::review")
> default:
> - return aerc.conf.Bindings.Compose
> + return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.Compose,
> config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "compose")
> }
> case *MessageViewer:
> - return aerc.conf.Bindings.MessageView
> + return aerc.conf.MergeContextualBinds(aerc.conf.Bindings.MessageView,
> config.BIND_CONTEXT_ACCOUNT, selectedAccountName, "view")
> case *Terminal:
> return aerc.conf.Bindings.Terminal
> default:
> --
> 2.31.1
Reply to thread Export thread (mbox)