some support to prune_history;
authorwenzelm
Sat, 03 Sep 2011 12:31:27 +0200
changeset 44672 07dad1433cd7
parent 44671 7f0b4515588a
child 44673 2fa51ac191bc
some support to prune_history; clarified signature: recent_stable is supposed to be always defined;
src/Pure/PIDE/document.scala
src/Tools/jEdit/src/session_dockable.scala
--- a/src/Pure/PIDE/document.scala	Fri Sep 02 16:58:00 2011 -0700
+++ b/src/Pure/PIDE/document.scala	Sat Sep 03 12:31:27 2011 +0200
@@ -168,15 +168,19 @@
 
   object Change
   {
-    val init: Change = Change(Future.value(Version.init), Nil, Future.value(Version.init))
+    val init: Change = Change(Some(Future.value(Version.init)), Nil, Future.value(Version.init))
   }
 
   sealed case class Change(
-    val previous: Future[Version],
+    val previous: Option[Future[Version]],
     val edits: List[Edit_Text],
     val version: Future[Version])
   {
-    def is_finished: Boolean = previous.is_finished && version.is_finished
+    def is_finished: Boolean =
+      (previous match { case None => true case Some(future) => future.is_finished }) &&
+      version.is_finished
+
+    def truncate: Change = copy(previous = None, edits = Nil)
   }
 
 
@@ -184,16 +188,16 @@
 
   object History
   {
-    val init: History = new History(List(Change.init))
+    val init: History = History(List(Change.init))
   }
 
   // FIXME pruning, purging of state
-  class History(val undo_list: List[Change])
+  sealed case class History(val undo_list: List[Change])
   {
     require(!undo_list.isEmpty)
 
     def tip: Change = undo_list.head
-    def +(change: Change): History = new History(change :: undo_list)
+    def +(change: Change): History = copy(undo_list = change :: undo_list)
   }
 
 
@@ -342,7 +346,7 @@
     def is_stable(change: Change): Boolean =
       change.is_finished && is_assigned(change.version.get_finished)
 
-    def recent_stable: Option[Change] = history.undo_list.find(is_stable)
+    def recent_stable: Change = history.undo_list.find(is_stable) getOrElse fail
     def tip_stable: Boolean = is_stable(history.tip)
     def tip_version: Version = history.tip.version.get_finished
 
@@ -366,10 +370,25 @@
         edits: List[Edit_Text],
         version: Future[Version]): (Change, State) =
     {
-      val change = Change(previous, edits, version)
+      val change = Change(Some(previous), edits, version)
       (change, copy(history = history + change))
     }
 
+    def prune_history(retain: Int = 0): (List[Version], State) =
+    {
+      val undo_list = history.undo_list
+      val n = undo_list.iterator.zipWithIndex.find(p => is_stable(p._1)).get._2 + 1
+      val (retained, dropped) = undo_list.splitAt(n max retain)
+
+      retained.splitAt(retained.length - 1) match {
+        case (prefix, List(last)) =>
+          val dropped_versions = dropped.map(change => change.version.get_finished)
+          val state1 = copy(history = History(prefix ::: List(last.truncate)))
+          (dropped_versions, state1)
+        case _ => fail
+      }
+    }
+
     def command_state(version: Version, command: Command): Command.State =
     {
       require(is_assigned(version))
@@ -384,7 +403,7 @@
     // persistent user-view
     def snapshot(name: Node.Name, pending_edits: List[Text.Edit]): Snapshot =
     {
-      val stable = recent_stable.get
+      val stable = recent_stable
       val latest = history.tip
 
       // FIXME proper treatment of removed nodes
--- a/src/Tools/jEdit/src/session_dockable.scala	Fri Sep 02 16:58:00 2011 -0700
+++ b/src/Tools/jEdit/src/session_dockable.scala	Sat Sep 03 12:31:27 2011 +0200
@@ -80,23 +80,21 @@
     Swing_Thread.now {
       // FIXME correlation to changed_nodes!?
       val state = Isabelle.session.current_state()
-      state.recent_stable.map(change => change.version.get_finished) match {
-        case None =>
-        case Some(version) =>
-          var nodes_status1 = nodes_status
-          for {
-            name <- changed_nodes
-            node <- version.nodes.get(name)
-            val status = Isar_Document.node_status(state, version, node)
-          } nodes_status1 += (name -> status.toString)
+      val version = state.recent_stable.version.get_finished
 
-          if (nodes_status != nodes_status1) {
-            nodes_status = nodes_status1
-            val order =
-              Library.sort_wrt((name: Document.Node.Name) => name.theory,
-                nodes_status.keySet.toList)
-            status.listData = order.map(name => name.theory + " " + nodes_status(name))
-          }
+      var nodes_status1 = nodes_status
+      for {
+        name <- changed_nodes
+        node <- version.nodes.get(name)
+        val status = Isar_Document.node_status(state, version, node)
+      } nodes_status1 += (name -> status.toString)
+
+      if (nodes_status != nodes_status1) {
+        nodes_status = nodes_status1
+        val order =
+          Library.sort_wrt((name: Document.Node.Name) => name.theory,
+            nodes_status.keySet.toList)
+        status.listData = order.map(name => name.theory + " " + nodes_status(name))
       }
     }
   }