src/Tools/jEdit/src/isabelle_hyperlinks.scala
author wenzelm
Tue, 29 Nov 2011 20:18:02 +0100
changeset 45672 a497c5d4a523
parent 45666 d83797ef0d2d
child 45709 87017fcbad83
permissions -rw-r--r--
clarified modules;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43282
5d294220ca43 moved sources -- eliminated Netbeans artifact of jedit package directory;
wenzelm
parents: 42327
diff changeset
     1
/*  Title:      Tools/jEdit/src/isabelle_hyperlinks.scala
36760
b82a698ef6c9 tuned headers;
wenzelm
parents: 36015
diff changeset
     2
    Author:     Fabian Immler, TU Munich
b82a698ef6c9 tuned headers;
wenzelm
parents: 36015
diff changeset
     3
b82a698ef6c9 tuned headers;
wenzelm
parents: 36015
diff changeset
     4
Hyperlink setup for Isabelle proof documents.
b82a698ef6c9 tuned headers;
wenzelm
parents: 36015
diff changeset
     5
*/
34568
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
     6
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
     7
package isabelle.jedit
34569
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
     8
34760
dc7f5e0d9d27 misc modernization of names;
wenzelm
parents: 34759
diff changeset
     9
36015
6111de7c916a adapted to Scala 2.8.0 Beta 1;
wenzelm
parents: 34871
diff changeset
    10
import isabelle._
6111de7c916a adapted to Scala 2.8.0 Beta 1;
wenzelm
parents: 34871
diff changeset
    11
34569
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
    12
import java.io.File
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
    13
34791
b97d5b38dea4 explicit object Session.Global_Settings;
wenzelm
parents: 34788
diff changeset
    14
import gatchan.jedit.hyperlinks.{Hyperlink, HyperlinkSource, AbstractHyperlink}
34568
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
    15
34791
b97d5b38dea4 explicit object Session.Global_Settings;
wenzelm
parents: 34788
diff changeset
    16
import org.gjt.sp.jedit.{View, jEdit, Buffer, TextUtilities}
34568
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
    17
34588
e8ac8794971f superficial tuning;
wenzelm
parents: 34582
diff changeset
    18
44580
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    19
private class Internal_Hyperlink(name: String, start: Int, end: Int, line: Int, offset: Int)
34569
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
    20
  extends AbstractHyperlink(start, end, line, "")
34568
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
    21
{
44580
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    22
  override def click(view: View)
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    23
  {
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    24
    val text_area = view.getTextArea
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    25
    if (Isabelle.buffer_name(view.getBuffer) == name)
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    26
      text_area.moveCaretPosition(offset)
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    27
    else
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    28
      Isabelle.jedit_buffer(name) match {
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    29
        case Some(buffer) =>
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    30
          view.setBuffer(buffer)
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    31
          text_area.moveCaretPosition(offset)
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    32
        case None =>
3bc9a215a56d some support for hyperlinks between different buffers;
wenzelm
parents: 43661
diff changeset
    33
      }
34568
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
    34
  }
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
    35
}
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
    36
42327
7c7cc7590eb3 Name_Space.entry_markup: keep def position as separate properties;
wenzelm
parents: 39177
diff changeset
    37
class External_Hyperlink(start: Int, end: Int, line: Int, def_file: String, def_line: Int)
34569
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
    38
  extends AbstractHyperlink(start, end, line, "")
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
    39
{
34602
782b1948aca9 ExternalHyperlink.click: use IsabelleSystem.source_file provided in http://isabelle.in.tum.de/repos/isabelle/rev/dde1b4d1c95b
wenzelm
parents: 34588
diff changeset
    40
  override def click(view: View) = {
43661
39fdbd814c7f quasi-static Isabelle_System -- reduced tendency towards "functorial style";
wenzelm
parents: 43606
diff changeset
    41
    Isabelle_System.source_file(Path.explode(def_file)) match {
38853
f593754b0772 External_Hyperlink: proper error dialog;
wenzelm
parents: 38845
diff changeset
    42
      case None =>
42327
7c7cc7590eb3 Name_Space.entry_markup: keep def position as separate properties;
wenzelm
parents: 39177
diff changeset
    43
        Library.error_dialog(view, "File not found", "Could not find source file " + def_file)
34602
782b1948aca9 ExternalHyperlink.click: use IsabelleSystem.source_file provided in http://isabelle.in.tum.de/repos/isabelle/rev/dde1b4d1c95b
wenzelm
parents: 34588
diff changeset
    44
      case Some(file) =>
42327
7c7cc7590eb3 Name_Space.entry_markup: keep def position as separate properties;
wenzelm
parents: 39177
diff changeset
    45
        jEdit.openFiles(view, file.getParent, Array(file.getName, "+line:" + def_line))
34573
daa397b6401c changed handling of subdirectories
immler@in.tum.de
parents: 34569
diff changeset
    46
    }
34602
782b1948aca9 ExternalHyperlink.click: use IsabelleSystem.source_file provided in http://isabelle.in.tum.de/repos/isabelle/rev/dde1b4d1c95b
wenzelm
parents: 34588
diff changeset
    47
  }
34569
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
    48
}
15abc5f5f40a implemented links to other files
immler@in.tum.de
parents: 34568
diff changeset
    49
