diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index be694bff4..44516b319 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -529,6 +529,7 @@ pub fn doc(&self) -> &str { command_palette, "Open command palette", goto_word, "Jump to a two-character label", extend_to_word, "Extend to a two-character label", + select_register_history, "Select an item from a register's history", ); } @@ -6186,3 +6187,56 @@ fn jump_to_word(cx: &mut Context, behaviour: Movement) { } jump_to_label(cx, words, behaviour) } + +fn select_register_history(cx: &mut Context) { + struct HistoryEntry { + index: usize, + last_value: String, + } + + // TODO: only show the registers that support selecting from history. + cx.editor.autoinfo = Some(Info::from_registers(&cx.editor.registers)); + cx.on_next_key(move |cx, event| { + cx.editor.autoinfo = None; + let Some(register) = event.char() else { return }; + let Some(history) = cx.editor.registers.history(register) else { + cx.editor + .set_error(format!("No history for register '{register}'")); + return; + }; + + let items = history.map(|(index, entry)| HistoryEntry { + index, + last_value: entry + .last() + .and_then(|s| s.lines().next()) + .unwrap_or("") + .to_string(), + }); + let columns = vec![ + PickerColumn::new("entry", |entry: &HistoryEntry, _| { + entry.index.to_string().into() + }), + PickerColumn::new("contents", |entry: &HistoryEntry, _| { + entry.last_value.as_str().into() + }), + ]; + + let picker = Picker::new( + columns, + 1, // "contents" + items, + (), + move |cx, entry, _action| { + if let Err(err) = cx + .editor + .registers + .select_history_entry(register, entry.index) + { + cx.editor.set_error(err.to_string()); + } + }, + ); + cx.push_layer(Box::new(overlaid(picker))); + }) +} diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index 5a3e8eed4..e713cd711 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -323,6 +323,7 @@ pub fn default() -> HashMap { }, "\"" => select_register, + "C-r" => select_register_history, "|" => shell_pipe, "A-|" => shell_pipe_to, "!" => shell_insert_output,