# HG changeset patch # User wenzelm # Date 1315045887 -7200 # Node ID 07dad1433cd73056ad4c5e762031b8ac14805994 # Parent 7f0b4515588ac618995fa9fb8779c35d5deb91e5 some support to prune_history; clarified signature: recent_stable is supposed to be always defined; diff -r 7f0b4515588a -r 07dad1433cd7 src/Pure/PIDE/document.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 diff -r 7f0b4515588a -r 07dad1433cd7 src/Tools/jEdit/src/session_dockable.scala --- 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)) } } }