src/Tools/jEdit/src/token_markup.scala
changeset 75393 87ebf5a50283
parent 73909 1d0d9772fff0
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
    18   ParserRuleSet, ModeProvider, XModeHandler}
    18   ParserRuleSet, ModeProvider, XModeHandler}
    19 import org.gjt.sp.jedit.indent.IndentRule
    19 import org.gjt.sp.jedit.indent.IndentRule
    20 import org.gjt.sp.jedit.buffer.JEditBuffer
    20 import org.gjt.sp.jedit.buffer.JEditBuffer
    21 
    21 
    22 
    22 
    23 object Token_Markup
    23 object Token_Markup {
    24 {
       
    25   /* line context */
    24   /* line context */
    26 
    25 
    27   def mode_rule_set(mode: String): ParserRuleSet =
    26   def mode_rule_set(mode: String): ParserRuleSet =
    28     new ParserRuleSet(mode, "MAIN")
    27     new ParserRuleSet(mode, "MAIN")
    29 
    28 
    30   object Line_Context
    29   object Line_Context {
    31   {
       
    32     def init(mode: String): Line_Context =
    30     def init(mode: String): Line_Context =
    33       new Line_Context(mode, Some(Scan.Finished), Line_Structure.init)
    31       new Line_Context(mode, Some(Scan.Finished), Line_Structure.init)
    34 
    32 
    35     def refresh(buffer: JEditBuffer, line: Int): Unit =
    33     def refresh(buffer: JEditBuffer, line: Int): Unit =
    36       buffer.markTokens(line, DummyTokenHandler.INSTANCE)
    34       buffer.markTokens(line, DummyTokenHandler.INSTANCE)
    37 
    35 
    38     def before(buffer: JEditBuffer, line: Int): Line_Context =
    36     def before(buffer: JEditBuffer, line: Int): Line_Context =
    39       if (line == 0) init(JEdit_Lib.buffer_mode(buffer))
    37       if (line == 0) init(JEdit_Lib.buffer_mode(buffer))
    40       else after(buffer, line - 1)
    38       else after(buffer, line - 1)
    41 
    39 
    42     def after(buffer: JEditBuffer, line: Int): Line_Context =
    40     def after(buffer: JEditBuffer, line: Int): Line_Context = {
    43     {
       
    44       val line_mgr = JEdit_Lib.buffer_line_manager(buffer)
    41       val line_mgr = JEdit_Lib.buffer_line_manager(buffer)
    45       def context =
    42       def context =
    46         line_mgr.getLineContext(line) match {
    43         line_mgr.getLineContext(line) match {
    47           case c: Line_Context => Some(c)
    44           case c: Line_Context => Some(c)
    48           case _ => None
    45           case _ => None
    54       }
    51       }
    55     }
    52     }
    56   }
    53   }
    57 
    54 
    58   class Line_Context(
    55   class Line_Context(
    59       val mode: String,
    56     val mode: String,
    60       val context: Option[Scan.Line_Context],
    57     val context: Option[Scan.Line_Context],
    61       val structure: Line_Structure)
    58     val structure: Line_Structure)
    62     extends TokenMarker.LineContext(mode_rule_set(mode), null)
    59   extends TokenMarker.LineContext(mode_rule_set(mode), null) {
    63   {
       
    64     def get_context: Scan.Line_Context = context.getOrElse(Scan.Finished)
    60     def get_context: Scan.Line_Context = context.getOrElse(Scan.Finished)
    65 
    61 
    66     override def hashCode: Int = (mode, context, structure).hashCode
    62     override def hashCode: Int = (mode, context, structure).hashCode
    67     override def equals(that: Any): Boolean =
    63     override def equals(that: Any): Boolean =
    68       that match {
    64       that match {
    73   }
    69   }
    74 
    70 
    75 
    71 
    76   /* tokens from line (inclusive) */
    72   /* tokens from line (inclusive) */
    77 
    73 
    78   private def try_line_tokens(syntax: Outer_Syntax, buffer: JEditBuffer, line: Int)
    74   private def try_line_tokens(
    79     : Option[List[Token]] =
    75     syntax: Outer_Syntax,
    80   {
    76     buffer: JEditBuffer,
       
    77     line: Int
       
    78   ): Option[List[Token]] = {
    81     val line_context = Line_Context.before(buffer, line)
    79     val line_context = Line_Context.before(buffer, line)
    82     for {
    80     for {
    83       ctxt <- line_context.context
    81       ctxt <- line_context.context
    84       text <- JEdit_Lib.get_text(buffer, JEdit_Lib.line_range(buffer, line))
    82       text <- JEdit_Lib.get_text(buffer, JEdit_Lib.line_range(buffer, line))
    85     } yield Token.explode_line(syntax.keywords, text, ctxt)._1
    83     } yield Token.explode_line(syntax.keywords, text, ctxt)._1
   131     else Iterator.empty
   129     else Iterator.empty
   132 
   130 
   133 
   131 
   134   /* command spans */
   132   /* command spans */
   135 
   133 
   136   def command_span(syntax: Outer_Syntax, buffer: JEditBuffer, offset: Text.Offset)
   134   def command_span(
   137     : Option[Text.Info[Command_Span.Span]] =
   135     syntax: Outer_Syntax,
   138   {
   136     buffer: JEditBuffer,
       
   137     offset: Text.Offset
       
   138   ): Option[Text.Info[Command_Span.Span]] = {
   139     val keywords = syntax.keywords
   139     val keywords = syntax.keywords
   140 
   140 
   141     def maybe_command_start(i: Text.Offset): Option[Text.Info[Token]] =
   141     def maybe_command_start(i: Text.Offset): Option[Text.Info[Token]] =
   142       token_reverse_iterator(syntax, buffer, i).
   142       token_reverse_iterator(syntax, buffer, i).
   143         find(info => keywords.is_before_command(info.info) || info.info.is_command)
   143         find(info => keywords.is_before_command(info.info) || info.info.is_command)
   145     def maybe_command_stop(i: Text.Offset): Option[Text.Info[Token]] =
   145     def maybe_command_stop(i: Text.Offset): Option[Text.Info[Token]] =
   146       token_iterator(syntax, buffer, i).
   146       token_iterator(syntax, buffer, i).
   147         find(info => keywords.is_before_command(info.info) || info.info.is_command)
   147         find(info => keywords.is_before_command(info.info) || info.info.is_command)
   148 
   148 
   149     if (JEdit_Lib.buffer_range(buffer).contains(offset)) {
   149     if (JEdit_Lib.buffer_range(buffer).contains(offset)) {
   150       val start_info =
   150       val start_info = {
   151       {
       
   152         val info1 = maybe_command_start(offset)
   151         val info1 = maybe_command_start(offset)
   153         info1 match {
   152         info1 match {
   154           case Some(Text.Info(range1, tok1)) if tok1.is_command =>
   153           case Some(Text.Info(range1, tok1)) if tok1.is_command =>
   155             val info2 = maybe_command_start(range1.start - 1)
   154             val info2 = maybe_command_start(range1.start - 1)
   156             info2 match {
   155             info2 match {
   165           case Some(Text.Info(range, tok)) =>
   164           case Some(Text.Info(range, tok)) =>
   166             (keywords.is_before_command(tok), range.start, range.stop)
   165             (keywords.is_before_command(tok), range.start, range.stop)
   167           case None => (false, 0, 0)
   166           case None => (false, 0, 0)
   168         }
   167         }
   169 
   168 
   170       val stop_info =
   169       val stop_info = {
   171       {
       
   172         val info1 = maybe_command_stop(start_next)
   170         val info1 = maybe_command_stop(start_next)
   173         info1 match {
   171         info1 match {
   174           case Some(Text.Info(range1, tok1)) if tok1.is_command && start_before_command =>
   172           case Some(Text.Info(range1, tok1)) if tok1.is_command && start_before_command =>
   175             maybe_command_stop(range1.stop)
   173             maybe_command_stop(range1.stop)
   176           case _ => info1
   174           case _ => info1
   191     }
   189     }
   192     else None
   190     else None
   193   }
   191   }
   194 
   192 
   195   private def _command_span_iterator(
   193   private def _command_span_iterator(
   196       syntax: Outer_Syntax,
   194     syntax: Outer_Syntax,
   197       buffer: JEditBuffer,
   195     buffer: JEditBuffer,
   198       offset: Text.Offset,
   196     offset: Text.Offset,
   199       next_offset: Text.Range => Text.Offset): Iterator[Text.Info[Command_Span.Span]] =
   197     next_offset: Text.Range => Text.Offset
   200     new Iterator[Text.Info[Command_Span.Span]]
   198   ): Iterator[Text.Info[Command_Span.Span]] = {
   201     {
   199     new Iterator[Text.Info[Command_Span.Span]] {
   202       private var next_span = command_span(syntax, buffer, offset)
   200       private var next_span = command_span(syntax, buffer, offset)
   203       def hasNext: Boolean = next_span.isDefined
   201       def hasNext: Boolean = next_span.isDefined
   204       def next(): Text.Info[Command_Span.Span] =
   202       def next(): Text.Info[Command_Span.Span] = {
   205       {
       
   206         val span = next_span.getOrElse(Iterator.empty.next())
   203         val span = next_span.getOrElse(Iterator.empty.next())
   207         next_span = command_span(syntax, buffer, next_offset(span.range))
   204         next_span = command_span(syntax, buffer, next_offset(span.range))
   208         span
   205         span
   209       }
   206       }
   210     }
   207     }
       
   208   }
   211 
   209 
   212   def command_span_iterator(syntax: Outer_Syntax, buffer: JEditBuffer, offset: Text.Offset)
   210   def command_span_iterator(syntax: Outer_Syntax, buffer: JEditBuffer, offset: Text.Offset)
   213       : Iterator[Text.Info[Command_Span.Span]] =
   211       : Iterator[Text.Info[Command_Span.Span]] =
   214     _command_span_iterator(syntax, buffer, offset max 0, range => range.stop)
   212     _command_span_iterator(syntax, buffer, offset max 0, range => range.stop)
   215 
   213 
   221 
   219 
   222   /* token marker */
   220   /* token marker */
   223 
   221 
   224   class Marker(
   222   class Marker(
   225     protected val mode: String,
   223     protected val mode: String,
   226     protected val opt_buffer: Option[Buffer]) extends TokenMarker
   224     protected val opt_buffer: Option[Buffer]
   227   {
   225   ) extends TokenMarker {
   228     addRuleSet(mode_rule_set(mode))
   226     addRuleSet(mode_rule_set(mode))
   229 
   227 
   230     override def hashCode: Int = (mode, opt_buffer).hashCode
   228     override def hashCode: Int = (mode, opt_buffer).hashCode
   231     override def equals(that: Any): Boolean =
   229     override def equals(that: Any): Boolean =
   232       that match {
   230       that match {
   238       opt_buffer match {
   236       opt_buffer match {
   239         case None => "Marker(" + mode + ")"
   237         case None => "Marker(" + mode + ")"
   240         case Some(buffer) => "Marker(" + mode + "," + JEdit_Lib.buffer_name(buffer) + ")"
   238         case Some(buffer) => "Marker(" + mode + "," + JEdit_Lib.buffer_name(buffer) + ")"
   241       }
   239       }
   242 
   240 
   243     override def markTokens(context: TokenMarker.LineContext,
   241     override def markTokens(
   244         handler: TokenHandler, raw_line: Segment): TokenMarker.LineContext =
   242       context: TokenMarker.LineContext,
   245     {
   243       handler: TokenHandler,
       
   244       raw_line: Segment
       
   245     ): TokenMarker.LineContext = {
   246       val line = if (raw_line == null) new Segment else raw_line
   246       val line = if (raw_line == null) new Segment else raw_line
   247       val line_context =
   247       val line_context =
   248         context match { case c: Line_Context => c case _ => Line_Context.init(mode) }
   248         context match { case c: Line_Context => c case _ => Line_Context.init(mode) }
   249       val structure = line_context.structure
   249       val structure = line_context.structure
   250 
   250 
   251       val context1 =
   251       val context1 = {
   252       {
       
   253         val opt_syntax =
   252         val opt_syntax =
   254           opt_buffer match {
   253           opt_buffer match {
   255             case Some(buffer) => Isabelle.buffer_syntax(buffer)
   254             case Some(buffer) => Isabelle.buffer_syntax(buffer)
   256             case None => Isabelle.mode_syntax(mode)
   255             case None => Isabelle.mode_syntax(mode)
   257           }
   256           }
   305   }
   304   }
   306 
   305 
   307 
   306 
   308   /* mode provider */
   307   /* mode provider */
   309 
   308 
   310   class Mode_Provider(orig_provider: ModeProvider) extends ModeProvider
   309   class Mode_Provider(orig_provider: ModeProvider) extends ModeProvider {
   311   {
       
   312     for (mode <- orig_provider.getModes) addMode(mode)
   310     for (mode <- orig_provider.getModes) addMode(mode)
   313 
   311 
   314     override def loadMode(mode: Mode, xmh: XModeHandler): Unit =
   312     override def loadMode(mode: Mode, xmh: XModeHandler): Unit = {
   315     {
       
   316       super.loadMode(mode, xmh)
   313       super.loadMode(mode, xmh)
   317       Isabelle.mode_token_marker(mode.getName).foreach(mode.setTokenMarker)
   314       Isabelle.mode_token_marker(mode.getName).foreach(mode.setTokenMarker)
   318       Isabelle.indent_rule(mode.getName).foreach(indent_rule =>
   315       Isabelle.indent_rule(mode.getName).foreach(indent_rule =>
   319         Untyped.set[JList[IndentRule]](mode, "indentRules", JList.of(indent_rule)))
   316         Untyped.set[JList[IndentRule]](mode, "indentRules", JList.of(indent_rule)))
   320     }
   317     }