val cmds0 = commands.iterator(first, last).toList val blobs_spans0 =
syntax.parse_spans(cmds0.iterator.map(_.source).mkString).map(span =>
(Command.blobs_info(resources, syntax, get_blob, can_import, node_name, span), span))
val (cmds1, blobs_spans1) = chop_common(cmds0, blobs_spans0)
val (rev_cmds2, rev_blobs_spans2) = chop_common(cmds1.reverse, blobs_spans1.reverse) val cmds2 = rev_cmds2.reverse val blobs_spans2 = rev_blobs_spans2.reverse
cmds2 match { case Nil =>
assert(blobs_spans2.isEmpty)
commands case cmd :: _ => val hook = commands.prev(cmd) val inserted =
blobs_spans2.map({ case (blobs, span) =>
Command(Document_ID.make(), node_name, blobs, span) })
cmds2.foldLeft(commands)(_ - _).append_after(hook, inserted)
}
}
/* main */
def diff_commands(
old_cmds: Linear_Set[Command],
new_cmds: Linear_Set[Command]
) : List[Command.Edit] = { val removed = old_cmds.iterator.filter(!new_cmds.contains(_)).toList val inserted = new_cmds.iterator.filter(!old_cmds.contains(_)).toList
@tailrec def recover(cmds: Linear_Set[Command]): Linear_Set[Command] =
cmds.find(_.is_unparsed) match { case Some(first_unparsed) => val first = next_invisible(cmds.reverse, first_unparsed) val last = next_invisible(cmds, first_unparsed)
recover(
reparse_spans(resources, syntax, get_blob, can_import, name, cmds, first, last)) case None => cmds
}
recover(commands)
}
edit match { case (_, Document.Node.Blob(blob)) => Document.Node.init_blob(blob)
case (name, Document.Node.Edits(text_edits)) => if (name.is_theory) { val commands1 = edit_text(text_edits, node.commands) val commands2 = if (resources.loaded_theory(name)) commands1 else recover_spans(name, node.perspective.visible, commands1)
node.update_commands(commands2)
} else node
case (_, Document.Node.Deps(_)) => node
case (name, Document.Node.Perspective(_, _, _)) if resources.loaded_theory(name) => node
case (name, Document.Node.Perspective(required, text_perspective, overlays)) => val (visible, visible_overlay) = command_perspective(node, text_perspective, overlays) val perspective: Document.Node.Perspective_Command.T =
Document.Node.Perspective(required, visible_overlay, overlays) if (node.same_perspective(text_perspective, perspective)) node else { /* consolidate unfinished spans */ val is_visible = visible.commands.toSet val commands = node.commands val commands1 = if (is_visible.isEmpty) commands else {
commands.find(_.is_unfinished) match { case Some(first_unfinished) =>
commands.reverse.find(is_visible) match { case Some(last_visible) => val it = commands.iterator(last_visible) var last = last_visible var i = 0 while (i < reparse_limit && it.hasNext) {
last = it.next()
i += last.length
}
reparse_spans(resources, syntax, get_blob, can_import,
name, commands, first_unfinished, last) case None => commands
} case None => commands
}
}
node.update_perspective(text_perspective, perspective).update_commands(commands1)
}
}
}
val (doc_edits, version) = if (edits.isEmpty) (Nil, Document.Version.make(previous.nodes)) else { val reparse =
nodes0.iterator.foldLeft(syntax_changed) { case (reparse, (name, node)) => if (node.load_commands_changed(doc_blobs) && !reparse.contains(name)) {
name :: reparse
} else reparse
} val reparse_set = reparse.toSet
var nodes = nodes0 val doc_edits = mutable.ListBuffer.from(doc_edits0)
val node_edits = (edits ::: reparse.map((_, Document.Node.Edits(Nil)))).groupBy(_._1)
node_edits foreach { case (name, edits) => val node = nodes(name) val syntax = resources.session_base.node_syntax(nodes, name) val commands = node.commands
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.