1use std::fmt::{self, Write as FmtWrite};
2use std::io::{self, Write};
3use std::iter::FromIterator;
4use unicode_width::UnicodeWidthStr;
5
6#[derive(Debug, Clone)]
8pub enum Action {
9 Insert { start: usize, text: Vec<char> },
10 Remove { start: usize, text: Vec<char> },
11 StartGroup,
12 EndGroup,
13}
14
15impl Action {
16 pub fn do_on(&self, buf: &mut Buffer) {
17 match *self {
18 Action::Insert { start, ref text } => buf.insert_raw(start, &text[..]),
19 Action::Remove { start, ref text } => {
20 buf.remove_raw(start, start + text.len());
21 }
22 Action::StartGroup | Action::EndGroup => {}
23 }
24 }
25
26 pub fn undo(&self, buf: &mut Buffer) {
27 match *self {
28 Action::Insert { start, ref text } => {
29 buf.remove_raw(start, start + text.len());
30 }
31 Action::Remove { start, ref text } => buf.insert_raw(start, &text[..]),
32 Action::StartGroup | Action::EndGroup => {}
33 }
34 }
35}
36
37#[derive(Debug, Clone)]
41pub struct Buffer {
42 data: Vec<char>,
43 actions: Vec<Action>,
44 undone_actions: Vec<Action>,
45}
46
47impl PartialEq for Buffer {
48 fn eq(&self, other: &Self) -> bool {
49 self.data == other.data
50 }
51}
52impl Eq for Buffer {}
53
54impl From<Buffer> for String {
55 fn from(buf: Buffer) -> Self {
56 String::from_iter(buf.data)
57 }
58}
59
60impl From<String> for Buffer {
61 fn from(s: String) -> Self {
62 Buffer::from_iter(s.chars())
63 }
64}
65
66impl<'a> From<&'a str> for Buffer {
67 fn from(s: &'a str) -> Self {
68 Buffer::from_iter(s.chars())
69 }
70}
71
72impl fmt::Display for Buffer {
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 for &c in &self.data {
75 f.write_char(c)?;
76 }
77 Ok(())
78 }
79}
80
81impl FromIterator<char> for Buffer {
82 fn from_iter<T: IntoIterator<Item = char>>(t: T) -> Self {
83 Buffer {
84 data: t.into_iter().collect(),
85 actions: Vec::new(),
86 undone_actions: Vec::new(),
87 }
88 }
89}
90
91impl Default for Buffer {
92 fn default() -> Self {
93 Self::new()
94 }
95}
96
97impl Buffer {
98 pub fn new() -> Self {
99 Buffer {
100 data: Vec::new(),
101 actions: Vec::new(),
102 undone_actions: Vec::new(),
103 }
104 }
105
106 pub fn clear_actions(&mut self) {
107 self.actions.clear();
108 self.undone_actions.clear();
109 }
110
111 pub fn start_undo_group(&mut self) {
112 self.actions.push(Action::StartGroup);
113 }
114
115 pub fn end_undo_group(&mut self) {
116 self.actions.push(Action::EndGroup);
117 }
118
119 pub fn undo(&mut self) -> bool {
120 use Action::*;
121
122 let did = !self.actions.is_empty();
123 let mut group_nest = 0;
124 let mut group_count = 0;
125 while let Some(act) = self.actions.pop() {
126 act.undo(self);
127 self.undone_actions.push(act.clone());
128 match act {
129 EndGroup => {
130 group_nest += 1;
131 group_count = 0;
132 }
133 StartGroup => group_nest -= 1,
134 _ => group_count += 1,
136 }
137
138 if group_nest == 0 && group_count > 0 {
140 break;
141 }
142 }
143 did
144 }
145
146 pub fn redo(&mut self) -> bool {
147 use Action::*;
148
149 let did = !self.undone_actions.is_empty();
150 let mut group_nest = 0;
151 let mut group_count = 0;
152 while let Some(act) = self.undone_actions.pop() {
153 act.do_on(self);
154 self.actions.push(act.clone());
155 match act {
156 StartGroup => {
157 group_nest += 1;
158 group_count = 0;
159 }
160 EndGroup => group_nest -= 1,
161 _ => group_count += 1,
163 }
164
165 if group_nest == 0 && group_count > 0 {
167 break;
168 }
169 }
170 did
171 }
172
173 pub fn revert(&mut self) -> bool {
174 if self.actions.is_empty() {
175 return false;
176 }
177
178 while self.undo() {}
179 true
180 }
181
182 fn push_action(&mut self, act: Action) {
183 self.actions.push(act);
184 self.undone_actions.clear();
185 }
186
187 pub fn last_arg(&self) -> Option<&[char]> {
188 self.data
189 .split(|&c| c == ' ')
190 .filter(|s| !s.is_empty())
191 .last()
192 }
193
194 pub fn num_chars(&self) -> usize {
195 self.data.len()
196 }
197
198 pub fn num_bytes(&self) -> usize {
199 let s: String = self.clone().into();
200 s.len()
201 }
202
203 pub fn char_before(&self, cursor: usize) -> Option<char> {
204 if cursor == 0 {
205 None
206 } else {
207 self.data.get(cursor - 1).cloned()
208 }
209 }
210
211 pub fn char_after(&self, cursor: usize) -> Option<char> {
212 self.data.get(cursor).cloned()
213 }
214
215 pub fn remove(&mut self, start: usize, end: usize) -> usize {
217 let s = self.remove_raw(start, end);
218 let num_removed = s.len();
219 self.push_action(Action::Remove { start, text: s });
220 num_removed
221 }
222
223 pub fn insert(&mut self, start: usize, text: &[char]) {
224 let act = Action::Insert {
225 start,
226 text: text.into(),
227 };
228 act.do_on(self);
229 self.push_action(act);
230 }
231
232 pub fn insert_from_buffer(&mut self, other: &Buffer) {
234 let start = self.data.len();
235 self.insert(start, &other.data[start..])
236 }
237
238 pub fn copy_buffer(&mut self, other: &Buffer) {
239 let data_len = self.data.len();
240 self.remove(0, data_len);
241 self.insert(0, &other.data[0..])
242 }
243
244 pub fn range(&self, start: usize, end: usize) -> String {
245 self.data[start..end].iter().cloned().collect()
246 }
247
248 pub fn range_chars(&self, start: usize, end: usize) -> Vec<char> {
249 self.data[start..end].to_owned()
250 }
251
252 pub fn width(&self) -> Vec<usize> {
253 self.range_width(0, self.num_chars())
254 }
255
256 pub fn range_width(&self, start: usize, end: usize) -> Vec<usize> {
257 self.range(start, end)
258 .split('\n')
259 .map(|s| s.width())
260 .collect()
261 }
262
263 pub fn lines(&self) -> Vec<String> {
264 self.data
265 .split(|&c| c == '\n')
266 .map(|s| s.iter().cloned().collect())
267 .collect()
268 }
269
270 pub fn chars(&self) -> ::std::slice::Iter<char> {
271 self.data.iter()
272 }
273
274 pub fn truncate(&mut self, num: usize) {
275 let end = self.data.len();
276 self.remove(num, end);
277 }
278
279 pub fn print<W>(&self, out: &mut W) -> io::Result<()>
280 where
281 W: Write,
282 {
283 let string: String = self.data.iter().cloned().collect();
284 out.write_all(string.as_bytes())
285 }
286
287 pub fn as_bytes(&self) -> Vec<u8> {
288 self.to_string().into_bytes()
291 }
292
293 pub fn print_rest<W>(&self, out: &mut W, after: usize) -> io::Result<usize>
297 where
298 W: Write,
299 {
300 let string: String = self.data.iter().skip(after).cloned().collect();
301 out.write_all(string.as_bytes())?;
302
303 Ok(string.len())
304 }
305
306 fn remove_raw(&mut self, start: usize, end: usize) -> Vec<char> {
307 self.data.drain(start..end).collect()
308 }
309
310 fn insert_raw(&mut self, start: usize, text: &[char]) {
311 for (i, &c) in text.iter().enumerate() {
312 self.data.insert(start + i, c)
313 }
314 }
315
316 pub fn starts_with(&self, other: &Buffer) -> bool {
319 let other_len = other.data.len();
320 let self_len = self.data.len();
321 if !other.data.is_empty() && self_len != other_len {
322 let match_let = self
323 .data
324 .iter()
325 .zip(&other.data)
326 .take_while(|&(s, o)| *s == *o)
327 .count();
328 match_let == other_len
329 } else {
330 false
331 }
332 }
333
334 pub fn contains(&self, pattern: &Buffer) -> bool {
337 let search_term: &[char] = &pattern.data;
338 if search_term.is_empty() {
339 return false;
340 }
341 self.data
342 .windows(search_term.len())
343 .any(|window| window == search_term)
344 }
345
346 pub fn is_empty(&self) -> bool {
348 self.data.is_empty()
349 }
350}
351
352#[cfg(test)]
353mod tests {
354 use super::*;
355
356 #[test]
357 fn test_insert() {
358 let mut buf = Buffer::new();
359 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
360 assert_eq!(String::from(buf), "abcdefg");
361 }
362
363 #[test]
364 fn test_truncate_empty() {
365 let mut buf = Buffer::new();
366 buf.truncate(0);
367 assert_eq!(String::from(buf), "");
368 }
369
370 #[test]
371 fn test_truncate_all() {
372 let mut buf = Buffer::new();
373 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
374 buf.truncate(0);
375 assert_eq!(String::from(buf), "");
376 }
377
378 #[test]
379 fn test_truncate_end() {
380 let mut buf = Buffer::new();
381 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
382 let end = buf.num_chars();
383 buf.truncate(end);
384 assert_eq!(String::from(buf), "abcdefg");
385 }
386
387 #[test]
388 fn test_truncate_part() {
389 let mut buf = Buffer::new();
390 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
391 buf.truncate(3);
392 assert_eq!(String::from(buf), "abc");
393 }
394
395 #[test]
396 fn test_truncate_empty_undo() {
397 let mut buf = Buffer::new();
398 buf.truncate(0);
399 buf.undo();
400 assert_eq!(String::from(buf), "");
401 }
402
403 #[test]
404 fn test_truncate_all_then_undo() {
405 let mut buf = Buffer::new();
406 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
407 buf.truncate(0);
408 buf.undo();
409 assert_eq!(String::from(buf), "abcdefg");
410 }
411
412 #[test]
413 fn test_truncate_end_then_undo() {
414 let mut buf = Buffer::new();
415 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
416 let end = buf.num_chars();
417 buf.truncate(end);
418 buf.undo();
419 assert_eq!(String::from(buf), "abcdefg");
420 }
421
422 #[test]
423 fn test_truncate_part_then_undo() {
424 let mut buf = Buffer::new();
425 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
426 buf.truncate(3);
427 buf.undo();
428 assert_eq!(String::from(buf), "abcdefg");
429 }
430
431 #[test]
432 fn test_undo_group() {
433 let mut buf = Buffer::new();
434 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
435 buf.start_undo_group();
436 buf.remove(0, 1);
437 buf.remove(0, 1);
438 buf.remove(0, 1);
439 buf.end_undo_group();
440 assert_eq!(buf.undo(), true);
441 assert_eq!(String::from(buf), "abcdefg");
442 }
443
444 #[test]
445 fn test_redo_group() {
446 let mut buf = Buffer::new();
447 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
448 buf.start_undo_group();
449 buf.remove(0, 1);
450 buf.remove(0, 1);
451 buf.remove(0, 1);
452 buf.end_undo_group();
453 assert_eq!(buf.undo(), true);
454 assert_eq!(buf.redo(), true);
455 assert_eq!(String::from(buf), "defg");
456 }
457
458 #[test]
459 fn test_nested_undo_group() {
460 let mut buf = Buffer::new();
461 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
462 buf.start_undo_group();
463 buf.remove(0, 1);
464 buf.start_undo_group();
465 buf.remove(0, 1);
466 buf.end_undo_group();
467 buf.remove(0, 1);
468 buf.end_undo_group();
469 assert_eq!(buf.undo(), true);
470 assert_eq!(String::from(buf), "abcdefg");
471 }
472
473 #[test]
474 fn test_nested_redo_group() {
475 let mut buf = Buffer::new();
476 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
477 buf.start_undo_group();
478 buf.remove(0, 1);
479 buf.start_undo_group();
480 buf.remove(0, 1);
481 buf.end_undo_group();
482 buf.remove(0, 1);
483 buf.end_undo_group();
484 assert_eq!(buf.undo(), true);
485 assert_eq!(buf.redo(), true);
486 assert_eq!(String::from(buf), "defg");
487 }
488
489 #[test]
490 fn test_starts_with() {
491 let mut buf = Buffer::new();
492 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
493 let mut buf2 = Buffer::new();
494 buf2.insert(0, &['a', 'b', 'c']);
495 assert_eq!(buf.starts_with(&buf2), true);
496 }
497
498 #[test]
499 fn test_does_not_start_with() {
500 let mut buf = Buffer::new();
501 buf.insert(0, &['a', 'b', 'c']);
502 let mut buf2 = Buffer::new();
503 buf2.insert(0, &['a', 'b', 'c']);
504 assert_eq!(buf.starts_with(&buf2), false);
505 }
506
507 #[test]
508 fn test_is_not_match2() {
509 let mut buf = Buffer::new();
510 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
511 let mut buf2 = Buffer::new();
512 buf2.insert(0, &['x', 'y', 'z']);
513 assert_eq!(buf.starts_with(&buf2), false);
514 }
515
516 #[test]
517 fn test_contains() {
518 let mut buf = Buffer::new();
519 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
520 let mut buf2 = Buffer::new();
521 buf2.insert(0, &['a', 'b', 'c']);
522 assert_eq!(buf.contains(&buf2), true);
523 let mut buf2 = Buffer::new();
524 buf2.insert(0, &['c', 'd', 'e']);
525 assert_eq!(buf.contains(&buf2), true);
526 let mut buf2 = Buffer::new();
527 buf2.insert(0, &['e', 'f', 'g']);
528 assert_eq!(buf.contains(&buf2), true);
529 }
530
531 #[test]
532 fn test_does_not_contain() {
533 let mut buf = Buffer::new();
534 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
535 let mut buf2 = Buffer::new();
536 buf2.insert(0, &['x', 'b', 'c']);
537 assert_eq!(buf.contains(&buf2), false);
538 let mut buf2 = Buffer::new();
539 buf2.insert(0, &['a', 'b', 'd']);
540 assert_eq!(buf.contains(&buf2), false);
541 }
542
543 #[test]
544 fn test_print_rest() {
545 let mut buf = Buffer::new();
546 buf.insert(0, &['a', 'b', 'c', 'd', 'e', 'f', 'g']);
547 let mut buf2 = Buffer::new();
548 buf2.insert(0, &['a', 'b', 'c']);
549 let mut out: Vec<u8> = vec![];
550 buf.print_rest(&mut out, buf2.data.len()).unwrap();
551 assert_eq!(out.len(), 4);
552 }
553}