src/Pure/PIDE/document.scala
author blanchet
Wed, 08 Jun 2011 16:20:18 +0200
changeset 43293 a80cdc4b27a3
parent 40479 cc06f5528bb1
child 43425 0a5612040a8b
permissions -rw-r--r--
made "query" type systes a bit more sound -- local facts, e.g. the negated conjecture, may make invalid the infinity check, e.g. if we are proving that there exists two values of an infinite type, we can use the negated conjecture that there is only one value to derive unsound proofs unless the type is properly encoded
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36676
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 36012
diff changeset
     1
/*  Title:      Pure/PIDE/document.scala
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 36012
diff changeset
     2
    Author:     Makarius
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 36012
diff changeset
     3
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 37849
diff changeset
     4
Document as collection of named nodes, each consisting of an editable
38418
9a7af64d71bb more explicit / functional ML version of document model;
wenzelm
parents: 38417
diff changeset
     5
list of commands, associated with asynchronous execution process.
36676
ac7961d42ac3 some rearrangement of Scala sources;
wenzelm
parents: 36012
diff changeset
     6
*/
34407
aad6834ba380 added some headers and comments;
wenzelm
parents: 34390
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: 34868
diff changeset
     8
package isabelle
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
     9
34760
dc7f5e0d9d27 misc modernization of names;
wenzelm
parents: 34759
diff changeset
    10
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 37849
diff changeset
    11
import scala.collection.mutable
37073
5e42e36a6693 @tailrec annotation;
wenzelm
parents: 37072
diff changeset
    12
5e42e36a6693 @tailrec annotation;
wenzelm
parents: 37072
diff changeset
    13
34823
2f3ea37c5958 renamed Proof_Document to Document;
wenzelm
parents: 34819
diff changeset
    14
