@@ -241,7 +241,7 @@ pub fn select_line(view: &mut View, _count: usize) {
241241 let text = view.state.doc();
242242 let line = text.char_to_line(pos.head);
243243 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);
245245
246246 // TODO: use a transaction
247247 view.state.selection = Selection::single(start, end);
@@ -249,7 +249,7 @@ pub fn select_line(view: &mut View, _count: usize) {
249249
250250pub fn delete_selection(view: &mut View, _count: usize) {
251251 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));
253253 transaction.apply(&mut view.state);
254254
255255 append_changes_to_history(view);
@@ -267,6 +267,13 @@ pub fn collapse_selection(view: &mut View, _count: usize) {
267267 .transform(|range| Range::new(range.head, range.head))
268268}
269269
270+pub fn flip_selections(view: &mut View, _count: usize) {
271+ view.state.selection = view
272+ .state
273+ .selection
274+ .transform(|range| Range::new(range.head, range.anchor))
275+}
276+
270277fn enter_insert_mode(view: &mut View) {
271278 view.state.mode = Mode::Insert;
272279
@@ -463,7 +470,7 @@ pub fn delete_char_forward(view: &mut View, count: usize) {
463470pub fn undo(view: &mut View, _count: usize) {
464471 view.history.undo(&mut view.state);
465472
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?
467474}
468475
469476pub fn redo(view: &mut View, _count: usize) {
@@ -481,11 +488,15 @@ pub fn yank(view: &mut View, _count: usize) {
481488 .map(|cow| cow.into_owned())
482489 .collect();
483490
484− register::set('"', values);
491+ // TODO: allow specifying reg
492+ let reg = '"';
493+ register::set(reg, values);
485494}
486495
487496pub fn paste(view: &mut View, _count: usize) {
488− if let Some(values) = register::get('"') {
497+ // TODO: allow specifying reg
498+ let reg = '"';
499+ if let Some(values) = register::get(reg) {
489500 let repeat = std::iter::repeat(
490501 values
491502 .last()
@@ -493,13 +504,74 @@ pub fn paste(view: &mut View, _count: usize) {
493504 .unwrap(),
494505 );
495506
507+ // TODO: if any of values ends \n it's linewise paste
508+ //
509+ // p => paste after
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
515+ //
516+ // append => insert at next line
517+ // insert => insert at start of line
518+ // replace => replace
519+ // default insert
520+
521+ let linewise = values.iter().any(|value| value.ends_with('\n'));
522+
496523 let mut values = values.into_iter().map(Tendril::from).chain(repeat);
497524
498− let transaction = Transaction::change_by_selection(&view.state, |range| {
499− (range.head + 1, range.head + 1, Some(values.next().unwrap()))
500− });
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();
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()))
532+ })
533+ } else {
534+ Transaction::change_by_selection(&view.state, |range| {
535+ (range.head + 1, range.head + 1, Some(values.next().unwrap()))
536+ })
537+ };
501538
502539 transaction.apply(&mut view.state);
503540 append_changes_to_history(view);
504541 }
505542}
543+
544+const TAB_WIDTH: usize = 4;
545+
546+pub fn indent(view: &mut View, _count: usize) {
547+ let mut lines = Vec::new();
548+
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());
553+
554+ for line in start..=end {
555+ lines.push(line)
556+ }
557+ }
558+ lines.sort_unstable(); // sorting by usize so _unstable is preferred
559+ lines.dedup();
560+
561+ // Indent by one level
562+ let indent = Tendril::from(" ".repeat(TAB_WIDTH));
563+
564+ let transaction = Transaction::change(
565+ &view.state,
566+ lines.into_iter().map(|line| {
567+ let pos = view.state.doc.line_to_char(line);
568+ (pos, pos, Some(indent.clone()))
569+ }),
570+ );
571+ transaction.apply(&mut view.state);
572+ append_changes_to_history(view);
573+}
574+
575+pub fn unindent(view: &mut View, _count: usize) {
576+ unimplemented!()
577+}