src/Tools/jEdit/src/jedit/isabelle_token_marker.scala
author wenzelm
Mon, 11 Jan 2010 20:51:58 +0100
changeset 34870 d0057d9777ce
parent 34864 309d545295d3
child 36760 b82a698ef6c9
permissions -rw-r--r--
more tobust treatment of Document.current_state;
some timing;
immler@34470
     1
/*
immler@34470
     2
 * include isabelle's command- and keyword-declarations
immler@34470
     3
 * live in jEdits syntax-highlighting
immler@34520
     4
 *
immler@34470
     5
 * @author Fabian Immler, TU Munich
immler@34470
     6
 */
immler@34470
     7
immler@34470
     8
package isabelle.jedit
immler@34470
     9
wenzelm@34703
    10
immler@34520
    11
import isabelle.Markup
immler@34470
    12
immler@34520
    13
import org.gjt.sp.jedit.buffer.JEditBuffer
wenzelm@34864
    14
import org.gjt.sp.jedit.syntax.{Token, TokenMarker, TokenHandler, SyntaxStyle, ParserRuleSet}
immler@34470
    15
immler@34520
    16
import java.awt.Color
immler@34520
    17
import java.awt.Font
immler@34520
    18
import javax.swing.text.Segment;
immler@34470
    19
immler@34470
    20
wenzelm@34763
    21
object Isabelle_Token_Marker
wenzelm@34591
    22
{
wenzelm@34712
    23
  /* line context */
wenzelm@34712
    24
wenzelm@34730
    25
  private val rule_set = new ParserRuleSet("isabelle", "MAIN")
wenzelm@34712
    26
  private class LineContext(val line: Int, prev: LineContext)
wenzelm@34730
    27
    extends TokenMarker.LineContext(rule_set, prev)
wenzelm@34712
    28
wenzelm@34712
    29
wenzelm@34712
    30
  /* mapping to jEdit token types */
wenzelm@34641
    31
  // TODO: as properties or CSS style sheet
wenzelm@34712
    32
wenzelm@34641
    33
  private val choose_byte: Map[String, Byte] =
wenzelm@34641
    34
  {
wenzelm@34864
    35
    import Token._
wenzelm@34642
    36
    Map[String, Byte](
immler@34552
    37
      // logical entities
wenzelm@34642
    38
      Markup.TCLASS -> LABEL,
wenzelm@34642
    39
      Markup.TYCON -> LABEL,
wenzelm@34642
    40
      Markup.FIXED_DECL -> LABEL,
wenzelm@34642
    41
      Markup.FIXED -> LABEL,
wenzelm@34642
    42
      Markup.CONST_DECL -> LABEL,
wenzelm@34642
    43
      Markup.CONST -> LABEL,
wenzelm@34642
    44
      Markup.FACT_DECL -> LABEL,
wenzelm@34642
    45
      Markup.FACT -> LABEL,
wenzelm@34642
    46
      Markup.DYNAMIC_FACT -> LABEL,
wenzelm@34642
    47
      Markup.LOCAL_FACT_DECL -> LABEL,
wenzelm@34642
    48
      Markup.LOCAL_FACT -> LABEL,
immler@34552
    49
      // inner syntax
wenzelm@34641
    50
      Markup.TFREE -> LITERAL2,
wenzelm@34641
    51
      Markup.FREE -> LITERAL2,
wenzelm@34641
    52
      Markup.TVAR -> LITERAL3,
wenzelm@34641
    53
      Markup.SKOLEM -> LITERAL3,
wenzelm@34641
    54
      Markup.BOUND -> LITERAL3,
wenzelm@34641
    55
      Markup.VAR -> LITERAL3,
wenzelm@34642
    56
      Markup.NUM -> DIGIT,
wenzelm@34642
    57
      Markup.FLOAT -> DIGIT,
wenzelm@34642
    58
      Markup.XNUM -> DIGIT,
wenzelm@34641
    59
      Markup.XSTR -> LITERAL4,
wenzelm@34641
    60
      Markup.LITERAL -> LITERAL4,
wenzelm@34642
    61
      Markup.INNER_COMMENT -> COMMENT1,
wenzelm@34641
    62
      Markup.SORT -> FUNCTION,
wenzelm@34641
    63
      Markup.TYP -> FUNCTION,
wenzelm@34641
    64
      Markup.TERM -> FUNCTION,
wenzelm@34641
    65
      Markup.PROP -> FUNCTION,
wenzelm@34641
    66
      Markup.ATTRIBUTE -> FUNCTION,
wenzelm@34641
    67
      Markup.METHOD -> FUNCTION,
immler@34552
    68
      // ML syntax
wenzelm@34641
    69
      Markup.ML_KEYWORD -> KEYWORD2,
wenzelm@34643
    70
      Markup.ML_IDENT -> NULL,
wenzelm@34641
    71
      Markup.ML_TVAR -> LITERAL3,
wenzelm@34642
    72
      Markup.ML_NUMERAL -> DIGIT,
wenzelm@34641
    73
      Markup.ML_CHAR -> LITERAL1,
wenzelm@34641
    74
      Markup.ML_STRING -> LITERAL1,
wenzelm@34641
    75
      Markup.ML_COMMENT -> COMMENT1,
wenzelm@34641
    76
      Markup.ML_MALFORMED -> INVALID,
immler@34552
    77
      // embedded source text
wenzelm@34641
    78
      Markup.ML_SOURCE -> COMMENT4,
wenzelm@34641
    79
      Markup.DOC_SOURCE -> COMMENT4,
wenzelm@34641
    80
      Markup.ANTIQ -> COMMENT4,
wenzelm@34641
    81
      Markup.ML_ANTIQ -> COMMENT4,
wenzelm@34641
    82
      Markup.DOC_ANTIQ -> COMMENT4,
immler@34552
    83
      // outer syntax
wenzelm@34643
    84
      Markup.IDENT -> NULL,
wenzelm@34642
    85
      Markup.COMMAND -> OPERATOR,
wenzelm@34642
    86
      Markup.KEYWORD -> KEYWORD4,
wenzelm@34642
    87
      Markup.VERBATIM -> COMMENT3,
wenzelm@34642
    88
      Markup.COMMENT -> COMMENT1,
wenzelm@34641
    89
      Markup.CONTROL -> COMMENT3,
wenzelm@34641
    90
      Markup.MALFORMED -> INVALID,
wenzelm@34642
    91
      Markup.STRING -> LITERAL3,
wenzelm@34641
    92
      Markup.ALTSTRING -> LITERAL1
wenzelm@34643
    93
    ).withDefaultValue(NULL)
immler@34520
    94
  }
immler@34470
    95
wenzelm@34641
    96
  def choose_color(kind: String, styles: Array[SyntaxStyle]): Color =
wenzelm@34641
    97
    styles(choose_byte(kind)).getForegroundColor
immler@34470
    98
}
immler@34520
    99
