src/Pure/PIDE/change.scala
author wenzelm
Sat, 07 Aug 2010 16:49:03 +0200
changeset 38225 ee0f46c45c19
parent 38222 dac5fa0ac971
permissions -rw-r--r--
tuned;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36676
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 34871
diff changeset
     1
/*  Title:      Pure/PIDE/change.scala
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 34871
diff changeset
     2
    Author:     Fabian Immler, TU Munich
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 34871
diff changeset
     3
    Author:     Makarius
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 34871
diff changeset
     4
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
     5
Changes of plain text, resulting in document edits.
36676
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 34871
diff changeset
     6
*/
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
     7
34871
e596a0b71f3c incorporate "proofdocument" part into main Isabelle/Pure.jar -- except for html_panel.scala, which depends on external library (Lobo/Cobra browser);
wenzelm
parents: 34854
diff changeset
     8
package isabelle
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
     9
34703
ff037c17332a minor tuning;
wenzelm
parents: 34695
diff changeset
    10
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    11
object Change
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    12
{
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    13
  val init = new Change(Document.NO_ID, None, Nil, Future.value(Nil, Document.init))
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    14
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    15
  abstract class Snapshot
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    16
  {
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    17
    val document: Document
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    18
    val node: Document.Node
38152
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    19
    val is_outdated: Boolean
38153
469555615ec7 renamed to_current to convert, and from_current to revert;
wenzelm
parents: 38152
diff changeset
    20
    def convert(offset: Int): Int
469555615ec7 renamed to_current to convert, and from_current to revert;
wenzelm
parents: 38152
diff changeset
    21
    def revert(offset: Int): Int
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    22
  }
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    23
}
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    24
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
    25
class Change(
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    26
  val id: Document.Version_ID,
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
    27
  val parent: Option[Change],
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    28
  val edits: List[Document.Node_Text_Edit],
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    29
  val result: Future[(List[Document.Edit[Command]], Document)])
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
    30
{
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    31
  /* ancestor versions */
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    32
34833
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    33
  def ancestors: Iterator[Change] = new Iterator[Change]
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    34
  {
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    35
    private var state: Option[Change] = Some(Change.this)
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    36
    def hasNext = state.isDefined
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    37
    def next =
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    38
      state match {
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    39
        case Some(change) => state = change.parent; change
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    40
        case None => throw new NoSuchElementException("next on empty iterator")
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    41
      }
683ddf358698 recovered explicit Changed.id (copy of future document) -- avoids premature joining of result;
wenzelm
parents: 34827
diff changeset
    42
  }
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
    43
34853
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    44
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    45
  /* editing and state assignment */
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    46
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    47
  def join_document: Document = result.join._2
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    48
  def is_assigned: Boolean = result.is_finished && join_document.assignment.is_finished
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    49
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    50
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    51
  /* snapshot */
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    52
38225
wenzelm
parents: 38222
diff changeset
    53
  def snapshot(name: String, pending_edits: List[Text_Edit]): Change.Snapshot =
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    54
  {
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    55
    val latest = this
38156
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    56
    val stable = latest.ancestors.find(_.is_assigned)
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    57
    require(stable.isDefined)
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    58
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    59
    val edits =
38225
wenzelm
parents: 38222
diff changeset
    60
      (pending_edits /: latest.ancestors.takeWhile(_ != stable.get))((edits, change) =>
38152
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    61
          (for ((a, eds) <- change.edits if a == name) yield eds).flatten ::: edits)
38156
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    62
    lazy val reverse_edits = edits.reverse
38152
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    63
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    64
    new Change.Snapshot {
38156
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    65
      val document = stable.get.join_document
38152
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    66
      val node = document.nodes(name)
38225
wenzelm
parents: 38222
diff changeset
    67
      val is_outdated = !(pending_edits.isEmpty && latest == stable.get)
38156
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    68
      def convert(offset: Int): Int = (offset /: edits)((i, edit) => edit.convert(i))
5c8243580334 misc tuning -- produce reverse_edits at most once (note that foldRight produces a reversed list internally, while recursion is infisible due to small stack vs. large stack frames on JVM);
wenzelm
parents: 38154
diff changeset
    69
      def revert(offset: Int): Int = (offset /: reverse_edits)((i, edit) => edit.revert(i))
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    70
    }
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    71
  }
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
    72
}