on master help sign in
Simple yank/paste registers.
1dba0f2Blaž Hrastnik
helix-core/src/lib.rs+1
@@ -3,6 +3,7 @@ pub mod graphemes;
3mod history;
3mod history;
4pub mod macros;
4pub mod macros;
5mod position;
5mod position;
6+pub mod register;
6pub mod selection;
7pub mod selection;
7pub mod state;
8pub mod state;
8pub mod syntax;
9pub mod syntax;
helix-core/src/register.rsnew file+21
@@ -0,0 +1,21 @@
1+use crate::Tendril;
2+use once_cell::sync::Lazy;
3+use std::{collections::HashMap, sync::RwLock};
4+
5+// TODO: could be an instance on Editor
6+static REGISTRY: Lazy<RwLock<HashMap<char, Vec<String>>>> =
7+ Lazy::new(|| RwLock::new(HashMap::new()));
8+
9+pub fn get(register: char) -> Option<Vec<String>> {
10+ let registry = REGISTRY.read().unwrap();
11+
12+ // TODO: no cloning
13+ registry.get(&register).cloned()
14+}
15+
16+// restoring: bool
17+pub fn set(register: char, values: Vec<String>) {
18+ let mut registry = REGISTRY.write().unwrap();
19+
20+ registry.insert(register, values);
21+}
helix-core/src/selection.rs+2−1
@@ -110,7 +110,8 @@ impl Range {
110
110
111 #[inline]
111 #[inline]
112 pub fn fragment<'a>(&'a self, text: &'a RopeSlice) -> Cow<'a, str> {
112 pub fn fragment<'a>(&'a self, text: &'a RopeSlice) -> Cow<'a, str> {
113+ // end inclusive
113− Cow::from(text.slice(self.from()..self.to()))
114+ Cow::from(text.slice(self.from()..self.to() + 1))
114 }
115 }
115}
116}
116
117
helix-core/src/transaction.rs+1−1
@@ -445,7 +445,7 @@ impl Transaction {
445 /// Generate a transaction with a change per selection range.
445 /// Generate a transaction with a change per selection range.
446 pub fn change_by_selection<F>(state: &State, f: F) -> Self
446 pub fn change_by_selection<F>(state: &State, f: F) -> Self
447 where
447 where
448− F: Fn(&Range) -> Change,
448+ F: FnMut(&Range) -> Change,
449 {
449 {
450 Self::change(state, state.selection.ranges().iter().map(f))
450 Self::change(state, state.selection.ranges().iter().map(f))
451 }
451 }
helix-view/src/commands.rs+34−1
@@ -1,7 +1,7 @@
1use helix_core::{
1use helix_core::{
2 graphemes,
2 graphemes,
3 regex::Regex,
3 regex::Regex,
4− selection,
4+ register, selection,
5 state::{Direction, Granularity, Mode, State},
5 state::{Direction, Granularity, Mode, State},
6 ChangeSet, Range, Selection, Tendril, Transaction,
6 ChangeSet, Range, Selection, Tendril, Transaction,
7};
7};
@@ -443,3 +443,36 @@ pub fn undo(view: &mut View, _count: usize) {
443pub fn redo(view: &mut View, _count: usize) {
443pub fn redo(view: &mut View, _count: usize) {
444 view.history.redo(&mut view.state);
444 view.history.redo(&mut view.state);
445}
445}
446+
447+// Yank / Paste
448+
449+pub fn yank(view: &mut View, _count: usize) {
450+ // TODO: should selections be made end inclusive?
451+ let values = view
452+ .state
453+ .selection()
454+ .fragments(&view.state.doc().slice(..))
455+ .map(|cow| cow.into_owned())
456+ .collect();
457+
458+ register::set('"', values);
459+}
460+
461+pub fn paste(view: &mut View, _count: usize) {
462+ if let Some(values) = register::get('"') {
463+ let repeat = std::iter::repeat(
464+ values
465+ .last()
466+ .map(|value| Tendril::from_slice(value))
467+ .unwrap(),
468+ );
469+
470+ let mut values = values.into_iter().map(Tendril::from).chain(repeat);
471+
472+ let transaction = Transaction::change_by_selection(&view.state, |range| {
473+ (range.head + 1, range.head + 1, Some(values.next().unwrap()))
474+ });
475+
476+ transaction.apply(&mut view.state);
477+ }
478+}
helix-view/src/keymap.rs+2
@@ -147,6 +147,8 @@ pub fn default() -> Keymaps {
147 vec![key!(';')] => commands::collapse_selection,
147 vec![key!(';')] => commands::collapse_selection,
148 vec![key!('u')] => commands::undo,
148 vec![key!('u')] => commands::undo,
149 vec![shift!('U')] => commands::redo,
149 vec![shift!('U')] => commands::redo,
150+ vec![key!('y')] => commands::yank,
151+ vec![key!('p')] => commands::paste,
150 vec![Key {
152 vec![Key {
151 code: KeyCode::Esc,
153 code: KeyCode::Esc,
152 modifiers: Modifiers::NONE
154 modifiers: Modifiers::NONE