src/Pure/PIDE/change.scala
author wenzelm
Thu, 05 Aug 2010 18:13:12 +0200
changeset 38153 469555615ec7
parent 38152 eab0d1c2e46e
child 38154 343cb5d4034a
permissions -rw-r--r--
renamed to_current to convert, and from_current to revert;
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 edit(session: Session, edits: List[Document.Node_Text_Edit]): Change =
34853
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    48
  {
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    49
    val new_id = session.create_id()
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 36676
diff changeset
    50
    val result: Future[(List[Document.Edit[Command]], Document)] =
34853
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    51
      Future.fork {
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    52
        val old_doc = join_document
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    53
        old_doc.await_assignment
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    54
        Document.text_edits(session, old_doc, new_id, edits)
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    55
      }
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    56
    new Change(new_id, Some(this), edits, result)
32b49207ca20 misc tuning and clarification of Document/Change;
wenzelm
parents: 34838
diff changeset
    57
  }
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    58
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    59
  def join_document: Document = result.join._2
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    60
  def is_assigned: Boolean = result.is_finished && join_document.assignment.is_finished
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    61
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    62
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    63
  /* snapshot */
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    64
38152
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    65
  def snapshot(name: String, extra_edits: List[Text_Edit]): Change.Snapshot =
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    66
  {
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    67
    val latest = this
38152
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    68
    val stable = latest.ancestors.find(_.is_assigned).get
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    69
    val changes =
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    70
      (extra_edits /: latest.ancestors.takeWhile(_ != stable))((edits, change) =>
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    71
          (for ((a, eds) <- change.edits if a == name) yield eds).flatten ::: edits)
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    72
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    73
    new Change.Snapshot {
38152
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    74
      val document = stable.join_document
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    75
      val node = document.nodes(name)
eab0d1c2e46e Change.Snapshot: include from_current/to_current here, with precomputed changes;
wenzelm
parents: 38151
diff changeset
    76
      val is_outdated = !(extra_edits.isEmpty && latest == stable)
38153
469555615ec7 renamed to_current to convert, and from_current to revert;
wenzelm
parents: 38152
diff changeset
    77
      def convert(offset: Int): Int = (offset /: changes)((i, change) => change after i)
469555615ec7 renamed to_current to convert, and from_current to revert;
wenzelm
parents: 38152
diff changeset
    78
      def revert(offset: Int): Int = (offset /: changes.reverse)((i, change) => change before i)  // FIXME fold_rev (!?)
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    79
    }
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    80
  }
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents:
diff changeset
    81
}