1use std::{mem, cmp};
2use std::io::{self, Write};
3use termion::event::Key;
4
5use KeyMap;
6use Editor;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9enum CharMovement {
10 RightUntil,
11 RightAt,
12 LeftUntil,
13 LeftAt,
14 Repeat,
15 ReverseRepeat,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19enum MoveType {
20 Inclusive,
21 Exclusive,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26enum Mode {
27 Insert,
28 Normal,
29 Replace,
30 Delete(usize),
31 MoveToChar(CharMovement),
32 G,
33 Tilde,
34}
35
36struct ModeStack(Vec<Mode>);
37
38impl ModeStack {
39 fn with_insert() -> Self {
40 ModeStack(vec![Mode::Insert])
41 }
42
43 fn mode(&self) -> Mode {
47 self.0.last()
48 .map(|&m| m)
49 .unwrap_or(Mode::Normal)
50 }
51
52 fn clear(&mut self) {
54 self.0.clear()
55 }
56
57 fn push(&mut self, m: Mode) {
59 self.0.push(m)
60 }
61
62 fn pop(&mut self) -> Mode {
63 self.0.pop()
64 .unwrap_or(Mode::Normal)
65 }
66}
67
68fn is_movement_key(key: Key) -> bool {
69 match key {
70 Key::Char('h') | Key::Char('l') | Key::Left | Key::Right |
71 Key::Char('w') | Key::Char('W') | Key::Char('b') | Key::Char('B') |
72 Key::Char('e') | Key::Char('E') | Key::Char('g') |
73 Key::Backspace | Key::Char(' ') | Key::Home | Key::End |
74 Key::Char('$') |
75 Key::Char('t') | Key::Char('f') | Key::Char('T') | Key::Char('F') |
76 Key::Char(';') | Key::Char(',')
77 => true,
78 _ => false,
79 }
80}
81
82#[derive(PartialEq)]
83enum ViMoveMode {
84 Keyword,
85 Whitespace,
86}
87
88#[derive(PartialEq, Clone, Copy)]
89enum ViMoveDir {
90 Left,
91 Right,
92}
93
94impl ViMoveDir {
95 pub fn advance(&self, cursor: &mut usize, max: usize) -> bool {
96 self.move_cursor(cursor, max, *self)
97 }
98
99 pub fn go_back(&self, cursor: &mut usize, max: usize) -> bool {
100 match *self {
101 ViMoveDir::Right => self.move_cursor(cursor, max, ViMoveDir::Left),
102 ViMoveDir::Left => self.move_cursor(cursor, max, ViMoveDir::Right),
103 }
104 }
105
106 fn move_cursor(&self, cursor: &mut usize, max: usize, dir: ViMoveDir) -> bool {
107 if dir == ViMoveDir::Right && *cursor == max {
108 return false;
109 }
110
111 if dir == ViMoveDir::Left && *cursor == 0 {
112 return false;
113 }
114
115 match dir {
116 ViMoveDir::Right => *cursor += 1,
117 ViMoveDir::Left => *cursor -= 1,
118 };
119 true
120 }
121}
122
123fn is_vi_keyword(c: char) -> bool {
125 c == '_' || c.is_alphanumeric()
126}
127
128fn move_word<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
129 vi_move_word(ed, ViMoveMode::Keyword, ViMoveDir::Right, count)
130}
131
132fn move_word_ws<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
133 vi_move_word(ed, ViMoveMode::Whitespace, ViMoveDir::Right, count)
134}
135
136fn move_to_end_of_word_back<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
137 vi_move_word(ed, ViMoveMode::Keyword, ViMoveDir::Left, count)
138}
139
140fn move_to_end_of_word_ws_back<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
141 vi_move_word(ed, ViMoveMode::Whitespace, ViMoveDir::Left, count)
142}
143
144fn vi_move_word<W: Write>(ed: &mut Editor<W>, move_mode: ViMoveMode, direction: ViMoveDir, count: usize) -> io::Result<()> {
145 enum State {
146 Whitespace,
147 Keyword,
148 NonKeyword,
149 };
150
151 let mut cursor = ed.cursor();
152 'repeat: for _ in 0..count {
153 let buf = ed.current_buffer();
154 let mut state = match buf.char_after(cursor) {
155 None => break,
156 Some(c) => match c {
157 c if c.is_whitespace() => State::Whitespace,
158 c if is_vi_keyword(c) => State::Keyword,
159 _ => State::NonKeyword,
160 },
161 };
162
163 while direction.advance(&mut cursor, buf.num_chars()) {
164 let c = match buf.char_after(cursor) {
165 Some(c) => c,
166 _ => break 'repeat,
167 };
168
169 match state {
170 State::Whitespace => match c {
171 c if c.is_whitespace() => {},
172 _ => break,
173 },
174 State::Keyword => match c {
175 c if c.is_whitespace() => state = State::Whitespace,
176 c if move_mode == ViMoveMode::Keyword
177 && !is_vi_keyword(c)
178 => break,
179 _ => {}
180 },
181 State::NonKeyword => match c {
182 c if c.is_whitespace() => state = State::Whitespace,
183 c if move_mode == ViMoveMode::Keyword
184 && is_vi_keyword(c)
185 => break,
186 _ => {}
187 },
188 }
189 }
190 }
191
192 ed.move_cursor_to(cursor)
193}
194
195fn move_to_end_of_word<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
196 vi_move_word_end(ed, ViMoveMode::Keyword, ViMoveDir::Right, count)
197}
198
199fn move_to_end_of_word_ws<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
200 vi_move_word_end(ed, ViMoveMode::Whitespace, ViMoveDir::Right, count)
201}
202
203fn move_word_back<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
204 vi_move_word_end(ed, ViMoveMode::Keyword, ViMoveDir::Left, count)
205}
206
207fn move_word_ws_back<W: Write>(ed: &mut Editor<W>, count: usize) -> io::Result<()> {
208 vi_move_word_end(ed, ViMoveMode::Whitespace, ViMoveDir::Left, count)
209}
210
211fn vi_move_word_end<W: Write>(ed: &mut Editor<W>, move_mode: ViMoveMode, direction: ViMoveDir, count: usize) -> io::Result<()> {
212 enum State {
213 Whitespace,
214 EndOnWord,
215 EndOnOther,
216 EndOnWhitespace,
217 };
218
219 let mut cursor = ed.cursor();
220 'repeat: for _ in 0..count {
221 let buf = ed.current_buffer();
222 let mut state = State::Whitespace;
223
224 while direction.advance(&mut cursor, buf.num_chars()) {
225 let c = match buf.char_after(cursor) {
226 Some(c) => c,
227 _ => break 'repeat,
228 };
229
230 match state {
231 State::Whitespace => match c {
232 c if c.is_whitespace() => {},
234 c if move_mode == ViMoveMode::Keyword
236 && is_vi_keyword(c) =>
237 {
238 state = State::EndOnWord;
239 },
240 _ if move_mode == ViMoveMode::Whitespace => {
242 state = State::EndOnWhitespace;
243 }
244 _ => {
246 state = State::EndOnOther;
247 }
248 },
249 State::EndOnWord if !is_vi_keyword(c) => {
250 direction.go_back(&mut cursor, buf.num_chars());
251 break;
252 },
253 State::EndOnWhitespace if c.is_whitespace() => {
254 direction.go_back(&mut cursor, buf.num_chars());
255 break;
256 },
257 State::EndOnOther if c.is_whitespace() || is_vi_keyword(c) => {
258 direction.go_back(&mut cursor, buf.num_chars());
259 break;
260 },
261 _ => {},
262 }
263 }
264 }
265
266 ed.move_cursor_to(cursor)
267}
268
269fn find_char(buf: &::buffer::Buffer, start: usize, ch: char, count: usize) -> Option<usize> {
270 assert!(count > 0);
271 buf.chars()
272 .enumerate()
273 .skip(start)
274 .filter(|&(_, &c)| c == ch)
275 .skip(count - 1)
276 .next()
277 .map(|(i, _)| i)
278}
279
280fn find_char_rev(buf: &::buffer::Buffer, start: usize, ch: char, count: usize) -> Option<usize> {
281 assert!(count > 0);
282 let rstart = buf.num_chars() - start;
283 buf.chars()
284 .enumerate()
285 .rev()
286 .skip(rstart)
287 .filter(|&(_, &c)| c == ch)
288 .skip(count - 1)
289 .next()
290 .map(|(i, _)| i)
291}
292
293pub struct Vi<'a, W: Write> {
301 ed: Editor<'a, W>,
302 mode_stack: ModeStack,
303 current_command: Vec<Key>,
304 last_command: Vec<Key>,
305 current_insert: Option<Key>,
306 last_insert: Option<Key>,
307 count: u32,
308 secondary_count: u32,
309 last_count: u32,
310 movement_reset: bool,
311 last_char_movement: Option<(char, CharMovement)>,
312}
313
314impl<'a, W: Write> Vi<'a, W> {
315 pub fn new(mut ed: Editor<'a, W>) -> Self {
316 ed.current_buffer_mut().start_undo_group();
318
319 Vi {
320 ed: ed,
321 mode_stack: ModeStack::with_insert(),
322 current_command: Vec::new(),
323 last_command: Vec::new(),
324 current_insert: None,
325 last_insert: Some(Key::Char('i')),
327 count: 0,
328 secondary_count: 0,
329 last_count: 0,
330 movement_reset: false,
331 last_char_movement: None,
332 }
333 }
334
335 fn mode(&self) -> Mode {
337 self.mode_stack.mode()
338 }
339
340 fn set_mode(&mut self, mode: Mode) {
341 use self::Mode::*;
342 self.set_mode_preserve_last(mode);
343 if mode == Insert {
344 self.last_count = 0;
345 self.last_command.clear();
346 }
347 }
348
349 fn set_mode_preserve_last(&mut self, mode: Mode) {
350 use self::Mode::*;
351
352 self.ed.no_eol = mode == Normal;
353 self.movement_reset = mode != Insert;
354 self.mode_stack.push(mode);
355
356 if mode == Insert || mode == Tilde {
357 self.ed.current_buffer_mut().start_undo_group();
358 }
359 }
360
361 fn pop_mode_after_movement(&mut self, move_type: MoveType) -> io::Result<()> {
362 use self::Mode::*;
363 use self::MoveType::*;
364
365 let original_mode = self.mode_stack.pop();
366 let last_mode = {
367 match self.mode() {
370 Delete(_) => self.mode_stack.pop(),
371 _ => original_mode,
372 }
373 };
374
375 self.ed.no_eol = self.mode() == Mode::Normal;
376 self.movement_reset = self.mode() != Mode::Insert;
377
378 match last_mode {
379 Delete(start_pos) => {
380 match move_type {
382 Exclusive => try!(self.ed.delete_until(start_pos)),
383 Inclusive => try!(self.ed.delete_until_inclusive(start_pos)),
384 }
385
386 mem::swap(&mut self.last_command, &mut self.current_command);
388 self.last_insert = self.current_insert;
389 self.last_count = self.count;
390
391 self.count = 0;
393 self.secondary_count = 0;
394 }
395 _ => {}
396 };
397
398 if original_mode == Normal {
400 self.count = 0;
401 }
402
403 Ok(())
404 }
405
406 fn pop_mode(&mut self) {
407 use self::Mode::*;
408
409 let last_mode = self.mode_stack.pop();
410 self.ed.no_eol = self.mode() == Normal;
411 self.movement_reset = self.mode() != Insert;
412
413 if last_mode == Insert || last_mode == Tilde {
414 self.ed.current_buffer_mut().end_undo_group();
415 }
416
417 if last_mode == Tilde {
418 self.ed.display().unwrap();
419 }
420 }
421
422 fn normal_mode_abort(&mut self) {
424 self.mode_stack.clear();
425 self.ed.no_eol = true;
426 self.count = 0;
427 }
428
429 fn move_count(&mut self) -> usize {
431 match self.count {
432 0 => 1,
433 _ => self.count as usize,
434 }
435 }
436
437 fn move_count_left(&mut self) -> usize {
439 cmp::min(self.ed.cursor(), self.move_count())
440 }
441
442 fn move_count_right(&mut self) -> usize {
444 cmp::min(self.ed.current_buffer().num_chars() - self.ed.cursor(), self.move_count())
445 }
446
447 fn repeat(&mut self) -> io::Result<()> {
448 self.last_count = self.count;
449 let keys = mem::replace(&mut self.last_command, Vec::new());
450
451 if let Some(insert_key) = self.last_insert {
452 try!(self.handle_key_core(insert_key));
454 }
455
456 for k in keys.iter() {
457 try!(self.handle_key_core(*k));
458 }
459
460 if self.last_insert.is_some() {
461 try!(self.handle_key_core(Key::Esc));
463 }
464
465 mem::replace(&mut self.last_command, keys);
467
468 Ok(())
469 }
470
471 fn handle_key_common(&mut self, key: Key) -> io::Result<()> {
472 match key {
473 Key::Ctrl('l') => self.ed.clear(),
474 Key::Left => self.ed.move_cursor_left(1),
475 Key::Right => self.ed.move_cursor_right(1),
476 Key::Up => self.ed.move_up(),
477 Key::Down => self.ed.move_down(),
478 Key::Home => self.ed.move_cursor_to_start_of_line(),
479 Key::End => self.ed.move_cursor_to_end_of_line(),
480 Key::Backspace => self.ed.delete_before_cursor(),
481 Key::Delete => self.ed.delete_after_cursor(),
482 Key::Null => Ok(()),
483 _ => Ok(()),
484 }
485 }
486
487 fn handle_key_insert(&mut self, key: Key) -> io::Result<()> {
488 match key {
489 Key::Esc => {
490 if self.count > 0 {
492 self.last_count = self.count;
493 for _ in 1..self.count {
494 let keys = mem::replace(&mut self.last_command, Vec::new());
495 for k in keys.into_iter() {
496 try!(self.handle_key_core(k));
497 }
498 }
499 self.count = 0;
500 }
501 try!(self.ed.move_cursor_left(1));
503 self.pop_mode();
504 Ok(())
505 }
506 Key::Char(c) => {
507 if self.movement_reset {
508 self.ed.current_buffer_mut().end_undo_group();
509 self.ed.current_buffer_mut().start_undo_group();
510 self.last_command.clear();
511 self.movement_reset = false;
512 self.last_insert = Some(Key::Char('i'));
514 }
515 self.last_command.push(key);
516 self.ed.insert_after_cursor(c)
517 }
518 Key::Backspace | Key::Delete => {
520 if self.movement_reset {
521 self.ed.current_buffer_mut().end_undo_group();
522 self.ed.current_buffer_mut().start_undo_group();
523 self.last_command.clear();
524 self.movement_reset = false;
525 self.last_insert = Some(Key::Char('i'));
527 }
528 self.last_command.push(key);
529 self.handle_key_common(key)
530 }
531 Key::Left | Key::Right | Key::Home | Key::End => {
533 self.count = 0;
534 self.movement_reset = true;
535 self.handle_key_common(key)
536 }
537 Key::Up => {
539 self.count = 0;
540 self.movement_reset = true;
541 self.ed.current_buffer_mut().end_undo_group();
542 try!(self.ed.move_up());
543 self.ed.current_buffer_mut().start_undo_group();
544 Ok(())
545 }
546 Key::Down => {
547 self.count = 0;
548 self.movement_reset = true;
549 self.ed.current_buffer_mut().end_undo_group();
550 try!(self.ed.move_down());
551 self.ed.current_buffer_mut().start_undo_group();
552 Ok(())
553 }
554 _ => self.handle_key_common(key),
555 }
556 }
557
558 fn handle_key_normal(&mut self, key: Key) -> io::Result<()> {
559 use self::Mode::*;
560 use self::CharMovement::*;
561 use self::MoveType::*;
562
563 match key {
564 Key::Esc => {
565 self.count = 0;
566 Ok(())
567 }
568 Key::Char('i') => {
569 self.last_insert = Some(key);
570 self.set_mode(Insert);
571 Ok(())
572 }
573 Key::Char('a') => {
574 self.last_insert = Some(key);
575 self.set_mode(Insert);
576 self.ed.move_cursor_right(1)
577 }
578 Key::Char('A') => {
579 self.last_insert = Some(key);
580 self.set_mode(Insert);
581 self.ed.move_cursor_to_end_of_line()
582 }
583 Key::Char('I') => {
584 self.last_insert = Some(key);
585 self.set_mode(Insert);
586 self.ed.move_cursor_to_start_of_line()
587 }
588 Key::Char('s') => {
589 self.last_insert = Some(key);
590 self.set_mode(Insert);
591 let pos = self.ed.cursor() + self.move_count_right();
592 try!(self.ed.delete_until(pos));
593 self.last_count = self.count;
594 self.count = 0;
595 Ok(())
596 }
597 Key::Char('r') => {
598 self.set_mode(Mode::Replace);
599 Ok(())
600 }
601 Key::Char('d') | Key::Char('c') => {
602 self.current_command.clear();
603
604 if key == Key::Char('d') {
605 self.current_insert = None;
607 self.current_command.push(key);
608 }
609 else {
610 self.current_insert = Some(key);
612 self.current_command.clear();
613 self.set_mode(Insert);
614 }
615
616 let start_pos = self.ed.cursor();
617 self.set_mode(Mode::Delete(start_pos));
618 self.secondary_count = self.count;
619 self.count = 0;
620 Ok(())
621 }
622 Key::Char('D') => {
623 self.last_insert = None;
625 self.last_command.clear();
626 self.last_command.push(key);
627 self.count = 0;
628 self.last_count = 0;
629
630 self.ed.delete_all_after_cursor()
631 }
632 Key::Char('C') => {
633 self.last_insert = None;
635 self.last_command.clear();
636 self.last_command.push(key);
637 self.count = 0;
638 self.last_count = 0;
639
640 self.set_mode_preserve_last(Insert);
641 self.ed.delete_all_after_cursor()
642 }
643 Key::Char('.') => {
644 self.count = match (self.count, self.last_count) {
646 (0, 0) => 1,
648 (0, _) => self.last_count,
650 (_, _) => self.count,
652 };
653 self.repeat()
654 }
655 Key::Char('h') | Key::Left | Key::Backspace => {
656 let count = self.move_count_left();
657 try!(self.ed.move_cursor_left(count));
658 self.pop_mode_after_movement(Exclusive)
659 }
660 Key::Char('l') | Key::Right | Key::Char(' ') => {
661 let count = self.move_count_right();
662 try!(self.ed.move_cursor_right(count));
663 self.pop_mode_after_movement(Exclusive)
664 }
665 Key::Char('k') | Key::Up => {
666 try!(self.ed.move_up());
667 self.pop_mode_after_movement(Exclusive)
668 }
669 Key::Char('j') | Key::Down => {
670 try!(self.ed.move_down());
671 self.pop_mode_after_movement(Exclusive)
672 }
673 Key::Char('t') => {
674 self.set_mode(Mode::MoveToChar(RightUntil));
675 Ok(())
676 }
677 Key::Char('T') => {
678 self.set_mode(Mode::MoveToChar(LeftUntil));
679 Ok(())
680 }
681 Key::Char('f') => {
682 self.set_mode(Mode::MoveToChar(RightAt));
683 Ok(())
684 }
685 Key::Char('F') => {
686 self.set_mode(Mode::MoveToChar(LeftAt));
687 Ok(())
688 }
689 Key::Char(';') => self.handle_key_move_to_char(key, Repeat),
690 Key::Char(',') => self.handle_key_move_to_char(key, ReverseRepeat),
691 Key::Char('w') => {
692 let count = self.move_count();
693 try!(move_word(&mut self.ed, count));
694 self.pop_mode_after_movement(Exclusive)
695 }
696 Key::Char('W') => {
697 let count = self.move_count();
698 try!(move_word_ws(&mut self.ed, count));
699 self.pop_mode_after_movement(Exclusive)
700 }
701 Key::Char('e') => {
702 let count = self.move_count();
703 try!(move_to_end_of_word(&mut self.ed, count));
704 self.pop_mode_after_movement(Exclusive)
705 }
706 Key::Char('E') => {
707 let count = self.move_count();
708 try!(move_to_end_of_word_ws(&mut self.ed, count));
709 self.pop_mode_after_movement(Exclusive)
710 }
711 Key::Char('b') => {
712 let count = self.move_count();
713 try!(move_word_back(&mut self.ed, count));
714 self.pop_mode_after_movement(Exclusive)
715 }
716 Key::Char('B') => {
717 let count = self.move_count();
718 try!(move_word_ws_back(&mut self.ed, count));
719 self.pop_mode_after_movement(Exclusive)
720 }
721 Key::Char('g') => {
722 self.set_mode(Mode::G);
723 Ok(())
724 }
725 Key::Char('0') if self.count == 0 => {
727 try!(self.ed.move_cursor_to_start_of_line());
728 self.pop_mode_after_movement(Exclusive)
729 }
730 Key::Char(i @ '0'...'9') => {
731 let i = i.to_digit(10).unwrap();
732 self.count = self.count
734 .saturating_mul(10)
735 .saturating_add(i);
736 Ok(())
737 }
738 Key::Char('$') => {
739 try!(self.ed.move_cursor_to_end_of_line());
740 self.pop_mode_after_movement(Exclusive)
741 }
742 Key::Char('x') | Key::Delete => {
743 self.last_insert = None;
745 self.last_command.clear();
746 self.last_command.push(key);
747 self.last_count = self.count;
748
749 let pos = self.ed.cursor() + self.move_count_right();
750 try!(self.ed.delete_until(pos));
751 self.count = 0;
752 Ok(())
753 }
754 Key::Char('~') => {
755 self.last_insert = None;
757 self.last_command.clear();
758 self.last_command.push(key);
759 self.last_count = self.count;
760
761 self.set_mode(Tilde);
762 for _ in 0..self.move_count_right() {
763 let c = self.ed.current_buffer().char_after(self.ed.cursor()).unwrap();
764 if c.is_lowercase() {
765 try!(self.ed.delete_after_cursor());
766 for c in c.to_uppercase() {
767 try!(self.ed.insert_after_cursor(c));
768 }
769 }
770 else if c.is_uppercase() {
771 try!(self.ed.delete_after_cursor());
772 for c in c.to_lowercase() {
773 try!(self.ed.insert_after_cursor(c));
774 }
775 }
776 else {
777 try!(self.ed.move_cursor_right(1));
778 }
779 }
780 self.pop_mode();
781 Ok(())
782 }
783 Key::Char('u') => {
784 let count = self.move_count();
785 self.count = 0;
786 for _ in 0..count {
787 let did = try!(self.ed.undo());
788 if !did {
789 break;
790 }
791 }
792 Ok(())
793 }
794 Key::Ctrl('r') => {
795 let count = self.move_count();
796 self.count = 0;
797 for _ in 0..count {
798 let did = try!(self.ed.redo());
799 if !did {
800 break;
801 }
802 }
803 Ok(())
804 }
805 _ => self.handle_key_common(key),
806 }
807 }
808
809 fn handle_key_replace(&mut self, key: Key) -> io::Result<()> {
810 match key {
811 Key::Char(c) => {
812 if self.move_count_right() == self.move_count() {
814 self.last_insert = None;
816 self.last_command.clear();
817 self.last_command.push(Key::Char('r'));
818 self.last_command.push(key);
819 self.last_count = self.count;
820
821 self.ed.current_buffer_mut().start_undo_group();
823 for _ in 0..self.move_count_right() {
824 try!(self.ed.delete_after_cursor());
825 try!(self.ed.insert_after_cursor(c));
826 }
827 self.ed.current_buffer_mut().end_undo_group();
828
829 try!(self.ed.move_cursor_left(1));
830 }
831 self.pop_mode();
832 }
833 _ => {
835 self.normal_mode_abort();
836 }
837 };
838
839 self.count = 0;
841 Ok(())
842 }
843
844 fn handle_key_delete_or_change(&mut self, key: Key) -> io::Result<()> {
845 match (key, self.current_insert) {
846 (key, _) if is_movement_key(key) | (key == Key::Char('0') && self.count == 0) => {
848 self.count = match (self.count, self.secondary_count) {
850 (0, 0) => 0,
851 (_, 0) => self.count,
852 (0, _) => self.secondary_count,
853 _ => {
854 self.secondary_count
856 .saturating_mul(self.count)
857 }
858 };
859
860 self.current_command.push(key);
862
863 self.handle_key_normal(key)
865 }
866 (Key::Char('0'...'9'), _) => {
868 self.handle_key_normal(key)
869 }
870 (Key::Char('c'), Some(Key::Char('c'))) | (Key::Char('d'), None) => {
871 self.current_command.push(key);
877
878 self.count = 0;
880 self.secondary_count = 0;
881 try!(self.ed.move_cursor_to_start_of_line());
882 try!(self.ed.delete_all_after_cursor());
883
884 self.pop_mode();
886 Ok(())
887 }
888 _ => {
890 self.normal_mode_abort();
891 Ok(())
892 }
893 }
894 }
895
896 fn handle_key_move_to_char(&mut self, key: Key, movement: CharMovement) -> io::Result<()> {
897 use self::CharMovement::*;
898 use self::MoveType::*;
899
900 let count = self.move_count();
901 self.count = 0;
902
903 let (key, movement) = match (key, movement, self.last_char_movement) {
904 (_, Repeat, Some((c, last_movement))) => (Key::Char(c), last_movement),
906 (_, ReverseRepeat, Some((c, LeftUntil))) => (Key::Char(c), RightUntil),
908 (_, ReverseRepeat, Some((c, RightUntil))) => (Key::Char(c), LeftUntil),
909 (_, ReverseRepeat, Some((c, LeftAt))) => (Key::Char(c), RightAt),
910 (_, ReverseRepeat, Some((c, RightAt))) => (Key::Char(c), LeftAt),
911 (Key::Char(c), _, _) => {
913 self.last_char_movement = Some((c, movement));
915 self.current_command.push(key);
916 (key, movement)
917 }
918 _ => {
921 self.normal_mode_abort();
922 return Ok(());
923 }
924 };
925
926 match key {
927 Key::Char(c) => {
928 let move_type;
929 try!(match movement {
930 RightUntil => {
931 move_type = Inclusive;
932 match find_char(self.ed.current_buffer(), self.ed.cursor() + 1, c, count) {
933 Some(i) => self.ed.move_cursor_to(i - 1),
934 None => Ok(()),
935 }
936 }
937 RightAt => {
938 move_type = Inclusive;
939 match find_char(self.ed.current_buffer(), self.ed.cursor() + 1, c, count) {
940 Some(i) => self.ed.move_cursor_to(i),
941 None => Ok(()),
942 }
943 }
944 LeftUntil => {
945 move_type = Exclusive;
946 match find_char_rev(self.ed.current_buffer(), self.ed.cursor(), c, count) {
947 Some(i) => self.ed.move_cursor_to(i + 1),
948 None => Ok(()),
949 }
950 }
951 LeftAt => {
952 move_type = Exclusive;
953 match find_char_rev(self.ed.current_buffer(), self.ed.cursor(), c, count) {
954 Some(i) => self.ed.move_cursor_to(i),
955 None => Ok(()),
956 }
957 }
958 Repeat | ReverseRepeat => unreachable!(),
959 });
960
961 self.pop_mode_after_movement(move_type)
963 }
964
965 _ => unreachable!(),
967 }
968 }
969
970 fn handle_key_g(&mut self, key: Key) -> io::Result<()> {
971 use self::MoveType::*;
972
973 let count = self.move_count();
974 self.current_command.push(key);
975
976 let res = match key {
977 Key::Char('e') => {
978 try!(move_to_end_of_word_back(&mut self.ed, count));
979 self.pop_mode_after_movement(Inclusive)
980 }
981 Key::Char('E') => {
982 try!(move_to_end_of_word_ws_back(&mut self.ed, count));
983 self.pop_mode_after_movement(Inclusive)
984 }
985
986 _ => {
988 self.normal_mode_abort();
989 Ok(())
990 }
991 };
992
993 self.count = 0;
994 res
995 }
996}
997
998impl<'a, W: Write> KeyMap<'a, W, Vi<'a, W>> for Vi<'a, W> {
999 fn handle_key_core(&mut self, key: Key) -> io::Result<()> {
1000 match self.mode() {
1001 Mode::Normal => self.handle_key_normal(key),
1002 Mode::Insert => self.handle_key_insert(key),
1003 Mode::Replace => self.handle_key_replace(key),
1004 Mode::Delete(_) => self.handle_key_delete_or_change(key),
1005 Mode::MoveToChar(movement) => self.handle_key_move_to_char(key, movement),
1006 Mode::G => self.handle_key_g(key),
1007 Mode::Tilde => unreachable!(),
1008 }
1009 }
1010
1011 fn editor_mut(&mut self) -> &mut Editor<'a, W> {
1012 &mut self.ed
1013 }
1014
1015 fn editor(&self) -> &Editor<'a, W> {
1016 &self.ed
1017 }
1018}
1019
1020impl<'a, W: Write> From<Vi<'a, W>> for String {
1021 fn from(vi: Vi<'a, W>) -> String {
1022 vi.ed.into()
1023 }
1024}
1025
1026#[cfg(test)]
1027mod tests {
1028 use super::*;
1029 use termion::event::Key;
1030 use termion::event::Key::*;
1031 use Buffer;
1032 use Context;
1033 use Editor;
1034 use KeyMap;
1035 use std::io::Write;
1036
1037 macro_rules! simulate_keys {
1038 ($keymap:ident, $keys:expr) => {{
1039 simulate_keys(&mut $keymap, $keys.into_iter())
1040 }}
1041 }
1042
1043 fn simulate_keys<'a, 'b, W: Write, T, M: KeyMap<'a, W, T>, I>(keymap: &mut M, keys: I) -> bool
1044 where I: Iterator<Item=&'b Key>
1045 {
1046 for k in keys {
1047 if keymap.handle_key(*k, &mut |_| {}).unwrap() {
1048 return true;
1049 }
1050 }
1051
1052 false
1053 }
1054
1055 #[test]
1056 fn enter_is_done() {
1057 let mut context = Context::new();
1058 let out = Vec::new();
1059 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1060 let mut map = Vi::new(ed);
1061 map.ed.insert_str_after_cursor("done").unwrap();
1062 assert_eq!(map.ed.cursor(), 4);
1063
1064 assert!(simulate_keys!(map, [
1065 Char('\n'),
1066 ]));
1067
1068 assert_eq!(map.ed.cursor(), 4);
1069 assert_eq!(String::from(map), "done");
1070 }
1071
1072 #[test]
1073 fn move_cursor_left() {
1074 let mut context = Context::new();
1075 let out = Vec::new();
1076 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1077 let mut map = Vi::new(ed);
1078 map.editor_mut().insert_str_after_cursor("let").unwrap();
1079 assert_eq!(map.ed.cursor(), 3);
1080
1081 simulate_keys!(map, [
1082 Left,
1083 Char('f'),
1084 ]);
1085
1086 assert_eq!(map.ed.cursor(), 3);
1087 assert_eq!(String::from(map), "left");
1088 }
1089
1090 #[test]
1091 fn cursor_movement() {
1092 let mut context = Context::new();
1093 let out = Vec::new();
1094 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1095 let mut map = Vi::new(ed);
1096 map.ed.insert_str_after_cursor("right").unwrap();
1097 assert_eq!(map.ed.cursor(), 5);
1098
1099 simulate_keys!(map, [
1100 Left,
1101 Left,
1102 Right,
1103 ]);
1104
1105 assert_eq!(map.ed.cursor(), 4);
1106 }
1107
1108 #[test]
1109 fn vi_initial_insert() {
1110 let mut context = Context::new();
1111 let out = Vec::new();
1112 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1113 let mut map = Vi::new(ed);
1114
1115 simulate_keys!(map, [
1116 Char('i'),
1117 Char('n'),
1118 Char('s'),
1119 Char('e'),
1120 Char('r'),
1121 Char('t'),
1122 ]);
1123
1124 assert_eq!(map.ed.cursor(), 6);
1125 assert_eq!(String::from(map), "insert");
1126 }
1127
1128 #[test]
1129 fn vi_left_right_movement() {
1130 let mut context = Context::new();
1131 let out = Vec::new();
1132 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1133 let mut map = Vi::new(ed);
1134 map.ed.insert_str_after_cursor("data").unwrap();
1135 assert_eq!(map.ed.cursor(), 4);
1136
1137 simulate_keys!(map, [Left]);
1138 assert_eq!(map.ed.cursor(), 3);
1139 simulate_keys!(map, [Right]);
1140 assert_eq!(map.ed.cursor(), 4);
1141
1142 simulate_keys!(map, [Esc, Left]);
1144 assert_eq!(map.ed.cursor(), 2);
1145 simulate_keys!(map, [Right]);
1146 assert_eq!(map.ed.cursor(), 3);
1147
1148 simulate_keys!(map, [Char('h')]);
1149 assert_eq!(map.ed.cursor(), 2);
1150 simulate_keys!(map, [Char('l')]);
1151 assert_eq!(map.ed.cursor(), 3);
1152 }
1153
1154 #[test]
1155 fn vi_no_eol() {
1157 let mut context = Context::new();
1158 let out = Vec::new();
1159 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1160 let mut map = Vi::new(ed);
1161 map.ed.insert_str_after_cursor("data").unwrap();
1162 assert_eq!(map.ed.cursor(), 4);
1163
1164 simulate_keys!(map, [Esc]);
1165 assert_eq!(map.ed.cursor(), 3);
1166
1167 simulate_keys!(map, [Right, Right]);
1168 assert_eq!(map.ed.cursor(), 3);
1169
1170 simulate_keys!(map, [Char('i'), Right, Right]);
1172 assert_eq!(map.ed.cursor(), 4);
1173 }
1174
1175 #[test]
1176 fn vi_switch_from_insert() {
1178 let mut context = Context::new();
1179 let out = Vec::new();
1180 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1181 let mut map = Vi::new(ed);
1182 map.ed.insert_str_after_cursor("data").unwrap();
1183 assert_eq!(map.ed.cursor(), 4);
1184
1185 simulate_keys!(map, [Esc]);
1186 assert_eq!(map.ed.cursor(), 3);
1187
1188 simulate_keys!(map, [
1189 Char('i'),
1190 Esc,
1191 Char('i'),
1192 Esc,
1193 Char('i'),
1194 Esc,
1195 Char('i'),
1196 Esc,
1197 ]);
1198 assert_eq!(map.ed.cursor(), 0);
1199 }
1200
1201 #[test]
1202 fn vi_normal_history_cursor_eol() {
1203 let mut context = Context::new();
1204 context.history.push("history".into()).unwrap();
1205 context.history.push("history".into()).unwrap();
1206 let out = Vec::new();
1207 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1208 let mut map = Vi::new(ed);
1209 map.ed.insert_str_after_cursor("data").unwrap();
1210 assert_eq!(map.ed.cursor(), 4);
1211
1212 simulate_keys!(map, [Up]);
1213 assert_eq!(map.ed.cursor(), 7);
1214
1215 simulate_keys!(map, [Esc, Up]);
1217 assert_eq!(map.ed.cursor(), 6);
1218 }
1219
1220 #[test]
1221 fn vi_normal_delete() {
1222 let mut context = Context::new();
1223 context.history.push("history".into()).unwrap();
1224 context.history.push("history".into()).unwrap();
1225 let out = Vec::new();
1226 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1227 let mut map = Vi::new(ed);
1228 map.ed.insert_str_after_cursor("data").unwrap();
1229 assert_eq!(map.ed.cursor(), 4);
1230
1231 simulate_keys!(map, [
1232 Esc,
1233 Char('0'),
1234 Delete,
1235 Char('x'),
1236 ]);
1237 assert_eq!(map.ed.cursor(), 0);
1238 assert_eq!(String::from(map), "ta");
1239 }
1240
1241 #[test]
1242 fn vi_substitute_command() {
1243 let mut context = Context::new();
1244 let out = Vec::new();
1245 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1246 let mut map = Vi::new(ed);
1247 map.ed.insert_str_after_cursor("data").unwrap();
1248 assert_eq!(map.ed.cursor(), 4);
1249
1250 simulate_keys!(map, [
1251 Esc,
1252 Char('0'),
1253 Char('s'),
1254 Char('s'),
1255 ]);
1256 assert_eq!(String::from(map), "sata");
1257 }
1258
1259 #[test]
1260 fn substitute_with_count() {
1261 let mut context = Context::new();
1262 let out = Vec::new();
1263 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1264 let mut map = Vi::new(ed);
1265 map.ed.insert_str_after_cursor("data").unwrap();
1266 assert_eq!(map.ed.cursor(), 4);
1267
1268 simulate_keys!(map, [
1269 Esc,
1270 Char('0'),
1271 Char('2'),
1272 Char('s'),
1273 Char('b'),
1274 Char('e'),
1275 ]);
1276 assert_eq!(String::from(map), "beta");
1277 }
1278
1279 #[test]
1280 fn substitute_with_count_repeat() {
1281 let mut context = Context::new();
1282 let out = Vec::new();
1283 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1284 let mut map = Vi::new(ed);
1285 map.ed.insert_str_after_cursor("data data").unwrap();
1286
1287 simulate_keys!(map, [
1288 Esc,
1289 Char('0'),
1290 Char('2'),
1291 Char('s'),
1292 Char('b'),
1293 Char('e'),
1294 Esc,
1295 Char('4'),
1296 Char('l'),
1297 Char('.'),
1298 ]);
1299 assert_eq!(String::from(map), "beta beta");
1300 }
1301
1302 #[test]
1303 fn vi_count() {
1305 let mut context = Context::new();
1306 let out = Vec::new();
1307 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1308 let mut map = Vi::new(ed);
1309
1310 simulate_keys!(map, [
1311 Esc,
1312 ]);
1313 assert_eq!(map.count, 0);
1314
1315 simulate_keys!(map, [
1316 Char('1'),
1317 ]);
1318 assert_eq!(map.count, 1);
1319
1320 simulate_keys!(map, [
1321 Char('1'),
1322 ]);
1323 assert_eq!(map.count, 11);
1324
1325 simulate_keys!(map, [
1327 Char('i'),
1328 Esc,
1329 ]);
1330 assert_eq!(map.count, 0);
1331
1332 assert_eq!(String::from(map), "");
1333 }
1334
1335 #[test]
1336 fn vi_count_overflow() {
1338 let mut context = Context::new();
1339 let out = Vec::new();
1340 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1341 let mut map = Vi::new(ed);
1342
1343 simulate_keys!(map, [
1345 Esc,
1346 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1347 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1348 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1349 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1350 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1351 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1352 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1353 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1354 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1355 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1356 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1357 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1358 Char('9'), Char('9'), Char('9'), Char('9'), Char('9'),
1359 ]);
1360 assert_eq!(String::from(map), "");
1361 }
1362
1363 #[test]
1364 fn vi_count_overflow_zero() {
1366 let mut context = Context::new();
1367 let out = Vec::new();
1368 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1369 let mut map = Vi::new(ed);
1370
1371 simulate_keys!(map, [
1373 Esc,
1374 Char('1'), Char('0'), Char('0'), Char('0'), Char('0'),
1375 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1376 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1377 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1378 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1379 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1380 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1381 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1382 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1383 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1384 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1385 Char('0'), Char('0'), Char('0'), Char('0'), Char('0'),
1386 ]);
1387 assert_eq!(String::from(map), "");
1388 }
1389
1390 #[test]
1391 fn vi_count_cancel() {
1393 let mut context = Context::new();
1394 let out = Vec::new();
1395 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1396 let mut map = Vi::new(ed);
1397
1398 simulate_keys!(map, [
1399 Esc,
1400 Char('1'),
1401 Char('0'),
1402 Esc,
1403 ]);
1404 assert_eq!(map.count, 0);
1405 assert_eq!(String::from(map), "");
1406 }
1407
1408 #[test]
1409 fn vi_count_simple() {
1411 let mut context = Context::new();
1412 let out = Vec::new();
1413 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1414 let mut map = Vi::new(ed);
1415
1416 simulate_keys!(map, [
1417 Esc,
1418 Char('3'),
1419 Char('i'),
1420 Char('t'),
1421 Char('h'),
1422 Char('i'),
1423 Char('s'),
1424 Esc,
1425 ]);
1426 assert_eq!(String::from(map), "thisthisthis");
1427 }
1428
1429 #[test]
1430 fn vi_dot_command() {
1432 let mut context = Context::new();
1433 let out = Vec::new();
1434 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1435 let mut map = Vi::new(ed);
1436
1437 simulate_keys!(map, [
1438 Char('i'),
1439 Char('f'),
1440 Esc,
1441 Char('.'),
1442 Char('.'),
1443 ]);
1444 assert_eq!(String::from(map), "iiifff");
1445 }
1446
1447 #[test]
1448 fn vi_dot_command_repeat() {
1450 let mut context = Context::new();
1451 let out = Vec::new();
1452 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1453 let mut map = Vi::new(ed);
1454
1455 simulate_keys!(map, [
1456 Char('i'),
1457 Char('f'),
1458 Esc,
1459 Char('3'),
1460 Char('.'),
1461 ]);
1462 assert_eq!(String::from(map), "iifififf");
1463 }
1464
1465 #[test]
1466 fn vi_dot_command_repeat_multiple() {
1468 let mut context = Context::new();
1469 let out = Vec::new();
1470 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1471 let mut map = Vi::new(ed);
1472
1473 simulate_keys!(map, [
1474 Char('i'),
1475 Char('f'),
1476 Esc,
1477 Char('3'),
1478 Char('.'),
1479 Char('.'),
1480 ]);
1481 assert_eq!(String::from(map), "iififiifififff");
1482 }
1483
1484 #[test]
1485 fn vi_dot_command_append() {
1487 let mut context = Context::new();
1488 let out = Vec::new();
1489 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1490 let mut map = Vi::new(ed);
1491
1492 simulate_keys!(map, [
1493 Esc,
1494 Char('a'),
1495 Char('i'),
1496 Char('f'),
1497 Esc,
1498 Char('.'),
1499 Char('.'),
1500 ]);
1501 assert_eq!(String::from(map), "ififif");
1502 }
1503
1504 #[test]
1505 fn vi_dot_command_append_repeat() {
1507 let mut context = Context::new();
1508 let out = Vec::new();
1509 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1510 let mut map = Vi::new(ed);
1511
1512 simulate_keys!(map, [
1513 Esc,
1514 Char('a'),
1515 Char('i'),
1516 Char('f'),
1517 Esc,
1518 Char('3'),
1519 Char('.'),
1520 ]);
1521 assert_eq!(String::from(map), "ifififif");
1522 }
1523
1524 #[test]
1525 fn vi_dot_command_movement() {
1527 let mut context = Context::new();
1528 let out = Vec::new();
1529 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1530 let mut map = Vi::new(ed);
1531
1532 simulate_keys!(map, [
1533 Esc,
1534 Char('a'),
1535 Char('d'),
1536 Char('t'),
1537 Char(' '),
1538 Left,
1539 Left,
1540 Char('a'),
1541 Esc,
1542 Right,
1543 Right,
1544 Char('.'),
1545 ]);
1546 assert_eq!(String::from(map), "data ");
1547 }
1548
1549 #[test]
1550 fn move_count() {
1552 let mut context = Context::new();
1553 let out = Vec::new();
1554 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1555 let mut map = Vi::new(ed);
1556
1557 assert_eq!(map.move_count(), 1);
1558 map.count = 1;
1559 assert_eq!(map.move_count(), 1);
1560 map.count = 99;
1561 assert_eq!(map.move_count(), 99);
1562 }
1563
1564 #[test]
1565 fn vi_count_movement_reset() {
1567 let mut context = Context::new();
1568 let out = Vec::new();
1569 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1570 let mut map = Vi::new(ed);
1571
1572 simulate_keys!(map, [
1573 Esc,
1574 Char('3'),
1575 Char('i'),
1576 Char('t'),
1577 Char('h'),
1578 Char('i'),
1579 Char('s'),
1580 Left,
1581 Esc,
1582 ]);
1583 assert_eq!(String::from(map), "this");
1584 }
1585
1586 #[test]
1587 fn movement_with_count() {
1589 let mut context = Context::new();
1590 let out = Vec::new();
1591 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1592 let mut map = Vi::new(ed);
1593 map.ed.insert_str_after_cursor("right").unwrap();
1594 assert_eq!(map.ed.cursor(), 5);
1595
1596 simulate_keys!(map, [
1597 Esc,
1598 Char('3'),
1599 Left,
1600 ]);
1601
1602 assert_eq!(map.ed.cursor(), 1);
1603 }
1604
1605 #[test]
1606 fn movement_with_count_then_insert() {
1608 let mut context = Context::new();
1609 let out = Vec::new();
1610 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1611 let mut map = Vi::new(ed);
1612 map.ed.insert_str_after_cursor("right").unwrap();
1613 assert_eq!(map.ed.cursor(), 5);
1614
1615 simulate_keys!(map, [
1616 Esc,
1617 Char('3'),
1618 Left,
1619 Char('i'),
1620 Char(' '),
1621 Esc,
1622 ]);
1623 assert_eq!(String::from(map), "r ight");
1624 }
1625
1626 #[test]
1627 fn count_at_buffer_edge() {
1629 let mut context = Context::new();
1630 let out = Vec::new();
1631 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1632 let mut map = Vi::new(ed);
1633 map.ed.insert_str_after_cursor("replace").unwrap();
1634 assert_eq!(map.ed.cursor(), 7);
1635
1636 simulate_keys!(map, [
1637 Esc,
1638 Char('3'),
1639 Char('r'),
1640 Char('x'),
1641 ]);
1642 assert_eq!(map.ed.cursor(), 6);
1644 assert_eq!(String::from(map), "replace");
1645 }
1646
1647 #[test]
1648 fn basic_replace() {
1650 let mut context = Context::new();
1651 let out = Vec::new();
1652 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1653 let mut map = Vi::new(ed);
1654 map.ed.insert_str_after_cursor("replace").unwrap();
1655 assert_eq!(map.ed.cursor(), 7);
1656
1657 simulate_keys!(map, [
1658 Esc,
1659 Char('r'),
1660 Char('x'),
1661 ]);
1662 assert_eq!(map.ed.cursor(), 6);
1663 assert_eq!(String::from(map), "replacx");
1664 }
1665
1666 #[test]
1667 fn replace_with_count() {
1668 let mut context = Context::new();
1669 let out = Vec::new();
1670 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1671 let mut map = Vi::new(ed);
1672 map.ed.insert_str_after_cursor("replace").unwrap();
1673 assert_eq!(map.ed.cursor(), 7);
1674
1675 simulate_keys!(map, [
1676 Esc,
1677 Char('0'),
1678 Char('3'),
1679 Char('r'),
1680 Char(' '),
1681 ]);
1682 assert_eq!(map.ed.cursor(), 2);
1684 assert_eq!(String::from(map), " lace");
1685 }
1686
1687 #[test]
1688 fn replace_with_count_eol() {
1690 let mut context = Context::new();
1691 let out = Vec::new();
1692 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1693 let mut map = Vi::new(ed);
1694 map.ed.insert_str_after_cursor("replace").unwrap();
1695 assert_eq!(map.ed.cursor(), 7);
1696
1697 simulate_keys!(map, [
1698 Esc,
1699 Char('3'),
1700 Char('r'),
1701 Char('x'),
1702 ]);
1703 assert_eq!(map.ed.cursor(), 6);
1705 assert_eq!(String::from(map), "replace");
1706 }
1707
1708 #[test]
1709 fn replace_then_normal() {
1711 let mut context = Context::new();
1712 let out = Vec::new();
1713 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1714 let mut map = Vi::new(ed);
1715 map.ed.insert_str_after_cursor("replace").unwrap();
1716 assert_eq!(map.ed.cursor(), 7);
1717
1718 simulate_keys!(map, [
1719 Esc,
1720 Char('r'),
1721 Char('x'),
1722 Char('0'),
1723 ]);
1724 assert_eq!(map.ed.cursor(), 0);
1725 assert_eq!(String::from(map), "replacx");
1726 }
1727
1728 #[test]
1729 fn dot_replace() {
1731 let mut context = Context::new();
1732 let out = Vec::new();
1733 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1734 let mut map = Vi::new(ed);
1735 map.ed.insert_str_after_cursor("replace").unwrap();
1736 assert_eq!(map.ed.cursor(), 7);
1737
1738 simulate_keys!(map, [
1739 Esc,
1740 Char('0'),
1741 Char('r'),
1742 Char('x'),
1743 Char('.'),
1744 Char('.'),
1745 Char('7'),
1746 Char('.'),
1747 ]);
1748 assert_eq!(String::from(map), "xxxxxxx");
1749 }
1750
1751 #[test]
1752 fn dot_replace_count() {
1754 let mut context = Context::new();
1755 let out = Vec::new();
1756 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1757 let mut map = Vi::new(ed);
1758 map.ed.insert_str_after_cursor("replace").unwrap();
1759 assert_eq!(map.ed.cursor(), 7);
1760
1761 simulate_keys!(map, [
1762 Esc,
1763 Char('0'),
1764 Char('2'),
1765 Char('r'),
1766 Char('x'),
1767 Char('.'),
1768 Char('.'),
1769 Char('.'),
1770 Char('.'),
1771 Char('.'),
1772 ]);
1773 assert_eq!(String::from(map), "xxxxxxx");
1774 }
1775
1776 #[test]
1777 fn dot_replace_eol() {
1779 let mut context = Context::new();
1780 let out = Vec::new();
1781 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1782 let mut map = Vi::new(ed);
1783 map.ed.insert_str_after_cursor("test").unwrap();
1784
1785 simulate_keys!(map, [
1786 Esc,
1787 Char('0'),
1788 Char('3'),
1789 Char('r'),
1790 Char('x'),
1791 Char('.'),
1792 Char('.'),
1793 ]);
1794 assert_eq!(String::from(map), "xxxt");
1795 }
1796
1797 #[test]
1798 fn dot_replace_eol_multiple() {
1800 let mut context = Context::new();
1801 let out = Vec::new();
1802 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1803 let mut map = Vi::new(ed);
1804 map.ed.insert_str_after_cursor("this is a test").unwrap();
1805
1806 simulate_keys!(map, [
1807 Esc,
1808 Char('0'),
1809 Char('3'),
1810 Char('r'),
1811 Char('x'),
1812 Char('$'),
1813 Char('.'),
1814 Char('4'),
1815 Char('h'),
1816 Char('.'),
1817 ]);
1818 assert_eq!(String::from(map), "xxxs is axxxst");
1819 }
1820
1821 #[test]
1822 fn move_count_right() {
1824 let mut context = Context::new();
1825 let out = Vec::new();
1826 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1827 let mut map = Vi::new(ed);
1828 map.ed.insert_str_after_cursor("replace").unwrap();
1829 assert_eq!(map.ed.cursor(), 7);
1830 assert_eq!(map.move_count_right(), 0);
1831 map.count = 10;
1832 assert_eq!(map.move_count_right(), 0);
1833
1834 map.count = 0;
1835 simulate_keys!(map, [
1836 Esc,
1837 Left,
1838 ]);
1839 assert_eq!(map.move_count_right(), 1);
1840 }
1841
1842 #[test]
1843 fn move_count_left() {
1845 let mut context = Context::new();
1846 let out = Vec::new();
1847 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1848 let mut map = Vi::new(ed);
1849 map.ed.insert_str_after_cursor("replace").unwrap();
1850 assert_eq!(map.ed.cursor(), 7);
1851 assert_eq!(map.move_count_left(), 1);
1852 map.count = 10;
1853 assert_eq!(map.move_count_left(), 7);
1854
1855 map.count = 0;
1856 simulate_keys!(map, [
1857 Esc,
1858 Char('0'),
1859 ]);
1860 assert_eq!(map.move_count_left(), 0);
1861 }
1862
1863 #[test]
1864 fn dot_x_delete() {
1866 let mut context = Context::new();
1867 let out = Vec::new();
1868 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1869 let mut map = Vi::new(ed);
1870 map.ed.insert_str_after_cursor("replace").unwrap();
1871 assert_eq!(map.ed.cursor(), 7);
1872
1873 simulate_keys!(map, [
1874 Esc,
1875 Char('0'),
1876 Char('2'),
1877 Char('x'),
1878 Char('.'),
1879 ]);
1880 assert_eq!(String::from(map), "ace");
1881 }
1882
1883 #[test]
1884 fn delete_line() {
1886 let mut context = Context::new();
1887 let out = Vec::new();
1888 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1889 let mut map = Vi::new(ed);
1890 map.ed.insert_str_after_cursor("delete").unwrap();
1891
1892 simulate_keys!(map, [
1893 Esc,
1894 Char('d'),
1895 Char('d'),
1896 ]);
1897 assert_eq!(map.ed.cursor(), 0);
1898 assert_eq!(String::from(map), "");
1899 }
1900
1901 #[test]
1902 fn delete_line_normal() {
1904 let mut context = Context::new();
1905 let out = Vec::new();
1906 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1907 let mut map = Vi::new(ed);
1908 map.ed.insert_str_after_cursor("delete").unwrap();
1909
1910 simulate_keys!(map, [
1911 Esc,
1912 Char('d'),
1913 Char('d'),
1914 Char('i'),
1915 Char('n'),
1916 Char('e'),
1917 Char('w'),
1918 Esc,
1919 ]);
1920 assert_eq!(map.ed.cursor(), 2);
1921 assert_eq!(String::from(map), "new");
1922 }
1923
1924 #[test]
1925 fn delete_abort() {
1927 let mut context = Context::new();
1928 let out = Vec::new();
1929 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1930 let mut map = Vi::new(ed);
1931 map.ed.insert_str_after_cursor("don't delete").unwrap();
1932
1933 simulate_keys!(map, [
1934 Esc,
1935 Char('d'),
1936 Esc,
1937 Char('d'),
1938 Char('c'),
1939 Char('c'),
1940 Char('d'),
1941 ]);
1942 assert_eq!(map.ed.cursor(), 11);
1943 assert_eq!(String::from(map), "don't delete");
1944 }
1945
1946 #[test]
1947 fn delete_char_left() {
1949 let mut context = Context::new();
1950 let out = Vec::new();
1951 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1952 let mut map = Vi::new(ed);
1953 map.ed.insert_str_after_cursor("delete").unwrap();
1954
1955 simulate_keys!(map, [
1956 Esc,
1957 Char('d'),
1958 Char('h'),
1959 ]);
1960 assert_eq!(map.ed.cursor(), 4);
1961 assert_eq!(String::from(map), "delee");
1962 }
1963
1964 #[test]
1965 fn delete_chars_left() {
1967 let mut context = Context::new();
1968 let out = Vec::new();
1969 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1970 let mut map = Vi::new(ed);
1971 map.ed.insert_str_after_cursor("delete").unwrap();
1972
1973 simulate_keys!(map, [
1974 Esc,
1975 Char('3'),
1976 Char('d'),
1977 Char('h'),
1978 ]);
1979 assert_eq!(map.ed.cursor(), 2);
1980 assert_eq!(String::from(map), "dee");
1981 }
1982
1983 #[test]
1984 fn delete_char_right() {
1986 let mut context = Context::new();
1987 let out = Vec::new();
1988 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
1989 let mut map = Vi::new(ed);
1990 map.ed.insert_str_after_cursor("delete").unwrap();
1991
1992 simulate_keys!(map, [
1993 Esc,
1994 Char('0'),
1995 Char('d'),
1996 Char('l'),
1997 ]);
1998 assert_eq!(map.ed.cursor(), 0);
1999 assert_eq!(String::from(map), "elete");
2000 }
2001
2002 #[test]
2003 fn delete_chars_right() {
2005 let mut context = Context::new();
2006 let out = Vec::new();
2007 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2008 let mut map = Vi::new(ed);
2009 map.ed.insert_str_after_cursor("delete").unwrap();
2010
2011 simulate_keys!(map, [
2012 Esc,
2013 Char('0'),
2014 Char('3'),
2015 Char('d'),
2016 Char('l'),
2017 ]);
2018 assert_eq!(map.ed.cursor(), 0);
2019 assert_eq!(String::from(map), "ete");
2020 }
2021
2022 #[test]
2023 fn delete_and_repeat() {
2025 let mut context = Context::new();
2026 let out = Vec::new();
2027 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2028 let mut map = Vi::new(ed);
2029 map.ed.insert_str_after_cursor("delete").unwrap();
2030
2031 simulate_keys!(map, [
2032 Esc,
2033 Char('0'),
2034 Char('d'),
2035 Char('l'),
2036 Char('.'),
2037 ]);
2038 assert_eq!(map.ed.cursor(), 0);
2039 assert_eq!(String::from(map), "lete");
2040 }
2041
2042 #[test]
2043 fn delete_until_end() {
2045 let mut context = Context::new();
2046 let out = Vec::new();
2047 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2048 let mut map = Vi::new(ed);
2049 map.ed.insert_str_after_cursor("delete").unwrap();
2050
2051 simulate_keys!(map, [
2052 Esc,
2053 Char('0'),
2054 Char('d'),
2055 Char('$'),
2056 ]);
2057 assert_eq!(map.ed.cursor(), 0);
2058 assert_eq!(String::from(map), "");
2059 }
2060
2061 #[test]
2062 fn delete_until_end_shift_d() {
2064 let mut context = Context::new();
2065 let out = Vec::new();
2066 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2067 let mut map = Vi::new(ed);
2068 map.ed.insert_str_after_cursor("delete").unwrap();
2069
2070 simulate_keys!(map, [
2071 Esc,
2072 Char('0'),
2073 Char('D'),
2074 ]);
2075 assert_eq!(map.ed.cursor(), 0);
2076 assert_eq!(String::from(map), "");
2077 }
2078
2079 #[test]
2080 fn delete_until_start() {
2082 let mut context = Context::new();
2083 let out = Vec::new();
2084 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2085 let mut map = Vi::new(ed);
2086 map.ed.insert_str_after_cursor("delete").unwrap();
2087
2088 simulate_keys!(map, [
2089 Esc,
2090 Char('$'),
2091 Char('d'),
2092 Char('0'),
2093 ]);
2094 assert_eq!(map.ed.cursor(), 0);
2095 assert_eq!(String::from(map), "e");
2096 }
2097
2098 #[test]
2099 fn delete_with_count() {
2101 let mut context = Context::new();
2102 let out = Vec::new();
2103 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2104 let mut map = Vi::new(ed);
2105 map.ed.insert_str_after_cursor("delete").unwrap();
2106
2107 simulate_keys!(map, [
2108 Esc,
2109 Char('0'),
2110 Char('2'),
2111 Char('d'),
2112 Char('2'),
2113 Char('l'),
2114 ]);
2115 assert_eq!(map.ed.cursor(), 0);
2116 assert_eq!(String::from(map), "te");
2117 }
2118
2119 #[test]
2120 fn delete_with_count_and_repeat() {
2122 let mut context = Context::new();
2123 let out = Vec::new();
2124 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2125 let mut map = Vi::new(ed);
2126 map.ed.insert_str_after_cursor("delete delete").unwrap();
2127
2128 simulate_keys!(map, [
2129 Esc,
2130 Char('0'),
2131 Char('2'),
2132 Char('d'),
2133 Char('2'),
2134 Char('l'),
2135 Char('.'),
2136 ]);
2137 assert_eq!(map.ed.cursor(), 0);
2138 assert_eq!(String::from(map), "elete");
2139 }
2140
2141 #[test]
2142 fn move_to_end_of_word_simple() {
2143 let mut context = Context::new();
2144 let out = Vec::new();
2145 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2146
2147 ed.insert_str_after_cursor("here are").unwrap();
2148 let start_pos = ed.cursor();
2149 ed.insert_str_after_cursor(" som").unwrap();
2150 let end_pos = ed.cursor();
2151 ed.insert_str_after_cursor("e words").unwrap();
2152 ed.move_cursor_to(start_pos).unwrap();
2153
2154 super::move_to_end_of_word(&mut ed, 1).unwrap();
2155 assert_eq!(ed.cursor(), end_pos);
2156 }
2157
2158 #[test]
2159 fn move_to_end_of_word_comma() {
2160 let mut context = Context::new();
2161 let out = Vec::new();
2162 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2163
2164 ed.insert_str_after_cursor("here ar").unwrap();
2165 let start_pos = ed.cursor();
2166 ed.insert_after_cursor('e').unwrap();
2167 let end_pos1 = ed.cursor();
2168 ed.insert_str_after_cursor(", som").unwrap();
2169 let end_pos2 = ed.cursor();
2170 ed.insert_str_after_cursor("e words").unwrap();
2171 ed.move_cursor_to(start_pos).unwrap();
2172
2173 super::move_to_end_of_word(&mut ed, 1).unwrap();
2174 assert_eq!(ed.cursor(), end_pos1);
2175 super::move_to_end_of_word(&mut ed, 1).unwrap();
2176 assert_eq!(ed.cursor(), end_pos2);
2177 }
2178
2179 #[test]
2180 fn move_to_end_of_word_nonkeywords() {
2181 let mut context = Context::new();
2182 let out = Vec::new();
2183 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2184
2185 ed.insert_str_after_cursor("here ar").unwrap();
2186 let start_pos = ed.cursor();
2187 ed.insert_str_after_cursor("e,,,").unwrap();
2188 let end_pos1 = ed.cursor();
2189 ed.insert_str_after_cursor(",som").unwrap();
2190 let end_pos2 = ed.cursor();
2191 ed.insert_str_after_cursor("e words").unwrap();
2192 ed.move_cursor_to(start_pos).unwrap();
2193
2194 super::move_to_end_of_word(&mut ed, 1).unwrap();
2195 assert_eq!(ed.cursor(), end_pos1);
2196 super::move_to_end_of_word(&mut ed, 1).unwrap();
2197 assert_eq!(ed.cursor(), end_pos2);
2198 }
2199
2200 #[test]
2201 fn move_to_end_of_word_whitespace() {
2202 let mut context = Context::new();
2203 let out = Vec::new();
2204 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2205
2206 assert_eq!(ed.cursor(), 0);
2207 ed.insert_str_after_cursor("here are").unwrap();
2208 let start_pos = ed.cursor();
2209 assert_eq!(ed.cursor(), 8);
2210 ed.insert_str_after_cursor(" som").unwrap();
2211 assert_eq!(ed.cursor(), 17);
2212 ed.insert_str_after_cursor("e words").unwrap();
2213 assert_eq!(ed.cursor(), 24);
2214 ed.move_cursor_to(start_pos).unwrap();
2215 assert_eq!(ed.cursor(), 8);
2216
2217 super::move_to_end_of_word(&mut ed, 1).unwrap();
2218 assert_eq!(ed.cursor(), 17);
2219 }
2220
2221 #[test]
2222 fn move_to_end_of_word_whitespace_nonkeywords() {
2223 let mut context = Context::new();
2224 let out = Vec::new();
2225 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2226
2227 ed.insert_str_after_cursor("here ar").unwrap();
2228 let start_pos = ed.cursor();
2229 ed.insert_str_after_cursor("e ,,,").unwrap();
2230 let end_pos1 = ed.cursor();
2231 ed.insert_str_after_cursor(", som").unwrap();
2232 let end_pos2 = ed.cursor();
2233 ed.insert_str_after_cursor("e words").unwrap();
2234 ed.move_cursor_to(start_pos).unwrap();
2235
2236 super::move_to_end_of_word(&mut ed, 1).unwrap();
2237 assert_eq!(ed.cursor(), end_pos1);
2238 super::move_to_end_of_word(&mut ed, 1).unwrap();
2239 assert_eq!(ed.cursor(), end_pos2);
2240 }
2241
2242 #[test]
2243 fn move_to_end_of_word_ws_simple() {
2244 let mut context = Context::new();
2245 let out = Vec::new();
2246 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2247
2248 ed.insert_str_after_cursor("here are").unwrap();
2249 let start_pos = ed.cursor();
2250 ed.insert_str_after_cursor(" som").unwrap();
2251 let end_pos = ed.cursor();
2252 ed.insert_str_after_cursor("e words").unwrap();
2253 ed.move_cursor_to(start_pos).unwrap();
2254
2255 super::move_to_end_of_word_ws(&mut ed, 1).unwrap();
2256 assert_eq!(ed.cursor(), end_pos);
2257 }
2258
2259 #[test]
2260 fn move_to_end_of_word_ws_comma() {
2261 let mut context = Context::new();
2262 let out = Vec::new();
2263 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2264
2265 ed.insert_str_after_cursor("here ar").unwrap();
2266 let start_pos = ed.cursor();
2267 ed.insert_after_cursor('e').unwrap();
2268 let end_pos1 = ed.cursor();
2269 ed.insert_str_after_cursor(", som").unwrap();
2270 let end_pos2 = ed.cursor();
2271 ed.insert_str_after_cursor("e words").unwrap();
2272 ed.move_cursor_to(start_pos).unwrap();
2273
2274 super::move_to_end_of_word_ws(&mut ed, 1).unwrap();
2275 assert_eq!(ed.cursor(), end_pos1);
2276 super::move_to_end_of_word_ws(&mut ed, 1).unwrap();
2277 assert_eq!(ed.cursor(), end_pos2);
2278 }
2279
2280 #[test]
2281 fn move_to_end_of_word_ws_nonkeywords() {
2282 let mut context = Context::new();
2283 let out = Vec::new();
2284 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2285
2286 ed.insert_str_after_cursor("here ar").unwrap();
2287 let start_pos = ed.cursor();
2288 ed.insert_str_after_cursor("e,,,,som").unwrap();
2289 let end_pos = ed.cursor();
2290 ed.insert_str_after_cursor("e words").unwrap();
2291 ed.move_cursor_to(start_pos).unwrap();
2292 super::move_to_end_of_word_ws(&mut ed, 1).unwrap();
2293 assert_eq!(ed.cursor(), end_pos);
2294 }
2295
2296 #[test]
2297 fn move_to_end_of_word_ws_whitespace() {
2298 let mut context = Context::new();
2299 let out = Vec::new();
2300 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2301
2302 ed.insert_str_after_cursor("here are").unwrap();
2303 let start_pos = ed.cursor();
2304 ed.insert_str_after_cursor(" som").unwrap();
2305 let end_pos = ed.cursor();
2306 ed.insert_str_after_cursor("e words").unwrap();
2307 ed.move_cursor_to(start_pos).unwrap();
2308
2309 super::move_to_end_of_word_ws(&mut ed, 1).unwrap();
2310 assert_eq!(ed.cursor(), end_pos);
2311 }
2312
2313 #[test]
2314 fn move_to_end_of_word_ws_whitespace_nonkeywords() {
2315 let mut context = Context::new();
2316 let out = Vec::new();
2317 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2318
2319 ed.insert_str_after_cursor("here ar").unwrap();
2320 let start_pos = ed.cursor();
2321 ed.insert_str_after_cursor("e ,,,").unwrap();
2322 let end_pos1 = ed.cursor();
2323 ed.insert_str_after_cursor(", som").unwrap();
2324 let end_pos2 = ed.cursor();
2325 ed.insert_str_after_cursor("e words").unwrap();
2326 ed.move_cursor_to(start_pos).unwrap();
2327
2328 super::move_to_end_of_word_ws(&mut ed, 1).unwrap();
2329 assert_eq!(ed.cursor(), end_pos1);
2330 super::move_to_end_of_word_ws(&mut ed, 1).unwrap();
2331 assert_eq!(ed.cursor(), end_pos2);
2332 }
2333
2334 #[test]
2335 fn move_word_simple() {
2336 let mut context = Context::new();
2337 let out = Vec::new();
2338 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2339
2340 ed.insert_str_after_cursor("here ").unwrap();
2341 let pos1 = ed.cursor();
2342 ed.insert_str_after_cursor("are ").unwrap();
2343 let pos2 = ed.cursor();
2344 ed.insert_str_after_cursor("some words").unwrap();
2345 ed.move_cursor_to_start_of_line().unwrap();
2346
2347 super::move_word(&mut ed, 1).unwrap();
2348 assert_eq!(ed.cursor(), pos1);
2349 super::move_word(&mut ed, 1).unwrap();
2350 assert_eq!(ed.cursor(), pos2);
2351
2352 ed.move_cursor_to_start_of_line().unwrap();
2353 super::move_word_ws(&mut ed, 1).unwrap();
2354 assert_eq!(ed.cursor(), pos1);
2355 super::move_word_ws(&mut ed, 1).unwrap();
2356 assert_eq!(ed.cursor(), pos2);
2357 }
2358
2359 #[test]
2360 fn move_word_whitespace() {
2361 let mut context = Context::new();
2362 let out = Vec::new();
2363 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2364
2365 ed.insert_str_after_cursor(" ").unwrap();
2366 let pos1 = ed.cursor();
2367 ed.insert_str_after_cursor("word").unwrap();
2368 let pos2 = ed.cursor();
2369 ed.move_cursor_to_start_of_line().unwrap();
2370
2371 super::move_word(&mut ed, 1).unwrap();
2372 assert_eq!(ed.cursor(), pos1);
2373 super::move_word(&mut ed, 1).unwrap();
2374 assert_eq!(ed.cursor(), pos2);
2375
2376 ed.move_cursor_to_start_of_line().unwrap();
2377 super::move_word_ws(&mut ed, 1).unwrap();
2378 assert_eq!(ed.cursor(), pos1);
2379 super::move_word_ws(&mut ed, 1).unwrap();
2380 assert_eq!(ed.cursor(), pos2);
2381 }
2382
2383 #[test]
2384 fn move_word_nonkeywords() {
2385 let mut context = Context::new();
2386 let out = Vec::new();
2387 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2388
2389 ed.insert_str_after_cursor("...").unwrap();
2390 let pos1 = ed.cursor();
2391 ed.insert_str_after_cursor("word").unwrap();
2392 let pos2 = ed.cursor();
2393 ed.move_cursor_to_start_of_line().unwrap();
2394
2395 super::move_word(&mut ed, 1).unwrap();
2396 assert_eq!(ed.cursor(), pos1);
2397 super::move_word(&mut ed, 1).unwrap();
2398 assert_eq!(ed.cursor(), pos2);
2399
2400 ed.move_cursor_to_start_of_line().unwrap();
2401 super::move_word_ws(&mut ed, 1).unwrap();
2402 assert_eq!(ed.cursor(), pos2);
2403 }
2404
2405 #[test]
2406 fn move_word_whitespace_nonkeywords() {
2407 let mut context = Context::new();
2408 let out = Vec::new();
2409 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2410
2411 ed.insert_str_after_cursor("... ").unwrap();
2412 let pos1 = ed.cursor();
2413 ed.insert_str_after_cursor("...").unwrap();
2414 let pos2 = ed.cursor();
2415 ed.insert_str_after_cursor("word").unwrap();
2416 let pos3 = ed.cursor();
2417 ed.move_cursor_to_start_of_line().unwrap();
2418
2419 super::move_word(&mut ed, 1).unwrap();
2420 assert_eq!(ed.cursor(), pos1);
2421 super::move_word(&mut ed, 1).unwrap();
2422 assert_eq!(ed.cursor(), pos2);
2423
2424 ed.move_cursor_to_start_of_line().unwrap();
2425 super::move_word_ws(&mut ed, 1).unwrap();
2426 assert_eq!(ed.cursor(), pos1);
2427 super::move_word_ws(&mut ed, 1).unwrap();
2428 assert_eq!(ed.cursor(), pos3);
2429 }
2430
2431 #[test]
2432 fn move_word_and_back() {
2433 let mut context = Context::new();
2434 let out = Vec::new();
2435 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2436
2437 ed.insert_str_after_cursor("here ").unwrap();
2438 let pos1 = ed.cursor();
2439 ed.insert_str_after_cursor("are ").unwrap();
2440 let pos2 = ed.cursor();
2441 ed.insert_str_after_cursor("some").unwrap();
2442 let pos3 = ed.cursor();
2443 ed.insert_str_after_cursor("... ").unwrap();
2444 let pos4 = ed.cursor();
2445 ed.insert_str_after_cursor("words").unwrap();
2446 let pos5 = ed.cursor();
2447
2448 ed.move_cursor_to_start_of_line().unwrap();
2451 super::move_word(&mut ed, 1).unwrap();
2452 assert_eq!(ed.cursor(), pos1);
2453 super::move_word(&mut ed, 1).unwrap();
2454 assert_eq!(ed.cursor(), pos2);
2455 super::move_word(&mut ed, 1).unwrap();
2456 assert_eq!(ed.cursor(), pos3);
2457 super::move_word(&mut ed, 1).unwrap();
2458 assert_eq!(ed.cursor(), pos4);
2459 super::move_word(&mut ed, 1).unwrap();
2460 assert_eq!(ed.cursor(), pos5);
2461
2462 super::move_word_back(&mut ed, 1).unwrap();
2463 assert_eq!(ed.cursor(), pos4);
2464 super::move_word_back(&mut ed, 1).unwrap();
2465 assert_eq!(ed.cursor(), pos3);
2466 super::move_word_back(&mut ed, 1).unwrap();
2467 assert_eq!(ed.cursor(), pos2);
2468 super::move_word_back(&mut ed, 1).unwrap();
2469 assert_eq!(ed.cursor(), pos1);
2470 super::move_word_back(&mut ed, 1).unwrap();
2471 assert_eq!(ed.cursor(), 0);
2472
2473 ed.move_cursor_to_start_of_line().unwrap();
2474 super::move_word_ws(&mut ed, 1).unwrap();
2475 assert_eq!(ed.cursor(), pos1);
2476 super::move_word_ws(&mut ed, 1).unwrap();
2477 assert_eq!(ed.cursor(), pos2);
2478 super::move_word_ws(&mut ed, 1).unwrap();
2479 assert_eq!(ed.cursor(), pos4);
2480 super::move_word_ws(&mut ed, 1).unwrap();
2481 assert_eq!(ed.cursor(), pos5);
2482
2483 super::move_word_ws_back(&mut ed, 1).unwrap();
2484 assert_eq!(ed.cursor(), pos4);
2485 super::move_word_ws_back(&mut ed, 1).unwrap();
2486 assert_eq!(ed.cursor(), pos2);
2487 super::move_word_ws_back(&mut ed, 1).unwrap();
2488 assert_eq!(ed.cursor(), pos1);
2489 super::move_word_ws_back(&mut ed, 1).unwrap();
2490 assert_eq!(ed.cursor(), 0);
2491 }
2492
2493 #[test]
2494 fn move_word_and_back_with_count() {
2495 let mut context = Context::new();
2496 let out = Vec::new();
2497 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2498
2499 ed.insert_str_after_cursor("here ").unwrap();
2500 ed.insert_str_after_cursor("are ").unwrap();
2501 let pos1 = ed.cursor();
2502 ed.insert_str_after_cursor("some").unwrap();
2503 let pos2 = ed.cursor();
2504 ed.insert_str_after_cursor("... ").unwrap();
2505 ed.insert_str_after_cursor("words").unwrap();
2506 let pos3 = ed.cursor();
2507
2508 ed.move_cursor_to_start_of_line().unwrap();
2510 super::move_word(&mut ed, 3).unwrap();
2511 assert_eq!(ed.cursor(), pos2);
2512 super::move_word(&mut ed, 2).unwrap();
2513 assert_eq!(ed.cursor(), pos3);
2514
2515 super::move_word_back(&mut ed, 2).unwrap();
2516 assert_eq!(ed.cursor(), pos2);
2517 super::move_word_back(&mut ed, 3).unwrap();
2518 assert_eq!(ed.cursor(), 0);
2519
2520 ed.move_cursor_to_start_of_line().unwrap();
2521 super::move_word_ws(&mut ed, 2).unwrap();
2522 assert_eq!(ed.cursor(), pos1);
2523 super::move_word_ws(&mut ed, 2).unwrap();
2524 assert_eq!(ed.cursor(), pos3);
2525
2526 super::move_word_ws_back(&mut ed, 2).unwrap();
2527 assert_eq!(ed.cursor(), pos1);
2528 super::move_word_ws_back(&mut ed, 2).unwrap();
2529 assert_eq!(ed.cursor(), 0);
2530 }
2531
2532 #[test]
2533 fn move_to_end_of_word_ws_whitespace_count() {
2534 let mut context = Context::new();
2535 let out = Vec::new();
2536 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2537
2538 ed.insert_str_after_cursor("here are").unwrap();
2539 let start_pos = ed.cursor();
2540 ed.insert_str_after_cursor(" som").unwrap();
2541 ed.insert_str_after_cursor("e word").unwrap();
2542 let end_pos = ed.cursor();
2543 ed.insert_str_after_cursor("s and some").unwrap();
2544
2545 ed.move_cursor_to(start_pos).unwrap();
2546 super::move_to_end_of_word_ws(&mut ed, 2).unwrap();
2547 assert_eq!(ed.cursor(), end_pos);
2548 }
2549
2550 #[test]
2551 fn delete_word() {
2553 let mut context = Context::new();
2554 let out = Vec::new();
2555 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2556 let mut map = Vi::new(ed);
2557 map.ed.insert_str_after_cursor("delete some words").unwrap();
2558
2559 simulate_keys!(map, [
2560 Esc,
2561 Char('0'),
2562 Char('d'),
2563 Char('w'),
2564 ]);
2565 assert_eq!(map.ed.cursor(), 0);
2566 assert_eq!(String::from(map), "some words");
2567 }
2568
2569 #[test]
2570 fn change_line() {
2572 let mut context = Context::new();
2573 let out = Vec::new();
2574 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2575 let mut map = Vi::new(ed);
2576 map.ed.insert_str_after_cursor("change").unwrap();
2577
2578 simulate_keys!(map, [
2579 Esc,
2580 Char('c'),
2581 Char('c'),
2582 Char('d'),
2583 Char('o'),
2584 Char('n'),
2585 Char('e'),
2586 ]);
2587 assert_eq!(map.ed.cursor(), 4);
2588 assert_eq!(String::from(map), "done");
2589 }
2590
2591 #[test]
2592 fn change_char_left() {
2594 let mut context = Context::new();
2595 let out = Vec::new();
2596 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2597 let mut map = Vi::new(ed);
2598 map.ed.insert_str_after_cursor("change").unwrap();
2599
2600 simulate_keys!(map, [
2601 Esc,
2602 Char('c'),
2603 Char('h'),
2604 Char('e'),
2605 Esc,
2606 ]);
2607 assert_eq!(map.ed.cursor(), 4);
2608 assert_eq!(String::from(map), "chanee");
2609 }
2610
2611 #[test]
2612 fn change_chars_left() {
2614 let mut context = Context::new();
2615 let out = Vec::new();
2616 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2617 let mut map = Vi::new(ed);
2618 map.ed.insert_str_after_cursor("change").unwrap();
2619
2620 simulate_keys!(map, [
2621 Esc,
2622 Char('3'),
2623 Char('c'),
2624 Char('h'),
2625 Char('e'),
2626 ]);
2627 assert_eq!(map.ed.cursor(), 3);
2628 assert_eq!(String::from(map), "chee");
2629 }
2630
2631 #[test]
2632 fn change_char_right() {
2634 let mut context = Context::new();
2635 let out = Vec::new();
2636 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2637 let mut map = Vi::new(ed);
2638 map.ed.insert_str_after_cursor("change").unwrap();
2639
2640 simulate_keys!(map, [
2641 Esc,
2642 Char('0'),
2643 Char('c'),
2644 Char('l'),
2645 Char('s'),
2646 ]);
2647 assert_eq!(map.ed.cursor(), 1);
2648 assert_eq!(String::from(map), "shange");
2649 }
2650
2651 #[test]
2652 fn change_chars_right() {
2654 let mut context = Context::new();
2655 let out = Vec::new();
2656 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2657 let mut map = Vi::new(ed);
2658 map.ed.insert_str_after_cursor("change").unwrap();
2659
2660 simulate_keys!(map, [
2661 Esc,
2662 Char('0'),
2663 Char('3'),
2664 Char('c'),
2665 Char('l'),
2666 Char('s'),
2667 Char('t'),
2668 Char('r'),
2669 Char('a'),
2670 Esc,
2671 ]);
2672 assert_eq!(map.ed.cursor(), 3);
2673 assert_eq!(String::from(map), "strange");
2674 }
2675
2676 #[test]
2677 fn change_and_repeat() {
2679 let mut context = Context::new();
2680 let out = Vec::new();
2681 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2682 let mut map = Vi::new(ed);
2683 map.ed.insert_str_after_cursor("change").unwrap();
2684
2685 simulate_keys!(map, [
2686 Esc,
2687 Char('0'),
2688 Char('c'),
2689 Char('l'),
2690 Char('s'),
2691 Esc,
2692 Char('l'),
2693 Char('.'),
2694 Char('l'),
2695 Char('.'),
2696 ]);
2697 assert_eq!(map.ed.cursor(), 2);
2698 assert_eq!(String::from(map), "sssnge");
2699 }
2700
2701 #[test]
2702 fn change_until_end() {
2704 let mut context = Context::new();
2705 let out = Vec::new();
2706 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2707 let mut map = Vi::new(ed);
2708 map.ed.insert_str_after_cursor("change").unwrap();
2709
2710 simulate_keys!(map, [
2711 Esc,
2712 Char('0'),
2713 Char('c'),
2714 Char('$'),
2715 Char('o'),
2716 Char('k'),
2717 Esc,
2718 ]);
2719 assert_eq!(map.ed.cursor(), 1);
2720 assert_eq!(String::from(map), "ok");
2721 }
2722
2723 #[test]
2724 fn change_until_end_shift_c() {
2726 let mut context = Context::new();
2727 let out = Vec::new();
2728 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2729 let mut map = Vi::new(ed);
2730 map.ed.insert_str_after_cursor("change").unwrap();
2731
2732 simulate_keys!(map, [
2733 Esc,
2734 Char('0'),
2735 Char('C'),
2736 Char('o'),
2737 Char('k'),
2738 ]);
2739 assert_eq!(map.ed.cursor(), 2);
2740 assert_eq!(String::from(map), "ok");
2741 }
2742
2743 #[test]
2744 fn change_until_end_from_middle_shift_c() {
2746 let mut context = Context::new();
2747 let out = Vec::new();
2748 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2749 let mut map = Vi::new(ed);
2750 map.ed.insert_str_after_cursor("change").unwrap();
2751
2752 simulate_keys!(map, [
2753 Esc,
2754 Char('0'),
2755 Char('2'),
2756 Char('l'),
2757 Char('C'),
2758 Char(' '),
2759 Char('o'),
2760 Char('k'),
2761 Esc,
2762 ]);
2763 assert_eq!(String::from(map), "ch ok");
2764 }
2765
2766 #[test]
2767 fn change_until_start() {
2769 let mut context = Context::new();
2770 let out = Vec::new();
2771 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2772 let mut map = Vi::new(ed);
2773 map.ed.insert_str_after_cursor("change").unwrap();
2774
2775 simulate_keys!(map, [
2776 Esc,
2777 Char('$'),
2778 Char('c'),
2779 Char('0'),
2780 Char('s'),
2781 Char('t'),
2782 Char('r'),
2783 Char('a'),
2784 Char('n'),
2785 Char('g'),
2786 ]);
2787 assert_eq!(map.ed.cursor(), 6);
2788 assert_eq!(String::from(map), "strange");
2789 }
2790
2791 #[test]
2792 fn change_with_count() {
2794 let mut context = Context::new();
2795 let out = Vec::new();
2796 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2797 let mut map = Vi::new(ed);
2798 map.ed.insert_str_after_cursor("change").unwrap();
2799
2800 simulate_keys!(map, [
2801 Esc,
2802 Char('0'),
2803 Char('2'),
2804 Char('c'),
2805 Char('2'),
2806 Char('l'),
2807 Char('s'),
2808 Char('t'),
2809 Char('r'),
2810 Char('a'),
2811 Char('n'),
2812 Esc,
2813 ]);
2814 assert_eq!(map.ed.cursor(), 4);
2815 assert_eq!(String::from(map), "strange");
2816 }
2817
2818 #[test]
2819 fn change_with_count_and_repeat() {
2821 let mut context = Context::new();
2822 let out = Vec::new();
2823 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2824 let mut map = Vi::new(ed);
2825 map.ed.insert_str_after_cursor("change change").unwrap();
2826
2827 simulate_keys!(map, [
2828 Esc,
2829 Char('0'),
2830 Char('2'),
2831 Char('c'),
2832 Char('2'),
2833 Char('l'),
2834 Char('o'),
2835 Esc,
2836 Char('.'),
2837 ]);
2838 assert_eq!(map.ed.cursor(), 0);
2839 assert_eq!(String::from(map), "ochange");
2840 }
2841
2842 #[test]
2843 fn change_word() {
2845 let mut context = Context::new();
2846 let out = Vec::new();
2847 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2848 let mut map = Vi::new(ed);
2849 map.ed.insert_str_after_cursor("change some words").unwrap();
2850
2851 simulate_keys!(map, [
2852 Esc,
2853 Char('0'),
2854 Char('c'),
2855 Char('w'),
2856 Char('t'),
2857 Char('w'),
2858 Char('e'),
2859 Char('a'),
2860 Char('k'),
2861 Char(' '),
2862 ]);
2863 assert_eq!(String::from(map), "tweak some words");
2864 }
2865
2866 #[test]
2867 fn test_count_reset_around_insert_and_delete() {
2869 let mut context = Context::new();
2870 let out = Vec::new();
2871 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2872 let mut map = Vi::new(ed);
2873 map.ed.insert_str_after_cursor("these are some words").unwrap();
2874
2875 simulate_keys!(map, [
2876 Esc,
2877 Char('0'),
2878 Char('d'),
2879 Char('3'),
2880 Char('w'),
2881 Char('i'),
2882 Char('w'),
2883 Char('o'),
2884 Char('r'),
2885 Char('d'),
2886 Char('s'),
2887 Char(' '),
2888 Esc,
2889 Char('l'),
2890 Char('.'),
2891 ]);
2892 assert_eq!(String::from(map), "words words words");
2893 }
2894
2895 #[test]
2896 fn test_t_not_found() {
2898 let mut context = Context::new();
2899 let out = Vec::new();
2900 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2901 let mut map = Vi::new(ed);
2902 map.ed.insert_str_after_cursor("abc defg").unwrap();
2903
2904 simulate_keys!(map, [
2905 Esc,
2906 Char('0'),
2907 Char('t'),
2908 Char('z'),
2909 ]);
2910 assert_eq!(map.ed.cursor(), 0);
2911 }
2912
2913 #[test]
2914 fn test_t_movement() {
2916 let mut context = Context::new();
2917 let out = Vec::new();
2918 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2919 let mut map = Vi::new(ed);
2920 map.ed.insert_str_after_cursor("abc defg").unwrap();
2921
2922 simulate_keys!(map, [
2923 Esc,
2924 Char('0'),
2925 Char('t'),
2926 Char('d'),
2927 ]);
2928 assert_eq!(map.ed.cursor(), 3);
2929 }
2930
2931 #[test]
2932 fn test_t_movement_with_count() {
2934 let mut context = Context::new();
2935 let out = Vec::new();
2936 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2937 let mut map = Vi::new(ed);
2938 map.ed.insert_str_after_cursor("abc defg d").unwrap();
2939
2940 simulate_keys!(map, [
2941 Esc,
2942 Char('0'),
2943 Char('2'),
2944 Char('t'),
2945 Char('d'),
2946 ]);
2947 assert_eq!(map.ed.cursor(), 8);
2948 }
2949
2950 #[test]
2951 fn test_t_movement_then_normal() {
2953 let mut context = Context::new();
2954 let out = Vec::new();
2955 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2956 let mut map = Vi::new(ed);
2957 map.ed.insert_str_after_cursor("abc defg").unwrap();
2958
2959 simulate_keys!(map, [
2960 Esc,
2961 Char('0'),
2962 Char('t'),
2963 Char('d'),
2964 Char('l'),
2965 ]);
2966 assert_eq!(map.ed.cursor(), 4);
2967 }
2968
2969 #[test]
2970 fn test_t_movement_with_delete() {
2972 let mut context = Context::new();
2973 let out = Vec::new();
2974 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2975 let mut map = Vi::new(ed);
2976 map.ed.insert_str_after_cursor("abc defg").unwrap();
2977
2978 simulate_keys!(map, [
2979 Esc,
2980 Char('0'),
2981 Char('d'),
2982 Char('t'),
2983 Char('d'),
2984 ]);
2985 assert_eq!(map.ed.cursor(), 0);
2986 assert_eq!(String::from(map), "defg");
2987 }
2988
2989 #[test]
2990 fn test_t_movement_with_change() {
2992 let mut context = Context::new();
2993 let out = Vec::new();
2994 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
2995 let mut map = Vi::new(ed);
2996 map.ed.insert_str_after_cursor("abc defg").unwrap();
2997
2998 simulate_keys!(map, [
2999 Esc,
3000 Char('0'),
3001 Char('c'),
3002 Char('t'),
3003 Char('d'),
3004 Char('z'),
3005 Char(' '),
3006 Esc,
3007 ]);
3008 assert_eq!(map.ed.cursor(), 1);
3009 assert_eq!(String::from(map), "z defg");
3010 }
3011
3012 #[test]
3013 fn test_f_movement() {
3015 let mut context = Context::new();
3016 let out = Vec::new();
3017 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3018 let mut map = Vi::new(ed);
3019 map.ed.insert_str_after_cursor("abc defg").unwrap();
3020
3021 simulate_keys!(map, [
3022 Esc,
3023 Char('0'),
3024 Char('f'),
3025 Char('d'),
3026 ]);
3027 assert_eq!(map.ed.cursor(), 4);
3028 }
3029
3030 #[test]
3031 fn test_cap_t_movement() {
3033 let mut context = Context::new();
3034 let out = Vec::new();
3035 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3036 let mut map = Vi::new(ed);
3037 map.ed.insert_str_after_cursor("abc defg").unwrap();
3038
3039 simulate_keys!(map, [
3040 Esc,
3041 Char('$'),
3042 Char('T'),
3043 Char('d'),
3044 ]);
3045 assert_eq!(map.ed.cursor(), 5);
3046 }
3047
3048 #[test]
3049 fn test_cap_f_movement() {
3051 let mut context = Context::new();
3052 let out = Vec::new();
3053 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3054 let mut map = Vi::new(ed);
3055 map.ed.insert_str_after_cursor("abc defg").unwrap();
3056
3057 simulate_keys!(map, [
3058 Esc,
3059 Char('$'),
3060 Char('F'),
3061 Char('d'),
3062 ]);
3063 assert_eq!(map.ed.cursor(), 4);
3064 }
3065
3066 #[test]
3067 fn test_semi_movement() {
3069 let mut context = Context::new();
3070 let out = Vec::new();
3071 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3072 let mut map = Vi::new(ed);
3073 map.ed.insert_str_after_cursor("abc abc").unwrap();
3074
3075 simulate_keys!(map, [
3076 Esc,
3077 Char('0'),
3078 Char('f'),
3079 Char('c'),
3080 Char(';'),
3081 ]);
3082 assert_eq!(map.ed.cursor(), 6);
3083 }
3084
3085 #[test]
3086 fn test_comma_movement() {
3088 let mut context = Context::new();
3089 let out = Vec::new();
3090 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3091 let mut map = Vi::new(ed);
3092 map.ed.insert_str_after_cursor("abc abc").unwrap();
3093
3094 simulate_keys!(map, [
3095 Esc,
3096 Char('0'),
3097 Char('f'),
3098 Char('c'),
3099 Char('$'),
3100 Char(','),
3101 ]);
3102 assert_eq!(map.ed.cursor(), 2);
3103 }
3104
3105 #[test]
3106 fn test_semi_delete() {
3108 let mut context = Context::new();
3109 let out = Vec::new();
3110 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3111 let mut map = Vi::new(ed);
3112 map.ed.insert_str_after_cursor("abc abc").unwrap();
3113
3114 simulate_keys!(map, [
3115 Esc,
3116 Char('0'),
3117 Char('f'),
3118 Char('c'),
3119 Char('d'),
3120 Char(';'),
3121 ]);
3122 assert_eq!(map.ed.cursor(), 1);
3123 assert_eq!(String::from(map), "ab");
3124 }
3125
3126 #[test]
3127 fn test_semi_delete_repeat() {
3129 let mut context = Context::new();
3130 let out = Vec::new();
3131 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3132 let mut map = Vi::new(ed);
3133 map.ed.insert_str_after_cursor("abc abc abc abc").unwrap();
3134
3135 simulate_keys!(map, [
3136 Esc,
3137 Char('0'),
3138 Char('f'),
3139 Char('c'),
3140 Char('d'),
3141 Char(';'),
3142 Char('.'),
3143 Char('.'),
3144 ]);
3145 assert_eq!(String::from(map), "ab");
3146 }
3147
3148 #[test]
3149 fn test_find_char() {
3151 let mut context = Context::new();
3152 let out = Vec::new();
3153 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3154 ed.insert_str_after_cursor("abcdefg").unwrap();
3155 assert_eq!(super::find_char(ed.current_buffer(), 0, 'd', 1), Some(3));
3156 }
3157
3158 #[test]
3159 fn test_find_char_with_start() {
3161 let mut context = Context::new();
3162 let out = Vec::new();
3163 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3164 ed.insert_str_after_cursor("abcabc").unwrap();
3165 assert_eq!(super::find_char(ed.current_buffer(), 1, 'a', 1), Some(3));
3166 }
3167
3168 #[test]
3169 fn test_find_char_with_count() {
3171 let mut context = Context::new();
3172 let out = Vec::new();
3173 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3174 ed.insert_str_after_cursor("abcabc").unwrap();
3175 assert_eq!(super::find_char(ed.current_buffer(), 0, 'a', 2), Some(3));
3176 }
3177
3178 #[test]
3179 fn test_find_char_not_found() {
3181 let mut context = Context::new();
3182 let out = Vec::new();
3183 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3184 ed.insert_str_after_cursor("abcdefg").unwrap();
3185 assert_eq!(super::find_char(ed.current_buffer(), 0, 'z', 1), None);
3186 }
3187
3188 #[test]
3189 fn test_find_char_rev() {
3191 let mut context = Context::new();
3192 let out = Vec::new();
3193 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3194 ed.insert_str_after_cursor("abcdefg").unwrap();
3195 assert_eq!(super::find_char_rev(ed.current_buffer(), 6, 'd', 1), Some(3));
3196 }
3197
3198 #[test]
3199 fn test_find_char_rev_with_start() {
3201 let mut context = Context::new();
3202 let out = Vec::new();
3203 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3204 ed.insert_str_after_cursor("abcabc").unwrap();
3205 assert_eq!(super::find_char_rev(ed.current_buffer(), 5, 'c', 1), Some(2));
3206 }
3207
3208 #[test]
3209 fn test_find_char_rev_with_count() {
3211 let mut context = Context::new();
3212 let out = Vec::new();
3213 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3214 ed.insert_str_after_cursor("abcabc").unwrap();
3215 assert_eq!(super::find_char_rev(ed.current_buffer(), 6, 'c', 2), Some(2));
3216 }
3217
3218 #[test]
3219 fn test_find_char_rev_not_found() {
3221 let mut context = Context::new();
3222 let out = Vec::new();
3223 let mut ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3224 ed.insert_str_after_cursor("abcdefg").unwrap();
3225 assert_eq!(super::find_char_rev(ed.current_buffer(), 6, 'z', 1), None);
3226 }
3227
3228 #[test]
3229 fn test_undo_with_counts() {
3231 let mut context = Context::new();
3232 let out = Vec::new();
3233 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3234 let mut map = Vi::new(ed);
3235 map.ed.insert_str_after_cursor("abcdefg").unwrap();
3236
3237 simulate_keys!(map, [
3238 Esc,
3239 Char('x'),
3240 Char('x'),
3241 Char('x'),
3242 Char('3'),
3243 Char('u'),
3244 ]);
3245 assert_eq!(String::from(map), "abcdefg");
3246 }
3247
3248 #[test]
3249 fn test_redo_with_counts() {
3251 let mut context = Context::new();
3252 let out = Vec::new();
3253 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3254 let mut map = Vi::new(ed);
3255 map.ed.insert_str_after_cursor("abcdefg").unwrap();
3256
3257 simulate_keys!(map, [
3258 Esc,
3259 Char('x'),
3260 Char('x'),
3261 Char('x'),
3262 Char('u'),
3263 Char('u'),
3264 Char('u'),
3265 Char('2'),
3266 Ctrl('r'),
3267 ]);
3268 assert_eq!(String::from(map), "abcde");
3269 }
3270
3271 #[test]
3272 fn change_word_ge_ws() {
3274 let mut context = Context::new();
3275 let out = Vec::new();
3276 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3277 let mut map = Vi::new(ed);
3278 map.ed.insert_str_after_cursor("change some words").unwrap();
3279
3280 simulate_keys!(map, [
3281 Esc,
3282 Char('c'),
3283 Char('g'),
3284 Char('E'),
3285 Char('e'),
3286 Char('t'),
3287 Char('h'),
3288 Char('i'),
3289 Char('n'),
3290 Char('g'),
3291 Esc,
3292 ]);
3293 assert_eq!(String::from(map), "change something");
3294 }
3295
3296 #[test]
3297 fn undo_insert() {
3299 let mut context = Context::new();
3300 let out = Vec::new();
3301 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3302 let mut map = Vi::new(ed);
3303
3304 simulate_keys!(map, [
3305 Char('i'),
3306 Char('n'),
3307 Char('s'),
3308 Char('e'),
3309 Char('r'),
3310 Char('t'),
3311 Esc,
3312 Char('u'),
3313 ]);
3314 assert_eq!(String::from(map), "");
3315 }
3316
3317 #[test]
3318 fn undo_insert2() {
3320 let mut context = Context::new();
3321 let out = Vec::new();
3322 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3323 let mut map = Vi::new(ed);
3324
3325 simulate_keys!(map, [
3326 Esc,
3327 Char('i'),
3328 Char('i'),
3329 Char('n'),
3330 Char('s'),
3331 Char('e'),
3332 Char('r'),
3333 Char('t'),
3334 Esc,
3335 Char('u'),
3336 ]);
3337 assert_eq!(String::from(map), "");
3338 }
3339
3340 #[test]
3341 fn undo_insert_with_history() {
3343 let mut context = Context::new();
3344 context.history.push(Buffer::from("")).unwrap();
3345 let out = Vec::new();
3346 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3347 let mut map = Vi::new(ed);
3348
3349 simulate_keys!(map, [
3350 Esc,
3351 Char('i'),
3352 Char('i'),
3353 Char('n'),
3354 Char('s'),
3355 Char('e'),
3356 Char('r'),
3357 Char('t'),
3358 Up,
3359 Char('h'),
3360 Char('i'),
3361 Char('s'),
3362 Char('t'),
3363 Char('o'),
3364 Char('r'),
3365 Char('y'),
3366 Down,
3367 Char(' '),
3368 Char('t'),
3369 Char('e'),
3370 Char('x'),
3371 Char('t'),
3372 Esc,
3373 Char('u'),
3374 ]);
3375 assert_eq!(String::from(map), "insert");
3376 }
3377
3378 #[test]
3379 fn undo_insert_with_history2() {
3381 let mut context = Context::new();
3382 context.history.push(Buffer::from("")).unwrap();
3383 let out = Vec::new();
3384 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3385 let mut map = Vi::new(ed);
3386
3387 simulate_keys!(map, [
3388 Esc,
3389 Char('i'),
3390 Char('i'),
3391 Char('n'),
3392 Char('s'),
3393 Char('e'),
3394 Char('r'),
3395 Char('t'),
3396 Up,
3397 Esc,
3398 Down,
3399 Char('u'),
3400 ]);
3401 assert_eq!(String::from(map), "");
3402 }
3403
3404 #[test]
3405 fn undo_insert_with_movement_reset() {
3407 let mut context = Context::new();
3408 let out = Vec::new();
3409 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3410 let mut map = Vi::new(ed);
3411
3412 simulate_keys!(map, [
3413 Esc,
3414 Char('i'),
3415 Char('i'),
3416 Char('n'),
3417 Char('s'),
3418 Char('e'),
3419 Char('r'),
3420 Char('t'),
3421 Left,
3423 Right,
3424 Char(' '),
3425 Char('t'),
3426 Char('e'),
3427 Char('x'),
3428 Char('t'),
3429 Esc,
3430 Char('u'),
3431 ]);
3432 assert_eq!(String::from(map), "insert");
3433 }
3434
3435 #[test]
3436 fn undo_3x() {
3438 let mut context = Context::new();
3439 let out = Vec::new();
3440 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3441 let mut map = Vi::new(ed);
3442 map.ed.insert_str_after_cursor("rm some words").unwrap();
3443
3444 simulate_keys!(map, [
3445 Esc,
3446 Char('0'),
3447 Char('3'),
3448 Char('x'),
3449 Char('u'),
3450 ]);
3451 assert_eq!(String::from(map), "rm some words");
3452 }
3453
3454 #[test]
3455 fn undo_insert_with_count() {
3457 let mut context = Context::new();
3458 let out = Vec::new();
3459 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3460 let mut map = Vi::new(ed);
3461
3462 simulate_keys!(map, [
3463 Char('i'),
3464 Char('n'),
3465 Char('s'),
3466 Char('e'),
3467 Char('r'),
3468 Char('t'),
3469 Esc,
3470 Char('3'),
3471 Char('i'),
3472 Char('i'),
3473 Char('n'),
3474 Char('s'),
3475 Char('e'),
3476 Char('r'),
3477 Char('t'),
3478 Esc,
3479 Char('u'),
3480 ]);
3481 assert_eq!(String::from(map), "insert");
3482 }
3483
3484 #[test]
3485 fn undo_insert_with_repeat() {
3487 let mut context = Context::new();
3488 let out = Vec::new();
3489 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3490 let mut map = Vi::new(ed);
3491
3492 simulate_keys!(map, [
3493 Char('i'),
3494 Char('n'),
3495 Char('s'),
3496 Char('e'),
3497 Char('r'),
3498 Char('t'),
3499 Esc,
3500 Char('3'),
3501 Char('.'),
3502 Esc,
3503 Char('u'),
3504 ]);
3505 assert_eq!(String::from(map), "insert");
3506 }
3507
3508 #[test]
3509 fn undo_s_with_count() {
3511 let mut context = Context::new();
3512 let out = Vec::new();
3513 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3514 let mut map = Vi::new(ed);
3515 map.ed.insert_str_after_cursor("replace some words").unwrap();
3516
3517 simulate_keys!(map, [
3518 Esc,
3519 Char('0'),
3520 Char('8'),
3521 Char('s'),
3522 Char('o'),
3523 Char('k'),
3524 Esc,
3525 Char('u'),
3526 ]);
3527 assert_eq!(String::from(map), "replace some words");
3528 }
3529
3530 #[test]
3531 fn undo_multiple_groups() {
3533 let mut context = Context::new();
3534 let out = Vec::new();
3535 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3536 let mut map = Vi::new(ed);
3537 map.ed.insert_str_after_cursor("replace some words").unwrap();
3538
3539 simulate_keys!(map, [
3540 Esc,
3541 Char('A'),
3542 Char(' '),
3543 Char('h'),
3544 Char('e'),
3545 Char('r'),
3546 Char('e'),
3547 Esc,
3548 Char('0'),
3549 Char('8'),
3550 Char('s'),
3551 Char('o'),
3552 Char('k'),
3553 Esc,
3554 Char('2'),
3555 Char('u'),
3556 ]);
3557 assert_eq!(String::from(map), "replace some words");
3558 }
3559
3560 #[test]
3561 fn undo_r_command_with_count() {
3563 let mut context = Context::new();
3564 let out = Vec::new();
3565 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3566 let mut map = Vi::new(ed);
3567 map.ed.insert_str_after_cursor("replace some words").unwrap();
3568
3569 simulate_keys!(map, [
3570 Esc,
3571 Char('0'),
3572 Char('8'),
3573 Char('r'),
3574 Char(' '),
3575 Char('u'),
3576 ]);
3577 assert_eq!(String::from(map), "replace some words");
3578 }
3579
3580 #[test]
3581 fn tilde_basic() {
3583 let mut context = Context::new();
3584 let out = Vec::new();
3585 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3586 let mut map = Vi::new(ed);
3587 map.ed.insert_str_after_cursor("tilde").unwrap();
3588
3589 simulate_keys!(map, [
3590 Esc,
3591 Char('~'),
3592 ]);
3593 assert_eq!(String::from(map), "tildE");
3594 }
3595
3596 #[test]
3597 fn tilde_basic2() {
3599 let mut context = Context::new();
3600 let out = Vec::new();
3601 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3602 let mut map = Vi::new(ed);
3603 map.ed.insert_str_after_cursor("tilde").unwrap();
3604
3605 simulate_keys!(map, [
3606 Esc,
3607 Char('~'),
3608 Char('~'),
3609 ]);
3610 assert_eq!(String::from(map), "tilde");
3611 }
3612
3613 #[test]
3614 fn tilde_move() {
3616 let mut context = Context::new();
3617 let out = Vec::new();
3618 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3619 let mut map = Vi::new(ed);
3620 map.ed.insert_str_after_cursor("tilde").unwrap();
3621
3622 simulate_keys!(map, [
3623 Esc,
3624 Char('0'),
3625 Char('~'),
3626 Char('~'),
3627 ]);
3628 assert_eq!(String::from(map), "TIlde");
3629 }
3630
3631
3632 #[test]
3633 fn tilde_repeat() {
3635 let mut context = Context::new();
3636 let out = Vec::new();
3637 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3638 let mut map = Vi::new(ed);
3639 map.ed.insert_str_after_cursor("tilde").unwrap();
3640
3641 simulate_keys!(map, [
3642 Esc,
3643 Char('~'),
3644 Char('.'),
3645 ]);
3646 assert_eq!(String::from(map), "tilde");
3647 }
3648
3649 #[test]
3650 fn tilde_count() {
3652 let mut context = Context::new();
3653 let out = Vec::new();
3654 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3655 let mut map = Vi::new(ed);
3656 map.ed.insert_str_after_cursor("tilde").unwrap();
3657
3658 simulate_keys!(map, [
3659 Esc,
3660 Char('0'),
3661 Char('1'),
3662 Char('0'),
3663 Char('~'),
3664 ]);
3665 assert_eq!(String::from(map), "TILDE");
3666 }
3667
3668 #[test]
3669 fn tilde_count_short() {
3671 let mut context = Context::new();
3672 let out = Vec::new();
3673 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3674 let mut map = Vi::new(ed);
3675 map.ed.insert_str_after_cursor("TILDE").unwrap();
3676
3677 simulate_keys!(map, [
3678 Esc,
3679 Char('0'),
3680 Char('2'),
3681 Char('~'),
3682 ]);
3683 assert_eq!(String::from(map), "tiLDE");
3684 }
3685
3686 #[test]
3687 fn tilde_nocase() {
3689 let mut context = Context::new();
3690 let out = Vec::new();
3691 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3692 let mut map = Vi::new(ed);
3693 map.ed.insert_str_after_cursor("ti_lde").unwrap();
3694
3695 simulate_keys!(map, [
3696 Esc,
3697 Char('0'),
3698 Char('6'),
3699 Char('~'),
3700 ]);
3701 assert_eq!(String::from(map), "TI_LDE");
3702 }
3703
3704 #[test]
3705 fn ctrl_h() {
3707 let mut context = Context::new();
3708 let out = Vec::new();
3709 let ed = Editor::new(out, "prompt".to_owned(), &mut context).unwrap();
3710 let mut map = Vi::new(ed);
3711 map.ed.insert_str_after_cursor("not empty").unwrap();
3712
3713 let res = map.handle_key(Ctrl('h'), &mut |_| {});
3714 assert_eq!(res.is_ok(), true);
3715 assert_eq!(map.ed.current_buffer().to_string(), "not empt".to_string());
3716 }
3717}