aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--commands/msg/mark.go8
-rw-r--r--doc/aerc.1.scd2
-rw-r--r--lib/marker/marker.go18
-rw-r--r--lib/marker/marker_test.go2
4 files changed, 23 insertions, 7 deletions
diff --git a/commands/msg/mark.go b/commands/msg/mark.go
index 13d6c928..939d456a 100644
--- a/commands/msg/mark.go
+++ b/commands/msg/mark.go
@@ -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)
diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd
index 17e25c2a..b5edc320 100644
--- a/doc/aerc.1.scd
+++ b/doc/aerc.1.scd
@@ -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.
diff --git a/lib/marker/marker.go b/lib/marker/marker.go
index 46400f1a..21c151f3 100644
--- a/lib/marker/marker.go
+++ b/lib/marker/marker.go
@@ -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
- mc.resetMark()
+ 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{}{}
}
diff --git a/lib/marker/marker_test.go b/lib/marker/marker_test.go
index 1611623e..df9eb2a3 100644
--- a/lib/marker/marker_test.go
+++ b/lib/marker/marker_test.go
@@ -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)