src/Tools/VSCode/src/state_panel.scala
author wenzelm
Sat, 22 Mar 2025 23:03:11 +0100
changeset 82320 8d9b5289304c
parent 81394 95b53559af80
child 82757 9fea73244f06
permissions -rw-r--r--
discontinue macOS 11 Big Sur; update test machines;
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))))
81029
f4cb1e35c63e lsp: added Output_Set_Margin and State_Set_Margin Notifications;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81028
diff changeset
    43
f4cb1e35c63e lsp: added Output_Set_Margin and State_Set_Margin Notifications;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81028
diff changeset
    44
  def set_margin(id: Counter.ID, margin: Double): Unit =
f4cb1e35c63e lsp: added Output_Set_Margin and State_Set_Margin Notifications;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81028
diff changeset
    45
    instances.value.get(id).foreach(state => {
81056
ccbddf0372c4 lsp: converted state panel to use a pretty text panel;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81051
diff changeset
    46
      state.pretty_panel.value.update_margin(margin)
81029
f4cb1e35c63e lsp: added Output_Set_Margin and State_Set_Margin Notifications;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81028
diff changeset
    47
    })
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    48
}
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    49
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    50
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
    51
class State_Panel private(val server: Language_Server) {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    52
  /* output */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    53
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    54
  val id: Counter.ID = State_Panel.make_id()
81042
f1e0ca5aaa6b lsp: added decorations to state updates;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81036
diff changeset
    55
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
    56
  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
    57
    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
    58
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    59
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    60
  /* query operation */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    61
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
    62
  private val output_active = Synchronized(true)
81084
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81059
diff changeset
    63
  private val pretty_panel =
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81059
diff changeset
    64
    Synchronized(Pretty_Text_Panel(
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81059
diff changeset
    65
      server.resources,
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81059
diff changeset
    66
      server.channel,
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81059
diff changeset
    67
      (content, decorations) =>
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81059
diff changeset
    68
        LSP.State_Output(id, content, auto_update_enabled.value, decorations)
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81059
diff changeset
    69
    ))
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
    70
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    71
  private val print_state =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    72
    new Query_Operation(server.editor, (), "print_state", _ => (),
81394
95b53559af80 clarified signature;
wenzelm
parents: 81084
diff changeset
    73
      (_, _, output) =>
95b53559af80 clarified signature;
wenzelm
parents: 81084
diff changeset
    74
        if (output_active.value && output.nonEmpty) {
95b53559af80 clarified signature;
wenzelm
parents: 81084
diff changeset
    75
          pretty_panel.value.refresh(output)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    76
        })
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    77
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
    78
  def locate(): Unit = print_state.locate_query()
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    79
81056
ccbddf0372c4 lsp: converted state panel to use a pretty text panel;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81051
diff changeset
    80
  def update(): Unit = {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    81
    server.editor.current_node_snapshot(()) match {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    82
      case Some(snapshot) =>
81056
ccbddf0372c4 lsp: converted state panel to use a pretty text panel;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81051
diff changeset
    83
        (server.editor.current_command((), snapshot), print_state.get_location) match {
ccbddf0372c4 lsp: converted state panel to use a pretty text panel;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81051
diff changeset
    84
          case (Some(command1), Some(command2)) if command1.id == command2.id =>
ccbddf0372c4 lsp: converted state panel to use a pretty text panel;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81051
diff changeset
    85
          case _ => print_state.apply_query(Nil)
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
      case None =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    88
    }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    89
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    90
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    91
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    92
  /* auto update */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    93
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    94
  private val auto_update_enabled = Synchronized(true)
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    95
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
    96
  def auto_update(set: Option[Boolean] = None): Unit = {
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    97
    val enabled =
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    98
      auto_update_enabled.guarded_access(a =>
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    99
        set match {
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   100
          case None => Some((a, a))
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   101
          case Some(b) => Some((b, b))
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   102
        })
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   103
    if (enabled) update()
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   104
  }
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   105
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   106
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   107
  /* main */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   108
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   109
  private val main =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   110
    Session.Consumer[Any](getClass.getName) {
66099
wenzelm
parents: 66098
diff changeset
   111
      case changed: Session.Commands_Changed =>
wenzelm
parents: 66098
diff changeset
   112
        if (changed.assignment) auto_update()
wenzelm
parents: 66098
diff changeset
   113
wenzelm
parents: 66098
diff changeset
   114
      case Session.Caret_Focus =>
wenzelm
parents: 66098
diff changeset
   115
        auto_update()
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   116
    }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   117
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
   118
  def init(): Unit = {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   119
    server.session.commands_changed += main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   120
    server.session.caret_focus += main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   121
    server.editor.send_wait_dispatcher { print_state.activate() }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   122
    server.editor.send_dispatcher { auto_update() }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   123
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   124
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75154
diff changeset
   125
  def exit(): Unit = {
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
   126
    output_active.change(_ => false)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   127
    server.session.commands_changed -= main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   128
    server.session.caret_focus -= main
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
   129
    server.editor.send_wait_dispatcher { print_state.deactivate() }
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   130
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   131
}