src/Tools/VSCode/src/vscode_rendering.scala
author wenzelm
Wed, 09 Dec 2020 15:14:24 +0100
changeset 72856 3a27e6f83ce1
parent 72761 4519eeefe3b5
child 72900 c9813630cca4
permissions -rw-r--r--
clarified signature;
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
65913
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
    15
import scala.annotation.tailrec
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
    16
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
    17
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    18
object VSCode_Rendering
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    19
{
65104
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    20
  /* decorations */
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    21
65122
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
    22
  private def color_decorations(prefix: String, types: Set[Rendering.Color.Value],
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    23
    colors: List[Text.Info[Rendering.Color.Value]]): List[VSCode_Model.Decoration] =
65104
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    24
  {
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    25
    val color_ranges =
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    26
      (Map.empty[Rendering.Color.Value, List[Text.Range]] /: colors) {
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    27
        case (m, Text.Info(range, c)) => m + (c -> (range :: m.getOrElse(c, Nil)))
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    28
      }
65105
1f47b92021de clarified signature;
wenzelm
parents: 65104
diff changeset
    29
    types.toList.map(c =>
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    30
      VSCode_Model.Decoration.ranges(prefix + c.toString, color_ranges.getOrElse(c, Nil).reverse))
65104
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    31
  }
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    32
65176
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65174
diff changeset
    33
  private val background_colors =
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65174
diff changeset
    34
    Rendering.Color.background_colors - Rendering.Color.active - Rendering.Color.active_result -
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65174
diff changeset
    35
      Rendering.Color.entity
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65174
diff changeset
    36
65122
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
    37
  private val dotted_colors =
65134
511bf19348d3 clarified messages (with improved scalability): legacy/error as diagnostics, writeln/information/warning/bad as tooltips (dynamic hover);
wenzelm
parents: 65122
diff changeset
    38
    Set(Rendering.Color.writeln, Rendering.Color.information, Rendering.Color.warning)
65122
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
    39
65104
66b19d05dcee decorations for background and foreground colors;
wenzelm
parents: 65095
diff changeset
    40
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    41
  /* diagnostic messages */
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    42
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    43
  private val message_severity =
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    44
    Map(
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    45
      Markup.LEGACY -> LSP.DiagnosticSeverity.Warning,
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    46
      Markup.ERROR -> LSP.DiagnosticSeverity.Error)
64679
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
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    49
  /* markup elements */
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    50
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    51
  private val diagnostics_elements =
65134
511bf19348d3 clarified messages (with improved scalability): legacy/error as diagnostics, writeln/information/warning/bad as tooltips (dynamic hover);
wenzelm
parents: 65122
diff changeset
    52
    Markup.Elements(Markup.LEGACY, Markup.ERROR)
65095
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
    53
65176
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65174
diff changeset
    54
  private val background_elements =
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65174
diff changeset
    55
    Rendering.background_elements - Markup.ENTITY -- Rendering.active_elements
908d8be90533 suppress irrelevant markup for VSCode;
wenzelm
parents: 65174
diff changeset
    56
65122
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
    57
  private val dotted_elements =
65134
511bf19348d3 clarified messages (with improved scalability): legacy/error as diagnostics, writeln/information/warning/bad as tooltips (dynamic hover);
wenzelm
parents: 65122
diff changeset
    58
    Markup.Elements(Markup.WRITELN, Markup.INFORMATION, Markup.WARNING)
65122
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
    59
65134
511bf19348d3 clarified messages (with improved scalability): legacy/error as diagnostics, writeln/information/warning/bad as tooltips (dynamic hover);
wenzelm
parents: 65122
diff changeset
    60
  val tooltip_elements =
511bf19348d3 clarified messages (with improved scalability): legacy/error as diagnostics, writeln/information/warning/bad as tooltips (dynamic hover);
wenzelm
parents: 65122
diff changeset
    61
    Markup.Elements(Markup.WRITELN, Markup.INFORMATION, Markup.WARNING, Markup.BAD) ++
511bf19348d3 clarified messages (with improved scalability): legacy/error as diagnostics, writeln/information/warning/bad as tooltips (dynamic hover);
wenzelm
parents: 65122
diff changeset
    62
    Rendering.tooltip_elements
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
    63
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    64
  private val hyperlink_elements =
64833
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
    65
    Markup.Elements(Markup.ENTITY, Markup.PATH, Markup.POSITION, Markup.CITATION)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
    66
}
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    67
72856
3a27e6f83ce1 clarified signature;
wenzelm
parents: 72761
diff changeset
    68
