src/Tools/jEdit/src/proofdocument/proof_document.scala
changeset 34760 dc7f5e0d9d27
parent 34759 bfea7839d9e1
child 34778 8eccd35e975e
equal deleted inserted replaced
34759:bfea7839d9e1 34760:dc7f5e0d9d27
     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)
   114     var new_tokens: List[Token] = Nil
   113     var new_tokens: List[Token] = Nil
   115     var old_suffix: List[Token] = Nil
   114     var old_suffix: List[Token] = Nil
   116 
   115 
   117     val match_start = invalid_tokens.firstOption.map(start(_)).getOrElse(0)
   116     val match_start = invalid_tokens.firstOption.map(start(_)).getOrElse(0)
   118     val matcher =
   117     val matcher =
   119       ProofDocument.token_pattern.matcher(Token.string_from_tokens(invalid_tokens, start))
   118       Proof_Document.token_pattern.matcher(Token.string_from_tokens(invalid_tokens, start))
   120 
   119 
   121     while (matcher.find() && invalid_tokens != Nil) {
   120     while (matcher.find() && invalid_tokens != Nil) {
   122 			val kind =
   121 			val kind =
   123         if (is_command_keyword(matcher.group))
   122         if (is_command_keyword(matcher.group))
   124           Token.Kind.COMMAND_START
   123           Token.Kind.COMMAND_START
   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) =>
   234       delete_between(cmd_before_change, cmd_after_change).
   233       delete_between(cmd_before_change, cmd_after_change).
   235       append_after(cmd_before_change, inserted_commands)
   234       append_after(cmd_before_change, inserted_commands)
   236 
   235 
   237 
   236 
   238     val doc =
   237     val doc =
   239       new ProofDocument(new_id, new_tokenset, new_token_start, new_commandset,
   238       new Proof_Document(new_id, new_tokenset, new_token_start, new_commandset,
   240         states -- removed_commands, is_command_keyword)
   239         states -- removed_commands, is_command_keyword)
   241 
   240 
   242     val removes =
   241     val removes =
   243       for (cmd <- removed_commands) yield (cmd_before_change -> None)
   242       for (cmd <- removed_commands) yield (cmd_before_change -> None)
   244     val inserts =
   243     val inserts =