34760
dc7f5e0d9d27 misc modernization of names;
wenzelm
parents: 34759
diff changeset
    50
class Isabelle_Hyperlinks extends HyperlinkSource
34568
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
    51
{
38575
80d962964216 Isabelle_Hyperlinks: select relevant information directly from Markup_Tree, without intermediate RefInfo;
wenzelm
parents: 38427
diff changeset
    52
  def getHyperlink(buffer: Buffer, buffer_offset: Int): Hyperlink =
37175
be764a7adb10 eliminated hard tabs;
wenzelm
parents: 36990
diff changeset
    53
  {
38223
2a368e8e0a80 more explicit treatment of Swing thread context;
wenzelm
parents: 38153
diff changeset
    54
    Swing_Thread.assert()
38843
d95522496593 more careful locking of jEdit buffer;
wenzelm
parents: 38722
diff changeset
    55
    Isabelle.buffer_lock(buffer) {
d95522496593 more careful locking of jEdit buffer;
wenzelm
parents: 38722
diff changeset
    56
      Document_Model(buffer) match {
d95522496593 more careful locking of jEdit buffer;
wenzelm
parents: 38722
diff changeset
    57
        case Some(model) =>
d95522496593 more careful locking of jEdit buffer;
wenzelm
parents: 38722
diff changeset
    58
          val snapshot = model.snapshot()
38845
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38843
diff changeset
    59
          val markup =
45468
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    60
            snapshot.select_markup(Text.Range(buffer_offset, buffer_offset + 1))(
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    61
              Markup_Tree.Select[Hyperlink](
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    62
                {
45672
a497c5d4a523 clarified modules;
wenzelm
parents: 45666
diff changeset
    63
                  // FIXME Isabelle_Document.Hyperlink extractor
45468
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    64
                  case Text.Info(info_range,
45666
d83797ef0d2d separate module for concrete Isabelle markup;
wenzelm
parents: 45474
diff changeset
    65
                      XML.Elem(Markup(Isabelle_Markup.ENTITY, props), _))
45468
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    66
                    if (props.find(
45666
d83797ef0d2d separate module for concrete Isabelle markup;
wenzelm
parents: 45474
diff changeset
    67
                      { case (Markup.KIND, Isabelle_Markup.ML_OPEN) => true
d83797ef0d2d separate module for concrete Isabelle markup;
wenzelm
parents: 45474
diff changeset
    68
                        case (Markup.KIND, Isabelle_Markup.ML_STRUCT) => true
45468
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    69
                        case _ => false }).isEmpty) =>
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    70
                    val Text.Range(begin, end) = info_range
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    71
                    val line = buffer.getLineOfOffset(begin)
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    72
                    (Position.File.unapply(props), Position.Line.unapply(props)) match {
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    73
                      case (Some(def_file), Some(def_line)) =>
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    74
                        new External_Hyperlink(begin, end, line, def_file, def_line)
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    75
                      case _ if !snapshot.is_outdated =>
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    76
                        (props, props) match {
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    77
                          case (Position.Id(def_id), Position.Offset(def_offset)) =>
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    78
                            snapshot.state.find_command(snapshot.version, def_id) match {
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    79
                              case Some((def_node, def_cmd)) =>
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    80
                                def_node.command_start(def_cmd) match {
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    81
                                  case Some(def_cmd_start) =>
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    82
                                    new Internal_Hyperlink(def_cmd.node_name.node, begin, end, line,
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    83
                                      def_cmd_start + def_cmd.decode(def_offset))
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    84
                                  case None => null
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    85
                                }
38845
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38843
diff changeset
    86
                              case None => null
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38843
diff changeset
    87
                            }
45468
33e946d3f449 tuned signature;
wenzelm
parents: 44615
diff changeset
    88
                          case _ => null
38845
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38843
diff changeset
    89
                        }
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38843
diff changeset
    90
                      case _ => null
a9e37daf5bd0 added Document.Snapshot.select_markup, which includes command iteration, range conversion etc.;
wenzelm
parents: 38843
diff changeset
    91
                    }
45474
f793dd5d84b2 index markup elements for more efficient cumulate/select operations;
wenzelm
parents: 45468
diff changeset
    92
                },
45666
d83797ef0d2d separate module for concrete Isabelle markup;
wenzelm
parents: 45474
diff changeset
    93
                Some(Set(Isabelle_Markup.ENTITY))))
39177
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38853
diff changeset
    94
          markup match {
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38853
diff changeset
    95
            case Text.Info(_, Some(link)) #:: _ => link
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38853
diff changeset
    96
            case _ => null
0468964aec11 simplified Markup_Tree.select: Stream instead of Iterator (again), explicit Option instead of default;
wenzelm
parents: 38853
diff changeset
    97
          }
38843
d95522496593 more careful locking of jEdit buffer;
wenzelm
parents: 38722
diff changeset
    98
        case None => null
d95522496593 more careful locking of jEdit buffer;
wenzelm
parents: 38722
diff changeset
    99
      }
34568
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
   100
    }
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
   101
  }
b517d0607297 implemented IsabelleHyperlinkSource (only links inside the current buffer)
immler@in.tum.de
parents:
diff changeset
   102
}