object Document
34483
0923926022d7 superficial tuning;
wenzelm
parents: 34482
diff changeset
    15
{
38227
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    16
  /* formal identifiers */
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 37849
diff changeset
    17
38363
af7f41a8a0a8 clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents: 38361
diff changeset
    18
  type ID = Long
38414
49f1f657adc2 more basic Markup.parse_int/print_int (using signed_string_of_int) (ML);
wenzelm
parents: 38374
diff changeset
    19
40478
4bae781b8f7c replaced Document.Node_Text_Edit by Document.Text_Edit, with treatment of deleted nodes;
wenzelm
parents: 39698
diff changeset
    20
  object ID
4bae781b8f7c replaced Document.Node_Text_Edit by Document.Text_Edit, with treatment of deleted nodes;
wenzelm
parents: 39698
diff changeset
    21
  {
38414
49f1f657adc2 more basic Markup.parse_int/print_int (using signed_string_of_int) (ML);
wenzelm
parents: 38374
diff changeset
    22
    def apply(id: ID): String = Markup.Long.apply(id)
49f1f657adc2 more basic Markup.parse_int/print_int (using signed_string_of_int) (ML);
wenzelm
parents: 38374
diff changeset
    23
    def unapply(s: String): Option[ID] = Markup.Long.unapply(s)
49f1f657adc2 more basic Markup.parse_int/print_int (using signed_string_of_int) (ML);
wenzelm
parents: 38374
diff changeset
    24
  }
49f1f657adc2 more basic Markup.parse_int/print_int (using signed_string_of_int) (ML);
wenzelm
parents: 38374
diff changeset
    25
38373
wenzelm
parents: 38370
diff changeset
    26
  type Version_ID = ID
38363
af7f41a8a0a8 clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents: 38361
diff changeset
    27
  type Command_ID = ID
38373
wenzelm
parents: 38370
diff changeset
    28
  type Exec_ID = ID
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 37849
diff changeset
    29
38363
af7f41a8a0a8 clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents: 38361
diff changeset
    30
  val NO_ID: ID = 0
38355
8cb265fb12fe represent document ids by (long) int, to benefit from the somewhat faster Inttab in ML (LinearSet in Scala is invariably indexed by native object ids);
wenzelm
parents: 38227
diff changeset
    31
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 37849
diff changeset
    32
34818
7df68a8f0e3e register Proof_Document instances as session entities -- handle Markup.EDIT messages locally;
wenzelm
parents: 34815
diff changeset
    33
38424
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
    34
  /** document structure **/
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
    35
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
    36
  /* named nodes -- development graph */
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
    37
40479
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
    38
  type Edit[A] =
40478
4bae781b8f7c replaced Document.Node_Text_Edit by Document.Text_Edit, with treatment of deleted nodes;
wenzelm
parents: 39698
diff changeset
    39
   (String,  // node name
40479
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
    40
    Option[List[A]])  // None: remove node, Some: edit content
38424
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
    41
40479
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
    42
  type Edit_Text = Edit[Text.Edit]
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
    43
  type Edit_Command = Edit[(Option[Command], Option[Command])]
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
    44
  type Edit_Command_ID = Edit[(Option[Command_ID], Option[Command_ID])]
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    45
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    46
  object Node
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    47
  {
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    48
    val empty: Node = new Node(Linear_Set())
38227
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    49
38426
2858ec7b6dd8 specific types Text.Offset and Text.Range;
wenzelm
parents: 38425
diff changeset
    50
    def command_starts(commands: Iterator[Command], offset: Text.Offset = 0)
2858ec7b6dd8 specific types Text.Offset and Text.Range;
wenzelm
parents: 38425
diff changeset
    51
      : Iterator[(Command, Text.Offset)] =
38227
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    52
    {
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    53
      var i = offset
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    54
      for (command <- commands) yield {
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    55
        val start = i
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    56
        i += command.length
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    57
        (command, start)
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    58
      }
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
    59
    }
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    60
  }
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    61
38880
5b4efe90c120 simplified/clarified Document_View.text_area_extension;
wenzelm
parents: 38879
diff changeset
    62
  private val block_size = 1024
38879
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    63
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    64
  class Node(val commands: Linear_Set[Command])
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    65
  {
38879
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    66
    private lazy val full_index: (Array[(Command, Text.Offset)], Text.Range) =
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    67
    {
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    68
      val blocks = new mutable.ListBuffer[(Command, Text.Offset)]
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    69
      var next_block = 0
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    70
      var last_stop = 0
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    71
      for ((command, start) <- Node.command_starts(commands.iterator)) {
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    72
        last_stop = start + command.length
38885
06582837872b Node.full_index: allow command spans larger than block_size;
wenzelm
parents: 38882
diff changeset
    73
        while (last_stop + 1 > next_block) {
38879
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    74
          blocks += (command -> start)
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    75
          next_block += block_size
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    76
        }
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    77
      }
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    78
      (blocks.toArray, Text.Range(0, last_stop))
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    79
    }
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    80
38879
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    81
    def full_range: Text.Range = full_index._2
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    82
38569
9d480f6a2589 tuned signatures;
wenzelm
parents: 38427
diff changeset
    83
    def command_range(i: Text.Offset = 0): Iterator[(Command, Text.Offset)] =
38879
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    84
    {
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    85
      if (!commands.isEmpty && full_range.contains(i)) {
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    86
        val (cmd0, start0) = full_index._1(i / block_size)
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    87
        Node.command_starts(commands.iterator(cmd0), start0) dropWhile {
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    88
          case (cmd, start) => start + cmd.length <= i }
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    89
      }
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    90
      else Iterator.empty
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
    91
    }
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    92
38569
9d480f6a2589 tuned signatures;
wenzelm
parents: 38427
diff changeset
    93
    def command_range(range: Text.Range): Iterator[(Command, Text.Offset)] =
9d480f6a2589 tuned signatures;
wenzelm
parents: 38427
diff changeset
    94
      command_range(range.start) takeWhile { case (_, start) => start < range.stop }
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    95
38426
2858ec7b6dd8 specific types Text.Offset and Text.Range;
wenzelm
parents: 38425
diff changeset
    96
    def command_at(i: Text.Offset): Option[(Command, Text.Offset)] =
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    97
    {
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    98
      val range = command_range(i)
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
    99
      if (range.hasNext) Some(range.next) else None
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   100
    }
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   101
38426
2858ec7b6dd8 specific types Text.Offset and Text.Range;
wenzelm
parents: 38425
diff changeset
   102
    def proper_command_at(i: Text.Offset): Option[Command] =
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   103
      command_at(i) match {
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   104
        case Some((command, _)) =>
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   105
          commands.reverse_iterator(command).find(cmd => !cmd.is_ignored)
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   106
        case None => None
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   107
      }
38879
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
   108
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
   109
    def command_start(cmd: Command): Option[Text.Offset] =
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
   110
      command_starts.find(_._1 == cmd).map(_._2)
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
   111
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
   112
    def command_starts: Iterator[(Command, Text.Offset)] =
dde403450419 Document.Node: significant speedup of command_range etc. via lazy full_index;
wenzelm
parents: 38872
diff changeset
   113
      Node.command_starts(commands.iterator)
38151
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   114
  }
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   115
2837c952ca31 explicit Change.Snapshot and Document.Node;
wenzelm
parents: 38150
diff changeset
   116
38424
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   117
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   118
  /** versioning **/
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   119
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   120
  /* particular document versions */
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   121
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   122
  object Version
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   123
  {
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   124
    val init: Version = new Version(NO_ID, Map().withDefaultValue(Node.empty))
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   125
  }
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   126
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   127
  class Version(val id: Version_ID, val nodes: Map[String, Node])
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents: 34657
diff changeset
   128
34859
f986d84dd44b renamed Command.content to source;
wenzelm
parents: 34855
diff changeset
   129
38424
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   130
  /* changes of plain text, eventually resulting in document edits */
38227
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   131
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   132
  object Change
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   133
  {
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   134
    val init = new Change(Future.value(Version.init), Nil, Future.value(Nil, Version.init))
38227
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   135
  }
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   136
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   137
  class Change(
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   138
    val previous: Future[Version],
40479
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
   139
    val edits: List[Edit_Text],
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
   140
    val result: Future[(List[Edit_Command], Version)])
38227
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   141
  {
39698
625a3bc4417b tuned signature;
wenzelm
parents: 39621
diff changeset
   142
    val version: Future[Version] = result.map(_._2)
625a3bc4417b tuned signature;
wenzelm
parents: 39621
diff changeset
   143
    def is_finished: Boolean = previous.is_finished && version.is_finished
38227
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   144
  }
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   145
6bbb42843b6e concentrate structural document notions in document.scala;
wenzelm
parents: 38220
diff changeset
   146
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   147
  /* history navigation */
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   148
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   149
  object History
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   150
  {
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   151
    val init = new History(List(Change.init))
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   152
  }
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   153
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   154
  // FIXME pruning, purging of state
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   155
  class History(val undo_list: List[Change])
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   156
  {
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   157
    require(!undo_list.isEmpty)
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   158
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   159
    def tip: Change = undo_list.head
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   160
    def +(change: Change): History = new History(change :: undo_list)
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   161
  }
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   162
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   163
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   164
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   165
  /** global state -- document structure, execution process, editing history **/
38424
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   166
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   167
  abstract class Snapshot
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   168
  {
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   169
    val version: Version
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   170
    val node: Node
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   171
    val is_outdated: Boolean
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   172
    def lookup_command(id: Command_ID): Option[Command]
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   173
    def state(command: Command): Command.State
38427
7066fbd315ae some derived operations on Text.Range;
wenzelm
parents: 38426
diff changeset
   174
    def convert(i: Text.Offset): Text.Offset
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   175
    def convert(range: Text.Range): Text.Range
38427
7066fbd315ae some derived operations on Text.Range;
wenzelm
parents: 38426
diff changeset
   176
    def revert(i: Text.Offset): Text.Offset
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   177
    def revert(range: Text.Range): Text.Range
39178
83e9f3ccea9f concentrate Isabelle specific physical rendering markup selection in isabelle_markup.scala;
wenzelm
parents: 39177
diff changeset
   178
    def select_markup[A](range: Text.Range)(result: Markup_Tree.Select[A])
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   179
      : Stream[Text.Info[Option[A]]]
38424
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   180
  }
940a404e45e2 moved History/Snapshot to document.scala;
wenzelm
parents: 38418
diff changeset
   181
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   182
  object State
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   183
  {
38373
wenzelm
parents: 38370
diff changeset
   184
    class Fail(state: State) extends Exception
wenzelm
parents: 38370
diff changeset
   185
38882
e1fb3bbc22ab Document state assignment indicates command change;
wenzelm
parents: 38880
diff changeset
   186
    val init = State().define_version(Version.init, Map()).assign(Version.init.id, Nil)._2
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   187
38976
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   188
    case class Assignment(
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   189
      val assignment: Map[Command, Exec_ID],
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   190
      val is_finished: Boolean = false)
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   191
    {
38976
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   192
      def get_finished: Map[Command, Exec_ID] = { require(is_finished); assignment }
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   193
      def assign(command_execs: List[(Command, Exec_ID)]): Assignment =
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   194
      {
38976
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   195
        require(!is_finished)
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   196
        Assignment(assignment ++ command_execs, true)
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 37849
diff changeset
   197
      }
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   198
    }
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   199
  }
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   200
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   201
  case class State(
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   202
    val versions: Map[Version_ID, Version] = Map(),
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   203
    val commands: Map[Command_ID, Command.State] = Map(),
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   204
    val execs: Map[Exec_ID, (Command.State, Set[Version])] = Map(),
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   205
    val assignments: Map[Version, State.Assignment] = Map(),
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   206
    val disposed: Set[ID] = Set(),  // FIXME unused!?
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   207
    val history: History = History.init)
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   208
  {
38373
wenzelm
parents: 38370
diff changeset
   209
    private def fail[A]: A = throw new State.Fail(this)
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   210
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   211
    def define_version(version: Version, former_assignment: Map[Command, Exec_ID]): State =
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   212
    {
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   213
      val id = version.id
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   214
      if (versions.isDefinedAt(id) || disposed(id)) fail
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   215
      copy(versions = versions + (id -> version),
38976
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   216
        assignments = assignments + (version -> State.Assignment(former_assignment)))
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   217
    }
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   218
38373
wenzelm
parents: 38370
diff changeset
   219
    def define_command(command: Command): State =
wenzelm
parents: 38370
diff changeset
   220
    {
wenzelm
parents: 38370
diff changeset
   221
      val id = command.id
wenzelm
parents: 38370
diff changeset
   222
      if (commands.isDefinedAt(id) || disposed(id)) fail
wenzelm
parents: 38370
diff changeset
   223
      copy(commands = commands + (id -> command.empty_state))
wenzelm
parents: 38370
diff changeset
   224
    }
wenzelm
parents: 38370
diff changeset
   225
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   226
    def lookup_command(id: Command_ID): Option[Command] = commands.get(id).map(_.command)
38373
wenzelm
parents: 38370
diff changeset
   227
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   228
    def the_version(id: Version_ID): Version = versions.getOrElse(id, fail)
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   229
    def the_command(id: Command_ID): Command.State = commands.getOrElse(id, fail)
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   230
    def the_exec_state(id: Exec_ID): Command.State = execs.getOrElse(id, fail)._1
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   231
    def the_assignment(version: Version): State.Assignment = assignments.getOrElse(version, fail)
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   232
38872
26c505765024 Command.results: ordered by serial number;
wenzelm
parents: 38848
diff changeset
   233
    def accumulate(id: ID, message: XML.Elem): (Command.State, State) =
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   234
      execs.get(id) match {
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   235
        case Some((st, occs)) =>
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   236
          val new_st = st.accumulate(message)
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   237
          (new_st, copy(execs = execs + (id -> (new_st, occs))))
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   238
        case None =>
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   239
          commands.get(id) match {
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   240
            case Some(st) =>
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   241
              val new_st = st.accumulate(message)
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   242
              (new_st, copy(commands = commands + (id -> new_st)))
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   243
            case None => fail
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   244
          }
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   245
      }
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   246
38882
e1fb3bbc22ab Document state assignment indicates command change;
wenzelm
parents: 38880
diff changeset
   247
    def assign(id: Version_ID, edits: List[(Command_ID, Exec_ID)]): (List[Command], State) =
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   248
    {
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   249
      val version = the_version(id)
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   250
      val occs = Set(version)  // FIXME unused (!?)
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   251
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   252
      var new_execs = execs
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   253
      val assigned_execs =
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   254
        for ((cmd_id, exec_id) <- edits) yield {
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   255
          val st = the_command(cmd_id)
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   256
          if (new_execs.isDefinedAt(exec_id) || disposed(exec_id)) fail
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   257
          new_execs += (exec_id -> (st, occs))
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   258
          (st.command, exec_id)
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   259
        }
38976
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   260
      val new_assignment = the_assignment(version).assign(assigned_execs)
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   261
      val new_state =
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   262
        copy(assignments = assignments + (version -> new_assignment), execs = new_execs)
a4a465dc89d9 Document.State.Assignment: eliminated promise in favour of plain values -- signalling is done via event bus in Session;
wenzelm
parents: 38885
diff changeset
   263
      (assigned_execs.map(_._1), new_state)
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   264
    }
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   265
38417
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   266
    def is_assigned(version: Version): Boolean =
b8922ae21111 renamed class Document to Document.Version etc.;
wenzelm
parents: 38414
diff changeset
   267
      assignments.get(version) match {
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   268
        case Some(assgn) => assgn.is_finished
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   269
        case None => false
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   270
      }
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   271
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   272
    def extend_history(previous: Future[Version],
40479
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
   273
        edits: List[Edit_Text],
cc06f5528bb1 unified type Document.Edit;
wenzelm
parents: 40478
diff changeset
   274
        result: Future[(List[Edit_Command], Version)]): (Change, State) =
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   275
    {
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   276
      val change = new Change(previous, edits, result)
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   277
      (change, copy(history = history + change))
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   278
    }
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   279
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   280
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   281
    // persistent user-view
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   282
    def snapshot(name: String, pending_edits: List[Text.Edit]): Snapshot =
38370
8b15d0f98962 explicit Document.State value, instead of individual state variables in Session, Command, Document;
wenzelm
parents: 38367
diff changeset
   283
    {
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   284
      val found_stable = history.undo_list.find(change =>
39698
625a3bc4417b tuned signature;
wenzelm
parents: 39621
diff changeset
   285
        change.is_finished && is_assigned(change.version.get_finished))
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   286
      require(found_stable.isDefined)
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   287
      val stable = found_stable.get
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   288
      val latest = history.undo_list.head
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   289
40478
4bae781b8f7c replaced Document.Node_Text_Edit by Document.Text_Edit, with treatment of deleted nodes;
wenzelm
parents: 39698
diff changeset
   290
      // FIXME proper treatment of deleted nodes
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   291
      val edits =
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   292
        (pending_edits /: history.undo_list.takeWhile(_ != stable))((edits, change) =>
40478
4bae781b8f7c replaced Document.Node_Text_Edit by Document.Text_Edit, with treatment of deleted nodes;
wenzelm
parents: 39698
diff changeset
   293
            (for ((a, Some(eds)) <- change.edits if a == name) yield eds).flatten ::: edits)
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   294
      lazy val reverse_edits = edits.reverse
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   295
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   296
      new Snapshot
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   297
      {
39698
625a3bc4417b tuned signature;
wenzelm
parents: 39621
diff changeset
   298
        val version = stable.version.get_finished
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   299
        val node = version.nodes(name)
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   300
        val is_outdated = !(pending_edits.isEmpty && latest == stable)
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   301
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   302
        def lookup_command(id: Command_ID): Option[Command] = State.this.lookup_command(id)
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   303
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   304
        def state(command: Command): Command.State =
38848
9483bb678d96 use Future.get_finished where this is the intended meaning -- prefer immediate crash over deadlock due to promises that are never fulfilled;
wenzelm
parents: 38845
diff changeset
   305
          try { the_exec_state(the_assignment(version).get_finished.getOrElse(command, fail)) }
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   306
          catch { case _: State.Fail => command.empty_state }
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   307
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   308
        def convert(offset: Text.Offset) = (offset /: edits)((i, edit) => edit.convert(i))
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   309
        def revert(offset: Text.Offset) = (offset /: reverse_edits)((i, edit) => edit.revert(i))
38845
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   310
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   311
        def convert(range: Text.Range): Text.Range =
39621
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   312
          try { if (edits.isEmpty) range else range.map(convert(_)) }
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   313
          catch { // FIXME tmp
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   314
            case e: IllegalArgumentException =>
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   315
              System.err.println((true, range, edits)); throw(e)
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   316
          }
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   317
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   318
        def revert(range: Text.Range): Text.Range =
39621
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   319
          try { if (edits.isEmpty) range else range.map(revert(_)) }
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   320
          catch { // FIXME tmp
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   321
            case e: IllegalArgumentException =>
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   322
              System.err.println((false, range, reverse_edits)); throw(e)
20bba9cc4b51 Snapshot.convert/revert: explicit error report to isolate sporadic crash;
wenzelm
parents: 39178
diff changeset
   323
          }
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   324
39178
83e9f3ccea9f concentrate Isabelle specific physical rendering markup selection in isabelle_markup.scala;
wenzelm
parents: 39177
diff changeset
   325
        def select_markup[A](range: Text.Range)(result: Markup_Tree.Select[A])
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   326
          : Stream[Text.Info[Option[A]]] =
38845
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   327
        {
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   328
          val former_range = revert(range)
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   329
          for {
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   330
            (command, command_start) <- node.command_range(former_range).toStream
38845
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   331
            Text.Info(r0, x) <- state(command).markup.
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   332
              select((former_range - command_start).restrict(command.range)) {
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   333
                case Text.Info(r0, info)
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   334
                if result.isDefinedAt(Text.Info(convert(r0 + command_start), info)) =>
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   335
                  result(Text.Info(convert(r0 + command_start), info))
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38976
diff changeset
   336
              }
38845
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   337
            val r = convert(r0 + command_start)
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   338
            if !r.is_singularity
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   339
          } yield Text.Info(r, x)
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38841
diff changeset
   340
        }
38841
4df7b76249a0 include Document.History in Document.State -- just one universal session state maintained by main actor;
wenzelm
parents: 38569
diff changeset
   341
      }
38150
67fc24df3721 simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents: 37849
diff changeset
   342
    }
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   343
  }
34840
6c5560d48561 more precise treatment of document/state assigment;
wenzelm
parents: 34838
diff changeset
   344
}
6c5560d48561 more precise treatment of document/state assigment;
wenzelm
parents: 34838
diff changeset
   345