1use std::borrow::Cow;
2use std::collections::HashMap;
3
4use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
5use lazy_static::lazy_static;
6
7use crate::keymap::KeyMap;
8use crate::modes::{
9 mode::{Mode, ModeTransition},
10 normal::Normal,
11};
12use crate::selection::Direction;
13use crate::Buffers;
14
15#[derive(Debug, PartialEq, Eq, Clone, Copy)]
16pub struct JumpTo {
17 pub extend: bool,
18}
19
20fn default_maps() -> KeyMap<Direction> {
21 KeyMap {
22 maps: keys!(
23 (key KeyCode::Left => Direction::Left),
24 ('h' => Direction::Left),
25 (key KeyCode::Down => Direction::Down),
26 ('j' => Direction::Down),
27 (key KeyCode::Up => Direction::Up),
28 ('k' => Direction::Up),
29 (key KeyCode::Right => Direction::Right),
30 ('l' => Direction::Right)
31 ),
32 }
33}
34
35lazy_static! {
36 static ref DEFAULT_MAPS: KeyMap<Direction> = default_maps();
37}
38
39impl Mode for JumpTo {
40 fn name(&self) -> Cow<'static, str> {
41 if self.extend {
42 "EXTEND".into()
43 } else {
44 "JUMP".into()
45 }
46 }
47
48 fn transition(
49 &self,
50 evt: &Event,
51 buffers: &mut Buffers,
52 bytes_per_line: usize,
53 ) -> Option<ModeTransition> {
54 let buffer = buffers.current_mut();
55 if let Some(direction) = DEFAULT_MAPS.event_to_action(evt) {
56 let max_bytes = buffer.data.len();
57 Some(ModeTransition::new_mode_and_dirty(
58 Normal::new(),
59 if self.extend {
60 buffer.map_selections(|region| {
61 vec![region.extend_to_boundary(direction, bytes_per_line, max_bytes)]
62 })
63 } else {
64 buffer.map_selections(|region| {
65 vec![region.jump_to_boundary(direction, bytes_per_line, max_bytes)]
66 })
67 },
68 ))
69 } else if let Event::Key(_) = evt {
70 Some(ModeTransition::new_mode(Normal::new()))
71 } else {
72 None
73 }
74 }
75
76 fn as_any(&self) -> &dyn std::any::Any {
77 self
78 }
79}