|
1 /* |
|
2 * Changes of plain text |
|
3 * |
|
4 * @author Johannes Hölzl, TU Munich |
|
5 * @author Fabian Immler, TU Munich |
|
6 */ |
|
7 |
|
8 package isabelle.proofdocument |
|
9 |
|
10 |
|
11 sealed abstract class Edit |
|
12 { |
|
13 val start: Int |
|
14 def before(offset: Int): Int |
|
15 def after(offset: Int): Int |
|
16 } |
|
17 |
|
18 |
|
19 case class Insert(start: Int, text: String) extends Edit |
|
20 { |
|
21 def before(offset: Int): Int = |
|
22 if (start > offset) offset |
|
23 else (offset - text.length) max start |
|
24 |
|
25 def after(offset: Int): Int = |
|
26 if (start <= offset) offset + text.length else offset |
|
27 } |
|
28 |
|
29 |
|
30 case class Remove(start: Int, text: String) extends Edit |
|
31 { |
|
32 def before(offset: Int): Int = |
|
33 if (start <= offset) offset + text.length else offset |
|
34 |
|
35 def after(offset: Int): Int = |
|
36 if (start > offset) offset |
|
37 else (offset - text.length) max start |
|
38 } |
|
39 // TODO: merge multiple inserts? |
|
40 |
|
41 |
|
42 class Change( |
|
43 val id: String, |
|
44 val parent: Option[Change], |
|
45 val edits: List[Edit]) |
|
46 { |
|
47 def ancestors(done: Change => Boolean): List[Change] = |
|
48 if (done(this)) Nil |
|
49 else this :: parent.map(_.ancestors(done)).getOrElse(Nil) |
|
50 def ancestors: List[Change] = ancestors(_ => false) |
|
51 |
|
52 override def toString = |
|
53 "Change(" + id + " <- " + parent.map(_.id) + ", " + edits + ")" |
|
54 } |