src/Tools/VSCode/src/language_server.scala
author wenzelm
Sun, 02 Nov 2025 23:41:05 +0100
changeset 83463 e7c174e33556
parent 83462 b6916f2ff672
child 83464 bbb47e048642
permissions -rw-r--r--
clarified names;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
     1
/*  Title:      Tools/VSCode/src/language_server.scala
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
     3
65160
6e042537555d incremental document changes;
wenzelm
parents: 65134
diff changeset
     4
Server for VS Code Language Server Protocol 2.0/3.0, see also
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
     5
https://github.com/Microsoft/language-server-protocol
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
     6
https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md
65160
6e042537555d incremental document changes;
wenzelm
parents: 65134
diff changeset
     7
6e042537555d incremental document changes;
wenzelm
parents: 65134
diff changeset
     8
PIDE protocol extensions depend on system option "vscode_pide_extensions".
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
     9
*/
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    10
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    11
package isabelle.vscode
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    12
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    13
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    14
import isabelle._
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    15
83434
5c70d1c27a2e clarified modules;
wenzelm
parents: 83433
diff changeset
    16
import java.io.{File => JFile}
83433
e26f102d2498 minor performance tuning: prefer mutable.ListBuffer;
wenzelm
parents: 83430
diff changeset
    17
e26f102d2498 minor performance tuning: prefer mutable.ListBuffer;
wenzelm
parents: 83430
diff changeset
    18
import scala.collection.mutable
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    19
import scala.annotation.tailrec
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    20
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
    21
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
    22
