1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use frappe::Signal;
#[derive(Clone)]
pub enum CursorCmd {
Enter,
Backspace, Delete,
Indent(Signal<String>), Dedent(Signal<String>),
Left(bool), Right(bool),
Vertical(bool, Signal<isize>),
LineHome(bool, bool),
LineEnd(bool),
WordLeft(bool), WordRight(bool),
SelectWord,
SpawnMultiCursor, KillMultiCursor, SkipMultiCursor
}
use {Buffer, Cursor, cursor};
impl CursorCmd {
pub fn run(&self, cur: &Cursor, buf: &Buffer) -> Option<cursor::Event> {
use cursor::{Event, CursorEvent, BufferEvent};
match self {
&CursorCmd::Enter => Some(Event::Buf(BufferEvent::Insert('\n'.to_string()))),
&CursorCmd::Backspace => Some(Event::Buf(BufferEvent::Backspace)),
&CursorCmd::Delete => Some(Event::Buf(BufferEvent::Delete)),
&CursorCmd::Indent(ref indent) => Some(Event::Buf(BufferEvent::Indent(indent.clone()))),
&CursorCmd::Dedent(ref indent) => Some(Event::Buf(BufferEvent::Dedent(indent.clone()))),
&CursorCmd::Left(select) => Some(Event::Cur(CursorEvent::Jump(
cur.positions()
.map(|(char_idx, sel_start)| (
match sel_start {
Some(sel_start) if !select => cursor::select((sel_start, char_idx)).start,
_ => cursor::jump::left(char_idx)
},
if select { sel_start.or(Some(char_idx)) } else { None }
))
.collect()
))),
&CursorCmd::Right(select) => Some(Event::Cur(CursorEvent::Jump(
cur.positions()
.map(|(char_idx, sel_start)| (
match sel_start {
Some(sel_start) if !select => cursor::select((sel_start, char_idx)).end,
_ => cursor::jump::right(buf.text(), char_idx)
},
if select { sel_start.or(Some(char_idx)) } else { None }
))
.collect()
))),
&CursorCmd::Vertical(select, ref num_lines) => Some(Event::Cur(CursorEvent::Jump(
cur.positions()
.map(|(char_idx, sel_start)| (
cursor::jump::vertical(buf.text(), char_idx, num_lines.sample()),
if select { sel_start.or(Some(char_idx)) } else { None }
))
.collect()
))),
&CursorCmd::LineHome(select, _smart) => Some(Event::Cur(CursorEvent::Jump(
cur.positions()
.map(|(char_idx, sel_start)| (
cursor::jump::line_start(buf.text(), char_idx),
if select { sel_start.or(Some(char_idx)) } else { None }
))
.collect()
))),
&CursorCmd::LineEnd(select) => Some(Event::Cur(CursorEvent::Jump(
cur.positions()
.map(|(char_idx, sel_start)| (
cursor::jump::line_end(buf.text(), char_idx),
if select { sel_start.or(Some(char_idx)) } else { None }
))
.collect()
))),
&CursorCmd::WordLeft(select) => Some(Event::Cur(CursorEvent::Jump(
cur.positions()
.map(|(char_idx, sel_start)| (
cursor::jump::word_left(buf.text(), char_idx),
if select { sel_start.or(Some(char_idx)) } else { None }
))
.collect()
))),
&CursorCmd::WordRight(select) => Some(Event::Cur(CursorEvent::Jump(
cur.positions()
.map(|(char_idx, sel_start)| (
cursor::jump::word_right(buf.text(), char_idx),
if select { sel_start.or(Some(char_idx)) } else { None }
))
.collect()
))),
&CursorCmd::SelectWord => Some(Event::Cur(CursorEvent::Jump(cursor::jump::select_words(cur, buf.text())))),
&CursorCmd::SpawnMultiCursor => cursor::jump::spawn(cur, buf.text()).map(CursorEvent::Jump).map(Event::Cur),
&CursorCmd::KillMultiCursor => cursor::jump::die(cur) .map(CursorEvent::Jump).map(Event::Cur),
&CursorCmd::SkipMultiCursor => cursor::jump::skip(cur, buf.text()) .map(CursorEvent::Jump).map(Event::Cur)
}
}
}