6 * @author Makarius |
6 * @author Makarius |
7 */ |
7 */ |
8 |
8 |
9 package isabelle.proofdocument |
9 package isabelle.proofdocument |
10 |
10 |
|
11 |
11 import scala.actors.Actor, Actor._ |
12 import scala.actors.Actor, Actor._ |
12 |
13 |
13 import java.util.regex.Pattern |
14 import java.util.regex.Pattern |
14 |
15 |
15 import isabelle.prover.{Prover, Command, Command_State} |
16 |
16 |
17 object Proof_Document |
17 |
|
18 object ProofDocument |
|
19 { |
18 { |
20 // Be careful when changing this regex. Not only must it handle the |
19 // Be careful when changing this regex. Not only must it handle the |
21 // spurious end of a token but also: |
20 // spurious end of a token but also: |
22 // Bug ID: 5050507 Pattern.matches throws StackOverflow Error |
21 // Bug ID: 5050507 Pattern.matches throws StackOverflow Error |
23 // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507 |
22 // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507 |
32 "\"([^\\\\\"]?(\\\\(.|\\z))?)*+(\"|\\z)|" + |
31 "\"([^\\\\\"]?(\\\\(.|\\z))?)*+(\"|\\z)|" + |
33 "`([^\\\\`]?(\\\\(.|\\z))?)*+(`|\\z)|" + |
32 "`([^\\\\`]?(\\\\(.|\\z))?)*+(`|\\z)|" + |
34 "[()\\[\\]{}:;]", Pattern.MULTILINE) |
33 "[()\\[\\]{}:;]", Pattern.MULTILINE) |
35 |
34 |
36 val empty = |
35 val empty = |
37 new ProofDocument(isabelle.jedit.Isabelle.system.id(), |
36 new Proof_Document(isabelle.jedit.Isabelle.system.id(), |
38 Linear_Set(), Map(), Linear_Set(), Map(), _ => false) |
37 Linear_Set(), Map(), Linear_Set(), Map(), _ => false) |
39 |
38 |
40 type StructureChange = List[(Option[Command], Option[Command])] |
39 type StructureChange = List[(Option[Command], Option[Command])] |
41 |
40 |
42 } |
41 } |
43 |
42 |
44 class ProofDocument( |
43 class Proof_Document( |
45 val id: String, |
44 val id: String, |
46 val tokens: Linear_Set[Token], |
45 val tokens: Linear_Set[Token], |
47 val token_start: Map[Token, Int], |
46 val token_start: Map[Token, Int], |
48 val commands: Linear_Set[Command], |
47 val commands: Linear_Set[Command], |
49 var states: Map[Command, Command_State], // FIXME immutable |
48 var states: Map[Command, Command_State], // FIXME immutable |
50 is_command_keyword: String => Boolean) |
49 is_command_keyword: String => Boolean) |
51 { |
50 { |
52 import ProofDocument.StructureChange |
51 import Proof_Document.StructureChange |
53 |
52 |
54 def set_command_keyword(f: String => Boolean): ProofDocument = |
53 def set_command_keyword(f: String => Boolean): Proof_Document = |
55 new ProofDocument(id, tokens, token_start, commands, states, f) |
54 new Proof_Document(id, tokens, token_start, commands, states, f) |
56 |
55 |
57 def content = Token.string_from_tokens(Nil ++ tokens, token_start) |
56 def content = Token.string_from_tokens(Nil ++ tokens, token_start) |
58 |
57 |
59 |
58 |
60 |
59 |
61 /** token view **/ |
60 /** token view **/ |
62 |
61 |
63 def text_changed(change: Change): (ProofDocument, StructureChange) = |
62 def text_changed(change: Change): (Proof_Document, StructureChange) = |
64 { |
63 { |
65 def edit_doc(doc_chgs: (ProofDocument, StructureChange), edit: Edit) = { |
64 def edit_doc(doc_chgs: (Proof_Document, StructureChange), edit: Edit) = { |
66 val (doc, chgs) = doc_chgs |
65 val (doc, chgs) = doc_chgs |
67 val (new_doc, chg) = doc.text_edit(edit, change.id) |
66 val (new_doc, chg) = doc.text_edit(edit, change.id) |
68 (new_doc, chgs ++ chg) |
67 (new_doc, chgs ++ chg) |
69 } |
68 } |
70 ((this, Nil: StructureChange) /: change.edits)(edit_doc) |
69 ((this, Nil: StructureChange) /: change.edits)(edit_doc) |
71 } |
70 } |
72 |
71 |
73 def text_edit(e: Edit, id: String): (ProofDocument, StructureChange) = |
72 def text_edit(e: Edit, id: String): (Proof_Document, StructureChange) = |
74 { |
73 { |
75 case class TextChange(start: Int, added: String, removed: String) |
74 case class TextChange(start: Int, added: String, removed: String) |
76 val change = e match { |
75 val change = e match { |
77 case Insert(s, a) => TextChange(s, a, "") |
76 case Insert(s, a) => TextChange(s, a, "") |
78 case Remove(s, r) => TextChange(s, "", r) |
77 case Remove(s, r) => TextChange(s, "", r) |
156 before_change: Option[Token], |
155 before_change: Option[Token], |
157 inserted_tokens: List[Token], |
156 inserted_tokens: List[Token], |
158 after_change: Option[Token], |
157 after_change: Option[Token], |
159 new_tokens: List[Token], |
158 new_tokens: List[Token], |
160 new_token_start: Map[Token, Int]): |
159 new_token_start: Map[Token, Int]): |
161 (ProofDocument, StructureChange) = |
160 (Proof_Document, StructureChange) = |
162 { |
161 { |
163 val new_tokenset = Linear_Set[Token]() ++ new_tokens |
162 val new_tokenset = Linear_Set[Token]() ++ new_tokens |
164 val cmd_before_change = before_change match { |
163 val cmd_before_change = before_change match { |
165 case None => None |
164 case None => None |
166 case Some(bc) => |
165 case Some(bc) => |