diff options
author | Koni Marti <koni.marti@gmail.com> | 2022-04-16 00:22:20 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-04-17 12:18:33 +0200 |
commit | cb887a2d9d7d7cd5eb57d8849df40cecc3b90090 (patch) | |
tree | b7b23c34a772048484ed6e645226ff64fe103d64 | |
parent | a34be9eb36d26afdd723146673694db70662429c (diff) | |
download | aerc-cb887a2d9d7d7cd5eb57d8849df40cecc3b90090.tar.gz |
store: keep current message selected
Keep current message selected when clearing or changing filters and when
toggling threads.
Add -s flag to the clear command to also clear the selected message and
set cursor to the top of the message list.
Implements: https://todo.sr.ht/~rjarry/aerc/36
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r-- | commands/account/clear.go | 25 | ||||
-rw-r--r-- | commands/msg/toggle-threads.go | 1 | ||||
-rw-r--r-- | doc/aerc.1.scd | 8 | ||||
-rw-r--r-- | lib/msgstore.go | 23 |
4 files changed, 55 insertions, 2 deletions
diff --git a/commands/account/clear.go b/commands/account/clear.go index 64e70122..69fac2dc 100644 --- a/commands/account/clear.go +++ b/commands/account/clear.go @@ -5,6 +5,7 @@ import ( "git.sr.ht/~rjarry/aerc/lib/statusline" "git.sr.ht/~rjarry/aerc/widgets" + "git.sr.ht/~sircmpwn/getopt" ) type Clear struct{} @@ -30,6 +31,30 @@ func (Clear) Execute(aerc *widgets.Aerc, args []string) error { if store == nil { return errors.New("Cannot perform action. Messages still loading") } + + clearSelected := false + opts, optind, err := getopt.Getopts(args, "s") + if err != nil { + return err + } + + for _, opt := range opts { + switch opt.Option { + case 's': + clearSelected = true + } + } + + if len(args) != optind { + return errors.New("Usage: clear [-s]") + } + + if clearSelected { + defer store.Select(0) + } else { + defer store.Reselect(store.Selected()) + } + store.ApplyClear() acct.SetStatus(statusline.SearchFilterClear()) diff --git a/commands/msg/toggle-threads.go b/commands/msg/toggle-threads.go index 79d515cb..ac4242b8 100644 --- a/commands/msg/toggle-threads.go +++ b/commands/msg/toggle-threads.go @@ -34,6 +34,7 @@ func (ToggleThreads) Execute(aerc *widgets.Aerc, args []string) error { if err != nil { return err } + defer store.Reselect(store.Selected()) store.SetBuildThreads(!store.BuildThreads()) acct.SetStatus(statusline.Threading(store.BuildThreads())) acct.Messages().Invalidate() diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd index dda8aedf..3713917b 100644 --- a/doc/aerc.1.scd +++ b/doc/aerc.1.scd @@ -216,9 +216,15 @@ message list, the message in the message viewer, etc). ## MESSAGE LIST COMMANDS -*clear* +*clear* [-s] Clears the current search or filter criteria. + By default, the selected message will be kept. To clear the selected + message and move cursor to the top of the message list, use the -s flag. + + *-s* + Selects the message at the top of the message list after clearing. + *cf* <folder> Change the folder shown in the message list. diff --git a/lib/msgstore.go b/lib/msgstore.go index bd8d54d5..a5c0e8f5 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -472,7 +472,12 @@ func (store *MessageStore) Uids() []uint32 { } func (store *MessageStore) Selected() *models.MessageInfo { - return store.Messages[store.Uids()[len(store.Uids())-store.selected-1]] + uids := store.Uids() + idx := len(uids) - store.selected - 1 + if len(uids) == 0 || idx < 0 || idx >= len(uids) { + return nil + } + return store.Messages[uids[idx]] } func (store *MessageStore) SelectedIndex() int { @@ -490,6 +495,21 @@ func (store *MessageStore) Select(index int) { store.updateVisual() } +func (store *MessageStore) Reselect(info *models.MessageInfo) { + if info == nil { + return + } + uid := info.Uid + newIdx := 0 + for idx, uidStore := range store.Uids() { + if uidStore == uid { + newIdx = len(store.Uids()) - idx - 1 + break + } + } + store.Select(newIdx) +} + // Mark sets the marked state on a MessageInfo func (store *MessageStore) Mark(uid uint32) { if store.visualMarkMode { @@ -660,6 +680,7 @@ func (store *MessageStore) ApplySearch(results []uint32) { } func (store *MessageStore) ApplyFilter(results []uint32) { + defer store.Reselect(store.Selected()) store.results = nil store.filtered = results store.filter = true |