lib/jedit/plugin/isabelle_plugin.scala
author wenzelm
Sun, 24 Aug 2008 21:15:48 +0200
changeset 27991 8e83800a35c8
parent 27988 efc6d38d16d2
child 27995 81cce44fa5d7
permissions -rw-r--r--
misc reorganization; simplified consumer thread; more robust stop;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     1
/*  Title:      lib/jedit/plugin/isabelle_plugin.scala
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     2
    ID:         $Id$
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     3
    Author:     Makarius
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     4
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     5
Isabelle/jEdit plugin -- main setup.
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     6
*/
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     7
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     8
package isabelle.jedit
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
     9
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    10
import org.gjt.sp.jedit.EditPlugin
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    11
import org.gjt.sp.util.Log
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    12
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    13
import errorlist.DefaultErrorSource
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    14
import errorlist.ErrorSource
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    15
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    16
import java.util.Properties
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    17
import java.lang.NumberFormatException
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    18
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    19
import scala.collection.mutable.ListBuffer
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    20
import scala.io.Source
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    21
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    22
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    23
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    24
/** global state **/
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    25
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    26
object IsabellePlugin {
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    27
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    28
  /* Isabelle process */
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    29
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    30
  var isabelle: IsabelleProcess = null
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    31
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    32
  def result_content(result: IsabelleProcess.Result) =
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    33
    XML.content(isabelle.decode_result(result)).mkString("")
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    34
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    35
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    36
  /* unique ids */
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    37
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    38
  private var id_count: BigInt = 0
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    39
27988
efc6d38d16d2 misc tuning of names;
wenzelm
parents: 27987
diff changeset
    40
  def id() : String = synchronized { id_count += 1; "jedit:" + id_count }
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    41
27988
efc6d38d16d2 misc tuning of names;
wenzelm
parents: 27987
diff changeset
    42
  def id_properties(value: String) : Properties = {
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    43
     val props = new Properties
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    44
     props.setProperty(Markup.ID, value)
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    45
     props
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    46
  }
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    47
27988
efc6d38d16d2 misc tuning of names;
wenzelm
parents: 27987
diff changeset
    48
  def id_properties() : Properties = { id_properties(id()) }
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    49
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    50
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    51
  /* result consumers */
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    52
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    53
  type Consumer = IsabelleProcess.Result => Boolean
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    54
  private var consumers = new ListBuffer[Consumer]
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    55
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    56
  def add_consumer(consumer: Consumer) = synchronized { consumers += consumer }
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    57
27988
efc6d38d16d2 misc tuning of names;
wenzelm
parents: 27987
diff changeset
    58
  def add_permanent_consumer(consumer: IsabelleProcess.Result => Unit) = {
efc6d38d16d2 misc tuning of names;
wenzelm
parents: 27987
diff changeset
    59
    add_consumer(result => { consumer(result); false })
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    60
  }
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    61
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    62
  def del_consumer(consumer: Consumer) = synchronized { consumers -= consumer }
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    63
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    64
  private def consume(result: IsabelleProcess.Result) = {
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    65
    synchronized { consumers.elements.toList } foreach (consumer =>
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    66
      {
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    67
        if (result != null && result.is_control) Log.log(Log.DEBUG, result, null)
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    68
        val finished =
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    69
          try { consumer(result) }
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    70
          catch { case e: Throwable => Log.log(Log.ERROR, result, e); true }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    71
        if (finished || result == null) del_consumer(consumer)
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    72
      })
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    73
  }
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    74
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    75
  class ConsumerThread extends Thread {
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    76
    override def run = {
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    77
      var finished = false
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    78
      while (!finished) {
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    79
        val result =
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    80
          try { IsabellePlugin.isabelle.get_result() }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    81
          catch { case _: NullPointerException => null }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    82
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    83
        if (result != null) {
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    84
          consume(result)
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    85
          if (result.kind == IsabelleProcess.Kind.EXIT) {
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    86
            consume(null)
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    87
            finished = true
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    88
          }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    89
        }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    90
        else finished = true
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    91
      }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    92
    }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    93
  }
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
    94
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    95
}
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    96
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    97
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    98
/* Main plugin setup */
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
    99
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   100
class IsabellePlugin extends EditPlugin {
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   101
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   102
  import IsabellePlugin._
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   103
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   104
  val errors = new DefaultErrorSource("isabelle")
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   105
  val consumer_thread = new ConsumerThread
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   106
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   107
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   108
  override def start = {
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   109
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   110
    /* error source */
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   111
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   112
    ErrorSource.registerErrorSource(errors)
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   113
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   114
    add_permanent_consumer (result =>
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   115
      if (result != null &&
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   116
          (result.kind == IsabelleProcess.Kind.WARNING ||
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   117
           result.kind == IsabelleProcess.Kind.ERROR)) {
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   118
        (Position.line_of(result.props), Position.file_of(result.props)) match {
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   119
          case (Some(line), Some(file)) =>
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   120
            val typ =
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   121
              if (result.kind == IsabelleProcess.Kind.WARNING) ErrorSource.WARNING
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   122
              else ErrorSource.ERROR
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   123
            val content = result_content(result)
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   124
            if (content.length > 0) {
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   125
              val lines = Source.fromString(content).getLines
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   126
              val err = new DefaultErrorSource.DefaultError(errors,
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   127
                  typ, file, line - 1, 0, 0, lines.next)
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   128
              for (msg <- lines) err.addExtraMessage(msg)
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   129
              errors.addError(err)
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   130
            }
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   131
          case _ =>
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   132
        }
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   133
      })
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   134
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   135
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   136
    /* Isabelle process */
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   137
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   138
    isabelle = new IsabelleProcess("-mno_brackets", "-mno_type_brackets", "-mxsymbols")
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   139
    consumer_thread.start
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   140
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   141
  }
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   142
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   143
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   144
  override def stop = {
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   145
    isabelle.kill
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   146
    consumer_thread.join
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   147
    ErrorSource.unregisterErrorSource(errors)
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   148
  }
27991
8e83800a35c8 misc reorganization;
wenzelm
parents: 27988
diff changeset
   149
27987
c3f7fa72af2a rearranged source files;
wenzelm
parents:
diff changeset
   150
}