src/Tools/VSCode/src/pretty_text_panel.scala
author wenzelm
Wed, 21 May 2025 22:03:53 +0200
changeset 82660 629fa9278081
parent 82192 7dc4aa407899
child 82720 956ecf2c07a0
permissions -rw-r--r--
merged
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     1
/*  Title:      Tools/VSCode/src/pretty_text_panel.scala
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     2
    Author:     Thomas Lindae, TU Muenchen
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     3
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     4
Pretty-printed text or HTML with decorations.
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     5
*/
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     6
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     7
package isabelle.vscode
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
     8
81084
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81064
diff changeset
     9
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    10
import isabelle._
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    11
81084
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81064
diff changeset
    12
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    13
object Pretty_Text_Panel {
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    14
  def apply(
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    15
    resources: VSCode_Resources,
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    16
    channel: Channel,
81060
159d1b09fe66 lsp: refactored conversion from Decoration_List to JSON;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81059
diff changeset
    17
    output: (String, Option[LSP.Decoration]) => JSON.T
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    18
  ): Pretty_Text_Panel = new Pretty_Text_Panel(resources, channel, output)
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    19
}
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    20
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    21
class Pretty_Text_Panel private(
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    22
  resources: VSCode_Resources,
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    23
  channel: Channel,
81398
f92ea68473f2 clarified signature with subtle change of semantics: output consists of individual messages that are formatted (and separated) internally;
wenzelm
parents: 81084
diff changeset
    24
  output_json: (String, Option[LSP.Decoration]) => JSON.T
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    25
) {
81398
f92ea68473f2 clarified signature with subtle change of semantics: output consists of individual messages that are formatted (and separated) internally;
wenzelm
parents: 81084
diff changeset
    26
  private var current_output: List[XML.Elem] = Nil
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    27
  private var current_formatted: XML.Body = Nil
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    28
  private var margin: Double = resources.message_margin
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    29
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    30
  private val delay_margin = Delay.last(resources.output_delay, channel.Error_Logger) {
81398
f92ea68473f2 clarified signature with subtle change of semantics: output consists of individual messages that are formatted (and separated) internally;
wenzelm
parents: 81084
diff changeset
    31
    refresh(current_output)
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    32
  }
81553
6dd6a6fa718b tuned whitespace;
wenzelm
parents: 81398
diff changeset
    33
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    34
  def update_margin(new_margin: Double): Unit = {
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    35
    margin = new_margin
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    36
    delay_margin.invoke()
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    37
  }
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    38
81398
f92ea68473f2 clarified signature with subtle change of semantics: output consists of individual messages that are formatted (and separated) internally;
wenzelm
parents: 81084
diff changeset
    39
  def refresh(output: List[XML.Elem]): Unit = {
f92ea68473f2 clarified signature with subtle change of semantics: output consists of individual messages that are formatted (and separated) internally;
wenzelm
parents: 81084
diff changeset
    40
    val formatted =
f92ea68473f2 clarified signature with subtle change of semantics: output consists of individual messages that are formatted (and separated) internally;
wenzelm
parents: 81084
diff changeset
    41
      Pretty.formatted(Pretty.separate(output), margin = margin, metric = Symbol.Metric)
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    42
82186
wenzelm
parents: 81558
diff changeset
    43
    if (formatted != current_formatted) {
wenzelm
parents: 81558
diff changeset
    44
      current_output = output
wenzelm
parents: 81558
diff changeset
    45
      current_formatted = formatted
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    46
82186
wenzelm
parents: 81558
diff changeset
    47
      if (resources.html_output) {
wenzelm
parents: 81558
diff changeset
    48
        val node_context =
wenzelm
parents: 81558
diff changeset
    49
          new Browser_Info.Node_Context {
wenzelm
parents: 81558
diff changeset
    50
            override def make_ref(props: Properties.T, body: XML.Body): Option[XML.Elem] =
wenzelm
parents: 81558
diff changeset
    51
              for {
wenzelm
parents: 81558
diff changeset
    52
                thy_file <- Position.Def_File.unapply(props)
wenzelm
parents: 81558
diff changeset
    53
                def_line <- Position.Def_Line.unapply(props)
82192
7dc4aa407899 proper File.standard_path for Windows: result of resources.source_file is platform_path (amending da1108a6d249);
wenzelm
parents: 82186
diff changeset
    54
                platform_path <- resources.source_file(thy_file)
7dc4aa407899 proper File.standard_path for Windows: result of resources.source_file is platform_path (amending da1108a6d249);
wenzelm
parents: 82186
diff changeset
    55
                uri = File.uri(Path.explode(File.standard_path(platform_path)).absolute_file)
82186
wenzelm
parents: 81558
diff changeset
    56
              } yield HTML.link(uri.toString + "#" + def_line, body)
wenzelm
parents: 81558
diff changeset
    57
          }
wenzelm
parents: 81558
diff changeset
    58
        val elements = Browser_Info.extra_elements.copy(entity = Markup.Elements.full)
wenzelm
parents: 81558
diff changeset
    59
        val html = node_context.make_html(elements, formatted)
wenzelm
parents: 81558
diff changeset
    60
        val message = output_json(HTML.source(html).toString, None)
wenzelm
parents: 81558
diff changeset
    61
        channel.write(message)
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    62
      }
82186
wenzelm
parents: 81558
diff changeset
    63
      else {
wenzelm
parents: 81558
diff changeset
    64
        def convert_symbols(body: XML.Body): XML.Body =
wenzelm
parents: 81558
diff changeset
    65
          body.map {
wenzelm
parents: 81558
diff changeset
    66
            case XML.Elem(markup, body) => XML.Elem(markup, convert_symbols(body))
wenzelm
parents: 81558
diff changeset
    67
            case XML.Text(content) => XML.Text(resources.output_text(content))
wenzelm
parents: 81558
diff changeset
    68
          }
81062
b2df8bf17071 lsp: created distinction for unicode symbols setting between output and edits and clarified output text functions;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81060
diff changeset
    69
82186
wenzelm
parents: 81558
diff changeset
    70
        val converted = convert_symbols(formatted)
wenzelm
parents: 81558
diff changeset
    71
wenzelm
parents: 81558
diff changeset
    72
        val tree = Markup_Tree.from_XML(converted)
wenzelm
parents: 81558
diff changeset
    73
        val text = XML.content(converted)
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    74
82186
wenzelm
parents: 81558
diff changeset
    75
        val document = Line.Document(text)
wenzelm
parents: 81558
diff changeset
    76
        val decorations =
wenzelm
parents: 81558
diff changeset
    77
          tree.cumulate[Option[Markup]](Text.Range.full, None, Rendering.text_color_elements,
wenzelm
parents: 81558
diff changeset
    78
            { case (_, m) => Some(Some(m.info.markup)) }
wenzelm
parents: 81558
diff changeset
    79
          ).flatMap(info =>
wenzelm
parents: 81558
diff changeset
    80
              info.info match {
wenzelm
parents: 81558
diff changeset
    81
                case Some(markup) =>
wenzelm
parents: 81558
diff changeset
    82
                  val range = document.range(info.range)
wenzelm
parents: 81558
diff changeset
    83
                  Some((range, "text_" + Rendering.get_text_color(markup).get.toString))
wenzelm
parents: 81558
diff changeset
    84
                case None => None
wenzelm
parents: 81558
diff changeset
    85
              }
wenzelm
parents: 81558
diff changeset
    86
          ).groupMap(_._2)(e => LSP.Decoration_Options(e._1, Nil)).toList
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    87
82186
wenzelm
parents: 81558
diff changeset
    88
        channel.write(output_json(text, Some(LSP.Decoration(decorations))))
wenzelm
parents: 81558
diff changeset
    89
      }
81054
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    90
    }
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    91
  }
4bfcb14547c6 lsp: added Pretty_Text_Panel module;
Thomas Lindae <thomas.lindae@in.tum.de>
parents:
diff changeset
    92
}