wenzelm@34703
   100
wenzelm@34787
   101
class Isabelle_Token_Marker(model: Document_Model) extends TokenMarker
wenzelm@34591
   102
{
immler@34520
   103
  override def markTokens(prev: TokenMarker.LineContext,
wenzelm@34641
   104
      handler: TokenHandler, line_segment: Segment): TokenMarker.LineContext =
wenzelm@34641
   105
  {
wenzelm@34763
   106
    val previous = prev.asInstanceOf[Isabelle_Token_Marker.LineContext]
wenzelm@34585
   107
    val line = if (prev == null) 0 else previous.line + 1
wenzelm@34763
   108
    val context = new Isabelle_Token_Marker.LineContext(line, previous)
wenzelm@34787
   109
    val start = model.buffer.getLineStartOffset(line)
immler@34520
   110
    val stop = start + line_segment.count
immler@34544
   111
wenzelm@34827
   112
    val document = model.recent_document()
wenzelm@34787
   113
    def to: Int => Int = model.to_current(document, _)
wenzelm@34787
   114
    def from: Int => Int = model.from_current(document, _)
immler@34520
   115
immler@34525
   116
    var next_x = start
wenzelm@34858
   117
    for {
wenzelm@34858
   118
      (command, command_start) <- document.command_range(from(start), from(stop))
wenzelm@34870
   119
      markup <- document.current_state(command).get.highlight.flatten
wenzelm@34858
   120
      val abs_start = to(command_start + markup.start)
wenzelm@34858
   121
      val abs_stop = to(command_start + markup.stop)
wenzelm@34858
   122
      if (abs_stop > start)
wenzelm@34858
   123
      if (abs_start < stop)
wenzelm@34858
   124
      val byte = Isabelle_Token_Marker.choose_byte(markup.info.toString)
wenzelm@34858
   125
      val token_start = (abs_start - start) max 0
wenzelm@34858
   126
      val token_length =
wenzelm@34858
   127
        (abs_stop - abs_start) -
wenzelm@34858
   128
        ((start - abs_start) max 0) -
wenzelm@34858
   129
        ((abs_stop - stop) max 0)
wenzelm@34858
   130
      }
wenzelm@34858
   131
      {
immler@34599
   132
        if (start + token_start > next_x)
wenzelm@34641
   133
          handler.handleToken(line_segment, 1,
wenzelm@34641
   134
            next_x - start, start + token_start - next_x, context)
wenzelm@34858
   135
        handler.handleToken(line_segment, byte, token_start, token_length, context)
immler@34599
   136
        next_x = start + token_start + token_length
immler@34599
   137
      }
immler@34525
   138
    if (next_x < stop)
immler@34525
   139
      handler.handleToken(line_segment, 1, next_x - start, stop - next_x, context)
immler@34520
   140
wenzelm@34864
   141
    handler.handleToken(line_segment, Token.END, line_segment.count, 0, context)
immler@34520
   142
    handler.setLineContext(context)
wenzelm@34858
   143
    context
immler@34520
   144
  }
wenzelm@34703
   145
}