object Language_Server {
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    23
  /* abstract editor operations */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    24
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    25
  class Editor(server: Language_Server) extends isabelle.Editor[Unit] {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    26
    /* PIDE session and document model */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    27
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    28
    override def session: VSCode_Session = server.session
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    29
    override def flush(): Unit = session.resources.flush_input(session, server.channel)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    30
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    31
    override def get_models(): Iterable[Document.Model] = session.resources.get_models()
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    32
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    33
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    34
    /* input from client */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    35
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    36
    private val delay_input: Delay =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    37
      Delay.last(server.options.seconds("vscode_input_delay"), server.channel.Error_Logger) {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    38
        session.resources.flush_input(session, server.channel)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    39
      }
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    40
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    41
    override def invoke(): Unit = delay_input.invoke()
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    42
    override def revoke(): Unit = delay_input.revoke()
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    43
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    44
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    45
    /* current situation */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    46
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    47
    override def current_node(context: Unit): Option[Document.Node.Name] =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    48
      session.resources.get_caret().map(_.model.node_name)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    49
    override def current_node_snapshot(context: Unit): Option[Document.Snapshot] =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    50
      session.resources.get_caret().map(caret => session.resources.snapshot(caret.model))
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    51
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    52
    override def node_snapshot(name: Document.Node.Name): Document.Snapshot = {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    53
      session.resources.get_snapshot(name) match {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    54
        case Some(snapshot) => snapshot
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    55
        case None => session.snapshot(name)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    56
      }
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    57
    }
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    58
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    59
    def current_command(snapshot: Document.Snapshot): Option[Command] = {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    60
      session.resources.get_caret() match {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    61
        case Some(caret) if snapshot.loaded_theory_command(caret.offset).isEmpty =>
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    62
          snapshot.current_command(caret.node_name, caret.offset)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    63
        case _ => None
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    64
      }
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    65
    }
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    66
    override def current_command(context: Unit, snapshot: Document.Snapshot): Option[Command] =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    67
      current_command(snapshot)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    68
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    69
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    70
    /* output messages */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    71
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    72
    override def output_state(): Boolean =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    73
      session.resources.options.bool("editor_output_state")
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    74
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    75
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    76
    /* overlays */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    77
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    78
    override def node_overlays(name: Document.Node.Name): Document.Node.Overlays =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    79
      session.resources.node_overlays(name)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    80
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    81
    override def insert_overlay(command: Command, fn: String, args: List[String]): Unit =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    82
      session.resources.insert_overlay(command, fn, args)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    83
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    84
    override def remove_overlay(command: Command, fn: String, args: List[String]): Unit =
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    85
      session.resources.remove_overlay(command, fn, args)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    86
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    87
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    88
    /* hyperlinks */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    89
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    90
    override def hyperlink_command(
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    91
      focus: Boolean,
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    92
      snapshot: Document.Snapshot,
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    93
      id: Document_ID.Generic,
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    94
      offset: Symbol.Offset = 0
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    95
    ): Option[Hyperlink] = {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    96
      if (snapshot.is_outdated) None
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    97
      else
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    98
        snapshot.find_command_position(id, offset).map(node_pos =>
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
    99
          new Hyperlink {
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   100
            def follow(unit: Unit): Unit = server.channel.write(LSP.Caret_Update(node_pos, focus))
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   101
          })
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   102
    }
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   103
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   104
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   105
    /* dispatcher thread */
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   106
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   107
    override def assert_dispatcher[A](body: => A): A = session.assert_dispatcher(body)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   108
    override def require_dispatcher[A](body: => A): A = session.require_dispatcher(body)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   109
    override def send_dispatcher(body: => Unit): Unit = session.send_dispatcher(body)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   110
    override def send_wait_dispatcher(body: => Unit): Unit = session.send_wait_dispatcher(body)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   111
  }
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   112
}
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   113
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   114
class Language_Server(
65191
4c9c83311cad dynamic output, depending on caret focus (see also Tools/jEdit/src/output_dockable.scala);
wenzelm
parents: 65189
diff changeset
   115
  val channel: Channel,
83401
1d9b1ca7977e dismantle redundant sledgehammer history in Isabelle/Scala, which does not quite work --- and is already done via vscode.setState / vscode.getState;
wenzelm
parents: 83384
diff changeset
   116
  val options: Options,
83435
0f9bae334ac6 more uniform Isabelle_System.default_logic, with subtle change of semantics due to getenv_strict;
wenzelm
parents: 83434
diff changeset
   117
  session_name: String = Isabelle_System.default_logic(),
75126
da1108a6d249 various improvements to Isabelle/VSCode (by Denis Paluca and Fabian Huch);
wenzelm
parents: 74307
diff changeset
   118
  include_sessions: List[String] = Nil,
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   119
  session_dirs: List[Path] = Nil,
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   120
  session_ancestor: Option[String] = None,
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   121
  session_requirements: Boolean = false,
75295
38398766be6b command-line arguments for "isabelle vscode", similar to "isabelle jedit";
wenzelm
parents: 75262
diff changeset
   122
  session_no_build: Boolean = false,
64717
d2b50eb3d9ab tuned signature;
wenzelm
parents: 64710
diff changeset
   123
  modes: List[String] = Nil,
79777
db9c6be8e236 prefer dynamic objects, following a5fda30edae2;
wenzelm
parents: 79775
diff changeset
   124
  log: Logger = new Logger
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   125
) {
66085
100f02099532 added abstract editor operations, notably for Query_Operation;
wenzelm
parents: 66054
diff changeset
   126
  server =>
100f02099532 added abstract editor operations, notably for Query_Operation;
wenzelm
parents: 66054
diff changeset
   127
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   128
  val editor: Language_Server.Editor = new Language_Server.Editor(server)
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   129
66085
100f02099532 added abstract editor operations, notably for Query_Operation;
wenzelm
parents: 66054
diff changeset
   130
64725
wenzelm
parents: 64724
diff changeset
   131
  /* prover session */
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   132
82744
0ca8b1861fa3 clarified signature: more explicit subtypes of Session, with corresponding subtypes of Resources;
wenzelm
parents: 82720
diff changeset
   133
  private val session_ = Synchronized(None: Option[VSCode_Session])
0ca8b1861fa3 clarified signature: more explicit subtypes of Session, with corresponding subtypes of Resources;
wenzelm
parents: 82720
diff changeset
   134
  def session: VSCode_Session = session_.value getOrElse error("Server inactive")
0ca8b1861fa3 clarified signature: more explicit subtypes of Session, with corresponding subtypes of Resources;
wenzelm
parents: 82720
diff changeset
   135
  def resources: VSCode_Resources = session.resources
83380
93a035696418 proper ml_settings, following Isabelle/jEdit;
wenzelm
parents: 83364
diff changeset
   136
  def ml_settings: ML_Settings = session.store.ml_settings
93a035696418 proper ml_settings, following Isabelle/jEdit;
wenzelm
parents: 83364
diff changeset
   137
83440
7108ed40a611 clarified signature;
wenzelm
parents: 83437
diff changeset
   138
  private val sledgehammer = new VSCode_Sledgehammer(server)
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   139
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
   140
  def rendering_offset(node_pos: Line.Node_Position): Option[(VSCode_Rendering, Text.Offset)] =
64649
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
   141
    for {
76765
c654103e9c9d more robust Document.Pending_Edits: cover all nodes simulataneously, and thus support proper Snapshot.switch;
wenzelm
parents: 76729
diff changeset
   142
      rendering <- resources.get_rendering(new JFile(node_pos.name))
c654103e9c9d more robust Document.Pending_Edits: cover all nodes simulataneously, and thus support proper Snapshot.switch;
wenzelm
parents: 76729
diff changeset
   143
      offset <- rendering.model.content.doc.offset(node_pos.pos)
64649
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
   144
    } yield (rendering, offset)
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
   145
66085
100f02099532 added abstract editor operations, notably for Query_Operation;
wenzelm
parents: 66054
diff changeset
   146
  private val dynamic_output = Dynamic_Output(server)
65191
4c9c83311cad dynamic output, depending on caret focus (see also Tools/jEdit/src/output_dockable.scala);
wenzelm
parents: 65189
diff changeset
   147
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   148
64725
wenzelm
parents: 64724
diff changeset
   149
  /* input from client or file-system */
wenzelm
parents: 64724
diff changeset
   150
73538
80db0d2759b5 tuned --- following hints by IntelliJ IDEA;
wenzelm
parents: 73523
diff changeset
   151
  private val file_watcher: File_Watcher =
80db0d2759b5 tuned --- following hints by IntelliJ IDEA;
wenzelm
parents: 73523
diff changeset
   152
    File_Watcher(sync_documents, options.seconds("vscode_load_delay"))
80db0d2759b5 tuned --- following hints by IntelliJ IDEA;
wenzelm
parents: 73523
diff changeset
   153
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents: 71692
diff changeset
   154
  private val delay_load: Delay =
b9a5eb0f3b43 clarified modules;
wenzelm
parents: 71692
diff changeset
   155
    Delay.last(options.seconds("vscode_load_delay"), channel.Error_Logger) {
66100
d1ad5a7458c2 proper treatment of editor overlays;
wenzelm
parents: 66098
diff changeset
   156
      val (invoke_input, invoke_load) =
d1ad5a7458c2 proper treatment of editor overlays;
wenzelm
parents: 66098
diff changeset
   157
        resources.resolve_dependencies(session, editor, file_watcher)
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   158
      if (invoke_input) editor.invoke()
73367
77ef8bef0593 clarified signature --- fewer warnings;
wenzelm
parents: 73357
diff changeset
   159
      if (invoke_load) delay_load.invoke()
64800
415dafeb9669 manage document blobs as well;
wenzelm
parents: 64783
diff changeset
   160
    }
64727
13e37567a0d6 automatically resolve dependencies from document models and file-system;
wenzelm
parents: 64725
diff changeset
   161
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   162
  private def close_document(file: JFile): Unit = {
65111
3224a6f7bd6b more robust treatment of pending input/output: these are often correlated;
wenzelm
parents: 65107
diff changeset
   163
    if (resources.close_model(file)) {
3224a6f7bd6b more robust treatment of pending input/output: these are often correlated;
wenzelm
parents: 65107
diff changeset
   164
      file_watcher.register_parent(file)
65116
06d9bcb66ef3 simplified;
wenzelm
parents: 65111
diff changeset
   165
      sync_documents(Set(file))
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   166
      editor.invoke()
65116
06d9bcb66ef3 simplified;
wenzelm
parents: 65111
diff changeset
   167
      delay_output.invoke()
65111
3224a6f7bd6b more robust treatment of pending input/output: these are often correlated;
wenzelm
parents: 65107
diff changeset
   168
    }
3224a6f7bd6b more robust treatment of pending input/output: these are often correlated;
wenzelm
parents: 65107
diff changeset
   169
  }
3224a6f7bd6b more robust treatment of pending input/output: these are often correlated;
wenzelm
parents: 65107
diff changeset
   170
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   171
  private def sync_documents(changed: Set[JFile]): Unit = {
65116
06d9bcb66ef3 simplified;
wenzelm
parents: 65111
diff changeset
   172
    resources.sync_models(changed)
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   173
    editor.invoke()
65116
06d9bcb66ef3 simplified;
wenzelm
parents: 65111
diff changeset
   174
    delay_output.invoke()
06d9bcb66ef3 simplified;
wenzelm
parents: 65111
diff changeset
   175
  }
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   176
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72763
diff changeset
   177
  private def change_document(
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   178
    file: JFile,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   179
    version: Long,
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   180
    changes: List[LSP.TextDocumentChange]
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   181
  ): Unit = {
81020
0efa8e784384 lsp: removed change_document normalization because it causes desyncs;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 79777
diff changeset
   182
    changes.foreach(change =>
66674
30d5195299e2 store document version;
wenzelm
parents: 66389
diff changeset
   183
      resources.change_model(session, editor, file, version, change.text, change.range))
65234
1d6e9048cb62 normalize changes strictly as specified in the protocol definition (assuming non-overlapping ranges, amending 0f555ce33970), e.g. relevant for automatic quotes/parentheses around selection;
wenzelm
parents: 65232
diff changeset
   184
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   185
    editor.invoke()
65111
3224a6f7bd6b more robust treatment of pending input/output: these are often correlated;
wenzelm
parents: 65107
diff changeset
   186
    delay_output.invoke()
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   187
  }
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   188
64710
72ca4e5f976e manage changes of external files;
wenzelm
parents: 64709
diff changeset
   189
65189
41d2452845fc support for caret handling and dynamic output;
wenzelm
parents: 65184
diff changeset
   190
  /* caret handling */
41d2452845fc support for caret handling and dynamic output;
wenzelm
parents: 65184
diff changeset
   191
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents: 71692
diff changeset
   192
  private val delay_caret_update: Delay =
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   193
    Delay.last(options.seconds("vscode_input_delay"), channel.Error_Logger) {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   194
      session.caret_focus.post(Session.Caret_Focus)
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   195
    }
65189
41d2452845fc support for caret handling and dynamic output;
wenzelm
parents: 65184
diff changeset
   196
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   197
  private def update_caret(caret: Option[(JFile, Line.Position)]): Unit = {
65189
41d2452845fc support for caret handling and dynamic output;
wenzelm
parents: 65184
diff changeset
   198
    resources.update_caret(caret)
41d2452845fc support for caret handling and dynamic output;
wenzelm
parents: 65184
diff changeset
   199
    delay_caret_update.invoke()
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   200
    editor.invoke()
65189
41d2452845fc support for caret handling and dynamic output;
wenzelm
parents: 65184
diff changeset
   201
  }
41d2452845fc support for caret handling and dynamic output;
wenzelm
parents: 65184
diff changeset
   202
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   203
65983
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   204
  /* preview */
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   205
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
   206
  private lazy val preview_panel = new Preview_Panel(resources)
65983
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   207
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents: 71692
diff changeset
   208
  private lazy val delay_preview: Delay =
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   209
    Delay.last(options.seconds("vscode_output_delay"), channel.Error_Logger) {
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
   210
      if (preview_panel.flush(channel)) delay_preview.invoke()
65983
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   211
    }
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   212
81031
c9e8461dd5f2 lsp: clarified preview_request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81030
diff changeset
   213
  private def preview_request(file: JFile, column: Int): Unit = {
66098
5aa9cb83e70e clarified modules;
wenzelm
parents: 66096
diff changeset
   214
    preview_panel.request(file, column)
65983
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   215
    delay_preview.invoke()
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   216
  }
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   217
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   218
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   219
  /* output to client */
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   220
71704
b9a5eb0f3b43 clarified modules;
wenzelm
parents: 71692
diff changeset
   221
  private val delay_output: Delay =
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   222
    Delay.last(options.seconds("vscode_output_delay"), channel.Error_Logger) {
65232
ca571c8c0788 avoid race condition between current_state().stable_tip_version and model.rendering();
wenzelm
parents: 65231
diff changeset
   223
      if (resources.flush_output(channel)) delay_output.invoke()
64679
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   224
    }
b2bf280b7e13 more uniform treatment of input/output wrt. client;
wenzelm
parents: 64673
diff changeset
   225
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   226
  def update_output(changed_nodes: Iterable[JFile]): Unit = {
66138
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   227
    resources.update_output(changed_nodes)
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   228
    delay_output.invoke()
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   229
  }
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   230
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   231
  def update_output_visible(): Unit = {
66138
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   232
    resources.update_output_visible()
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   233
    delay_output.invoke()
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   234
  }
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   235
64725
wenzelm
parents: 64724
diff changeset
   236
  private val prover_output =
wenzelm
parents: 64724
diff changeset
   237
    Session.Consumer[Session.Commands_Changed](getClass.getName) {
65119
a7bedf94e71c always invoke output: pending_output may be present due to other reasons;
wenzelm
parents: 65116
diff changeset
   238
      case changed =>
66138
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   239
        update_output(changed.nodes.toList.map(resources.node_file(_)))
64725
wenzelm
parents: 64724
diff changeset
   240
    }
64710
72ca4e5f976e manage changes of external files;
wenzelm
parents: 64709
diff changeset
   241
66389
wenzelm
parents: 66241
diff changeset
   242
  private val syslog_messages =
wenzelm
parents: 66241
diff changeset
   243
    Session.Consumer[Prover.Output](getClass.getName) {
82987
1143c65b5829 clarified signature: fewer operations;
wenzelm
parents: 82946
diff changeset
   244
      case output => channel.log_writeln(resources.output_text(XML.content(output.message)))
64692
ccf017e2f2b4 support for syslog messages;
wenzelm
parents: 64691
diff changeset
   245
    }
ccf017e2f2b4 support for syslog messages;
wenzelm
parents: 64691
diff changeset
   246
ccf017e2f2b4 support for syslog messages;
wenzelm
parents: 64691
diff changeset
   247
81043
2174ec5f0d0c lsp: added decoration_request notification;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81031
diff changeset
   248
  /* decoration request */
2174ec5f0d0c lsp: added decoration_request notification;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81031
diff changeset
   249
2174ec5f0d0c lsp: added decoration_request notification;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81031
diff changeset
   250
  private def decoration_request(file: JFile): Unit =
2174ec5f0d0c lsp: added decoration_request notification;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81031
diff changeset
   251
    resources.force_decorations(channel, file)
2174ec5f0d0c lsp: added decoration_request notification;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81031
diff changeset
   252
2174ec5f0d0c lsp: added decoration_request notification;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81031
diff changeset
   253
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   254
  /* init and exit */
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   255
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   256
  def init(id: LSP.Id): Unit = {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   257
    def reply_ok(msg: String): Unit = {
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   258
      channel.write(LSP.Initialize.reply(id, ""))
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   259
      channel.writeln(msg)
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   260
    }
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   261
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   262
    def reply_error(msg: String): Unit = {
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   263
      channel.write(LSP.Initialize.reply(id, msg))
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   264
      channel.error_message(msg)
64641
wenzelm
parents: 64623
diff changeset
   265
    }
wenzelm
parents: 64623
diff changeset
   266
64643
b755f6069ba2 more explicit error;
wenzelm
parents: 64642
diff changeset
   267
    val try_session =
b755f6069ba2 more explicit error;
wenzelm
parents: 64642
diff changeset
   268
      try {
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   269
        val session_background =
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   270
          Sessions.background(
75262
ec62c5401522 discontinued isabelle_filesystem (superseded by isabelle_encoding), see also da1108a6d249;
wenzelm
parents: 75209
diff changeset
   271
            options, session_name, dirs = session_dirs,
75126
da1108a6d249 various improvements to Isabelle/VSCode (by Denis Paluca and Fabian Huch);
wenzelm
parents: 74307
diff changeset
   272
            include_sessions = include_sessions, session_ancestor = session_ancestor,
75920
27bf2533f4a4 clarified signature: follow Sessions.Deps.check_errors (despite Process_Result.check);
wenzelm
parents: 75710
diff changeset
   273
            session_requirements = session_requirements).check_errors
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   274
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   275
        def build(no_build: Boolean = false): Build.Results =
71981
0be06f99b210 clarified signature;
wenzelm
parents: 71896
diff changeset
   276
          Build.build(options,
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   277
            selection = Sessions.Selection.session(session_background.session_name),
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   278
            build_heap = true, no_build = no_build, dirs = session_dirs,
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   279
            infos = session_background.infos)
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   280
75295
38398766be6b command-line arguments for "isabelle vscode", similar to "isabelle jedit";
wenzelm
parents: 75262
diff changeset
   281
        if (!session_no_build && !build(no_build = true).ok) {
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   282
          val start_msg = "Build started for Isabelle/" + session_background.session_name + " ..."
64733
20174e871623 automatically build session image;
wenzelm
parents: 64727
diff changeset
   283
          val fail_msg = "Session build failed -- prover process remains inactive!"
20174e871623 automatically build session image;
wenzelm
parents: 64727
diff changeset
   284
67856
ec9f1ec763a0 tuned signature;
wenzelm
parents: 67846
diff changeset
   285
          val progress = channel.progress(verbose = true)
64733
20174e871623 automatically build session image;
wenzelm
parents: 64727
diff changeset
   286
          progress.echo(start_msg); channel.writeln(start_msg)
20174e871623 automatically build session image;
wenzelm
parents: 64727
diff changeset
   287
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   288
          if (!build().ok) { progress.echo(fail_msg); error(fail_msg) }
64733
20174e871623 automatically build session image;
wenzelm
parents: 64727
diff changeset
   289
        }
20174e871623 automatically build session image;
wenzelm
parents: 64727
diff changeset
   290
82778
803731b62180 clarified signature;
wenzelm
parents: 82777
diff changeset
   291
        val session_resources = new VSCode_Resources(options, session_background, log)
803731b62180 clarified signature;
wenzelm
parents: 82777
diff changeset
   292
        val session_options = options.bool.update("editor_output_state", true)
803731b62180 clarified signature;
wenzelm
parents: 82777
diff changeset
   293
        val session =
803731b62180 clarified signature;
wenzelm
parents: 82777
diff changeset
   294
          new VSCode_Session(session_options, session_resources) {
803731b62180 clarified signature;
wenzelm
parents: 82777
diff changeset
   295
            override def deps_changed(): Unit = delay_load.invoke()
64727
13e37567a0d6 automatically resolve dependencies from document models and file-system;
wenzelm
parents: 64725
diff changeset
   296
          }
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   297
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   298
        Some((session_background, session))
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   299
      }
68690
354c04092cd0 more flexible session selection as in "isabelle jedit";
wenzelm
parents: 67870
diff changeset
   300
      catch { case ERROR(msg) => reply_error(msg); None }
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   301
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   302
    for ((session_background, session) <- try_session) {
78178
a177f71dc79f clarified modules;
wenzelm
parents: 77414
diff changeset
   303
      val store = Store(options)
77414
0d5994eef9e6 clarified signature: allow to provide session_heaps by different means, e.g. from tmp directory or alternative session structure;
wenzelm
parents: 76794
diff changeset
   304
      val session_heaps =
82752
20ffc02d0b0e clarified modules;
wenzelm
parents: 82744
diff changeset
   305
        store.session_heaps(session_background, logic = session_background.session_name)
76655
b3d458a90aeb clarified signature;
wenzelm
parents: 76590
diff changeset
   306
65191
4c9c83311cad dynamic output, depending on caret focus (see also Tools/jEdit/src/output_dockable.scala);
wenzelm
parents: 65189
diff changeset
   307
      session_.change(_ => Some(session))
4c9c83311cad dynamic output, depending on caret focus (see also Tools/jEdit/src/output_dockable.scala);
wenzelm
parents: 65189
diff changeset
   308
65227
wenzelm
parents: 65216
diff changeset
   309
      session.commands_changed += prover_output
66389
wenzelm
parents: 66241
diff changeset
   310
      session.syslog_messages += syslog_messages
65227
wenzelm
parents: 65216
diff changeset
   311
wenzelm
parents: 65216
diff changeset
   312
      dynamic_output.init()
83384
81a832cab4e2 misc tuning;
wenzelm
parents: 83381
diff changeset
   313
      sledgehammer.init()
65227
wenzelm
parents: 65216
diff changeset
   314
71607
d97f504c8145 clarified Isabelle_Process phases;
wenzelm
parents: 71604
diff changeset
   315
      try {
77414
0d5994eef9e6 clarified signature: allow to provide session_heaps by different means, e.g. from tmp directory or alternative session structure;
wenzelm
parents: 76794
diff changeset
   316
        Isabelle_Process.start(
0d5994eef9e6 clarified signature: allow to provide session_heaps by different means, e.g. from tmp directory or alternative session structure;
wenzelm
parents: 76794
diff changeset
   317
          options, session, session_background, session_heaps, modes = modes).await_startup()
76656
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   318
        reply_ok(
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   319
          "Welcome to Isabelle/" + session_background.session_name +
a8f452f7c503 clarified names;
wenzelm
parents: 76655
diff changeset
   320
          Isabelle_System.isabelle_heading())
71604
c6fa217c9d5e clarified signature: more robust startup_join;
wenzelm
parents: 71601
diff changeset
   321
      }
c6fa217c9d5e clarified signature: more robust startup_join;
wenzelm
parents: 71601
diff changeset
   322
      catch { case ERROR(msg) => reply_error(msg) }
64643
b755f6069ba2 more explicit error;
wenzelm
parents: 64642
diff changeset
   323
    }
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   324
  }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   325
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   326
  def shutdown(id: LSP.Id): Unit = {
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   327
    def reply(err: String): Unit = channel.write(LSP.Shutdown.reply(id, err))
64641
wenzelm
parents: 64623
diff changeset
   328
64703
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   329
    session_.change({
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   330
      case Some(session) =>
65228
b11099b7d868 clarified shutdown;
wenzelm
parents: 65227
diff changeset
   331
        session.commands_changed -= prover_output
66389
wenzelm
parents: 66241
diff changeset
   332
        session.syslog_messages -= syslog_messages
65228
b11099b7d868 clarified shutdown;
wenzelm
parents: 65227
diff changeset
   333
65191
4c9c83311cad dynamic output, depending on caret focus (see also Tools/jEdit/src/output_dockable.scala);
wenzelm
parents: 65189
diff changeset
   334
        dynamic_output.exit()
65228
b11099b7d868 clarified shutdown;
wenzelm
parents: 65227
diff changeset
   335
b11099b7d868 clarified shutdown;
wenzelm
parents: 65227
diff changeset
   336
        delay_load.revoke()
b11099b7d868 clarified shutdown;
wenzelm
parents: 65227
diff changeset
   337
        file_watcher.shutdown()
83437
0556adb3581b clarified modules;
wenzelm
parents: 83435
diff changeset
   338
        editor.revoke()
64703
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   339
        delay_output.revoke()
65228
b11099b7d868 clarified shutdown;
wenzelm
parents: 65227
diff changeset
   340
        delay_caret_update.revoke()
65983
d8c5603c1732 explicit preview request/response;
wenzelm
parents: 65977
diff changeset
   341
        delay_preview.revoke()
83384
81a832cab4e2 misc tuning;
wenzelm
parents: 83381
diff changeset
   342
        sledgehammer.exit()
65228
b11099b7d868 clarified shutdown;
wenzelm
parents: 65227
diff changeset
   343
66677
fa70edfcb6fa proper result type (cf. b9f5cd845616);
wenzelm
parents: 66676
diff changeset
   344
        val result = session.stop()
71747
1dd514c8c1df clarified signature;
wenzelm
parents: 71704
diff changeset
   345
        if (result.ok) reply("")
1dd514c8c1df clarified signature;
wenzelm
parents: 71704
diff changeset
   346
        else reply("Prover shutdown failed: " + result.rc)
64703
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   347
        None
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   348
      case None =>
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   349
        reply("Prover inactive")
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   350
        None
a115391494ed moved main state to VSCode_Resources;
wenzelm
parents: 64702
diff changeset
   351
    })
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   352
  }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   353
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   354
  def exit(): Unit = {
64717
d2b50eb3d9ab tuned signature;
wenzelm
parents: 64710
diff changeset
   355
    log("\n")
74307
wenzelm
parents: 74306
diff changeset
   356
    sys.exit(if (session_.value.isEmpty) Process_Result.RC.ok else Process_Result.RC.failure)
64646
805c5e6fa430 tuned messages;
wenzelm
parents: 64645
diff changeset
   357
  }
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   358
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   359
64877
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   360
  /* completion */
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   361
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   362
  def completion(id: LSP.Id, node_pos: Line.Node_Position): Unit = {
64877
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   363
    val result =
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   364
      (for ((rendering, offset) <- rendering_offset(node_pos))
75126
da1108a6d249 various improvements to Isabelle/VSCode (by Denis Paluca and Fabian Huch);
wenzelm
parents: 74307
diff changeset
   365
        yield rendering.completion(node_pos, offset)) getOrElse Nil
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   366
    channel.write(LSP.Completion.reply(id, result))
64877
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   367
  }
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   368
31e9920a0dc1 support for semantic completion;
wenzelm
parents: 64870
diff changeset
   369
66138
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   370
  /* spell-checker dictionary */
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   371
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   372
  def update_dictionary(include: Boolean, permanent: Boolean): Unit = {
66138
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   373
    for {
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   374
      spell_checker <- resources.spell_checker.get
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   375
      caret <- resources.get_caret()
76765
c654103e9c9d more robust Document.Pending_Edits: cover all nodes simulataneously, and thus support proper Snapshot.switch;
wenzelm
parents: 76729
diff changeset
   376
      rendering = resources.rendering(caret.model)
66138
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   377
      range = rendering.before_caret_range(caret.offset)
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   378
      Text.Info(_, word) <- Spell_Checker.current_word(rendering, range)
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   379
    } {
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   380
      spell_checker.update(word, include, permanent)
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   381
      update_output_visible()
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   382
    }
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   383
  }
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   384
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   385
  def reset_dictionary(): Unit = {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   386
    for (spell_checker <- resources.spell_checker.get) {
66138
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   387
      spell_checker.reset()
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   388
      update_output_visible()
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   389
    }
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   390
  }
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   391
f7ef4c50b747 added commands for spell-checker dictionary;
wenzelm
parents: 66101
diff changeset
   392
64622
529bbb8977c7 more uniform rendering for Isabelle/jEdit and Isabelle/VSCode;
wenzelm
parents: 64618
diff changeset
   393
  /* hover */
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   394
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   395
  def hover(id: LSP.Id, node_pos: Line.Node_Position): Unit = {
64641
wenzelm
parents: 64623
diff changeset
   396
    val result =
wenzelm
parents: 64623
diff changeset
   397
      for {
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
   398
        (rendering, offset) <- rendering_offset(node_pos)
65134
511bf19348d3 clarified messages (with improved scalability): legacy/error as diagnostics, writeln/information/warning/bad as tooltips (dynamic hover);
wenzelm
parents: 65129
diff changeset
   399
        info <- rendering.tooltips(VSCode_Rendering.tooltip_elements, Text.Range(offset, offset + 1))
64641
wenzelm
parents: 64623
diff changeset
   400
      } yield {
65197
8fada74d82be tuned signature;
wenzelm
parents: 65196
diff changeset
   401
        val range = rendering.model.content.doc.range(info.range)
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   402
        val contents = info.info.map(t => LSP.MarkedString(resources.output_pretty_tooltip(List(t))))
64748
155bf8632104 clarified multiple tooltips;
wenzelm
parents: 64747
diff changeset
   403
        (range, contents)
64641
wenzelm
parents: 64623
diff changeset
   404
      }
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   405
    channel.write(LSP.Hover.reply(id, result))
64641
wenzelm
parents: 64623
diff changeset
   406
  }
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   407
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   408
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64646
diff changeset
   409
  /* goto definition */
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64646
diff changeset
   410
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   411
  def goto_definition(id: LSP.Id, node_pos: Line.Node_Position): Unit = {
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64646
diff changeset
   412
    val result =
64651
ea5620f7b0d8 clarified signature;
wenzelm
parents: 64649
diff changeset
   413
      (for ((rendering, offset) <- rendering_offset(node_pos))
64649
d67c3094a0c2 tuned signature -- more explicit types;
wenzelm
parents: 64648
diff changeset
   414
        yield rendering.hyperlinks(Text.Range(offset, offset + 1))) getOrElse Nil
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   415
    channel.write(LSP.GotoDefinition.reply(id, result))
64648
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64646
diff changeset
   416
  }
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64646
diff changeset
   417
5d7f741aaccb basic support for hyperlinks / Goto Definition Request;
wenzelm
parents: 64646
diff changeset
   418
64767
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   419
  /* document highlights */
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   420
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   421
  def document_highlights(id: LSP.Id, node_pos: Line.Node_Position): Unit = {
64767
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   422
    val result =
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   423
      (for ((rendering, offset) <- rendering_offset(node_pos))
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   424
        yield {
65197
8fada74d82be tuned signature;
wenzelm
parents: 65196
diff changeset
   425
          val model = rendering.model
8fada74d82be tuned signature;
wenzelm
parents: 65196
diff changeset
   426
          rendering.caret_focus_ranges(Text.Range(offset, offset + 1), model.content.text_range)
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   427
            .map(r => LSP.DocumentHighlight.text(model.content.doc.range(r)))
64767
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   428
        }) getOrElse Nil
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   429
    channel.write(LSP.DocumentHighlights.reply(id, result))
64767
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   430
  }
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   431
f5c4ffdb1124 support VSCode DocumentHighlights;
wenzelm
parents: 64755
diff changeset
   432
81067
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   433
  /* code actions */
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   434
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   435
  def code_action_request(id: LSP.Id, file: JFile, range: Line.Range): Unit = {
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   436
    for {
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   437
      model <- resources.get_model(file)
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   438
      version <- model.version
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   439
      doc = model.content.doc
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   440
      text_range <- doc.text_range(range)
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   441
    } {
83424
4f4cff7c6a54 misc tuning;
wenzelm
parents: 83422
diff changeset
   442
      val snapshot = resources.snapshot(model)
83430
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   443
      val results =
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   444
        snapshot.command_results(Text.Range(text_range.start - 1, text_range.stop + 1))
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   445
          .iterator.map(_._2).toList
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   446
      val actions =
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   447
        List.from(
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   448
          for {
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   449
            (snippet, props) <- Protocol.sendback_snippets(results).iterator
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   450
            id <- Position.Id.unapply(props)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   451
            (node, command) <- snapshot.find_command(id)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   452
            start <- node.command_start(command)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   453
            range = command.core_range + start
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   454
            current_text <- model.get_text(range)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   455
          } yield {
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   456
            val line_range = doc.range(range)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   457
            val edit_text =
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   458
              if (props.contains(Markup.PADDING_COMMAND)) {
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   459
                val whole_line = doc.lines(line_range.start.line)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   460
                val indent = whole_line.text.takeWhile(_.isWhitespace)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   461
                current_text + "\n" + Library.prefix_lines(indent, snippet)
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   462
              }
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   463
              else current_text + snippet
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   464
            val edit = LSP.TextEdit(line_range, resources.output_edit(edit_text))
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   465
            LSP.CodeAction(snippet, List(LSP.TextDocumentEdit(file, Some(version), List(edit))))
53c253ee5399 misc tuning and clarification;
wenzelm
parents: 83429
diff changeset
   466
          })
83429
wenzelm
parents: 83428
diff changeset
   467
      channel.write(LSP.CodeActionRequest.reply(id, actions))
81067
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   468
    }
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   469
  }
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   470
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   471
81030
88879ff1cef5 lsp: added Symbols_Request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81029
diff changeset
   472
  /* symbols */
88879ff1cef5 lsp: added Symbols_Request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81029
diff changeset
   473
81075
f0341e6b1b30 lsp: added symbol conversion request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81069
diff changeset
   474
  def symbols_convert_request(id: LSP.Id, text: String, unicode: Boolean): Unit = {
f0341e6b1b30 lsp: added symbol conversion request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81069
diff changeset
   475
    val converted = Symbol.output(unicode, text)
f0341e6b1b30 lsp: added symbol conversion request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81069
diff changeset
   476
    channel.write(LSP.Symbols_Convert_Request.reply(id, converted))
f0341e6b1b30 lsp: added symbol conversion request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81069
diff changeset
   477
  }
81030
88879ff1cef5 lsp: added Symbols_Request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81029
diff changeset
   478
83463
e7c174e33556 clarified names;
wenzelm
parents: 83462
diff changeset
   479
  def symbols_request(): Unit = {
83363
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   480
    val abbrevs =
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   481
      resources.get_caret().flatMap { caret =>
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   482
        resources.get_model(caret.file).map(_.syntax().abbrevs)
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   483
      }.getOrElse(session.resources.session_base.overall_syntax.abbrevs)
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   484
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   485
    channel.write(LSP.Symbols_Response(Symbol.symbols, abbrevs))
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   486
  }
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   487
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   488
83406
9b3a9d739c2e discontinue pointless "init" flag;
wenzelm
parents: 83401
diff changeset
   489
  def documentation_request(): Unit =
83380
93a035696418 proper ml_settings, following Isabelle/jEdit;
wenzelm
parents: 83364
diff changeset
   490
    channel.write(LSP.Documentation_Response(ml_settings))
83363
486e094b676c various improvements of Isabelle/VSCode: original changeset by Diana Korchmar, LMU München;
wenzelm
parents: 82987
diff changeset
   491
81030
88879ff1cef5 lsp: added Symbols_Request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81029
diff changeset
   492
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   493
  /* main loop */
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   494
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   495
  def start(): Unit = {
64717
d2b50eb3d9ab tuned signature;
wenzelm
parents: 64710
diff changeset
   496
    log("Server started " + Date.now())
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   497
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   498
    def handle(json: JSON.T): Unit = {
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   499
      try {
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   500
        json match {
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   501
          case LSP.Initialize(id) => init(id)
83422
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   502
          case LSP.Initialized() =>
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   503
          case LSP.Shutdown(id) => shutdown(id)
83422
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   504
          case LSP.Exit() => exit()
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   505
          case LSP.DidOpenTextDocument(file, _, version, text) =>
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   506
            change_document(file, version, List(LSP.TextDocumentChange(None, text)))
67292
386ddccfccbf implicit thy_load context for bibtex files (VSCode);
wenzelm
parents: 66976
diff changeset
   507
            delay_load.invoke()
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   508
          case LSP.DidChangeTextDocument(file, version, changes) =>
66674
30d5195299e2 store document version;
wenzelm
parents: 66389
diff changeset
   509
            change_document(file, version, changes)
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   510
          case LSP.DidCloseTextDocument(file) => close_document(file)
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   511
          case LSP.Completion(id, node_pos) => completion(id, node_pos)
83422
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   512
          case LSP.Include_Word() => update_dictionary(true, false)
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   513
          case LSP.Include_Word_Permanently() => update_dictionary(true, true)
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   514
          case LSP.Exclude_Word() => update_dictionary(false, false)
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   515
          case LSP.Exclude_Word_Permanently() => update_dictionary(false, true)
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   516
          case LSP.Reset_Words() => reset_dictionary()
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   517
          case LSP.Hover(id, node_pos) => hover(id, node_pos)
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   518
          case LSP.GotoDefinition(id, node_pos) => goto_definition(id, node_pos)
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   519
          case LSP.DocumentHighlights(id, node_pos) => document_highlights(id, node_pos)
81067
1b1d72c45ff4 lsp: added support for code actions to apply active sendback markups;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81062
diff changeset
   520
          case LSP.CodeActionRequest(id, file, range) => code_action_request(id, file, range)
81043
2174ec5f0d0c lsp: added decoration_request notification;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81031
diff changeset
   521
          case LSP.Decoration_Request(file) => decoration_request(file)
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   522
          case LSP.Caret_Update(caret) => update_caret(caret)
81029
f4cb1e35c63e lsp: added Output_Set_Margin and State_Set_Margin Notifications;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81028
diff changeset
   523
          case LSP.Output_Set_Margin(margin) => dynamic_output.set_margin(margin)
81028
84f6f17274d0 lsp: changed State_Init notification into a request and removed State_Init_Response;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81027
diff changeset
   524
          case LSP.State_Init(id) => State_Panel.init(id, server)
81027
a9dc66e05297 lsp: tuned;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81020
diff changeset
   525
          case LSP.State_Exit(state_id) => State_Panel.exit(state_id)
a9dc66e05297 lsp: tuned;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81020
diff changeset
   526
          case LSP.State_Locate(state_id) => State_Panel.locate(state_id)
a9dc66e05297 lsp: tuned;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81020
diff changeset
   527
          case LSP.State_Update(state_id) => State_Panel.update(state_id)
81084
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81075
diff changeset
   528
          case LSP.State_Auto_Update(state_id, enabled) =>
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81075
diff changeset
   529
            State_Panel.auto_update(state_id, enabled)
81029
f4cb1e35c63e lsp: added Output_Set_Margin and State_Set_Margin Notifications;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81028
diff changeset
   530
          case LSP.State_Set_Margin(state_id, margin) => State_Panel.set_margin(state_id, margin)
81084
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81075
diff changeset
   531
          case LSP.Symbols_Convert_Request(id, text, boolean) =>
96eb20106a34 minor tuning;
Fabian Huch <huch@in.tum.de>
parents: 81075
diff changeset
   532
            symbols_convert_request(id, text, boolean)
81031
c9e8461dd5f2 lsp: clarified preview_request;
Thomas Lindae <thomas.lindae@in.tum.de>
parents: 81030
diff changeset
   533
          case LSP.Preview_Request(file, column) => preview_request(file, column)
83463
e7c174e33556 clarified names;
wenzelm
parents: 83462
diff changeset
   534
          case LSP.Symbols_Request() => symbols_request()
83460
613c26246717 proper pattern matching (amending 9b3a9d739c2e);
wenzelm
parents: 83456
diff changeset
   535
          case LSP.Documentation_Request() => documentation_request()
83456
8260cd98a7bc clarified signature;
wenzelm
parents: 83454
diff changeset
   536
          case LSP.Sledgehammer_Provers_Request() => sledgehammer.provers()
83446
c0c0d860acd2 clarified signature: more concise args;
wenzelm
parents: 83440
diff changeset
   537
          case LSP.Sledgehammer_Request(args) => sledgehammer.request(args)
83422
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   538
          case LSP.Sledgehammer_Cancel() => sledgehammer.cancel()
31aceecbd3f2 clarified signature: proper 0-parameter pattern;
wenzelm
parents: 83421
diff changeset
   539
          case LSP.Sledgehammer_Locate() => sledgehammer.locate()
83454
62178604511c clarified protocol for "PIDE/sledgehammer_sendback" vs. "PIDE/sledgehammer_insert": rely on existing Isabelle/Scala/PIDE operations;
wenzelm
parents: 83446
diff changeset
   540
          case LSP.Sledgehammer_Sendback(text) => sledgehammer.sendback(text)
72761
4519eeefe3b5 avoid conflicting base names;
wenzelm
parents: 72627
diff changeset
   541
          case _ => if (!LSP.ResponseMessage.is_empty(json)) log("### IGNORED")
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   542
        }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   543
      }
64687
04806ad1e43a clarified protocol errors;
wenzelm
parents: 64684
diff changeset
   544
      catch { case exn: Throwable => channel.log_error_message(Exn.message(exn)) }
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   545
    }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   546
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 75295
diff changeset
   547
    @tailrec def loop(): Unit = {
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   548
      channel.read() match {
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   549
        case Some(json) =>
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   550
          json match {
71601
97ccf48c2f0c misc tuning based on hints by IntelliJ IDEA;
wenzelm
parents: 71598
diff changeset
   551
            case bulk: List[_] => bulk.foreach(handle)
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   552
            case _ => handle(json)
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   553
          }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   554
          loop()
64717
d2b50eb3d9ab tuned signature;
wenzelm
parents: 64710
diff changeset
   555
        case None => log("### TERMINATE")
64605
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   556
      }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   557
    }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   558
    loop()
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   559
  }
9c1173a7e4cb basic support for VSCode Language Server protocol;
wenzelm
parents:
diff changeset
   560
}