src/Tools/VSCode/src/state_panel.scala
author Thomas Lindae <thomas.lindae@in.tum.de>
Mon, 01 Jul 2024 18:48:26 +0200
changeset 81028 84f6f17274d0
parent 81025 d4eb94b46e83
child 81029 f4cb1e35c63e
permissions -rw-r--r--
lsp: changed State_Init notification into a request and removed State_Init_Response;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
     1
/*  Title:      Tools/VSCode/src/state_panel.scala
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     3
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     4
Show proof state.
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     5
*/
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     6
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     7
package isabelle.vscode
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     8
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
     9
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    10
import isabelle._
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    11
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    12
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
    13
object State_Panel {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    14
  private val make_id = Counter.make()
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    15
  private val instances = Synchronized(Map.empty[Counter.ID, State_Panel])
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    16
81028
84f6f17274d0 lsp: changed State_Init notification into a request and removed State_Init_Response;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81025
diff changeset
    17
  def init(id: LSP.Id, server: Language_Server): Unit = {
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    18
    val instance = new State_Panel(server)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    19
    instances.change(_ + (instance.id -> instance))
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    20
    instance.init()
81028
84f6f17274d0 lsp: changed State_Init notification into a request and removed State_Init_Response;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81025
diff changeset
    21
    instance.init_response(id)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    22
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    23
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
    24
  def exit(id: Counter.ID): Unit = {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    25
    instances.change(map =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    26
      map.get(id) match {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    27
        case None => map
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    28
        case Some(instance) => instance.exit(); map - id
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    29
      })
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    30
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    31
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    32
  def locate(id: Counter.ID): Unit =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    33
    instances.value.get(id).foreach(state =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    34
      state.server.editor.send_dispatcher(state.locate()))
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    35
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    36
  def update(id: Counter.ID): Unit =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    37
    instances.value.get(id).foreach(state =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    38
      state.server.editor.send_dispatcher(state.update()))
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    39
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    40
  def auto_update(id: Counter.ID, enabled: Boolean): Unit =
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    41
    instances.value.get(id).foreach(state =>
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    42
      state.server.editor.send_dispatcher(state.auto_update(Some(enabled))))
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    43
}
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    44
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    45
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
    46
class State_Panel private(val server: Language_Server) {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    47
  /* output */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    48
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    49
  val id: Counter.ID = State_Panel.make_id()
81025
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    50
  private val margin: Double = 80
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    51
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    52
  private def output(content: String): Unit =
75126
da1108a6d249 various improvements to Isabelle/VSCode (by Denis Paluca and Fabian Huch);
wenzelm
parents: 73340
diff changeset
    53
    server.channel.write(LSP.State_Output(id, content, auto_update_enabled.value))
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    54
81028
84f6f17274d0 lsp: changed State_Init notification into a request and removed State_Init_Response;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81025
diff changeset
    55
  private def init_response(id: LSP.Id): Unit =
84f6f17274d0 lsp: changed State_Init notification into a request and removed State_Init_Response;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81025
diff changeset
    56
    server.channel.write(LSP.State_Init.reply(id, this.id))
81021
89bfada3a16d lsp: added State_Init_Response message;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 75979
diff changeset
    57
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    58
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    59
  /* query operation */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    60
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
    61
  private val output_active = Synchronized(true)
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
    62
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    63
  private val print_state =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    64
    new Query_Operation(server.editor, (), "print_state", _ => (),
75126
da1108a6d249 various improvements to Isabelle/VSCode (by Denis Paluca and Fabian Huch);
wenzelm
parents: 73340
diff changeset
    65
      (_, _, body) =>
81023
8602af6f4bd0 tuned formatting;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81021
diff changeset
    66
        if (output_active.value && body.nonEmpty) {
81025
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    67
          if (server.resources.html_output) {
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    68
            val node_context =
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    69
              new Browser_Info.Node_Context {
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    70
                override def make_ref(props: Properties.T, body: XML.Body): Option[XML.Elem] =
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    71
                  for {
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    72
                    thy_file <- Position.Def_File.unapply(props)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    73
                    def_line <- Position.Def_Line.unapply(props)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    74
                    source <- server.resources.source_file(thy_file)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    75
                    uri = File.uri(Path.explode(source).absolute_file)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    76
                  } yield HTML.link(uri.toString + "#" + def_line, body)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    77
              }
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    78
            val elements = Browser_Info.extra_elements.copy(entity = Markup.Elements.full)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    79
            val separate = Pretty.separate(body)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    80
            val formatted = Pretty.formatted(separate, margin = margin)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    81
            val html = node_context.make_html(elements, formatted)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    82
            output(HTML.source(html).toString)
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    83
          } else {
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    84
            output(server.resources.output_pretty(body, margin))
d4eb94b46e83 lsp: added State and Dynamic Output html_output and margin handling;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81023
diff changeset
    85
          }
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    86
        })
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    87
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
    88
  def locate(): Unit = print_state.locate_query()
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    89
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
    90
  def update(): Unit = {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    91
    server.editor.current_node_snapshot(()) match {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    92
      case Some(snapshot) =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    93
        (server.editor.current_command((), snapshot), print_state.get_location) match {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    94
          case (Some(command1), Some(command2)) if command1.id == command2.id =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    95
          case _ => print_state.apply_query(Nil)
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    96
        }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    97
      case None =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    98
    }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    99
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   100
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   101
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   102
  /* auto update */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   103
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   104
  private val auto_update_enabled = Synchronized(true)
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   105
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
   106
  def auto_update(set: Option[Boolean] = None): Unit = {
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   107
    val enabled =
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   108
      auto_update_enabled.guarded_access(a =>
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   109
        set match {
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   110
          case None => Some((a, a))
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   111
          case Some(b) => Some((b, b))
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   112
        })
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   113
    if (enabled) update()
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   114
  }
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   115
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   116
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   117
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   118
  /* main */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   119
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   120
  private val main =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   121
    Session.Consumer[Any](getClass.getName) {
66099
wenzelm
parents: 66098
diff changeset
   122
      case changed: Session.Commands_Changed =>
wenzelm
parents: 66098
diff changeset
   123
        if (changed.assignment) auto_update()
wenzelm
parents: 66098
diff changeset
   124
wenzelm
parents: 66098
diff changeset
   125
      case Session.Caret_Focus =>
wenzelm
parents: 66098
diff changeset
   126
        auto_update()
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   127
    }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   128
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
   129
  def init(): Unit = {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   130
    server.session.commands_changed += main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   131
    server.session.caret_focus += main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   132
    server.editor.send_wait_dispatcher { print_state.activate() }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   133
    server.editor.send_dispatcher { auto_update() }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   134
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   135
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
   136
  def exit(): Unit = {
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
   137
    output_active.change(_ => false)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   138
    server.session.commands_changed -= main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   139
    server.session.caret_focus -= main
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
   140
    server.editor.send_wait_dispatcher { print_state.deactivate() }
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   141
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   142
}