mark: allow multiple visual selections

When entering visual selection mode, the current selection is deleted.
This patch extends the visual mode behavior to select multiple blocks of
messages.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Koni Marti 2022-08-08 22:21:44 +02:00 committed by Robin Jarry
parent 16dbb94221
commit b12dd9f926
4 changed files with 23 additions and 7 deletions

View file

@ -32,19 +32,23 @@ func (Mark) Execute(aerc *widgets.Aerc, args []string) error {
return err
}
marker := store.Marker()
opts, _, err := getopt.Getopts(args, "atv")
opts, _, err := getopt.Getopts(args, "atvV")
if err != nil {
return err
}
var all bool
var toggle bool
var visual bool
var clearVisual bool
for _, opt := range opts {
switch opt.Option {
case 'a':
all = true
case 'v':
visual = true
clearVisual = true
case 'V':
visual = true
case 't':
toggle = true
}
@ -70,7 +74,7 @@ func (Mark) Execute(aerc *widgets.Aerc, args []string) error {
}
return nil
case visual:
marker.ToggleVisualMark()
marker.ToggleVisualMark(clearVisual)
return nil
default:
modFunc(selected.Uid)

View file

@ -412,6 +412,8 @@ message list, the message in the message viewer, etc).
*-v*: Enter / leave visual mark mode
*-V*: Same as -v but does not clear existing selection
*unmark* [-at]
Unmarks messages. The flags below can be combined as needed.

View file

@ -8,7 +8,7 @@ type Marker interface {
Remark()
Marked() []uint32
IsMarked(uint32) bool
ToggleVisualMark()
ToggleVisualMark(bool)
UpdateVisualMark()
ClearVisualMark()
}
@ -25,6 +25,7 @@ type controller struct {
lastMarked map[uint32]struct{}
visualStartUID uint32
visualMarkMode bool
visualBase map[uint32]struct{}
}
// New returns a new Marker
@ -114,15 +115,21 @@ func (mc *controller) Marked() []uint32 {
}
// ToggleVisualMark enters or leaves the visual marking mode
func (mc *controller) ToggleVisualMark() {
func (mc *controller) ToggleVisualMark(clear bool) {
mc.visualMarkMode = !mc.visualMarkMode
if mc.visualMarkMode {
// just entered visual mode, reset whatever marking was already done
if clear {
mc.resetMark()
}
uids := mc.uidProvider.Uids()
if idx := mc.uidProvider.SelectedIndex(); idx >= 0 && idx < len(uids) {
mc.visualStartUID = uids[idx]
mc.marked[mc.visualStartUID] = struct{}{}
mc.visualBase = make(map[uint32]struct{})
for key, value := range mc.marked {
mc.visualBase[key] = value
}
}
}
}
@ -160,7 +167,10 @@ func (mc *controller) UpdateVisualMark() {
} else {
visUids = uids[selectedIdx : startIdx+1]
}
mc.resetMark()
mc.marked = make(map[uint32]struct{})
for uid := range mc.visualBase {
mc.marked[uid] = struct{}{}
}
for _, uid := range visUids {
mc.marked[uid] = struct{}{}
}

View file

@ -90,7 +90,7 @@ func TestMarker_VisualMode(t *testing.T) {
m, up := createMarker()
// activate visual mode
m.ToggleVisualMark()
m.ToggleVisualMark(false)
// marking should now fail silently because we're in visual mode
m.Mark(1)