src/Tools/VSCode/src/vscode_rendering.scala
author wenzelm
Sun, 08 Jan 2017 12:00:37 +0100
changeset 64830 9bc44bef99e6
parent 64821 37bf7acf6a4b
child 64833 0f410e3b1d20
permissions -rw-r--r--
more explocit Document_Model.Content;
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
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
    13
import java.io.{File => JFile}
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
    14
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
    15
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    16
object VSCode_Rendering
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    17
{
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    18
  /* diagnostic messages */
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    19
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    20
  private val message_severity =
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    21
    Map(
64762
cd545bec3fd0 clarified message severity, based on empirical observation of VSCode 1.8.1;
wenzelm
parents: 64759
diff changeset
    22
      Markup.WRITELN -> Protocol.DiagnosticSeverity.Information,
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    23
      Markup.INFORMATION -> Protocol.DiagnosticSeverity.Information,
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    24
      Markup.WARNING -> Protocol.DiagnosticSeverity.Warning,
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    25
      Markup.LEGACY -> Protocol.DiagnosticSeverity.Warning,
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    26
      Markup.ERROR -> Protocol.DiagnosticSeverity.Error,
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    27
      Markup.BAD -> Protocol.DiagnosticSeverity.Error)
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    28
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    29
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    30
  /* markup elements */
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    31
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    32
  private val diagnostics_elements =
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    33
    Markup.Elements(Markup.WRITELN, Markup.INFORMATION, Markup.WARNING, Markup.LEGACY, Markup.ERROR,
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    34
      Markup.BAD)
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    35
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    36
  private val hyperlink_elements =
64652
ad55f164ae0d VSCode already detects URLs from plain text;
wenzelm
parents: 64651
diff changeset
    37
    Markup.Elements(Markup.ENTITY, Markup.PATH, Markup.POSITION)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    38
}
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    39
64649
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    40
class VSCode_Rendering(
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    41
    val model: Document_Model,
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
    42
    snapshot: Document.Snapshot,
64702
d95b9117cb5b re-use resources from session;
wenzelm
parents: 64688
diff changeset
    43
    resources: VSCode_Resources)
64704
08c2d80428ff re-use options from resources;
wenzelm
parents: 64702
diff changeset
    44
  extends Rendering(snapshot, resources.options, resources)
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    45
{
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    46
  /* diagnostics */
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    47
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    48
  def diagnostics: List[Text.Info[Command.Results]] =
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    49
    snapshot.cumulate[Command.Results](
64830
9bc44bef99e6 more explocit Document_Model.Content;
wenzelm
parents: 64821
diff changeset
    50
      model.content.text_range, Command.Results.empty, VSCode_Rendering.diagnostics_elements, _ =>
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    51
      {
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    52
        case (res, Text.Info(_, msg @ XML.Elem(Markup(_, Markup.Serial(i)), body)))
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    53
        if body.nonEmpty => Some(res + (i -> msg))
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    54
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    55
        case _ => None
64802
adc4c84b692c suppress empty results;
wenzelm
parents: 64779
diff changeset
    56
      }).filterNot(info => info.info.is_empty)
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    57
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    58
  val diagnostics_margin = options.int("vscode_diagnostics_margin")
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    59
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    60
  def diagnostics_output(results: List[Text.Info[Command.Results]]): List[Protocol.Diagnostic] =
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    61
  {
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    62
    (for {
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    63
      Text.Info(text_range, res) <- results.iterator
64830
9bc44bef99e6 more explocit Document_Model.Content;
wenzelm
parents: 64821
diff changeset
    64
      range = model.content.doc.range(text_range)
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    65
      (_, XML.Elem(Markup(name, _), body)) <- res.iterator
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    66
    } yield {
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    67
      val message = Pretty.string_of(body, margin = diagnostics_margin)
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    68
      val severity = VSCode_Rendering.message_severity.get(name)
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    69
      Protocol.Diagnostic(range, message, severity = severity)
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    70
    }).toList
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    71
  }
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    72
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    73
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    74
  /* tooltips */
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    75
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    76
  def tooltip_margin: Int = options.int("vscode_tooltip_margin")
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    77
  def timing_threshold: Double = options.real("vscode_timing_threshold")
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    78
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    79
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    80
  /* hyperlinks */
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    81
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    82
  def hyperlink_source_file(source_name: String, line1: Int, range: Symbol.Range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    83
    : Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    84
  {
64775
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64762
diff changeset
    85
    for {
64779
wenzelm
parents: 64778
diff changeset
    86
      platform_path <- resources.source_file(source_name)
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
    87
      file <-
64779
wenzelm
parents: 64778
diff changeset
    88
        (try { Some(new JFile(platform_path).getCanonicalFile) }
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
    89
         catch { case ERROR(_) => None })
64775
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64762
diff changeset
    90
    }
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    91
    yield {
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
    92
      Line.Node_Range(file.getPath,
64779
wenzelm
parents: 64778
diff changeset
    93
        resources.get_file_content(file) match {
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    94
          case Some(text) if range.start > 0 =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    95
            val chunk = Symbol.Text_Chunk(text)
64706
wenzelm
parents: 64704
diff changeset
    96
            val doc = Line.Document(text, resources.text_length)
64683
c0c09b6dfbe0 clarified signature: maintan Text.Length within Line.Document;
wenzelm
parents: 64679
diff changeset
    97
            doc.range(chunk.decode(range))
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    98
          case _ =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
    99
            Line.Range(Line.Position((line1 - 1) max 0))
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   100
        })
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   101
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   102
  }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   103
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   104
  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
   105
  {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   106
    if (snapshot.is_outdated) None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   107
    else
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   108
      for {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   109
        start <- snapshot.find_command_position(id, range.start)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   110
        stop <- snapshot.find_command_position(id, range.stop)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   111
      } yield Line.Node_Range(start.name, Line.Range(start.pos, stop.pos))
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   112
  }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   113
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   114
  def hyperlink_position(pos: Position.T): Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   115
    pos match {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   116
      case Position.Item_File(name, line, range) => hyperlink_source_file(name, line, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   117
      case Position.Item_Id(id, range) => hyperlink_command(id, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   118
      case _ => None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   119
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   120
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   121
  def hyperlink_def_position(pos: Position.T): Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   122
    pos match {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   123
      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
   124
      case Position.Item_Def_Id(id, range) => hyperlink_command(id, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   125
      case _ => None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   126
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   127
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
   128
  def hyperlinks(range: Text.Range): List[Line.Node_Range] =
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   129
  {
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
   130
    snapshot.cumulate[List[Line.Node_Range]](
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   131
      range, Nil, VSCode_Rendering.hyperlink_elements, _ =>
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   132
        {
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   133
          case (links, Text.Info(_, XML.Elem(Markup.Path(name), _))) =>
64759
100941134718 clarified master_dir: file-URL;
wenzelm
parents: 64730
diff changeset
   134
            val file = resources.append_file(snapshot.node_name.master_dir, name)
64654
31b681e38c70 clarified signature;
wenzelm
parents: 64652
diff changeset
   135
            Some(Line.Node_Range(file) :: links)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   136
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   137
          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.ENTITY, props), _))) =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   138
            hyperlink_def_position(props).map(_ :: links)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   139
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   140
          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.POSITION, props), _))) =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   141
            hyperlink_position(props).map(_ :: links)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   142
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   143
          case _ => None
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   144
        }) match { case Text.Info(_, links) :: _ => links.reverse case _ => Nil }
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   145
  }
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
   146
}