src/Tools/VSCode/src/vscode_rendering.scala
author wenzelm
Fri, 23 Dec 2016 19:19:59 +0100
changeset 64667 cdb0d559a24b
parent 64659 c64b258f6801
child 64668 39a6c88c059b
permissions -rw-r--r--
full range for Position.Item; more hyperlinks for VSCode;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     1
/*  Title:      Tools/VSCode/src/vscode_rendering.scala
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     3
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     4
Isabelle/VSCode-specific implementation of quasi-abstract rendering and
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     5
markup interpretation.
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     6
*/
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     7
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     8
package isabelle.vscode
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
     9
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    10
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    11
import isabelle._
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    12
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    13
object VSCode_Rendering
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    14
{
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    15
  private val hyperlink_elements =
64652
ad55f164ae0d VSCode already detects URLs from plain text;
wenzelm
parents: 64651
diff changeset
    16
    Markup.Elements(Markup.ENTITY, Markup.PATH, Markup.POSITION)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    17
}
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    18
64649
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    19
class VSCode_Rendering(
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    20
    val model: Document_Model,
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    21
    snapshot: Document.Snapshot,
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    22
    options: Options,
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    23
    text_length: Length,
64649
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    24
    resources: Resources)
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    25
  extends Rendering(snapshot, options, resources)
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    26
{
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    27
  /* tooltips */
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    28
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    29
  def tooltip_margin: Int = options.int("vscode_tooltip_margin")
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    30
  def timing_threshold: Double = options.real("vscode_timing_threshold")
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    31
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    32
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    33
  /* hyperlinks */
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    34
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    35
  def hyperlink_source_file(source_name: String, line1: Int, range: Symbol.Range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    36
    : Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    37
  {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    38
    for (name <- resources.source_file(source_name))
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    39
    yield {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    40
      val opt_text =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    41
        try { Some(File.read(Path.explode(name))) } // FIXME content from resources/models
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    42
        catch { case ERROR(_) => None }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    43
      Line.Node_Range(name,
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    44
        opt_text match {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    45
          case Some(text) if range.start > 0 =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    46
            val chunk = Symbol.Text_Chunk(text)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    47
            val doc = Line.Document(text)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    48
            def position(offset: Symbol.Offset) = doc.position(chunk.decode(offset), text_length)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    49
            Line.Range(position(range.start), position(range.stop))
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    50
          case _ =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    51
            Line.Range(Line.Position((line1 - 1) max 0))
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    52
        })
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    53
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    54
  }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    55
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    56
  def hyperlink_command(id: Document_ID.Generic, range: Symbol.Range): Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    57
  {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    58
    if (snapshot.is_outdated) None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    59
    else
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    60
      for {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    61
        start <- snapshot.find_command_position(id, range.start)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    62
        stop <- snapshot.find_command_position(id, range.stop)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    63
      } yield Line.Node_Range(start.name, Line.Range(start.pos, stop.pos))
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    64
  }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    65
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    66
  def hyperlink_position(pos: Position.T): Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    67
    pos match {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    68
      case Position.Item_File(name, line, range) => hyperlink_source_file(name, line, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    69
      case Position.Item_Id(id, range) => hyperlink_command(id, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    70
      case _ => None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    71
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    72
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    73
  def hyperlink_def_position(pos: Position.T): Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    74
    pos match {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    75
      case Position.Item_Def_File(name, line, range) => hyperlink_source_file(name, line, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    76
      case Position.Item_Def_Id(id, range) => hyperlink_command(id, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    77
      case _ => None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    78
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    79
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
    80
  def hyperlinks(range: Text.Range): List[Line.Node_Range] =
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    81
  {
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
    82
    snapshot.cumulate[List[Line.Node_Range]](
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    83
      range, Nil, VSCode_Rendering.hyperlink_elements, _ =>
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    84
        {
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    85
          case (links, Text.Info(_, XML.Elem(Markup.Path(name), _))) =>
64654
31b681e38c70 clarified signature;
wenzelm
parents: 64652
diff changeset
    86
            val file = resources.append_file_url(snapshot.node_name.master_dir, name)
31b681e38c70 clarified signature;
wenzelm
parents: 64652
diff changeset
    87
            Some(Line.Node_Range(file) :: links)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    88
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    89
          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.ENTITY, props), _))) =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    90
            hyperlink_def_position(props).map(_ :: links)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    91
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    92
          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.POSITION, props), _))) =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    93
            hyperlink_position(props).map(_ :: links)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    94
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    95
          case _ => None
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    96
        }) match { case Text.Info(_, links) :: _ => links.reverse case _ => Nil }
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    97
  }
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    98
}