diff --git a/src/audio_timing_dialogue.cpp b/src/audio_timing_dialogue.cpp
index 433a3f985cef4df759a115093df93fb612dbdf96..3b53c80103d766adf1135d1ceeed41d78f587dc3 100644
--- a/src/audio_timing_dialogue.cpp
+++ b/src/audio_timing_dialogue.cpp
@@ -735,7 +735,7 @@ void AudioTimingControllerDialogue::RegenerateInactiveLines()
 	bool was_empty = inactive_lines.empty();
 	inactive_lines.clear();
 
-	SubtitleSelection sel = context->selectionController->GetSelectedSet();
+	SubtitleSelection const& sel = context->selectionController->GetSelectedSet();
 
 	switch (int mode = inactive_line_mode->GetInt())
 	{
@@ -798,7 +798,7 @@ void AudioTimingControllerDialogue::RegenerateSelectedLines()
 	selected_lines.clear();
 
 	AssDialogue *active = context->selectionController->GetActiveLine();
-	SubtitleSelection sel = context->selectionController->GetSelectedSet();
+	SubtitleSelection const& sel = context->selectionController->GetSelectedSet();
 	for (auto line : sel)
 	{
 		if (line == active) continue;
diff --git a/src/command/audio.cpp b/src/command/audio.cpp
index 827b70cc2fd0996b675f8d73d365e30c53bcbffd..fe8e399254f0ab4ef9177c2841266fe82bb4ad2c 100644
--- a/src/command/audio.cpp
+++ b/src/command/audio.cpp
@@ -191,7 +191,7 @@ struct audio_save_clip : public Command {
 	}
 
 	void operator()(agi::Context *c) override {
-		SubtitleSelection sel = c->selectionController->GetSelectedSet();
+		SubtitleSelection const& sel = c->selectionController->GetSelectedSet();
 		if (sel.empty()) return;
 
 		AssTime start = INT_MAX, end = 0;
diff --git a/src/command/edit.cpp b/src/command/edit.cpp
index 204a672d658e2a496f9906378a4791d5252c7ead..3b99c8190e09d5d51e6113f338b984cc83330d05 100644
--- a/src/command/edit.cpp
+++ b/src/command/edit.cpp
@@ -476,7 +476,7 @@ struct edit_find_replace : public Command {
 
 static std::string get_entry_data(AssDialogue *d) { return d->GetEntryData(); }
 static void copy_lines(agi::Context *c) {
-	SubtitleSelection sel = c->selectionController->GetSelectedSet();
+	SubtitleSelection const& sel = c->selectionController->GetSelectedSet();
 	SetClipboard(join(c->ass->Line
 		| agi::of_type<AssDialogue>()
 		| filtered([&](AssDialogue *d) { return sel.count(d); })
@@ -485,7 +485,7 @@ static void copy_lines(agi::Context *c) {
 }
 
 static void delete_lines(agi::Context *c, wxString const& commit_message) {
-	SubtitleSelection sel = c->selectionController->GetSelectedSet();
+	SubtitleSelection const& sel = c->selectionController->GetSelectedSet();
 
 	// Find a line near the active line not being deleted to make the new active line
 	AssDialogue *pre_sel = nullptr;
@@ -686,7 +686,7 @@ struct edit_line_duplicate_shift_back : public validate_video_and_sel_nonempty {
 };
 
 static void combine_lines(agi::Context *c, void (*combiner)(AssDialogue *, AssDialogue *), wxString const& message) {
-	SubtitleSelection sel = c->selectionController->GetSelectedSet();
+	SubtitleSelection const& sel = c->selectionController->GetSelectedSet();
 
 	AssDialogue *first = nullptr;
 	for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ) {
@@ -703,9 +703,7 @@ static void combine_lines(agi::Context *c, void (*combiner)(AssDialogue *, AssDi
 		delete diag;
 	}
 
-	sel.clear();
-	sel.insert(first);
-	c->selectionController->SetSelectionAndActive(sel, first);
+	c->selectionController->SetSelectionAndActive({first}, first);
 
 	c->ass->Commit(message, AssFile::COMMIT_DIAG_ADDREM | AssFile::COMMIT_DIAG_FULL);
 }
@@ -915,7 +913,7 @@ struct edit_line_recombine : public validate_sel_multiple {
 	STR_HELP("Recombine subtitles which have been split and merged")
 
 	void operator()(agi::Context *c) override {
-		auto sel_set = c->selectionController->GetSelectedSet();
+		auto const& sel_set = c->selectionController->GetSelectedSet();
 		if (sel_set.size() < 2) return;
 
 		auto active_line = c->selectionController->GetActiveLine();
diff --git a/src/command/grid.cpp b/src/command/grid.cpp
index cd6985e06b4321bf07ca8a104ffd16a2eac51211..54d2a3a4300fc1c631028bc26b1a640cd535bd4e 100644
--- a/src/command/grid.cpp
+++ b/src/command/grid.cpp
@@ -387,7 +387,7 @@ struct grid_swap : public Command {
 	}
 
 	void operator()(agi::Context *c) override {
-		SubtitleSelection sel = c->selectionController->GetSelectedSet();
+		SubtitleSelection const& sel = c->selectionController->GetSelectedSet();
 		if (sel.size() == 2) {
 			(*sel.begin())->swap_nodes(**sel.rbegin());
 			c->ass->Commit(_("swap lines"), AssFile::COMMIT_ORDER);
diff --git a/src/command/time.cpp b/src/command/time.cpp
index 747634aa4f3286d09f085b42a8451fe5a0c54086..53d6831f7f2737f2c27e7559da3fb0a33eb90094 100644
--- a/src/command/time.cpp
+++ b/src/command/time.cpp
@@ -62,7 +62,7 @@ namespace {
 	struct validate_adjoinable : public Command {
 		CMD_TYPE(COMMAND_VALIDATE)
 		bool Validate(const agi::Context *c) override {
-			SubtitleSelection sel = c->selectionController->GetSelectedSet();
+			SubtitleSelection const& sel = c->selectionController->GetSelectedSet();
 			if (sel.size() < 2) return !sel.empty();
 
 			size_t found = 0;
@@ -79,7 +79,7 @@ namespace {
 	};
 
 static void adjoin_lines(agi::Context *c, bool set_start) {
-	auto sel = c->selectionController->GetSelectedSet();
+	auto const& sel = c->selectionController->GetSelectedSet();
 	AssDialogue *prev = nullptr;
 	size_t seen = 0;
 	bool prev_sel = false;
diff --git a/src/dialog_shift_times.cpp b/src/dialog_shift_times.cpp
index 01b0d6272e4df6f2ecf95e9945288b48a2c68fb2..ee54405a96cc6f641290ff0ab5e285afc7a7f893 100644
--- a/src/dialog_shift_times.cpp
+++ b/src/dialog_shift_times.cpp
@@ -333,7 +333,7 @@ void DialogShiftTimes::Process(wxCommandEvent &) {
 	bool start = type != 2;
 	bool end = type != 1;
 
-	SubtitleSelection sel = context->selectionController->GetSelectedSet();
+	SubtitleSelection const& sel = context->selectionController->GetSelectedSet();
 
 	long shift;
 	if (by_time) {