--- a/src/Pure/General/linear_set.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/General/linear_set.scala Mon Aug 23 11:18:38 2010 +0200
@@ -143,13 +143,13 @@
private def make_iterator(start: Option[A], which: Map[A, A]): Iterator[A] = new Iterator[A] {
private var next_elem = start
- def hasNext = next_elem.isDefined
- def next =
+ def hasNext(): Boolean = next_elem.isDefined
+ def next(): A =
next_elem match {
case Some(elem) =>
next_elem = which.get(elem)
elem
- case None => throw new NoSuchElementException("next on empty iterator")
+ case None => Iterator.empty.next()
}
}
--- a/src/Pure/General/position.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/General/position.scala Mon Aug 23 11:18:38 2010 +0200
@@ -22,9 +22,9 @@
def get_range(pos: T): Option[Text.Range] =
(get_offset(pos), get_end_offset(pos)) match {
- case (Some(start), Some(stop)) => Some(Text.Range(start, stop))
- case (Some(start), None) => Some(Text.Range(start, start + 1))
- case (None, _) => None
+ case (Some(start), Some(stop)) if start <= stop => Some(Text.Range(start, stop))
+ case (Some(start), None) => Some(Text.Range(start))
+ case (_, _) => None
}
object Id { def unapply(pos: T): Option[Long] = get_id(pos) }
--- a/src/Pure/General/pretty.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/General/pretty.scala Mon Aug 23 11:18:38 2010 +0200
@@ -14,12 +14,14 @@
{
/* markup trees with physical blocks and breaks */
+ def block(body: XML.Body): XML.Tree = Block(2, body)
+
object Block
{
- def apply(i: Int, body: List[XML.Tree]): XML.Tree =
+ def apply(i: Int, body: XML.Body): XML.Tree =
XML.Elem(Markup(Markup.BLOCK, List((Markup.INDENT, Markup.Int(i)))), body)
- def unapply(tree: XML.Tree): Option[(Int, List[XML.Tree])] =
+ def unapply(tree: XML.Tree): Option[(Int, XML.Body)] =
tree match {
case XML.Elem(
Markup(Markup.BLOCK, List((Markup.INDENT, Markup.Int(i)))), body) => Some((i, body))
@@ -45,7 +47,7 @@
/* formatted output */
- private def standard_format(tree: XML.Tree): List[XML.Tree] =
+ private def standard_format(tree: XML.Tree): XML.Body =
tree match {
case XML.Elem(markup, body) => List(XML.Elem(markup, body.flatMap(standard_format)))
case XML.Text(text) =>
@@ -53,12 +55,12 @@
Library.chunks(text).toList.map((s: CharSequence) => XML.Text(s.toString)))
}
- case class Text(tx: List[XML.Tree] = Nil, val pos: Double = 0.0, val nl: Int = 0)
+ case class Text(tx: XML.Body = Nil, val pos: Double = 0.0, val nl: Int = 0)
{
def newline: Text = copy(tx = FBreak :: tx, pos = 0.0, nl = nl + 1)
def string(s: String, len: Double): Text = copy(tx = XML.Text(s) :: tx, pos = pos + len)
def blanks(wd: Int): Text = string(Symbol.spaces(wd), wd.toDouble)
- def content: List[XML.Tree] = tx.reverse
+ def content: XML.Body = tx.reverse
}
private val margin_default = 76
@@ -71,8 +73,8 @@
((s: String) => if (s == "\n") 1.0 else metrics.stringWidth(s) / unit)
}
- def formatted(input: List[XML.Tree], margin: Int = margin_default,
- metric: String => Double = metric_default): List[XML.Tree] =
+ def formatted(input: XML.Body, margin: Int = margin_default,
+ metric: String => Double = metric_default): XML.Body =
{
val breakgain = margin / 20
val emergencypos = margin / 2
@@ -83,7 +85,7 @@
case XML.Text(s) => metric(s)
}
- def breakdist(trees: List[XML.Tree], after: Double): Double =
+ def breakdist(trees: XML.Body, after: Double): Double =
trees match {
case Break(_) :: _ => 0.0
case FBreak :: _ => 0.0
@@ -91,7 +93,7 @@
case Nil => after
}
- def forcenext(trees: List[XML.Tree]): List[XML.Tree] =
+ def forcenext(trees: XML.Body): XML.Body =
trees match {
case Nil => Nil
case FBreak :: _ => trees
@@ -99,7 +101,7 @@
case t :: ts => t :: forcenext(ts)
}
- def format(trees: List[XML.Tree], blockin: Double, after: Double, text: Text): Text =
+ def format(trees: XML.Body, blockin: Double, after: Double, text: Text): Text =
trees match {
case Nil => text
@@ -129,16 +131,16 @@
format(input.flatMap(standard_format), 0.0, 0.0, Text()).content
}
- def string_of(input: List[XML.Tree], margin: Int = margin_default,
+ def string_of(input: XML.Body, margin: Int = margin_default,
metric: String => Double = metric_default): String =
formatted(input, margin, metric).iterator.flatMap(XML.content).mkString
/* unformatted output */
- def unformatted(input: List[XML.Tree]): List[XML.Tree] =
+ def unformatted(input: XML.Body): XML.Body =
{
- def fmt(tree: XML.Tree): List[XML.Tree] =
+ def fmt(tree: XML.Tree): XML.Body =
tree match {
case Block(_, body) => body.flatMap(fmt)
case Break(wd) => List(XML.Text(Symbol.spaces(wd)))
@@ -149,6 +151,6 @@
input.flatMap(standard_format).flatMap(fmt)
}
- def str_of(input: List[XML.Tree]): String =
+ def str_of(input: XML.Body): String =
unformatted(input).iterator.flatMap(XML.content).mkString
}
--- a/src/Pure/Isar/toplevel.scala Sun Aug 22 14:27:30 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/* Title: Pure/Isar/toplevel.scala
- Author: Makarius
-
-Isabelle/Isar toplevel transactions.
-*/
-
-package isabelle
-
-
-object Toplevel
-{
- sealed abstract class Status
- case class Forked(forks: Int) extends Status
- case object Unprocessed extends Status
- case object Finished extends Status
- case object Failed extends Status
-
- def command_status(markup: XML.Body): Status =
- {
- val forks = (0 /: markup) {
- case (i, XML.Elem(Markup(Markup.FORKED, _), _)) => i + 1
- case (i, XML.Elem(Markup(Markup.JOINED, _), _)) => i - 1
- case (i, _) => i
- }
- if (forks != 0) Forked(forks)
- else if (markup.exists { case XML.Elem(Markup(Markup.FAILED, _), _) => true case _ => false })
- Failed
- else if (markup.exists { case XML.Elem(Markup(Markup.FINISHED, _), _) => true case _ => false })
- Finished
- else Unprocessed
- }
-}
-
--- a/src/Pure/PIDE/command.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/PIDE/command.scala Mon Aug 23 11:18:38 2010 +0200
@@ -14,20 +14,11 @@
object Command
{
- case class HighlightInfo(kind: String, sub_kind: Option[String]) {
- override def toString = kind
- }
- case class TypeInfo(ty: String)
- case class RefInfo(file: Option[String], line: Option[Int],
- command_id: Option[Document.Command_ID], offset: Option[Int]) // FIXME Command_ID vs. Exec_ID !?
-
-
-
/** accumulated results from prover **/
case class State(
val command: Command,
- val status: List[XML.Tree],
+ val status: List[Markup],
val reverse_results: List[XML.Tree],
val markup: Markup_Tree)
{
@@ -37,86 +28,31 @@
def add_result(result: XML.Tree): State = copy(reverse_results = result :: reverse_results)
- def add_markup(node: Markup_Tree.Node): State = copy(markup = markup + node)
-
- def markup_root_node: Markup_Tree.Node =
- new Markup_Tree.Node(command.range, XML.Elem(Markup(Markup.STATUS, Nil), status))
- def markup_root: Markup_Tree = markup + markup_root_node
-
-
- /* markup */
-
- lazy val highlight: List[Markup_Tree.Node] =
- {
- markup.filter(_.info match {
- case Command.HighlightInfo(_, _) => true
- case _ => false
- }).flatten(markup_root_node)
- }
+ def add_markup(info: Text.Info[Any]): State = copy(markup = markup + info)
- private lazy val types: List[Markup_Tree.Node] =
- markup.filter(_.info match {
- case Command.TypeInfo(_) => true
- case _ => false }).flatten(markup_root_node)
-
- def type_at(pos: Text.Offset): Option[String] =
- {
- types.find(_.range.contains(pos)) match {
- case Some(t) =>
- t.info match {
- case Command.TypeInfo(ty) => Some(command.source(t.range) + " : " + ty)
- case _ => None
- }
- case None => None
- }
- }
-
- private lazy val refs: List[Markup_Tree.Node] =
- markup.filter(_.info match {
- case Command.RefInfo(_, _, _, _) => true
- case _ => false }).flatten(markup_root_node)
-
- def ref_at(pos: Text.Offset): Option[Markup_Tree.Node] =
- refs.find(_.range.contains(pos))
+ def markup_root_info: Text.Info[Any] =
+ new Text.Info(command.range,
+ XML.Elem(Markup(Markup.STATUS, Nil), status.map(XML.Elem(_, Nil))))
+ def markup_root: Markup_Tree = markup + markup_root_info
/* message dispatch */
def accumulate(message: XML.Tree): Command.State =
message match {
- case XML.Elem(Markup(Markup.STATUS, _), body) => copy(status = body ::: status)
+ case XML.Elem(Markup(Markup.STATUS, _), body) => // FIXME explicit checks!?
+ copy(status = (for (XML.Elem(markup, _) <- body) yield markup) ::: status)
- case XML.Elem(Markup(Markup.REPORT, _), elems) =>
- (this /: elems)((state, elem) =>
- elem match {
- case XML.Elem(Markup(kind, atts), body) if Position.get_id(atts) == Some(command.id) =>
- atts match {
- case Position.Range(range) =>
- if (kind == Markup.ML_TYPING) {
- val info = Pretty.string_of(body, margin = 40)
- state.add_markup(command.decode_range(range, Command.TypeInfo(info)))
- }
- else if (kind == Markup.ML_REF) {
- body match {
- case List(XML.Elem(Markup(Markup.ML_DEF, props), _)) =>
- state.add_markup(
- command.decode_range(range,
- Command.RefInfo(
- Position.get_file(props),
- Position.get_line(props),
- Position.get_id(props),
- Position.get_offset(props))))
- case _ => state
- }
- }
- else {
- state.add_markup(
- command.decode_range(range,
- Command.HighlightInfo(kind, Markup.get_string(Markup.KIND, atts))))
- }
- case _ => state
- }
- case _ => System.err.println("Ignored report message: " + elem); state
+ case XML.Elem(Markup(Markup.REPORT, _), msgs) =>
+ (this /: msgs)((state, msg) =>
+ msg match {
+ case XML.Elem(Markup(name, atts), args)
+ if Position.get_id(atts) == Some(command.id) && Position.get_range(atts).isDefined =>
+ val range = command.decode(Position.get_range(atts).get)
+ val props = atts.filterNot(p => Markup.POSITION_PROPERTIES(p._1))
+ val info = Text.Info[Any](range, XML.Elem(Markup(name, props), args))
+ add_markup(info)
+ case _ => System.err.println("Ignored report message: " + msg); state
})
case _ => add_result(message)
}
@@ -152,15 +88,12 @@
val source: String = span.map(_.source).mkString
def source(range: Text.Range): String = source.substring(range.start, range.stop)
def length: Int = source.length
+
val range: Text.Range = Text.Range(0, length)
lazy val symbol_index = new Symbol.Index(source)
-
-
- /* markup */
-
- def decode_range(range: Text.Range, info: Any): Markup_Tree.Node =
- new Markup_Tree.Node(symbol_index.decode(range), info)
+ def decode(i: Text.Offset): Text.Offset = symbol_index.decode(i)
+ def decode(r: Text.Range): Text.Range = symbol_index.decode(r)
/* accumulated results */
--- a/src/Pure/PIDE/document.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/PIDE/document.scala Mon Aug 23 11:18:38 2010 +0200
@@ -65,11 +65,11 @@
def command_start(cmd: Command): Option[Text.Offset] =
command_starts.find(_._1 == cmd).map(_._2)
- def command_range(i: Text.Offset): Iterator[(Command, Text.Offset)] =
+ def command_range(i: Text.Offset = 0): Iterator[(Command, Text.Offset)] =
command_starts dropWhile { case (cmd, start) => start + cmd.length <= i }
- def command_range(i: Text.Offset, j: Text.Offset): Iterator[(Command, Text.Offset)] =
- command_range(i) takeWhile { case (_, start) => start < j }
+ def command_range(range: Text.Range): Iterator[(Command, Text.Offset)] =
+ command_range(range.start) takeWhile { case (_, start) => start < range.stop }
def command_at(i: Text.Offset): Option[(Command, Text.Offset)] =
{
--- a/src/Pure/PIDE/isar_document.ML Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/PIDE/isar_document.ML Mon Aug 23 11:18:38 2010 +0200
@@ -1,7 +1,7 @@
(* Title: Pure/PIDE/isar_document.ML
Author: Makarius
-Protocol commands for interactive Isar documents.
+Protocol message formats for interactive Isar documents.
*)
structure Isar_Document: sig end =
--- a/src/Pure/PIDE/isar_document.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/PIDE/isar_document.scala Mon Aug 23 11:18:38 2010 +0200
@@ -1,7 +1,7 @@
/* Title: Pure/PIDE/isar_document.scala
Author: Makarius
-Protocol commands for interactive Isar documents.
+Protocol message formats for interactive Isar documents.
*/
package isabelle
@@ -9,7 +9,7 @@
object Isar_Document
{
- /* protocol messages */
+ /* document editing */
object Assign {
def unapply(msg: XML.Tree)
@@ -32,6 +32,28 @@
case _ => None
}
}
+
+
+ /* toplevel transactions */
+
+ sealed abstract class Status
+ case class Forked(forks: Int) extends Status
+ case object Unprocessed extends Status
+ case object Finished extends Status
+ case object Failed extends Status
+
+ def command_status(markup: List[Markup]): Status =
+ {
+ val forks = (0 /: markup) {
+ case (i, Markup(Markup.FORKED, _)) => i + 1
+ case (i, Markup(Markup.JOINED, _)) => i - 1
+ case (i, _) => i
+ }
+ if (forks != 0) Forked(forks)
+ else if (markup.exists(_.name == Markup.FAILED)) Failed
+ else if (markup.exists(_.name == Markup.FINISHED)) Finished
+ else Unprocessed
+ }
}
--- a/src/Pure/PIDE/markup_tree.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/PIDE/markup_tree.scala Mon Aug 23 11:18:38 2010 +0200
@@ -17,26 +17,30 @@
object Markup_Tree
{
- case class Node(val range: Text.Range, val info: Any)
- {
- def contains(that: Node): Boolean = this.range contains that.range
- def intersect(r: Text.Range): Node = Node(range.intersect(r), info)
- }
-
-
- /* branches sorted by quasi-order -- overlapping intervals appear as equivalent */
+ /* branches sorted by quasi-order -- overlapping ranges appear as equivalent */
object Branches
{
- type Entry = (Node, Markup_Tree)
- type T = SortedMap[Node, Entry]
+ type Entry = (Text.Info[Any], Markup_Tree)
+ type T = SortedMap[Text.Range, Entry]
- val empty = SortedMap.empty[Node, Entry](new scala.math.Ordering[Node]
+ val empty = SortedMap.empty[Text.Range, Entry](new scala.math.Ordering[Text.Range]
{
- def compare(x: Node, y: Node): Int = x.range compare y.range
+ def compare(r1: Text.Range, r2: Text.Range): Int = r1 compare r2
})
- def update(branches: T, entries: Entry*): T =
- branches ++ entries.map(e => (e._1 -> e))
+
+ def update(branches: T, entry: Entry): T = branches + (entry._1.range -> entry)
+
+ def overlapping(range: Text.Range, branches: T): T =
+ {
+ val start = Text.Range(range.start)
+ val stop = Text.Range(range.stop)
+ branches.get(stop) match {
+ case Some(end) if range overlaps end._1.range =>
+ update(branches.range(start, stop), end)
+ case _ => branches.range(start, stop)
+ }
+ }
}
val empty = new Markup_Tree(Branches.empty)
@@ -47,95 +51,77 @@
{
import Markup_Tree._
- def + (new_node: Node): Markup_Tree =
+ override def toString =
+ branches.toList.map(_._2) match {
+ case Nil => "Empty"
+ case list => list.mkString("Tree(", ",", ")")
+ }
+
+ def + (new_info: Text.Info[Any]): Markup_Tree =
{
- branches.get(new_node) match {
+ val new_range = new_info.range
+ branches.get(new_range) match {
case None =>
- new Markup_Tree(Branches.update(branches, new_node -> empty))
- case Some((node, subtree)) =>
- if (node.range != new_node.range && node.contains(new_node))
- new Markup_Tree(Branches.update(branches, node -> (subtree + new_node)))
- else if (new_node.contains(branches.head._1) && new_node.contains(branches.last._1))
- new Markup_Tree(Branches.update(Branches.empty, (new_node -> this)))
+ new Markup_Tree(Branches.update(branches, new_info -> empty))
+ case Some((info, subtree)) =>
+ val range = info.range
+ if (range != new_range && range.contains(new_range))
+ new Markup_Tree(Branches.update(branches, info -> (subtree + new_info)))
+ else if (new_range.contains(branches.head._1) && new_range.contains(branches.last._1))
+ new Markup_Tree(Branches.update(Branches.empty, (new_info -> this)))
else {
- var overlapping = Branches.empty
- var rest = branches
- while (rest.isDefinedAt(new_node)) {
- overlapping = Branches.update(overlapping, rest(new_node))
- rest -= new_node
+ val body = Branches.overlapping(new_range, branches)
+ if (body.forall(e => new_range.contains(e._1))) {
+ val rest = (Branches.empty /: branches)((rest, entry) =>
+ if (body.isDefinedAt(entry._1)) rest else rest + entry)
+ new Markup_Tree(Branches.update(rest, new_info -> new Markup_Tree(body)))
}
- if (overlapping.forall(e => new_node.contains(e._1)))
- new Markup_Tree(Branches.update(rest, new_node -> new Markup_Tree(overlapping)))
else { // FIXME split markup!?
- System.err.println("Ignored overlapping markup: " + new_node)
+ System.err.println("Ignored overlapping markup information: " + new_info)
this
}
}
}
}
- // FIXME depth-first with result markup stack
- // FIXME projection to given range
- def flatten(parent: Node): List[Node] =
+ def select[A](root_range: Text.Range)
+ (result: PartialFunction[Text.Info[Any], A])(default: A): Stream[Text.Info[A]] =
{
- val result = new mutable.ListBuffer[Node]
- var offset = parent.range.start
- for ((_, (node, subtree)) <- branches.iterator) {
- if (offset < node.range.start)
- result += new Node(Text.Range(offset, node.range.start), parent.info)
- result ++= subtree.flatten(node)
- offset = node.range.stop
+ def stream(parent: Text.Info[A], bs: Branches.T): Stream[Text.Info[A]] =
+ {
+ val range = parent.range
+ val substream =
+ (for ((info_range, (info, subtree)) <- Branches.overlapping(range, bs).toStream) yield {
+ if (result.isDefinedAt(info)) {
+ val current = Text.Info(info_range.restrict(range), result(info))
+ stream(current, subtree.branches)
+ }
+ else stream(parent.restrict(info_range), subtree.branches)
+ }).flatten
+
+ def padding(last: Text.Offset, s: Stream[Text.Info[A]]): Stream[Text.Info[A]] =
+ s match {
+ case info #:: rest =>
+ val Text.Range(start, stop) = info.range
+ if (last < start)
+ parent.restrict(Text.Range(last, start)) #:: info #:: padding(stop, rest)
+ else info #:: padding(stop, rest)
+ case Stream.Empty =>
+ if (last < range.stop)
+ Stream(parent.restrict(Text.Range(last, range.stop)))
+ else Stream.Empty
+ }
+ if (substream.isEmpty) Stream(parent)
+ else padding(range.start, substream)
}
- if (offset < parent.range.stop)
- result += new Node(Text.Range(offset, parent.range.stop), parent.info)
- result.toList
- }
-
- def filter(pred: Node => Boolean): Markup_Tree =
- {
- val bs = branches.toList.flatMap(entry => {
- val (_, (node, subtree)) = entry
- if (pred(node)) List((node, (node, subtree.filter(pred))))
- else subtree.filter(pred).branches.toList
- })
- new Markup_Tree(Branches.empty ++ bs)
+ stream(Text.Info(root_range, default), branches)
}
- def select[A](range: Text.Range)(sel: PartialFunction[Node, A]): Stream[Node] =
+ def swing_tree(parent: DefaultMutableTreeNode)
+ (swing_node: Text.Info[Any] => DefaultMutableTreeNode)
{
- def stream(parent: Node, bs: Branches.T): Stream[Node] =
- {
- val start = Node(parent.range.start_range, Nil)
- val stop = Node(parent.range.stop_range, Nil)
- val substream =
- (for ((_, (node, subtree)) <- bs.range(start, stop).toStream) yield {
- if (sel.isDefinedAt(node))
- stream(node.intersect(parent.range), subtree.branches)
- else stream(parent, subtree.branches)
- }).flatten
-
- def padding(last: Text.Offset, s: Stream[Node]): Stream[Node] =
- s match {
- case node #:: rest =>
- if (last < node.range.start)
- parent.intersect(Text.Range(last, node.range.start)) #::
- node #:: padding(node.range.stop, rest)
- else node #:: padding(node.range.stop, rest)
- case Stream.Empty => // FIXME
- if (last < parent.range.stop)
- Stream(parent.intersect(Text.Range(last, parent.range.stop)))
- else Stream.Empty
- }
- padding(parent.range.start, substream)
- }
- // FIXME handle disjoint range!?
- stream(Node(range, Nil), branches)
- }
-
- def swing_tree(parent: DefaultMutableTreeNode)(swing_node: Node => DefaultMutableTreeNode)
- {
- for ((_, (node, subtree)) <- branches) {
- val current = swing_node(node)
+ for ((_, (info, subtree)) <- branches) {
+ val current = swing_node(info)
subtree.swing_tree(current)(swing_node)
parent.add(current)
}
--- a/src/Pure/PIDE/text.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/PIDE/text.scala Mon Aug 23 11:18:38 2010 +0200
@@ -15,37 +15,38 @@
type Offset = Int
- /* range: interval with total quasi-ordering */
+ /* range -- with total quasi-ordering */
object Range
{
- object Ordering extends scala.math.Ordering[Range]
- {
- override def compare(r1: Range, r2: Range): Int = r1 compare r2
- }
+ def apply(start: Offset): Range = Range(start, start)
}
sealed case class Range(val start: Offset, val stop: Offset)
{
+ // denotation: {start} Un {i. start < i & i < stop}
require(start <= stop)
+ override def toString = "[" + start.toString + ":" + stop.toString + "]"
+
def map(f: Offset => Offset): Range = Range(f(start), f(stop))
def +(i: Offset): Range = map(_ + i)
- def contains(i: Offset): Boolean = start <= i && i < stop
- def contains(that: Range): Boolean =
- this == that || this.contains(that.start) && that.stop <= this.stop
- def overlaps(that: Range): Boolean =
- this == that || this.contains(that.start) || that.contains(this.start)
- def compare(that: Range): Int =
- if (overlaps(that)) 0
- else if (this.start < that.start) -1
- else 1
+ def -(i: Offset): Range = map(_ - i)
+ def contains(i: Offset): Boolean = start == i || start < i && i < stop
+ def contains(that: Range): Boolean = this.contains(that.start) && that.stop <= this.stop
+ def overlaps(that: Range): Boolean = this.contains(that.start) || that.contains(this.start)
+ def compare(that: Range): Int = if (overlaps(that)) 0 else this.start compare that.start
- def start_range: Range = Range(start, start)
- def stop_range: Range = Range(stop, stop)
+ def restrict(that: Range): Range =
+ Range(this.start max that.start, this.stop min that.stop)
+ }
+
- def intersect(that: Range): Range =
- Range(this.start max that.start, this.stop min that.stop)
+ /* information associated with text range */
+
+ case class Info[A](val range: Text.Range, val info: A)
+ {
+ def restrict(r: Text.Range): Info[A] = Info(range.restrict(r), info)
}
--- a/src/Pure/System/isabelle_process.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/System/isabelle_process.scala Mon Aug 23 11:18:38 2010 +0200
@@ -95,7 +95,7 @@
private val xml_cache = new XML.Cache(131071)
- private def put_result(kind: String, props: List[(String, String)], body: List[XML.Tree])
+ private def put_result(kind: String, props: List[(String, String)], body: XML.Body)
{
if (pid.isEmpty && kind == Markup.INIT)
pid = props.find(_._1 == Markup.PID).map(_._1)
@@ -257,7 +257,7 @@
val default_buffer = new Array[Byte](65536)
var c = -1
- def read_chunk(): List[XML.Tree] =
+ def read_chunk(): XML.Body =
{
//{{{
// chunk size
--- a/src/Pure/System/session.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/System/session.scala Mon Aug 23 11:18:38 2010 +0200
@@ -60,7 +60,7 @@
/** main actor **/
@volatile private var syntax = new Outer_Syntax(system.symbols)
- def current_syntax: Outer_Syntax = syntax
+ def current_syntax(): Outer_Syntax = syntax
@volatile private var global_state = Document.State.init
private def change_state(f: Document.State => Document.State) { global_state = f(global_state) }
--- a/src/Pure/Thy/html.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/Thy/html.scala Mon Aug 23 11:18:38 2010 +0200
@@ -41,7 +41,7 @@
// document markup
- def span(cls: String, body: List[XML.Tree]): XML.Elem =
+ def span(cls: String, body: XML.Body): XML.Elem =
XML.Elem(Markup(SPAN, List((CLASS, cls))), body)
def hidden(txt: String): XML.Elem =
@@ -50,9 +50,9 @@
def sub(txt: String): XML.Elem = XML.elem("sub", List(XML.Text(txt)))
def sup(txt: String): XML.Elem = XML.elem("sup", List(XML.Text(txt)))
- def spans(input: XML.Tree, original_data: Boolean = false): List[XML.Tree] =
+ def spans(input: XML.Tree, original_data: Boolean = false): XML.Body =
{
- def html_spans(tree: XML.Tree): List[XML.Tree] =
+ def html_spans(tree: XML.Tree): XML.Body =
tree match {
case XML.Elem(Markup(name, _), ts) =>
if (original_data)
--- a/src/Pure/Thy/thy_syntax.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/Thy/thy_syntax.scala Mon Aug 23 11:18:38 2010 +0200
@@ -84,7 +84,7 @@
commands.iterator(first).takeWhile(_ != last).toList ::: List(last)
val sources = range.flatMap(_.span.map(_.source))
- val spans0 = parse_spans(session.current_syntax.scan(sources.mkString))
+ val spans0 = parse_spans(session.current_syntax().scan(sources.mkString))
val (before_edit, spans1) =
if (!spans0.isEmpty && first.is_command && first.span == spans0.head)
--- a/src/Pure/build-jars Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/build-jars Mon Aug 23 11:18:38 2010 +0200
@@ -37,7 +37,6 @@
Isar/keyword.scala
Isar/outer_syntax.scala
Isar/parse.scala
- Isar/toplevel.scala
Isar/token.scala
PIDE/command.scala
PIDE/document.scala
--- a/src/Pure/library.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Pure/library.scala Mon Aug 23 11:18:38 2010 +0200
@@ -79,7 +79,7 @@
def next(): CharSequence =
state match {
case Some((s, i)) => { state = next_chunk(i); s }
- case None => throw new NoSuchElementException("next on empty iterator")
+ case None => Iterator.empty.next()
}
}
--- a/src/Tools/jEdit/src/jedit/document_model.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Tools/jEdit/src/jedit/document_model.scala Mon Aug 23 11:18:38 2010 +0200
@@ -257,14 +257,17 @@
override def markTokens(prev: TokenMarker.LineContext,
handler: TokenHandler, line_segment: Segment): TokenMarker.LineContext =
{
+ // FIXME proper synchronization / thread context (!??)
+ val snapshot = Swing_Thread.now { Document_Model.this.snapshot() }
+
val previous = prev.asInstanceOf[Document_Model.Token_Markup.LineContext]
val line = if (prev == null) 0 else previous.line + 1
val context = new Document_Model.Token_Markup.LineContext(line, previous)
+
val start = buffer.getLineStartOffset(line)
val stop = start + line_segment.count
-
- // FIXME proper synchronization / thread context (!??)
- val snapshot = Swing_Thread.now { Document_Model.this.snapshot() }
+ val range = Text.Range(start, stop)
+ val former_range = snapshot.revert(range)
/* FIXME
for (text_area <- Isabelle.jedit_text_areas(buffer)
@@ -275,35 +278,38 @@
def handle_token(style: Byte, offset: Text.Offset, length: Int) =
handler.handleToken(line_segment, style, offset, length, context)
+ val syntax = session.current_syntax()
+ val token_markup: PartialFunction[Text.Info[Any], Byte] =
+ {
+ case Text.Info(_, XML.Elem(Markup(Markup.COMMAND, List((Markup.NAME, name))), _))
+ if syntax.keyword_kind(name).isDefined =>
+ Document_Model.Token_Markup.command_style(syntax.keyword_kind(name).get)
+
+ case Text.Info(_, XML.Elem(Markup(name, _), _))
+ if Document_Model.Token_Markup.token_style(name) != Token.NULL =>
+ Document_Model.Token_Markup.token_style(name)
+ }
+
var next_x = start
for {
- (command, command_start) <-
- snapshot.node.command_range(snapshot.revert(start), snapshot.revert(stop))
- markup <- snapshot.state(command).highlight
- val Text.Range(abs_start, abs_stop) = snapshot.convert(markup.range + command_start)
- if (abs_stop > start)
- if (abs_start < stop)
+ (command, command_start) <- snapshot.node.command_range(former_range)
+ info <- snapshot.state(command).markup.
+ select((former_range - command_start).restrict(command.range))(token_markup)(Token.NULL)
+ val Text.Range(abs_start, abs_stop) = snapshot.convert(info.range + command_start)
+ if abs_stop > start && abs_start < stop // FIXME abs_range overlaps range (redundant!?)
+ }
+ {
val token_start = (abs_start - start) max 0
val token_length =
(abs_stop - abs_start) -
((start - abs_start) max 0) -
((abs_stop - stop) max 0)
- }
- {
- val token_type =
- markup.info match {
- case Command.HighlightInfo(Markup.COMMAND, Some(kind)) =>
- Document_Model.Token_Markup.command_style(kind)
- case Command.HighlightInfo(kind, _) =>
- Document_Model.Token_Markup.token_style(kind)
- case _ => Token.NULL
- }
- if (start + token_start > next_x)
+ if (start + token_start > next_x) // FIXME ??
handle_token(Token.COMMENT1, next_x - start, start + token_start - next_x)
- handle_token(token_type, token_start, token_length)
+ handle_token(info.info, token_start, token_length)
next_x = start + token_start + token_length
}
- if (next_x < stop)
+ if (next_x < stop) // FIXME ??
handle_token(Token.COMMENT1, next_x - start, stop - next_x)
handle_token(Token.END, line_segment.count, 0)
--- a/src/Tools/jEdit/src/jedit/document_view.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Tools/jEdit/src/jedit/document_view.scala Mon Aug 23 11:18:38 2010 +0200
@@ -29,11 +29,11 @@
val state = snapshot.state(command)
if (snapshot.is_outdated) new Color(240, 240, 240)
else
- Toplevel.command_status(state.status) match {
- case Toplevel.Forked(i) if i > 0 => new Color(255, 228, 225)
- case Toplevel.Finished => new Color(234, 248, 255)
- case Toplevel.Failed => new Color(255, 193, 193)
- case Toplevel.Unprocessed => new Color(255, 228, 225)
+ Isar_Document.command_status(state.status) match {
+ case Isar_Document.Forked(i) if i > 0 => new Color(255, 228, 225)
+ case Isar_Document.Finished => new Color(234, 248, 255)
+ case Isar_Document.Failed => new Color(255, 193, 193)
+ case Isar_Document.Unprocessed => new Color(255, 228, 225)
case _ => Color.red
}
}
@@ -202,10 +202,12 @@
val offset = snapshot.revert(text_area.xyToOffset(x, y))
snapshot.node.command_at(offset) match {
case Some((command, command_start)) =>
- snapshot.state(command).type_at(offset - command_start) match {
- case Some(text) => Isabelle.tooltip(text)
- case None => null
- }
+ (snapshot.state(command).markup.select(Text.Range(offset) - command_start) {
+ case Text.Info(range, XML.Elem(Markup(Markup.ML_TYPING, _), body)) =>
+ val typing =
+ Pretty.block(XML.Text(command.source(range) + " : ") :: Pretty.Break(1) :: body)
+ Isabelle.tooltip(Pretty.string_of(List(typing), margin = 40))
+ } { null }).head.info
case None => null
}
}
--- a/src/Tools/jEdit/src/jedit/html_panel.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Tools/jEdit/src/jedit/html_panel.scala Mon Aug 23 11:18:38 2010 +0200
@@ -116,7 +116,7 @@
/* internal messages */
private case class Resize(font_family: String, font_size: Int)
- private case class Render(body: List[XML.Tree])
+ private case class Render(body: XML.Body)
private case object Refresh
private val main_actor = actor {
@@ -127,7 +127,7 @@
var current_font_family = ""
var current_font_size: Int = 0
var current_margin: Int = 0
- var current_body: List[XML.Tree] = Nil
+ var current_body: XML.Body = Nil
def resize(font_family: String, font_size: Int)
{
@@ -152,7 +152,7 @@
def refresh() { render(current_body) }
- def render(body: List[XML.Tree])
+ def render(body: XML.Body)
{
current_body = body
val html_body =
@@ -190,5 +190,5 @@
def resize(font_family: String, font_size: Int) { main_actor ! Resize(font_family, font_size) }
def refresh() { main_actor ! Refresh }
- def render(body: List[XML.Tree]) { main_actor ! Render(body) }
+ def render(body: XML.Body) { main_actor ! Render(body) }
}
--- a/src/Tools/jEdit/src/jedit/isabelle_hyperlinks.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Tools/jEdit/src/jedit/isabelle_hyperlinks.scala Mon Aug 23 11:18:38 2010 +0200
@@ -38,37 +38,41 @@
class Isabelle_Hyperlinks extends HyperlinkSource
{
- def getHyperlink(buffer: Buffer, original_offset: Int): Hyperlink =
+ def getHyperlink(buffer: Buffer, buffer_offset: Int): Hyperlink =
{
Swing_Thread.assert()
Document_Model(buffer) match {
case Some(model) =>
val snapshot = model.snapshot()
- val offset = snapshot.revert(original_offset)
+ val offset = snapshot.revert(buffer_offset)
snapshot.node.command_at(offset) match {
case Some((command, command_start)) =>
- snapshot.state(command).ref_at(offset - command_start) match {
- case Some(ref) =>
- val Text.Range(begin, end) = snapshot.convert(ref.range + command_start)
+ (snapshot.state(command).markup.select(Text.Range(offset) - command_start) {
+ case Text.Info(info_range, XML.Elem(Markup(Markup.ML_REF, _),
+ List(XML.Elem(Markup(Markup.ML_DEF, props), _)))) =>
+ val Text.Range(begin, end) = snapshot.convert(info_range + command_start)
val line = buffer.getLineOfOffset(begin)
- ref.info match {
- case Command.RefInfo(Some(ref_file), Some(ref_line), _, _) =>
+
+ (Position.get_file(props), Position.get_line(props)) match {
+ case (Some(ref_file), Some(ref_line)) =>
new External_Hyperlink(begin, end, line, ref_file, ref_line)
- case Command.RefInfo(_, _, Some(id), Some(offset)) =>
- snapshot.lookup_command(id) match { // FIXME Command_ID vs. Exec_ID (!??)
- case Some(ref_cmd) =>
- snapshot.node.command_start(ref_cmd) match {
- case Some(ref_cmd_start) =>
- new Internal_Hyperlink(begin, end, line,
- snapshot.convert(ref_cmd_start + offset - 1))
- case None => null // FIXME external ref
+ case _ =>
+ (Position.get_id(props), Position.get_offset(props)) match {
+ case (Some(ref_id), Some(ref_offset)) =>
+ snapshot.lookup_command(ref_id) match {
+ case Some(ref_cmd) =>
+ snapshot.node.command_start(ref_cmd) match {
+ case Some(ref_cmd_start) =>
+ new Internal_Hyperlink(begin, end, line,
+ snapshot.convert(ref_cmd_start + ref_cmd.decode(ref_offset)))
+ case None => null
+ }
+ case None => null
}
case _ => null
}
- case _ => null
}
- case None => null
- }
+ } { null }).head.info
case None => null
}
case None => null
--- a/src/Tools/jEdit/src/jedit/isabelle_sidekick.scala Sun Aug 22 14:27:30 2010 +0200
+++ b/src/Tools/jEdit/src/jedit/isabelle_sidekick.scala Mon Aug 23 11:18:38 2010 +0200
@@ -72,7 +72,7 @@
val start = buffer.getLineStartOffset(line)
val text = buffer.getSegment(start, caret - start)
- val completion = Isabelle.session.current_syntax.completion
+ val completion = Isabelle.session.current_syntax().completion
completion.complete(text) match {
case None => null
@@ -97,7 +97,7 @@
val root = data.root
val snapshot = Swing_Thread.now { model.snapshot() } // FIXME cover all nodes (!??)
for {
- (command, command_start) <- snapshot.node.command_range(0)
+ (command, command_start) <- snapshot.node.command_range()
if command.is_command && !stopped
}
{
@@ -128,22 +128,22 @@
val root = data.root
val snapshot = Swing_Thread.now { model.snapshot() } // FIXME cover all nodes (!??)
- for ((command, command_start) <- snapshot.node.command_range(0) if !stopped) {
- snapshot.state(command).markup_root.swing_tree(root)((node: Markup_Tree.Node) =>
+ for ((command, command_start) <- snapshot.node.command_range() if !stopped) {
+ snapshot.state(command).markup_root.swing_tree(root)((info: Text.Info[Any]) =>
{
- val content = command.source(node.range).replace('\n', ' ')
+ val content = command.source(info.range).replace('\n', ' ')
val id = command.id
new DefaultMutableTreeNode(new IAsset {
override def getIcon: Icon = null
override def getShortString: String = content
- override def getLongString: String = node.info.toString
+ override def getLongString: String = info.info.toString
override def getName: String = Markup.Long(id)
override def setName(name: String) = ()
override def setStart(start: Position) = ()
- override def getStart: Position = command_start + node.range.start
+ override def getStart: Position = command_start + info.range.start
override def setEnd(end: Position) = ()
- override def getEnd: Position = command_start + node.range.stop
+ override def getEnd: Position = command_start + info.range.stop
override def toString = id + ": " + content + "[" + getStart + " - " + getEnd + "]"
})
})