diff --git a/commands.c b/commands.c
index 360b771..33ae5a3 100644
--- a/commands.c
+++ b/commands.c
@@ -46,6 +46,7 @@ extern fileinfo_t *files;
 extern int filecnt, fileidx;
 extern int alternate;
 extern int markcnt;
+extern int toggledidx;
 
 extern int prefix;
 extern bool extprefix;
@@ -196,6 +197,7 @@ bool cg_toggle_image_mark(arg_t _)
 	markcnt += files[fileidx].flags & FF_MARK ? 1 : -1;
 	if (mode == MODE_THUMB)
 		tns_mark(&tns, fileidx, !!(files[fileidx].flags & FF_MARK));
+	toggledidx = fileidx;
 	return true;
 }
 
@@ -212,6 +214,39 @@ bool cg_reverse_marks(arg_t _)
 	return true;
 }
 
+bool cg_mark_range(arg_t _)
+{
+	int i, from, to;
+
+	if (toggledidx < 0)
+		return true;
+	if (toggledidx == fileidx)
+		return true;
+
+	from = toggledidx;
+	to = fileidx;
+	if (fileidx < toggledidx) {
+		from = fileidx;
+		to = toggledidx;
+	}
+	for (i = from; i <= to; i++) {
+		if (files[toggledidx].flags & FF_MARK) {
+			if (!(files[i].flags & FF_MARK)) {
+				files[i].flags |= FF_MARK;
+				markcnt += 1;
+			}
+		} else {
+			if (files[i].flags & FF_MARK) {
+				files[i].flags &= ~FF_MARK;
+				markcnt -= 1;
+			}
+		}
+		if (mode == MODE_THUMB)
+			tns_mark(&tns, i, !!(files[i].flags & FF_MARK));
+	}
+	return true;
+}
+
 bool cg_unmark_all(arg_t _)
 {
 	int i;
diff --git a/commands.lst b/commands.lst
index bf9e3ed..06e7d78 100644
--- a/commands.lst
+++ b/commands.lst
@@ -11,6 +11,7 @@ G_CMD(scroll_screen)
 G_CMD(zoom)
 G_CMD(toggle_image_mark)
 G_CMD(reverse_marks)
+G_CMD(mark_range)
 G_CMD(unmark_all)
 G_CMD(navigate_marked)
 G_CMD(change_gamma)
diff --git a/config.def.h b/config.def.h
index de9ca51..09eab69 100644
--- a/config.def.h
+++ b/config.def.h
@@ -91,6 +91,7 @@ static const keymap_t keys[] = {
 	{ 0,            XK_KP_Subtract,   g_zoom,               -1 },
 	{ 0,            XK_m,             g_toggle_image_mark,  None },
 	{ 0,            XK_M,             g_reverse_marks,      None },
+	{ ControlMask,  XK_M,             g_mark_range,         None },
 	{ ControlMask,  XK_m,             g_unmark_all,         None },
 	{ 0,            XK_N,             g_navigate_marked,    +1 },
 	{ 0,            XK_P,             g_navigate_marked,    -1 },
diff --git a/main.c b/main.c
index a9c9c44..b362c3e 100644
--- a/main.c
+++ b/main.c
@@ -57,6 +57,7 @@ fileinfo_t *files;
 int filecnt, fileidx;
 int alternate;
 int markcnt;
+int toggledidx = -1;
 
 int prefix;
 bool extprefix;
diff --git a/sxiv.1 b/sxiv.1
index c5f42a7..05efca3 100644
--- a/sxiv.1
+++ b/sxiv.1
@@ -172,6 +172,10 @@ Mark/unmark the current image.
 .B M
 Reverse all image marks.
 .TP
+.B Ctrl-M
+Repeat last mark action on all images from the last marked/unmarked up to the
+current one.
+.TP
 .B Ctrl-m
 Remove all image marks.
 .TP