src/Tools/VSCode/src/server.scala
changeset 65196 e8760a98db78
parent 65191 4c9c83311cad
child 65197 8fada74d82be
equal deleted inserted replaced
65195:ffab6f460a82 65196:e8760a98db78
    20 
    20 
    21 object Server
    21 object Server
    22 {
    22 {
    23   /* Isabelle tool wrapper */
    23   /* Isabelle tool wrapper */
    24 
    24 
    25   private val default_text_length = "UTF-16"
       
    26   private lazy val default_logic = Isabelle_System.getenv("ISABELLE_LOGIC")
    25   private lazy val default_logic = Isabelle_System.getenv("ISABELLE_LOGIC")
    27 
    26 
    28   val isabelle_tool = Isabelle_Tool("vscode_server", "VSCode Language Server for PIDE", args =>
    27   val isabelle_tool = Isabelle_Tool("vscode_server", "VSCode Language Server for PIDE", args =>
    29   {
    28   {
    30     try {
    29     try {
    31       var log_file: Option[Path] = None
    30       var log_file: Option[Path] = None
    32       var text_length = Text.Length.encoding(default_text_length)
       
    33       var dirs: List[Path] = Nil
    31       var dirs: List[Path] = Nil
    34       var logic = default_logic
    32       var logic = default_logic
    35       var modes: List[String] = Nil
    33       var modes: List[String] = Nil
    36       var options = Options.init()
    34       var options = Options.init()
    37       var system_mode = false
    35       var system_mode = false
    38 
    36 
    39       def text_length_choice: String =
       
    40         commas(Text.Length.encodings.map(
       
    41           { case (a, _) => if (a == default_text_length) a + " (default)" else a }))
       
    42 
       
    43       val getopts = Getopts("""
    37       val getopts = Getopts("""
    44 Usage: isabelle vscode_server [OPTIONS]
    38 Usage: isabelle vscode_server [OPTIONS]
    45 
    39 
    46   Options are:
    40   Options are:
    47     -L FILE      enable logging on FILE
    41     -L FILE      enable logging on FILE
    48     -T LENGTH    text length encoding: """ + text_length_choice + """
       
    49     -d DIR       include session directory
    42     -d DIR       include session directory
    50     -l NAME      logic session name (default ISABELLE_LOGIC=""" + quote(default_logic) + """)
    43     -l NAME      logic session name (default ISABELLE_LOGIC=""" + quote(default_logic) + """)
    51     -m MODE      add print mode for output
    44     -m MODE      add print mode for output
    52     -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
    45     -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
    53     -s           system build mode for session image
    46     -s           system build mode for session image
    54 
    47 
    55   Run the VSCode Language Server protocol (JSON RPC) over stdin/stdout.
    48   Run the VSCode Language Server protocol (JSON RPC) over stdin/stdout.
    56 """,
    49 """,
    57         "L:" -> (arg => log_file = Some(Path.explode(File.standard_path(arg)))),
    50         "L:" -> (arg => log_file = Some(Path.explode(File.standard_path(arg)))),
    58         "T:" -> (arg => Text.Length.encoding(arg)),
       
    59         "d:" -> (arg => dirs = dirs ::: List(Path.explode(File.standard_path(arg)))),
    51         "d:" -> (arg => dirs = dirs ::: List(Path.explode(File.standard_path(arg)))),
    60         "l:" -> (arg => logic = arg),
    52         "l:" -> (arg => logic = arg),
    61         "m:" -> (arg => modes = arg :: modes),
    53         "m:" -> (arg => modes = arg :: modes),
    62         "o:" -> (arg => options = options + arg),
    54         "o:" -> (arg => options = options + arg),
    63         "s" -> (_ => system_mode = true))
    55         "s" -> (_ => system_mode = true))
    65       val more_args = getopts(args)
    57       val more_args = getopts(args)
    66       if (more_args.nonEmpty) getopts.usage()
    58       if (more_args.nonEmpty) getopts.usage()
    67 
    59 
    68       val log = Logger.make(log_file)
    60       val log = Logger.make(log_file)
    69       val channel = new Channel(System.in, System.out, log)
    61       val channel = new Channel(System.in, System.out, log)
    70       val server = new Server(channel, options, text_length, logic, dirs, modes, system_mode, log)
    62       val server = new Server(channel, options, logic, dirs, modes, system_mode, log)
    71 
    63 
    72       // prevent spurious garbage on the main protocol channel
    64       // prevent spurious garbage on the main protocol channel
    73       val orig_out = System.out
    65       val orig_out = System.out
    74       try {
    66       try {
    75         System.setOut(new PrintStream(new OutputStream { def write(n: Int) {} }))
    67         System.setOut(new PrintStream(new OutputStream { def write(n: Int) {} }))
    87 }
    79 }
    88 
    80 
    89 class Server(
    81 class Server(
    90   val channel: Channel,
    82   val channel: Channel,
    91   options: Options,
    83   options: Options,
    92   text_length: Text.Length = Text.Length.encoding(Server.default_text_length),
       
    93   session_name: String = Server.default_logic,
    84   session_name: String = Server.default_logic,
    94   session_dirs: List[Path] = Nil,
    85   session_dirs: List[Path] = Nil,
    95   modes: List[String] = Nil,
    86   modes: List[String] = Nil,
    96   system_mode: Boolean = false,
    87   system_mode: Boolean = false,
    97   log: Logger = No_Logger)
    88   log: Logger = No_Logger)
   220             progress.echo(fail_msg); error(fail_msg)
   211             progress.echo(fail_msg); error(fail_msg)
   221           }
   212           }
   222         }
   213         }
   223 
   214 
   224         val base = Build.session_base(options, false, session_dirs, session_name)
   215         val base = Build.session_base(options, false, session_dirs, session_name)
   225         val resources =
   216         val resources = new VSCode_Resources(options, base, log)
   226           new VSCode_Resources(options, text_length, base, log)
       
   227           {
   217           {
   228             override def commit(change: Session.Change): Unit =
   218             override def commit(change: Session.Change): Unit =
   229               if (change.deps_changed || undefined_blobs(change.version.nodes).nonEmpty)
   219               if (change.deps_changed || undefined_blobs(change.version.nodes).nonEmpty)
   230                 delay_load.invoke()
   220                 delay_load.invoke()
   231           }
   221           }