@@ -241,7 +241,7 @@ pub fn select_line(view: &mut View, _count: usize) {
241 let text = view.state.doc();
241 let text = view.state.doc();
242 let line = text.char_to_line(pos.head);
242 let line = text.char_to_line(pos.head);
243 let start = text.line_to_char(line);
243 let start = text.line_to_char(line);
244− let end = text.line_to_char(line + 1);
244+ let end = text.line_to_char(line + 1).saturating_sub(1);
246 // TODO: use a transaction
246 // TODO: use a transaction
247 view.state.selection = Selection::single(start, end);
247 view.state.selection = Selection::single(start, end);
@@ -249,7 +249,7 @@ pub fn select_line(view: &mut View, _count: usize) {
250pub fn delete_selection(view: &mut View, _count: usize) {
250pub fn delete_selection(view: &mut View, _count: usize) {
251 let transaction =
251 let transaction =
252− Transaction::change_by_selection(&view.state, |range| (range.from(), range.to(), None));
252+ Transaction::change_by_selection(&view.state, |range| (range.from(), range.to() + 1, None));
253 transaction.apply(&mut view.state);
253 transaction.apply(&mut view.state);
255 append_changes_to_history(view);
255 append_changes_to_history(view);
@@ -267,6 +267,13 @@ pub fn collapse_selection(view: &mut View, _count: usize) {
267 .transform(|range| Range::new(range.head, range.head))
267 .transform(|range| Range::new(range.head, range.head))
270+pub fn flip_selections(view: &mut View, _count: usize) {
271+ view.state.selection = view
274+ .transform(|range| Range::new(range.head, range.anchor))
270fn enter_insert_mode(view: &mut View) {
277fn enter_insert_mode(view: &mut View) {
271 view.state.mode = Mode::Insert;
278 view.state.mode = Mode::Insert;
@@ -463,7 +470,7 @@ pub fn delete_char_forward(view: &mut View, count: usize) {
463pub fn undo(view: &mut View, _count: usize) {
470pub fn undo(view: &mut View, _count: usize) {
464 view.history.undo(&mut view.state);
471 view.history.undo(&mut view.state);
466− // TODO: each command should simply return a Option<transaction>, then the higher level handles storing it?
473+ // TODO: each command could simply return a Option<transaction>, then the higher level handles storing it?
469pub fn redo(view: &mut View, _count: usize) {
476pub fn redo(view: &mut View, _count: usize) {
@@ -481,11 +488,15 @@ pub fn yank(view: &mut View, _count: usize) {
481 .map(|cow| cow.into_owned())
488 .map(|cow| cow.into_owned())
482 .collect();
489 .collect();
491+ // TODO: allow specifying reg
484− register::set('"', values);
493+ register::set(reg, values);
487pub fn paste(view: &mut View, _count: usize) {
496pub fn paste(view: &mut View, _count: usize) {
497+ // TODO: allow specifying reg
488− if let Some(values) = register::get('"') {
499+ if let Some(values) = register::get(reg) {
489 let repeat = std::iter::repeat(
500 let repeat = std::iter::repeat(
@@ -493,13 +504,74 @@ pub fn paste(view: &mut View, _count: usize) {
493 .unwrap(),
504 .unwrap(),
507+ // TODO: if any of values ends \n it's linewise paste
510+ // P => paste before
511+ // alt-p => paste every yanked selection after selected text
512+ // alt-P => paste every yanked selection before selected text
513+ // R => replace selected text with yanked text
514+ // alt-R => replace selected text with every yanked text
516+ // append => insert at next line
517+ // insert => insert at start of line
518+ // replace => replace
521+ let linewise = values.iter().any(|value| value.ends_with('\n'));
496 let mut values = values.into_iter().map(Tendril::from).chain(repeat);
523 let mut values = values.into_iter().map(Tendril::from).chain(repeat);
525+ let transaction = if linewise {
526+ // paste on the next line
527+ // TODO: can simply take a range + modifier and compute the right pos without ifs
528+ let text = view.state.doc();
498− let transaction = Transaction::change_by_selection(&view.state, |range| {
529+ Transaction::change_by_selection(&view.state, |range| {
530+ let line_end = text.line_to_char(text.char_to_line(range.head) + 1);
531+ (line_end, line_end, Some(values.next().unwrap()))
534+ Transaction::change_by_selection(&view.state, |range| {
499− (range.head + 1, range.head + 1, Some(values.next().unwrap()))
535+ (range.head + 1, range.head + 1, Some(values.next().unwrap()))
502 transaction.apply(&mut view.state);
539 transaction.apply(&mut view.state);
503 append_changes_to_history(view);
540 append_changes_to_history(view);
544+const TAB_WIDTH: usize = 4;
546+pub fn indent(view: &mut View, _count: usize) {
547+ let mut lines = Vec::new();
549+ // Get all line numbers
550+ for range in view.state.selection.ranges() {
551+ let start = view.state.doc.char_to_line(range.from());
552+ let end = view.state.doc.char_to_line(range.to());
554+ for line in start..=end {
558+ lines.sort_unstable(); // sorting by usize so _unstable is preferred
561+ // Indent by one level
562+ let indent = Tendril::from(" ".repeat(TAB_WIDTH));
564+ let transaction = Transaction::change(
566+ lines.into_iter().map(|line| {
567+ let pos = view.state.doc.line_to_char(line);
568+ (pos, pos, Some(indent.clone()))
571+ transaction.apply(&mut view.state);
572+ append_changes_to_history(view);
575+pub fn unindent(view: &mut View, _count: usize) {