sealed Edit;
Change.edits: plain field, plain list -- no reverse;
TheoryView.edits: ListBuffer -- no reverse;
misc tuning;
--- a/src/Tools/jEdit/src/jedit/TheoryView.scala Tue Sep 01 21:05:57 2009 +0200
+++ b/src/Tools/jEdit/src/jedit/TheoryView.scala Wed Sep 02 21:21:54 2009 +0200
@@ -10,6 +10,7 @@
import scala.actors.Actor
import scala.actors.Actor._
+import scala.collection.mutable
import isabelle.proofdocument.{ProofDocument, Change, Edit, Insert, Remove}
import isabelle.prover.{Prover, ProverEvents, Command}
@@ -108,14 +109,14 @@
// changes in buffer must be ignored
buffer.removeBufferListener(this)
- def apply(c: Change) = c.map {
- case Insert(start, added) => buffer.insert(start, added)
- case Remove(start, removed) => buffer.remove(start, removed.length)
+ def apply(change: Change): Unit = change.edits.foreach {
+ case Insert(start, text) => buffer.insert(start, text)
+ case Remove(start, text) => buffer.remove(start, text.length)
}
- def unapply(c: Change) = c.toList.reverse.map {
- case Insert(start, added) => buffer.remove(start, added.length)
- case Remove(start, removed) => buffer.insert(start, removed)
+ def unapply(change: Change): Unit = change.edits.reverse.foreach {
+ case Insert(start, text) => buffer.remove(start, text.length)
+ case Remove(start, text) => buffer.insert(start, text)
}
// undo/redo changes
@@ -151,36 +152,40 @@
buffer.addBufferListener(this)
}
+
/* sending edits to prover */
- private var edits: List[Edit] = Nil
+ private val edits = new mutable.ListBuffer[Edit] // owned by Swing/AWT thread
private val col_timer = new Timer(300, new ActionListener() {
- override def actionPerformed(e: ActionEvent) = commit
+ override def actionPerformed(e: ActionEvent) = commit()
})
col_timer.stop
col_timer.setRepeats(true)
- private def commit: Unit = synchronized {
+ private def commit() {
+ Swing_Thread.require()
if (!edits.isEmpty) {
- val change = new Change(Isabelle.system.id(), Some(current_change), edits)
+ val change = new Change(Isabelle.system.id(), Some(current_change), edits.toList)
_changes ::= change
prover ! change
current_change = change
+ edits.clear
}
- edits = Nil
if (col_timer.isRunning())
col_timer.stop()
}
private def delay_commit {
+ Swing_Thread.require()
if (col_timer.isRunning())
col_timer.restart()
else
col_timer.start()
}
+
/* BufferListener methods */
override def contentInserted(buffer: JEditBuffer,
@@ -192,14 +197,14 @@
override def preContentInserted(buffer: JEditBuffer,
start_line: Int, offset: Int, num_lines: Int, length: Int)
{
- edits ::= Insert(offset, buffer.getText(offset, length))
+ edits += Insert(offset, buffer.getText(offset, length))
delay_commit
}
override def preContentRemoved(buffer: JEditBuffer,
start_line: Int, start: Int, num_lines: Int, removed_length: Int)
{
- edits ::= Remove(start, buffer.getText(start, removed_length))
+ edits += Remove(start, buffer.getText(start, removed_length))
delay_commit
}
@@ -211,8 +216,8 @@
/* transforming offsets */
- private def changes_to(doc: ProofDocument) =
- edits ::: current_change.ancestors(_.id == doc.id).flatten(_.toList)
+ private def changes_to(doc: ProofDocument): List[Edit] =
+ edits.toList ::: List.flatten(current_change.ancestors(_.id == doc.id).map(_.edits))
def from_current(doc: ProofDocument, pos: Int) =
(pos /: changes_to(doc)) ((p, c) => c from_where p)
@@ -314,9 +319,12 @@
lazy val change_receiver: Actor = actor {
loop {
react {
- case ProverEvents.Activate =>
- edits = List(Insert(0, buffer.getText(0, buffer.getLength)))
- commit
+ case ProverEvents.Activate => // FIXME !?
+ Swing_Thread.now {
+ edits.clear
+ edits += Insert(0, buffer.getText(0, buffer.getLength))
+ commit()
+ }
case c: Command =>
actor{Isabelle.plugin.command_change.event(c)}
if(current_document().commands.contains(c))
--- a/src/Tools/jEdit/src/proofdocument/Change.scala Tue Sep 01 21:05:57 2009 +0200
+++ b/src/Tools/jEdit/src/proofdocument/Change.scala Wed Sep 02 21:21:54 2009 +0200
@@ -7,41 +7,42 @@
package isabelle.proofdocument
-abstract class Edit {
+sealed abstract class Edit
+{
val start: Int
def from_where (x: Int): Int //where has x been before applying this edit
def where_to(x: Int): Int //where will x be when we apply this edit
}
-case class Insert(start: Int, added: String) extends Edit {
+case class Insert(start: Int, text: String) extends Edit
+{
def from_where(x: Int) =
if (start > x) x
- else (x - added.length) max start
+ else (x - text.length) max start
def where_to(x: Int) =
- if (start <= x) x + added.length else x
+ if (start <= x) x + text.length else x
}
-case class Remove(start: Int, removed: String) extends Edit {
+case class Remove(start: Int, text: String) extends Edit
+{
def from_where(x: Int) =
- if (start <= x) x + removed.length else x
+ if (start <= x) x + text.length else x
def where_to(x: Int) =
if (start > x) x
- else (x - removed.length) max start
+ else (x - text.length) max start
}
// TODO: merge multiple inserts?
class Change(
val id: String,
val parent: Option[Change],
- edits: List[Edit]) extends Iterable[Edit]
+ val edits: List[Edit])
{
- override def elements = edits.reverse.elements
-
- def ancestors(root_p: Change => Boolean): List[Change] =
- if (root_p(this)) Nil
- else this :: parent.map(_.ancestors(root_p)).getOrElse(Nil)
+ def ancestors(done: Change => Boolean): List[Change] =
+ if (done(this)) Nil
+ else this :: parent.map(_.ancestors(done)).getOrElse(Nil)
def ancestors: List[Change] = ancestors(_ => false)
override def toString =
--- a/src/Tools/jEdit/src/proofdocument/ProofDocument.scala Tue Sep 01 21:05:57 2009 +0200
+++ b/src/Tools/jEdit/src/proofdocument/ProofDocument.scala Wed Sep 02 21:21:54 2009 +0200
@@ -62,20 +62,20 @@
def content = Token.string_from_tokens(Nil ++ tokens, token_start)
+
/** token view **/
- def text_changed(c: Change): (ProofDocument, StructureChange) =
+ def text_changed(change: Change): (ProofDocument, StructureChange) =
{
def edit_doc(doc_chgs: (ProofDocument, StructureChange), edit: Edit) = {
val (doc, chgs) = doc_chgs
- val (new_doc, chg) = doc.text_edit(edit, c.id)
+ val (new_doc, chg) = doc.text_edit(edit, change.id)
(new_doc, chgs ++ chg)
}
- ((this, Nil: StructureChange) /: c) (edit_doc)
+ ((this, Nil: StructureChange) /: change.edits)(edit_doc)
}
- def text_edit(e: Edit, id: String):
- (ProofDocument,StructureChange) =
+ def text_edit(e: Edit, id: String): (ProofDocument,StructureChange) =
{
case class TextChange(start: Int, added: String, removed: String)
val change = e match {