diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 38e65537..841af22a 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -44,7 +44,7 @@ use once_cell::sync::Lazy;
 use serde::de::{self, Deserialize, Deserializer};
 
 pub struct Context<'a> {
-    pub selected_register: helix_view::RegisterSelection,
+    pub register: Option<char>,
     pub count: Option<NonZeroUsize>,
     pub editor: &'a mut Editor,
 
@@ -1030,7 +1030,8 @@ fn select_all(cx: &mut Context) {
 }
 
 fn select_regex(cx: &mut Context) {
-    let prompt = ui::regex_prompt(cx, "select:".into(), move |view, doc, _, regex| {
+    let reg = cx.register.unwrap_or('/');
+    let prompt = ui::regex_prompt(cx, "select:".into(), Some(reg), move |view, doc, regex| {
         let text = doc.text().slice(..);
         if let Some(selection) = selection::select_on_matches(text, doc.selection(view.id), &regex)
         {
@@ -1042,7 +1043,8 @@ fn select_regex(cx: &mut Context) {
 }
 
 fn split_selection(cx: &mut Context) {
-    let prompt = ui::regex_prompt(cx, "split:".into(), move |view, doc, _, regex| {
+    let reg = cx.register.unwrap_or('/');
+    let prompt = ui::regex_prompt(cx, "split:".into(), Some(reg), move |view, doc, regex| {
         let text = doc.text().slice(..);
         let selection = selection::split_on_matches(text, doc.selection(view.id), &regex);
         doc.set_selection(view.id, selection);
@@ -1100,6 +1102,7 @@ fn search_impl(doc: &mut Document, view: &mut View, contents: &str, regex: &Rege
 
 // TODO: use one function for search vs extend
 fn search(cx: &mut Context) {
+    let reg = cx.register.unwrap_or('/');
     let (_, doc) = current!(cx.editor);
 
     // TODO: could probably share with select_on_matches?
@@ -1108,10 +1111,8 @@ fn search(cx: &mut Context) {
     // feed chunks into the regex yet
     let contents = doc.text().slice(..).to_string();
 
-    let prompt = ui::regex_prompt(cx, "search:".into(), move |view, doc, registers, regex| {
+    let prompt = ui::regex_prompt(cx, "search:".into(), Some(reg), move |view, doc, regex| {
         search_impl(doc, view, &contents, &regex, false);
-        // TODO: only store on enter (accept), not update
-        registers.write('/', vec![regex.as_str().to_string()]);
     });
 
     cx.push_layer(Box::new(prompt));
@@ -1119,9 +1120,9 @@ fn search(cx: &mut Context) {
 
 fn search_next_impl(cx: &mut Context, extend: bool) {
     let (view, doc) = current!(cx.editor);
-    let registers = &mut cx.editor.registers;
+    let registers = &cx.editor.registers;
     if let Some(query) = registers.read('/') {
-        let query = query.first().unwrap();
+        let query = query.last().unwrap();
         let contents = doc.text().slice(..).to_string();
         let regex = Regex::new(query).unwrap();
         search_impl(doc, view, &contents, &regex, extend);
@@ -1141,7 +1142,7 @@ fn search_selection(cx: &mut Context) {
     let contents = doc.text().slice(..);
     let query = doc.selection(view.id).primary().fragment(contents);
     let regex = regex::escape(&query);
-    cx.editor.registers.write('/', vec![regex]);
+    cx.editor.registers.get_mut('/').push(regex);
     search_next(cx);
 }
 
@@ -1200,7 +1201,7 @@ fn delete_selection_impl(reg: &mut Register, doc: &mut Document, view_id: ViewId
 }
 
 fn delete_selection(cx: &mut Context) {
-    let reg_name = cx.selected_register.name();
+    let reg_name = cx.register.unwrap_or('"');
     let (view, doc) = current!(cx.editor);
     let registers = &mut cx.editor.registers;
     let reg = registers.get_mut(reg_name);
@@ -1213,7 +1214,7 @@ fn delete_selection(cx: &mut Context) {
 }
 
 fn change_selection(cx: &mut Context) {
-    let reg_name = cx.selected_register.name();
+    let reg_name = cx.register.unwrap_or('"');
     let (view, doc) = current!(cx.editor);
     let registers = &mut cx.editor.registers;
     let reg = registers.get_mut(reg_name);
@@ -3346,12 +3347,12 @@ fn yank(cx: &mut Context) {
     let msg = format!(
         "yanked {} selection(s) to register {}",
         values.len(),
-        cx.selected_register.name()
+        cx.register.unwrap_or('"')
     );
 
     cx.editor
         .registers
-        .write(cx.selected_register.name(), values);
+        .write(cx.register.unwrap_or('"'), values);
 
     cx.editor.set_status(msg);
     exit_select_mode(cx);
@@ -3524,7 +3525,7 @@ fn paste_primary_clipboard_before(cx: &mut Context) {
 }
 
 fn replace_with_yanked(cx: &mut Context) {
-    let reg_name = cx.selected_register.name();
+    let reg_name = cx.register.unwrap_or('"');
     let (view, doc) = current!(cx.editor);
     let registers = &mut cx.editor.registers;
 
@@ -3575,7 +3576,7 @@ fn replace_selections_with_primary_clipboard(cx: &mut Context) {
 }
 
 fn paste_after(cx: &mut Context) {
-    let reg_name = cx.selected_register.name();
+    let reg_name = cx.register.unwrap_or('"');
     let (view, doc) = current!(cx.editor);
     let registers = &mut cx.editor.registers;
 
@@ -3589,7 +3590,7 @@ fn paste_after(cx: &mut Context) {
 }
 
 fn paste_before(cx: &mut Context) {
-    let reg_name = cx.selected_register.name();
+    let reg_name = cx.register.unwrap_or('"');
     let (view, doc) = current!(cx.editor);
     let registers = &mut cx.editor.registers;
 
@@ -3770,7 +3771,8 @@ fn join_selections(cx: &mut Context) {
 
 fn keep_selections(cx: &mut Context) {
     // keep selections matching regex
-    let prompt = ui::regex_prompt(cx, "keep:".into(), move |view, doc, _, regex| {
+    let reg = cx.register.unwrap_or('/');
+    let prompt = ui::regex_prompt(cx, "keep:".into(), Some(reg), move |view, doc, regex| {
         let text = doc.text().slice(..);
 
         if let Some(selection) = selection::keep_matches(text, doc.selection(view.id), &regex) {
@@ -4103,7 +4105,7 @@ fn wclose(cx: &mut Context) {
 fn select_register(cx: &mut Context) {
     cx.on_next_key(move |cx, event| {
         if let Some(ch) = event.char() {
-            cx.editor.selected_register.select(ch);
+            cx.editor.selected_register = Some(ch);
         }
     })
 }
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index e8cd40cf..52cf3d2b 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -710,7 +710,7 @@ impl EditorView {
                 // debug_assert!(cxt.count != 0);
 
                 // set the register
-                cxt.selected_register = cxt.editor.selected_register.take();
+                cxt.register = cxt.editor.selected_register.take();
 
                 self.handle_keymap_event(mode, cxt, event);
                 if self.keymaps.pending().is_empty() {
@@ -887,9 +887,9 @@ impl EditorView {
 impl Component for EditorView {
     fn handle_event(&mut self, event: Event, cx: &mut Context) -> EventResult {
         let mut cxt = commands::Context {
-            selected_register: helix_view::RegisterSelection::default(),
             editor: &mut cx.editor,
             count: None,
+            register: None,
             callback: None,
             on_next_key_callback: None,
             jobs: cx.jobs,
diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs
index 0a1e24b5..07eef352 100644
--- a/helix-term/src/ui/mod.rs
+++ b/helix-term/src/ui/mod.rs
@@ -20,7 +20,6 @@ pub use spinner::{ProgressSpinners, Spinner};
 pub use text::Text;
 
 use helix_core::regex::Regex;
-use helix_core::register::Registers;
 use helix_view::{Document, Editor, View};
 
 use std::path::PathBuf;
@@ -28,7 +27,8 @@ use std::path::PathBuf;
 pub fn regex_prompt(
     cx: &mut crate::commands::Context,
     prompt: std::borrow::Cow<'static, str>,
-    fun: impl Fn(&mut View, &mut Document, &mut Registers, Regex) + 'static,
+    history_register: Option<char>,
+    fun: impl Fn(&mut View, &mut Document, Regex) + 'static,
 ) -> Prompt {
     let (view, doc) = current!(cx.editor);
     let view_id = view.id;
@@ -36,7 +36,7 @@ pub fn regex_prompt(
 
     Prompt::new(
         prompt,
-        None,
+        history_register,
         |_input: &str| Vec::new(), // this is fine because Vec::new() doesn't allocate
         move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| {
             match event {
@@ -56,12 +56,11 @@ pub fn regex_prompt(
                     match Regex::new(input) {
                         Ok(regex) => {
                             let (view, doc) = current!(cx.editor);
-                            let registers = &mut cx.editor.registers;
 
                             // revert state to what it was before the last update
                             doc.set_selection(view.id, snapshot.clone());
 
-                            fun(view, doc, registers, regex);
+                            fun(view, doc, regex);
 
                             view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff);
                         }
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 3d2d4a87..52a0060c 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -3,7 +3,7 @@ use crate::{
     graphics::{CursorKind, Rect},
     theme::{self, Theme},
     tree::Tree,
-    Document, DocumentId, RegisterSelection, View, ViewId,
+    Document, DocumentId, View, ViewId,
 };
 
 use futures_util::future;
@@ -73,7 +73,7 @@ pub struct Editor {
     pub tree: Tree,
     pub documents: SlotMap<DocumentId, Document>,
     pub count: Option<std::num::NonZeroUsize>,
-    pub selected_register: RegisterSelection,
+    pub selected_register: Option<char>,
     pub registers: Registers,
     pub theme: Theme,
     pub language_servers: helix_lsp::Registry,
@@ -111,7 +111,7 @@ impl Editor {
             tree: Tree::new(area),
             documents: SlotMap::with_key(),
             count: None,
-            selected_register: RegisterSelection::default(),
+            selected_register: None,
             theme: themes.default(),
             language_servers,
             syn_loader: config_loader,
diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs
index 9bcc0b7d..c37474d6 100644
--- a/helix-view/src/lib.rs
+++ b/helix-view/src/lib.rs
@@ -8,7 +8,6 @@ pub mod graphics;
 pub mod info;
 pub mod input;
 pub mod keyboard;
-pub mod register_selection;
 pub mod theme;
 pub mod tree;
 pub mod view;
@@ -20,6 +19,5 @@ slotmap::new_key_type! {
 
 pub use document::Document;
 pub use editor::Editor;
-pub use register_selection::RegisterSelection;
 pub use theme::Theme;
 pub use view::View;
diff --git a/helix-view/src/register_selection.rs b/helix-view/src/register_selection.rs
deleted file mode 100644
index a2b78f72..00000000
--- a/helix-view/src/register_selection.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-/// Register selection and configuration
-///
-/// This is a kind a of specialized `Option<char>` for register selection.
-/// Point is to keep whether the register selection has been explicitely
-/// set or not while being convenient by knowing the default register name.
-#[derive(Debug)]
-pub struct RegisterSelection {
-    selected: char,
-    default_name: char,
-}
-
-impl RegisterSelection {
-    pub fn new(default_name: char) -> Self {
-        Self {
-            selected: default_name,
-            default_name,
-        }
-    }
-
-    pub fn select(&mut self, name: char) {
-        self.selected = name;
-    }
-
-    pub fn take(&mut self) -> Self {
-        Self {
-            selected: std::mem::replace(&mut self.selected, self.default_name),
-            default_name: self.default_name,
-        }
-    }
-
-    pub fn is_default(&self) -> bool {
-        self.selected == self.default_name
-    }
-
-    pub fn name(&self) -> char {
-        self.selected
-    }
-}
-
-impl Default for RegisterSelection {
-    fn default() -> Self {
-        let default_name = '"';
-        Self {
-            selected: default_name,
-            default_name,
-        }
-    }
-}