class VSCode_Rendering(snapshot: Document.Snapshot, val model: VSCode_Model)
3a27e6f83ce1 clarified signature;
wenzelm
parents: 72761
diff changeset
    69
  extends Rendering(snapshot, model.resources.options, model.session)
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
    70
{
66054
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
    71
  rendering =>
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
    72
66143
51f74025a3e3 tuned signature;
wenzelm
parents: 66142
diff changeset
    73
  def resources: VSCode_Resources = model.resources
66114
c137a9f038a6 clarified signature;
wenzelm
parents: 66057
diff changeset
    74
72856
3a27e6f83ce1 clarified signature;
wenzelm
parents: 72761
diff changeset
    75
  override def get_text(range: Text.Range): Option[String] = model.get_text(range)
3a27e6f83ce1 clarified signature;
wenzelm
parents: 72761
diff changeset
    76
66054
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
    77
66152
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    78
  /* bibtex */
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    79
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    80
  def bibtex_entries_iterator(): Iterator[Text.Info[(String, VSCode_Model)]] =
66152
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    81
    Bibtex.entries_iterator(resources.get_models)
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    82
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    83
  def bibtex_completion(history: Completion.History, caret: Text.Offset): Option[Completion.Result] =
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    84
    Bibtex.completion(history, rendering, caret, resources.get_models)
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    85
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
    86
64877
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
    87
  /* completion */
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
    88
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    89
  def completion(caret_pos: Line.Position, caret: Text.Offset): List[LSP.CompletionItem] =
66054
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
    90
  {
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
    91
    val doc = model.content.doc
66057
wenzelm
parents: 66055
diff changeset
    92
    val line = caret_pos.line
wenzelm
parents: 66055
diff changeset
    93
    doc.offset(Line.Position(line)) match {
wenzelm
parents: 66055
diff changeset
    94
      case None => Nil
wenzelm
parents: 66055
diff changeset
    95
      case Some(line_start) =>
wenzelm
parents: 66055
diff changeset
    96
        val history = Completion.History.empty
wenzelm
parents: 66055
diff changeset
    97
        val caret_range = before_caret_range(caret)
66054
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
    98
66057
wenzelm
parents: 66055
diff changeset
    99
        val syntax = model.syntax()
wenzelm
parents: 66055
diff changeset
   100
        val syntax_completion =
67005
11fca474d87a tuned signature;
wenzelm
parents: 66235
diff changeset
   101
          syntax.complete(history, unicode = false, explicit = true,
66057
wenzelm
parents: 66055
diff changeset
   102
            line_start, doc.lines(line).text, caret - line_start,
wenzelm
parents: 66055
diff changeset
   103
            language_context(caret_range) getOrElse syntax.language_context)
64877
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   104
66057
wenzelm
parents: 66055
diff changeset
   105
        val (no_completion, semantic_completion) =
wenzelm
parents: 66055
diff changeset
   106
          rendering.semantic_completion_result(
66114
c137a9f038a6 clarified signature;
wenzelm
parents: 66057
diff changeset
   107
            history, false, syntax_completion.map(_.range), caret_range)
66054
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
   108
66057
wenzelm
parents: 66055
diff changeset
   109
        if (no_completion) Nil
wenzelm
parents: 66055
diff changeset
   110
        else {
66121
070f2be51330 added spell-checker completion;
wenzelm
parents: 66117
diff changeset
   111
          val results =
66157
cb57fcdbaf70 tuned signature;
wenzelm
parents: 66153
diff changeset
   112
            Completion.Result.merge(history,
66151
26eecd42cbc5 tuned signature;
wenzelm
parents: 66150
diff changeset
   113
              semantic_completion,
26eecd42cbc5 tuned signature;
wenzelm
parents: 66150
diff changeset
   114
              syntax_completion,
66153
236339f97a88 more completion;
wenzelm
parents: 66152
diff changeset
   115
              VSCode_Spell_Checker.completion(rendering, caret),
66159
907720561c82 more completion;
wenzelm
parents: 66157
diff changeset
   116
              path_completion(caret),
66153
236339f97a88 more completion;
wenzelm
parents: 66152
diff changeset
   117
              bibtex_completion(history, caret))
66142
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   118
          val items =
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   119
            results match {
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   120
              case None => Nil
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   121
              case Some(result) =>
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   122
                result.items.map(item =>
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   123
                  LSP.CompletionItem(
66142
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   124
                    label = item.replacement,
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   125
                    detail = Some(item.description.mkString(" ")),
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   126
                    range = Some(doc.range(item.range))))
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   127
            }
90629b166203 proper treatment of empty result;
wenzelm
parents: 66141
diff changeset
   128
          items ::: VSCode_Spell_Checker.menu_items(rendering, caret)
66057
wenzelm
parents: 66055
diff changeset
   129
        }
66054
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
   130
    }
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
   131
  }
fb0eea226a4d more uniform syntax_completion + semantic_completion;
wenzelm
parents: 65925
diff changeset
   132
64877
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   133
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   134
  /* diagnostics */
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   135
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   136
  def diagnostics: List[Text.Info[Command.Results]] =
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   137
    snapshot.cumulate[Command.Results](
67824
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   138
      model.content.text_range, Command.Results.empty, VSCode_Rendering.diagnostics_elements,
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   139
        command_states =>
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   140
          {
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   141
            case (res, Text.Info(_, msg @ XML.Elem(Markup(Markup.BAD, Markup.Serial(i)), body)))
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   142
            if body.nonEmpty => Some(res + (i -> msg))
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   143
67824
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   144
            case (res, Text.Info(_, msg)) =>
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   145
              Command.State.get_result_proper(command_states, msg.markup.properties).map(res + _)
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   146
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   147
            case _ => None
661cd25304ae more compact markup tree: output messages are already stored in command results (e.g. relevant for XML data representation);
wenzelm
parents: 67005
diff changeset
   148
          }).filterNot(info => info.info.is_empty)
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   149
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   150
  def diagnostics_output(results: List[Text.Info[Command.Results]]): List[LSP.Diagnostic] =
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   151
  {
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   152
    (for {
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   153
      Text.Info(text_range, res) <- results.iterator
64830
9bc44bef99e6 more explocit Document_Model.Content;
wenzelm
parents: 64821
diff changeset
   154
      range = model.content.doc.range(text_range)
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   155
      (_, XML.Elem(Markup(name, _), body)) <- res.iterator
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   156
    } yield {
66143
51f74025a3e3 tuned signature;
wenzelm
parents: 66142
diff changeset
   157
      val message = resources.output_pretty_message(body)
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   158
      val severity = VSCode_Rendering.message_severity.get(name)
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   159
      LSP.Diagnostic(range, message, severity = severity)
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   160
    }).toList
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   161
  }
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   162
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64668
diff changeset
   163
65146
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   164
  /* text color */
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   165
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   166
  def text_color(range: Text.Range): List[Text.Info[Rendering.Color.Value]] =
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   167
  {
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   168
    snapshot.select(range, Rendering.text_color_elements, _ =>
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   169
      {
65174
c0388fbd8096 avoid extra decorations for regular command keywords;
wenzelm
parents: 65173
diff changeset
   170
        case Text.Info(_, XML.Elem(Markup(name, props), _)) =>
c0388fbd8096 avoid extra decorations for regular command keywords;
wenzelm
parents: 65173
diff changeset
   171
          if (name != Markup.IMPROPER && props.contains((Markup.KIND, Markup.COMMAND))) None
c0388fbd8096 avoid extra decorations for regular command keywords;
wenzelm
parents: 65173
diff changeset
   172
          else Rendering.text_color.get(name)
65146
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   173
      })
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   174
  }
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   175
69ea3f1715be decorations for text color;
wenzelm
parents: 65143
diff changeset
   176
65913
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   177
  /* text overview color */
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   178
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   179
  private sealed case class Color_Info(
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   180
    color: Rendering.Color.Value, offset: Text.Offset, end_offset: Text.Offset, end_line: Int)
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   181
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   182
  def text_overview_color: List[Text.Info[Rendering.Color.Value]] =
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   183
  {
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   184
    @tailrec def loop(offset: Text.Offset, line: Int, lines: List[Line], colors: List[Color_Info])
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   185
      : List[Text.Info[Rendering.Color.Value]] =
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   186
    {
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   187
      if (lines.nonEmpty) {
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   188
        val end_offset = offset + lines.head.text.length
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   189
        val colors1 =
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   190
          (overview_color(Text.Range(offset, end_offset)), colors) match {
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   191
            case (Some(color), old :: rest) if color == old.color && line == old.end_line =>
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   192
              old.copy(end_offset = end_offset, end_line = line + 1) :: rest
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   193
            case (Some(color), _) =>
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   194
              Color_Info(color, offset, end_offset, line + 1) :: colors
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   195
            case (None, _) => colors
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   196
          }
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   197
        loop(end_offset + 1, line + 1, lines.tail, colors1)
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   198
      }
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   199
      else {
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   200
        colors.reverse.map(info =>
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   201
          Text.Info(Text.Range(info.offset, info.end_offset), info.color))
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   202
      }
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   203
    }
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   204
    loop(0, 0, model.content.doc.lines, Nil)
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   205
  }
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   206
f330f538dae6 support text overview colors via decorations;
wenzelm
parents: 65488
diff changeset
   207
65122
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
   208
  /* dotted underline */
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
   209
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
   210
  def dotted(range: Text.Range): List[Text.Info[Rendering.Color.Value]] =
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
   211
    message_underline_color(VSCode_Rendering.dotted_elements, range)
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
   212
1edb570f5b17 decorations for dotted underline: less intrusive;
wenzelm
parents: 65120
diff changeset
   213
65095
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   214
  /* decorations */
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   215
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   216
  def decorations: List[VSCode_Model.Decoration] = // list of canonical length and order
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   217
    Par_List.map((f: () => List[VSCode_Model.Decoration]) => f(),
65925
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   218
      List(
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   219
        () =>
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   220
          VSCode_Rendering.color_decorations("background_", VSCode_Rendering.background_colors,
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   221
            background(VSCode_Rendering.background_elements, model.content.text_range, Set.empty)),
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   222
        () =>
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   223
          VSCode_Rendering.color_decorations("foreground_", Rendering.Color.foreground_colors,
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   224
            foreground(model.content.text_range)),
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   225
        () =>
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   226
          VSCode_Rendering.color_decorations("text_", Rendering.Color.text_colors,
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   227
            text_color(model.content.text_range)),
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   228
        () =>
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   229
          VSCode_Rendering.color_decorations("text_overview_", Rendering.Color.text_overview_colors,
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   230
            text_overview_color),
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   231
        () =>
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   232
          VSCode_Rendering.color_decorations("dotted_", VSCode_Rendering.dotted_colors,
4a1b666b6362 parallel retrieval of PIDE markup;
wenzelm
parents: 65913
diff changeset
   233
            dotted(model.content.text_range)))).flatten :::
66141
81c8bb1d33b9 clarified modules;
wenzelm
parents: 66140
diff changeset
   234
    List(VSCode_Spell_Checker.decoration(rendering))
65095
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   235
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   236
  def decoration_output(decoration: VSCode_Model.Decoration): LSP.Decoration =
65095
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   237
  {
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   238
    val content =
65105
1f47b92021de clarified signature;
wenzelm
parents: 65104
diff changeset
   239
      for (Text.Info(text_range, msgs) <- decoration.content)
65095
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   240
      yield {
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   241
        val range = model.content.doc.range(text_range)
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   242
        LSP.DecorationOpts(range,
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   243
          msgs.map(msg => LSP.MarkedString(resources.output_pretty_tooltip(msg))))
65095
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   244
      }
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
   245
    LSP.Decoration(decoration.typ, content)
65095
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   246
  }
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   247
eb21a4f70b0e publish decorations like diagnostics;
wenzelm
parents: 64877
diff changeset
   248
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
   249
  /* tooltips */
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
   250
69898
990c6e8faf2c tuned signature;
wenzelm
parents: 69256
diff changeset
   251
  override def timing_threshold: Double = options.real("vscode_timing_threshold")
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   252
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   253
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   254
  /* hyperlinks */
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   255
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   256
  def hyperlink_source_file(source_name: String, line1: Int, range: Symbol.Range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   257
    : Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   258
  {
64775
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64762
diff changeset
   259
    for {
66143
51f74025a3e3 tuned signature;
wenzelm
parents: 66142
diff changeset
   260
      platform_path <- resources.source_file(source_name)
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
   261
      file <-
66235
d4fa51e7c4ff retain symlinks in file names from VSCode: relevant for proper file locations in decorations etc.;
wenzelm
parents: 66234
diff changeset
   262
        (try { Some(File.absolute(new JFile(platform_path))) }
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
   263
         catch { case ERROR(_) => None })
64775
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64762
diff changeset
   264
    }
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   265
    yield {
64778
7884a19de325 proper interpretation of Resources.source_file as platform file;
wenzelm
parents: 64777
diff changeset
   266
      Line.Node_Range(file.getPath,
64841
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   267
        if (range.start > 0) {
69256
c78c95d2a3d1 more uniform read_file_content for Isabelle/jEdit and Isabelle/VSCode: make_theory_content is required for semantic checking of user file-formats (e.g. bibtex);
wenzelm
parents: 67824
diff changeset
   268
          resources.get_file_content(resources.node_name(file)) match {
64841
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   269
            case Some(text) =>
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   270
              val chunk = Symbol.Text_Chunk(text)
65196
e8760a98db78 discontinued pointless Text.Length: Javascript and Java agree in old-fashioned UTF-16;
wenzelm
parents: 65176
diff changeset
   271
              val doc = Line.Document(text)
64841
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   272
              doc.range(chunk.decode(range))
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   273
            case _ =>
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   274
              Line.Range(Line.Position((line1 - 1) max 0))
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   275
          }
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   276
        }
d53696aed874 added node_name(String): imitate jEdit buffer operations;
wenzelm
parents: 64833
diff changeset
   277
        else Line.Range(Line.Position((line1 - 1) max 0)))
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   278
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   279
  }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   280
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   281
  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
   282
  {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   283
    if (snapshot.is_outdated) None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   284
    else
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   285
      for {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   286
        start <- snapshot.find_command_position(id, range.start)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   287
        stop <- snapshot.find_command_position(id, range.stop)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   288
      } yield Line.Node_Range(start.name, Line.Range(start.pos, stop.pos))
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   289
  }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   290
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   291
  def hyperlink_position(pos: Position.T): Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   292
    pos match {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   293
      case Position.Item_File(name, line, range) => hyperlink_source_file(name, line, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   294
      case Position.Item_Id(id, range) => hyperlink_command(id, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   295
      case _ => None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   296
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   297
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   298
  def hyperlink_def_position(pos: Position.T): Option[Line.Node_Range] =
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   299
    pos match {
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   300
      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
   301
      case Position.Item_Def_Id(id, range) => hyperlink_command(id, range)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   302
      case _ => None
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   303
    }
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   304
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
   305
  def hyperlinks(range: Text.Range): List[Line.Node_Range] =
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   306
  {
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
   307
    snapshot.cumulate[List[Line.Node_Range]](
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   308
      range, Nil, VSCode_Rendering.hyperlink_elements, _ =>
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   309
        {
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   310
          case (links, Text.Info(_, XML.Elem(Markup.Path(name), _))) =>
65488
331f09d9535e tuned signature;
wenzelm
parents: 65487
diff changeset
   311
            val file = perhaps_append_file(snapshot.node_name, name)
64654
31b681e38c70 clarified signature;
wenzelm
parents: 64652
diff changeset
   312
            Some(Line.Node_Range(file) :: links)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   313
64667
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   314
          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.ENTITY, props), _))) =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   315
            hyperlink_def_position(props).map(_ :: links)
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   316
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   317
          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.POSITION, props), _))) =>
cdb0d559a24b full range for Position.Item;
wenzelm
parents: 64659
diff changeset
   318
            hyperlink_position(props).map(_ :: links)
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   319
64833
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
   320
          case (links, Text.Info(info_range, XML.Elem(Markup.Citation(name), _))) =>
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
   321
            val iterator =
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
   322
              for {
66152
18e1aba549f6 tuned signature;
wenzelm
parents: 66151
diff changeset
   323
                Text.Info(entry_range, (entry, model)) <- bibtex_entries_iterator()
64833
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
   324
                if entry == name
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
   325
              } yield Line.Node_Range(model.node_name.node, model.content.doc.range(entry_range))
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
   326
            if (iterator.isEmpty) None else Some((links /: iterator)(_ :+ _))
0f410e3b1d20 support for bibtex entries;
wenzelm
parents: 64830
diff changeset
   327
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   328
          case _ => None
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   329
        }) match { case Text.Info(_, links) :: _ => links.reverse case _ => Nil }
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64622
diff changeset
   330
  }
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents:
diff changeset
   331
}