src/Tools/jEdit/src/proofdocument/ProofDocument.scala
changeset 34494 47f9303db81d
parent 34491 20e9d420dbbb
child 34496 1b2995592bb9
equal deleted inserted replaced
34493:0ffbc5ce9654 34494:47f9303db81d
    10 
    10 
    11 import java.util.regex.Pattern
    11 import java.util.regex.Pattern
    12 import isabelle.prover.{Prover, Command}
    12 import isabelle.prover.{Prover, Command}
    13 
    13 
    14 
    14 
    15 class StructureChange(
    15 case class StructureChange(
    16   val beforeChange: Command,
    16   val before_change: Command,
    17   val addedCommands: List[Command],
    17   val added_commands: List[Command],
    18   val removedCommands: List[Command])
    18   val removed_commands: List[Command])
    19 
    19 
    20 object ProofDocument
    20 object ProofDocument
    21 {
    21 {
    22   // Be carefully when changing this regex. Not only must it handle the 
    22   // Be carefully when changing this regex. Not only must it handle the 
    23   // spurious end of a token but also:  
    23   // spurious end of a token but also:  
    51 
    51 
    52 
    52 
    53 
    53 
    54   /** token view **/
    54   /** token view **/
    55 
    55 
    56   protected var firstToken: Token = null
    56   private var first_token: Token = null
    57   protected var lastToken: Token = null
    57   private var last_token: Token = null
    58   
    58   
    59   protected def tokens(start: Token, stop: Token) = new Iterator[Token] {
    59   private def tokens(start: Token, stop: Token) = new Iterator[Token] {
    60       var current = start
    60       var current = start
    61       def hasNext = current != stop && current != null
    61       def hasNext = current != stop && current != null
    62       def next() = { val save = current ; current = current.next ; save }
    62       def next() = { val save = current; current = current.next; save }
    63     }
    63     }
    64   protected def tokens(start: Token): Iterator[Token] = tokens(start, null)
    64   private def tokens(start: Token): Iterator[Token] = tokens(start, null)
    65   protected def tokens() : Iterator[Token] = tokens(firstToken, null)
    65   private def tokens(): Iterator[Token] = tokens(first_token, null)
    66 
    66 
    67 
    67 
    68   private def text_changed(start: Int, addedLen: Int, removedLen: Int)
    68   private def text_changed(start: Int, added_len: Int, removed_len: Int)
    69   {
    69   {
    70     if (!active)
    70     if (!active)
    71       return
    71       return
    72 
    72 
    73     var beforeChange = 
    73     var before_change =
    74       if (Token.check_stop(firstToken, _ < start)) Token.scan(firstToken, _.stop >= start)
    74       if (Token.check_stop(first_token, _ < start)) Token.scan(first_token, _.stop >= start)
    75       else null
    75       else null
    76     
    76     
    77     var firstRemoved = 
    77     var first_removed =
    78       if (beforeChange != null) beforeChange.next
    78       if (before_change != null) before_change.next
    79       else if (Token.check_start(firstToken, _ <= start + removedLen)) firstToken
    79       else if (Token.check_start(first_token, _ <= start + removed_len)) first_token
    80       else null 
    80       else null 
    81 
    81 
    82     var lastRemoved = Token.scan(firstRemoved, _.start > start + removedLen)
    82     var last_removed = Token.scan(first_removed, _.start > start + removed_len)
    83 
    83 
    84     var shiftToken = 
    84     var shift_token =
    85       if (lastRemoved != null) lastRemoved
    85       if (last_removed != null) last_removed
    86       else if (Token.check_start(firstToken, _ > start)) firstToken
    86       else if (Token.check_start(first_token, _ > start)) first_token
    87       else null
    87       else null
    88     
    88     
    89     while (shiftToken != null) {
    89     while (shift_token != null) {
    90       shiftToken.shift(addedLen - removedLen, start)
    90       shift_token.shift(added_len - removed_len, start)
    91       shiftToken = shiftToken.next
    91       shift_token = shift_token.next
    92     }
    92     }
    93     
    93     
    94     // scan changed tokens until the end of the text or a matching token is
    94     // scan changed tokens until the end of the text or a matching token is
    95     // found which is beyond the changed area
    95     // found which is beyond the changed area
    96     val matchStart = if (beforeChange == null) 0 else beforeChange.stop
    96     val match_start = if (before_change == null) 0 else before_change.stop
    97     var firstAdded: Token = null
    97     var first_added: Token = null
    98     var lastAdded: Token = null
    98     var last_added: Token = null
    99 
    99 
   100     val matcher = ProofDocument.token_pattern.matcher(text.content(matchStart, text.length))
   100     val matcher = ProofDocument.token_pattern.matcher(text.content(match_start, text.length))
   101     var finished = false
   101     var finished = false
   102     var position = 0 
   102     var position = 0 
   103     while (matcher.find(position) && ! finished) {
   103     while (matcher.find(position) && !finished) {
   104       position = matcher.end()
   104       position = matcher.end
   105 			val kind =
   105 			val kind =
   106         if (prover.is_command_keyword(matcher.group()))
   106         if (prover.is_command_keyword(matcher.group))
   107           Token.Kind.COMMAND_START
   107           Token.Kind.COMMAND_START
   108         else if (matcher.end() - matcher.start() > 2 && matcher.group().substring(0, 2) == "(*")
   108         else if (matcher.end - matcher.start > 2 && matcher.group.substring(0, 2) == "(*")
   109           Token.Kind.COMMENT
   109           Token.Kind.COMMENT
   110         else
   110         else
   111           Token.Kind.OTHER
   111           Token.Kind.OTHER
   112       val newToken = new Token(matcher.start() + matchStart, matcher.end() + matchStart, kind)
   112       val new_token = new Token(matcher.start + match_start, matcher.end + match_start, kind)
   113 
   113 
   114       if (firstAdded == null)
   114       if (first_added == null)
   115         firstAdded = newToken
   115         first_added = new_token
   116       else {
   116       else {
   117         newToken.prev = lastAdded
   117         new_token.prev = last_added
   118         lastAdded.next = newToken
   118         last_added.next = new_token
   119       }
   119       }
   120       lastAdded = newToken
   120       last_added = new_token
   121       
   121       
   122       while (Token.check_stop(lastRemoved, _ < newToken.stop) &&
   122       while (Token.check_stop(last_removed, _ < new_token.stop) &&
   123               lastRemoved.next != null)	
   123               last_removed.next != null)
   124         lastRemoved = lastRemoved.next
   124         last_removed = last_removed.next
   125 			
   125 			
   126       if (newToken.stop >= start + addedLen && 
   126       if (new_token.stop >= start + added_len &&
   127             Token.check_stop(lastRemoved, _ == newToken.stop))
   127             Token.check_stop(last_removed, _ == new_token.stop))
   128         finished = true
   128         finished = true
   129     }
   129     }
   130 
   130 
   131     var afterChange = if (lastRemoved != null) lastRemoved.next else null
   131     var after_change = if (last_removed != null) last_removed.next else null
   132 		
   132 		
   133     // remove superflous first token-change
   133     // remove superflous first token-change
   134     if (firstAdded != null && firstAdded == firstRemoved && 
   134     if (first_added != null && first_added == first_removed &&
   135           firstAdded.stop < start) {
   135           first_added.stop < start) {
   136       beforeChange = firstRemoved
   136       before_change = first_removed
   137       if (lastRemoved == firstRemoved) {
   137       if (last_removed == first_removed) {
   138         lastRemoved = null
   138         last_removed = null
   139         firstRemoved = null
   139         first_removed = null
   140       }
   140       }
   141       else {
   141       else {
   142         firstRemoved = firstRemoved.next
   142         first_removed = first_removed.next
   143         assert(firstRemoved != null)
   143         assert(first_removed != null)
   144       }
   144       }
   145 
   145 
   146       if (lastAdded == firstAdded) {
   146       if (last_added == first_added) {
   147         lastAdded = null
   147         last_added = null
   148         firstAdded = null
   148         first_added = null
   149       }
   149       }
   150       if (firstAdded != null)
   150       if (first_added != null)
   151         firstAdded = firstAdded.next
   151         first_added = first_added.next
   152     }
   152     }
   153     
   153     
   154     // remove superflous last token-change
   154     // remove superflous last token-change
   155     if (lastAdded != null && lastAdded == lastRemoved &&
   155     if (last_added != null && last_added == last_removed &&
   156           lastAdded.start > start + addedLen) {
   156           last_added.start > start + added_len) {
   157       afterChange = lastRemoved
   157       after_change = last_removed
   158       if (firstRemoved == lastRemoved) {
   158       if (first_removed == last_removed) {
   159         firstRemoved = null
   159         first_removed = null
   160         lastRemoved = null
   160         last_removed = null
   161       }
   161       }
   162       else {
   162       else {
   163         lastRemoved = lastRemoved.prev
   163         last_removed = last_removed.prev
   164         assert(lastRemoved != null)
   164         assert(last_removed != null)
   165       }
   165       }
   166       
   166       
   167       if (lastAdded == firstAdded) {
   167       if (last_added == first_added) {
   168         lastAdded = null
   168         last_added = null
   169         firstAdded = null
   169         first_added = null
   170       }
   170       }
   171       else
   171       else
   172         lastAdded = lastAdded.prev
   172         last_added = last_added.prev
   173     }
   173     }
   174     
   174     
   175     if (firstRemoved == null && firstAdded == null)
   175     if (first_removed == null && first_added == null)
   176       return
   176       return
   177     
   177     
   178     if (firstToken == null) {
   178     if (first_token == null) {
   179       firstToken = firstAdded
   179       first_token = first_added
   180       lastToken = lastAdded
   180       last_token = last_added
   181     }
   181     }
   182     else {
   182     else {
   183       // cut removed tokens out of list
   183       // cut removed tokens out of list
   184       if (firstRemoved != null)
   184       if (first_removed != null)
   185         firstRemoved.prev = null
   185         first_removed.prev = null
   186       if (lastRemoved != null)
   186       if (last_removed != null)
   187         lastRemoved.next = null
   187         last_removed.next = null
   188       
   188       
   189       if (firstToken == firstRemoved)
   189       if (first_token == first_removed)
   190         if (firstAdded != null)
   190         if (first_added != null)
   191           firstToken = firstAdded
   191           first_token = first_added
   192         else
   192         else
   193           firstToken = afterChange
   193           first_token = after_change
   194       
   194       
   195       if (lastToken == lastRemoved)
   195       if (last_token == last_removed)
   196         if (lastAdded != null)
   196         if (last_added != null)
   197           lastToken = lastAdded
   197           last_token = last_added
   198         else
   198         else
   199           lastToken = beforeChange
   199           last_token = before_change
   200       
   200       
   201       // insert new tokens into list
   201       // insert new tokens into list
   202       if (firstAdded != null) {
   202       if (first_added != null) {
   203         firstAdded.prev = beforeChange
   203         first_added.prev = before_change
   204         if (beforeChange != null)
   204         if (before_change != null)
   205           beforeChange.next = firstAdded
   205           before_change.next = first_added
   206         else
   206         else
   207           firstToken = firstAdded
   207           first_token = first_added
   208       }
   208       }
   209       else if (beforeChange != null)
   209       else if (before_change != null)
   210         beforeChange.next = afterChange
   210         before_change.next = after_change
   211       
   211       
   212       if (lastAdded != null) {
   212       if (last_added != null) {
   213         lastAdded.next = afterChange
   213         last_added.next = after_change
   214         if (afterChange != null)
   214         if (after_change != null)
   215           afterChange.prev = lastAdded
   215           after_change.prev = last_added
   216         else
   216         else
   217           lastToken = lastAdded
   217           last_token = last_added
   218       }
   218       }
   219       else if (afterChange != null)
   219       else if (after_change != null)
   220         afterChange.prev = beforeChange
   220         after_change.prev = before_change
   221     }
   221     }
   222     
   222     
   223     token_changed(beforeChange, afterChange, firstRemoved)
   223     token_changed(before_change, after_change, first_removed)
   224   }
   224   }
   225   
   225   
   226 
   226 
   227   
   227   
   228   /** command view **/
   228   /** command view **/
   229 
   229 
   230   val structural_changes = new EventBus[StructureChange]
   230   val structural_changes = new EventBus[StructureChange]
   231 
   231 
   232   def commands = new Iterator[Command] {
   232   def commands = new Iterator[Command] {
   233     var current = firstToken
   233     var current = first_token
   234     def hasNext = current != null
   234     def hasNext = current != null
   235     def next() = { val s = current.command ; current = s.last.next ; s }
   235     def next() = { val s = current.command ; current = s.last.next ; s }
   236   }
   236   }
   237 
   237 
   238   def getNextCommandContaining(pos: Int): Command = {
   238   def getNextCommandContaining(pos: Int): Command = {
   240     return null
   240     return null
   241   }
   241   }
   242 
   242 
   243   private def token_changed(start: Token, stop: Token, removed: Token)
   243   private def token_changed(start: Token, stop: Token, removed: Token)
   244   {
   244   {
   245     var removedCommands: List[Command] = Nil
   245     var removed_commands: List[Command] = Nil
   246     var first: Command = null
   246     var first: Command = null
   247     var last: Command = null
   247     var last: Command = null
   248 
   248 
   249     for(t <- tokens(removed)) {
   249     for(t <- tokens(removed)) {
   250       if (first == null)
   250       if (first == null)
   251         first = t.command
   251         first = t.command
   252       if (t.command != last)
   252       if (t.command != last)
   253         removedCommands = t.command :: removedCommands
   253         removed_commands = t.command :: removed_commands
   254       last = t.command
   254       last = t.command
   255     }
   255     }
   256 
   256 
   257     var before: Command = null
   257     var before: Command = null
   258     if (!removedCommands.isEmpty) {
   258     if (!removed_commands.isEmpty) {
   259       if (first.first == removed) {
   259       if (first.first == removed) {
   260         if (start == null)
   260         if (start == null)
   261           before = null
   261           before = null
   262         else
   262         else
   263           before = start.command
   263           before = start.command
   264       }
   264       }
   265       else
   265       else
   266         before = first.prev
   266         before = first.prev
   267     }
   267     }
   268 
   268 
   269     var addedCommands: List[Command] = Nil
   269     var added_commands: List[Command] = Nil
   270     var scan: Token = null
   270     var scan: Token = null
   271     if (start != null) {
   271     if (start != null) {
   272       val next = start.next
   272       val next = start.next
   273       if (first != null && first.first != removed) {
   273       if (first != null && first.first != removed) {
   274         scan = first.first
   274         scan = first.first
   280           before = start.command
   280           before = start.command
   281           scan = next
   281           scan = next
   282         }
   282         }
   283         else if (first == null || first.first == removed) {
   283         else if (first == null || first.first == removed) {
   284           first = start.command
   284           first = start.command
   285           removedCommands = first :: removedCommands
   285           removed_commands = first :: removed_commands
   286           scan = first.first
   286           scan = first.first
   287           if (before == null)
   287           if (before == null)
   288             before = first.prev
   288             before = first.prev
   289         }
   289         }
   290         else {
   290         else {
   293             before = first.prev
   293             before = first.prev
   294         }
   294         }
   295       }
   295       }
   296     }
   296     }
   297     else
   297     else
   298       scan = firstToken
   298       scan = first_token
   299 
   299 
   300     var stopScan: Token = null
   300     var stopScan: Token = null
   301     if (stop != null) {
   301     if (stop != null) {
   302       if (stop == stop.command.first)
   302       if (stop == stop.command.first)
   303         stopScan = stop
   303         stopScan = stop
   321           overrun = true
   321           overrun = true
   322       }
   322       }
   323 
   323 
   324       if (scan.kind == Token.Kind.COMMAND_START && cmdStart != null && !finished) {
   324       if (scan.kind == Token.Kind.COMMAND_START && cmdStart != null && !finished) {
   325         if (!overrun) {
   325         if (!overrun) {
   326           addedCommands = new Command(text, cmdStart, cmdStop) :: addedCommands
   326           added_commands = new Command(text, cmdStart, cmdStop) :: added_commands
   327           cmdStart = scan
   327           cmdStart = scan
   328           cmdStop = scan
   328           cmdStop = scan
   329         }
   329         }
   330         else
   330         else
   331           finished = true
   331           finished = true
   335           cmdStart = scan
   335           cmdStart = scan
   336         cmdStop = scan
   336         cmdStop = scan
   337       }
   337       }
   338       if (overrun && !finished) {
   338       if (overrun && !finished) {
   339         if (scan.command != last)
   339         if (scan.command != last)
   340           removedCommands = scan.command :: removedCommands
   340           removed_commands = scan.command :: removed_commands
   341         last = scan.command
   341         last = scan.command
   342       }
   342       }
   343 
   343 
   344       if (!finished)
   344       if (!finished)
   345         scan = scan.next
   345         scan = scan.next
   346     }
   346     }
   347 
   347 
   348     if (cmdStart != null)
   348     if (cmdStart != null)
   349       addedCommands = new Command(text, cmdStart, cmdStop) :: addedCommands
   349       added_commands = new Command(text, cmdStart, cmdStop) :: added_commands
   350 
   350 
   351     // relink commands
   351     // relink commands
   352     addedCommands = addedCommands.reverse
   352     added_commands = added_commands.reverse
   353     removedCommands = removedCommands.reverse
   353     removed_commands = removed_commands.reverse
   354 
   354 
   355     structural_changes.event(new StructureChange(before, addedCommands, removedCommands))
   355     structural_changes.event(new StructureChange(before, added_commands, removed_commands))
   356   }
   356   }
   357 }
   357 }