Simple yank/paste registers.

pull/4/head
Blaž Hrastnik 4 years ago
parent eba5b1ef33
commit 1dba0f2b1c

@ -3,6 +3,7 @@ pub mod graphemes;
mod history; mod history;
pub mod macros; pub mod macros;
mod position; mod position;
pub mod register;
pub mod selection; pub mod selection;
pub mod state; pub mod state;
pub mod syntax; pub mod syntax;

@ -0,0 +1,21 @@
use crate::Tendril;
use once_cell::sync::Lazy;
use std::{collections::HashMap, sync::RwLock};
// TODO: could be an instance on Editor
static REGISTRY: Lazy<RwLock<HashMap<char, Vec<String>>>> =
Lazy::new(|| RwLock::new(HashMap::new()));
pub fn get(register: char) -> Option<Vec<String>> {
let registry = REGISTRY.read().unwrap();
// TODO: no cloning
registry.get(&register).cloned()
}
// restoring: bool
pub fn set(register: char, values: Vec<String>) {
let mut registry = REGISTRY.write().unwrap();
registry.insert(register, values);
}

@ -110,7 +110,8 @@ impl Range {
#[inline] #[inline]
pub fn fragment<'a>(&'a self, text: &'a RopeSlice) -> Cow<'a, str> { pub fn fragment<'a>(&'a self, text: &'a RopeSlice) -> Cow<'a, str> {
Cow::from(text.slice(self.from()..self.to())) // end inclusive
Cow::from(text.slice(self.from()..self.to() + 1))
} }
} }

@ -445,7 +445,7 @@ impl Transaction {
/// Generate a transaction with a change per selection range. /// Generate a transaction with a change per selection range.
pub fn change_by_selection<F>(state: &State, f: F) -> Self pub fn change_by_selection<F>(state: &State, f: F) -> Self
where where
F: Fn(&Range) -> Change, F: FnMut(&Range) -> Change,
{ {
Self::change(state, state.selection.ranges().iter().map(f)) Self::change(state, state.selection.ranges().iter().map(f))
} }

@ -1,7 +1,7 @@
use helix_core::{ use helix_core::{
graphemes, graphemes,
regex::Regex, regex::Regex,
selection, register, selection,
state::{Direction, Granularity, Mode, State}, state::{Direction, Granularity, Mode, State},
ChangeSet, Range, Selection, Tendril, Transaction, ChangeSet, Range, Selection, Tendril, Transaction,
}; };
@ -443,3 +443,36 @@ pub fn undo(view: &mut View, _count: usize) {
pub fn redo(view: &mut View, _count: usize) { pub fn redo(view: &mut View, _count: usize) {
view.history.redo(&mut view.state); view.history.redo(&mut view.state);
} }
// Yank / Paste
pub fn yank(view: &mut View, _count: usize) {
// TODO: should selections be made end inclusive?
let values = view
.state
.selection()
.fragments(&view.state.doc().slice(..))
.map(|cow| cow.into_owned())
.collect();
register::set('"', values);
}
pub fn paste(view: &mut View, _count: usize) {
if let Some(values) = register::get('"') {
let repeat = std::iter::repeat(
values
.last()
.map(|value| Tendril::from_slice(value))
.unwrap(),
);
let mut values = values.into_iter().map(Tendril::from).chain(repeat);
let transaction = Transaction::change_by_selection(&view.state, |range| {
(range.head + 1, range.head + 1, Some(values.next().unwrap()))
});
transaction.apply(&mut view.state);
}
}

@ -147,6 +147,8 @@ pub fn default() -> Keymaps {
vec![key!(';')] => commands::collapse_selection, vec![key!(';')] => commands::collapse_selection,
vec![key!('u')] => commands::undo, vec![key!('u')] => commands::undo,
vec![shift!('U')] => commands::redo, vec![shift!('U')] => commands::redo,
vec![key!('y')] => commands::yank,
vec![key!('p')] => commands::paste,
vec![Key { vec![Key {
code: KeyCode::Esc, code: KeyCode::Esc,
modifiers: Modifiers::NONE modifiers: Modifiers::NONE

Loading…
Cancel
Save