aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src
diff options
context:
space:
mode:
authorBenoît CORTIER2021-06-05 02:21:31 +0000
committerBlaž Hrastnik2021-06-07 12:52:09 +0000
commit68affa3c598723a8b9451ef3dcceda83ae161e39 (patch)
tree06a6c0ed9f6e0483b138b44d969f4341206cf4c0 /helix-term/src
parentd5de9183ef8392168b06131278554e483eddfff3 (diff)
Implement register selection
User can select register to yank into with the " command. A new state is added to `Editor` and `commands::Context` structs. This state is managed by leveraging a new struct `RegisterSelection`.
Diffstat (limited to 'helix-term/src')
-rw-r--r--helix-term/src/commands.rs45
-rw-r--r--helix-term/src/keymap.rs2
-rw-r--r--helix-term/src/ui/editor.rs8
3 files changed, 38 insertions, 17 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 15fac7ad..94175006 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -35,6 +35,7 @@ use crossterm::event::{KeyCode, KeyEvent};
use once_cell::sync::Lazy;
pub struct Context<'a> {
+ pub register: helix_view::RegisterSelection,
pub count: usize,
pub editor: &'a mut Editor,
@@ -777,7 +778,7 @@ pub fn extend_line(cx: &mut Context) {
// heuristic: append changes to history after each command, unless we're in insert mode
-fn _delete_selection(doc: &mut Document, view_id: ViewId) {
+fn _delete_selection(reg: char, doc: &mut Document, view_id: ViewId) {
// first yank the selection
let values: Vec<String> = doc
.selection(view_id)
@@ -785,8 +786,6 @@ fn _delete_selection(doc: &mut Document, view_id: ViewId) {
.map(Cow::into_owned)
.collect();
- // TODO: allow specifying reg
- let reg = '"';
register::set(reg, values);
// then delete
@@ -800,8 +799,9 @@ fn _delete_selection(doc: &mut Document, view_id: ViewId) {
}
pub fn delete_selection(cx: &mut Context) {
+ let reg = cx.register.name();
let (view, doc) = cx.current();
- _delete_selection(doc, view.id);
+ _delete_selection(reg, doc, view.id);
doc.append_changes_to_history(view.id);
@@ -810,8 +810,9 @@ pub fn delete_selection(cx: &mut Context) {
}
pub fn change_selection(cx: &mut Context) {
+ let reg = cx.register.name();
let (view, doc) = cx.current();
- _delete_selection(doc, view.id);
+ _delete_selection(reg, doc, view.id);
enter_insert_mode(doc);
}
@@ -1893,11 +1894,13 @@ pub fn yank(cx: &mut Context) {
.map(Cow::into_owned)
.collect();
- // TODO: allow specifying reg
- let reg = '"';
- let msg = format!("yanked {} selection(s) to register {}", values.len(), reg);
+ let msg = format!(
+ "yanked {} selection(s) to register {}",
+ values.len(),
+ cx.register.name()
+ );
- register::set(reg, values);
+ register::set(cx.register.name(), values);
cx.editor.set_status(msg)
}
@@ -1908,9 +1911,7 @@ enum Paste {
After,
}
-fn _paste(doc: &mut Document, view: &View, action: Paste) -> Option<Transaction> {
- // TODO: allow specifying reg
- let reg = '"';
+fn _paste(reg: char, doc: &mut Document, view: &View, action: Paste) -> Option<Transaction> {
if let Some(values) = register::get(reg) {
let repeat = std::iter::repeat(
values
@@ -1956,18 +1957,20 @@ fn _paste(doc: &mut Document, view: &View, action: Paste) -> Option<Transaction>
// default insert
pub fn paste_after(cx: &mut Context) {
+ let reg = cx.register.name();
let (view, doc) = cx.current();
- if let Some(transaction) = _paste(doc, view, Paste::After) {
+ if let Some(transaction) = _paste(reg, doc, view, Paste::After) {
doc.apply(&transaction, view.id);
doc.append_changes_to_history(view.id);
}
}
pub fn paste_before(cx: &mut Context) {
+ let reg = cx.register.name();
let (view, doc) = cx.current();
- if let Some(transaction) = _paste(doc, view, Paste::Before) {
+ if let Some(transaction) = _paste(reg, doc, view, Paste::Before) {
doc.apply(&transaction, view.id);
doc.append_changes_to_history(view.id);
}
@@ -2426,6 +2429,18 @@ pub fn wclose(cx: &mut Context) {
cx.editor.close(view_id, /* close_buffer */ false);
}
+pub fn select_register(cx: &mut Context) {
+ cx.on_next_key(move |cx, event| {
+ if let KeyEvent {
+ code: KeyCode::Char(ch),
+ ..
+ } = event
+ {
+ cx.editor.register.select(ch);
+ }
+ })
+}
+
pub fn space_mode(cx: &mut Context) {
cx.on_next_key(move |cx, event| {
if let KeyEvent {
@@ -2439,7 +2454,7 @@ pub fn space_mode(cx: &mut Context) {
'b' => buffer_picker(cx),
'w' => window_mode(cx),
// ' ' => toggle_alternate_buffer(cx),
- // TODO: temporary since space mode took it's old key
+ // TODO: temporary since space mode took its old key
' ' => keep_primary_selection(cx),
_ => (),
}
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 27ef9b9e..d2fa46c7 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -284,6 +284,8 @@ pub fn default() -> Keymaps {
key!(' ') => commands::space_mode,
key!('z') => commands::view_mode,
+
+ key!('"') => commands::select_register,
);
// TODO: decide whether we want normal mode to also be select mode (kakoune-like), or whether
// we keep this separate select mode. More keys can fit into normal mode then, but it's weird
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index cd66b703..4f485ed2 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -537,6 +537,9 @@ impl EditorView {
// if this fails, count was Some(0)
// debug_assert!(cxt.count != 0);
+ // set the register
+ cxt.register = cxt.editor.register.take();
+
if let Some(command) = self.keymap[&mode].get(&event) {
command(cxt);
}
@@ -575,11 +578,12 @@ impl Component for EditorView {
let mode = doc.mode();
let mut cxt = commands::Context {
- editor: &mut cx.editor,
+ register: helix_view::RegisterSelection::default(),
count: 1,
+ editor: &mut cx.editor,
callback: None,
- callbacks: cx.callbacks,
on_next_key_callback: None,
+ callbacks: cx.callbacks,
};
if let Some(on_next_key) = self.on_next_key.take() {