src/Tools/VSCode/src/state_panel.scala
author wenzelm
Mon, 21 Feb 2022 20:50:01 +0100
changeset 75119 7bf685cbc789
parent 73340 0ffcad1f6130
child 75126 da1108a6d249
permissions -rw-r--r--
HTTP view of Isabelle PDF documentation;
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
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    13
object State_Panel
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    14
{
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    15
  private val make_id = Counter.make()
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    16
  private val instances = Synchronized(Map.empty[Counter.ID, State_Panel])
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    17
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
    18
  def init(server: Language_Server): Unit =
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    19
  {
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    20
    val instance = new State_Panel(server)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    21
    instances.change(_ + (instance.id -> instance))
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    22
    instance.init()
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    23
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    24
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
    25
  def exit(id: Counter.ID): Unit =
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    26
  {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    27
    instances.change(map =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    28
      map.get(id) match {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    29
        case None => map
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    30
        case Some(instance) => instance.exit(); map - id
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    31
      })
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    32
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    33
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    34
  def locate(id: Counter.ID): Unit =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    35
    instances.value.get(id).foreach(state =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    36
      state.server.editor.send_dispatcher(state.locate()))
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    37
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    38
  def update(id: Counter.ID): Unit =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    39
    instances.value.get(id).foreach(state =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    40
      state.server.editor.send_dispatcher(state.update()))
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    41
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    42
  def auto_update(id: Counter.ID, enabled: Boolean): Unit =
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    43
    instances.value.get(id).foreach(state =>
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    44
      state.server.editor.send_dispatcher(state.auto_update(Some(enabled))))
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    45
}
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    46
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    47
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    48
class State_Panel private(val server: Language_Server)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    49
{
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    50
  /* output */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    51
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
    52
  val id: Counter.ID = State_Panel.make_id()
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    53
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    54
  private def output(content: String): Unit =
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 71774
diff changeset
    55
    server.channel.write(LSP.State_Output(id, content))
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    56
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    57
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    58
  /* query operation */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    59
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
    60
  private val output_active = Synchronized(true)
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
    61
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    62
  private val print_state =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    63
    new Query_Operation(server.editor, (), "print_state", _ => (),
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    64
      (snapshot, results, body) =>
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
    65
        if (output_active.value) {
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    66
          val text = server.resources.output_pretty_message(Pretty.separate(body))
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    67
          val content =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    68
            HTML.output_document(
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    69
              List(HTML.style(HTML.fonts_css()),
66212
f41396c15bb1 tuned signature;
wenzelm
parents: 66211
diff changeset
    70
                HTML.style_file(HTML.isabelle_css),
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    71
                HTML.script(controls_script)),
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
    72
              List(controls, HTML.source(text)),
67337
4254cfd15b00 more tight HTML output: avoid extra lines within <pre>;
wenzelm
parents: 66397
diff changeset
    73
              css = "", structural = true)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    74
          output(content)
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    75
        })
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    76
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
    77
  def locate(): Unit = print_state.locate_query()
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    78
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
    79
  def update(): Unit =
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    80
  {
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) =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    83
        (server.editor.current_command((), snapshot), print_state.get_location) match {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    84
          case (Some(command1), Some(command2)) if command1.id == command2.id =>
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
    85
          case _ => print_state.apply_query(Nil)
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
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
    96
  def auto_update(set: Option[Boolean] = None): Unit =
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    97
  {
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    98
    val enabled =
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
    99
      auto_update_enabled.guarded_access(a =>
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   100
        set match {
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   101
          case None => Some((a, a))
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   102
          case Some(b) => Some((b, b))
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   103
        })
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   104
    if (enabled) update()
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   105
  }
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   106
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   107
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   108
  /* controls */
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   109
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   110
  private def controls_script =
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   111
"""
71476
ecefde4f9103 proper message passing -- discontinued obsolete auxiliary commands;
wenzelm
parents: 70302
diff changeset
   112
const vscode = acquireVsCodeApi();
ecefde4f9103 proper message passing -- discontinued obsolete auxiliary commands;
wenzelm
parents: 70302
diff changeset
   113
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   114
function invoke_auto_update(enabled)
71476
ecefde4f9103 proper message passing -- discontinued obsolete auxiliary commands;
wenzelm
parents: 70302
diff changeset
   115
{ vscode.postMessage({'command': 'auto_update', 'enabled': enabled}) }
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   116
71476
ecefde4f9103 proper message passing -- discontinued obsolete auxiliary commands;
wenzelm
parents: 70302
diff changeset
   117
function invoke_update()
ecefde4f9103 proper message passing -- discontinued obsolete auxiliary commands;
wenzelm
parents: 70302
diff changeset
   118
{ vscode.postMessage({'command': 'update'}) }
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   119
71476
ecefde4f9103 proper message passing -- discontinued obsolete auxiliary commands;
wenzelm
parents: 70302
diff changeset
   120
function invoke_locate()
ecefde4f9103 proper message passing -- discontinued obsolete auxiliary commands;
wenzelm
parents: 70302
diff changeset
   121
{ vscode.postMessage({'command': 'locate'}) }
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   122
"""
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   123
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   124
  private def auto_update_button: XML.Elem =
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   125
    HTML.GUI.checkbox(HTML.text("Auto update"),
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   126
      name = "auto_update",
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   127
      tooltip = "Indicate automatic update following cursor movement",
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   128
      selected = auto_update_enabled.value,
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   129
      script = "invoke_auto_update(this.checked)")
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   130
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   131
  private def update_button: XML.Elem =
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   132
    HTML.GUI.button(List(HTML.bold(HTML.text("Update"))),
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   133
      name = "update",
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   134
      tooltip = "Update display according to the command at cursor position",
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   135
      script = "invoke_update()")
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   136
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   137
  private def locate_button: XML.Elem =
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   138
    HTML.GUI.button(HTML.text("Locate"),
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   139
      name = "locate",
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   140
      tooltip = "Locate printed command within source text",
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   141
      script = "invoke_locate()")
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   142
66213
9380ec9babfb proper dynamic controls, notably for auto_update_enabled;
wenzelm
parents: 66212
diff changeset
   143
  private def controls: XML.Elem =
66211
100c9c997e2b HTML GUI actions via JavaScript;
wenzelm
parents: 66206
diff changeset
   144
    HTML.Wrap_Panel(List(auto_update_button, update_button, locate_button))
66201
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   145
d8f2c745f572 GUI controls similar to Tools/jEdit/src/state_dockable.scala;
wenzelm
parents: 66099
diff changeset
   146
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   147
  /* main */
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   148
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   149
  private val main =
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   150
    Session.Consumer[Any](getClass.getName) {
66099
wenzelm
parents: 66098
diff changeset
   151
      case changed: Session.Commands_Changed =>
wenzelm
parents: 66098
diff changeset
   152
        if (changed.assignment) auto_update()
wenzelm
parents: 66098
diff changeset
   153
wenzelm
parents: 66098
diff changeset
   154
      case Session.Caret_Focus =>
wenzelm
parents: 66098
diff changeset
   155
        auto_update()
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   156
    }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   157
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
   158
  def init(): Unit =
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   159
  {
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   160
    server.session.commands_changed += main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   161
    server.session.caret_focus += main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   162
    server.editor.send_wait_dispatcher { print_state.activate() }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   163
    server.editor.send_dispatcher { auto_update() }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   164
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   165
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72761
diff changeset
   166
  def exit(): Unit =
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   167
  {
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
   168
    output_active.change(_ => false)
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   169
    server.session.commands_changed -= main
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   170
    server.session.caret_focus -= main
66397
f55d2e2c2ca0 avoid spurious output after exit;
wenzelm
parents: 66213
diff changeset
   171
    server.editor.send_wait_dispatcher { print_state.deactivate() }
66096
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   172
  }
6187612e83c1 support for separate proof state output;
wenzelm
parents:
diff changeset
   173
}