products/sources/formale sprachen/Isabelle/Tools/jEdit/src image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: jedit_rendering.scala   Sprache: Scala

Original von: Isabelle©

/*  Title:      Tools/jEdit/src/jedit_rendering.scala
    Author:     Makarius

Isabelle/jEdit-specific implementation of quasi-abstract rendering and
markup interpretation.
*/


package isabelle.jedit


import isabelle._

import java.awt.Color
import javax.swing.Icon

import org.gjt.sp.jedit.syntax.{Token => JEditToken}
import org.gjt.sp.jedit.jEdit

import scala.collection.immutable.SortedMap


object JEdit_Rendering
{
  /* make rendering */

  def apply(snapshot: Document.Snapshot, model: Document_Model, options: Options): JEdit_Rendering =
    new JEdit_Rendering(snapshot, model, options)

  def text(snapshot: Document.Snapshot, formatted_body: XML.Body,
    results: Command.Results = Command.Results.empty): (String, JEdit_Rendering) =
  {
    val command = Command.rich_text(Document_ID.make(), results, formatted_body)
    val snippet = snapshot.snippet(command)
    val model = File_Model.empty(PIDE.session)
    val rendering = apply(snippet, model, PIDE.options.value)
    (command.source, rendering)
  }


  /* popup window bounds */

  def popup_bounds: Double = (PIDE.options.real("jedit_popup_bounds") max 0.2) min 0.8


  /* Isabelle/Isar token markup */

  private val command_style: Map[String, Byte] =
  {
    import JEditToken._
    Map[String, Byte](
      Keyword.THY_END -> KEYWORD2,
      Keyword.PRF_ASM -> KEYWORD3,
      Keyword.PRF_ASM_GOAL -> KEYWORD3
    ).withDefaultValue(KEYWORD1)
  }

  private val token_style: Map[Token.Kind.Value, Byte] =
  {
    import JEditToken._
    Map[Token.Kind.Value, Byte](
      Token.Kind.KEYWORD -> KEYWORD2,
      Token.Kind.IDENT -> NULL,
      Token.Kind.LONG_IDENT -> NULL,
      Token.Kind.SYM_IDENT -> NULL,
      Token.Kind.VAR -> NULL,
      Token.Kind.TYPE_IDENT -> NULL,
      Token.Kind.TYPE_VAR -> NULL,
      Token.Kind.NAT -> NULL,
      Token.Kind.FLOAT -> NULL,
      Token.Kind.SPACE -> NULL,
      Token.Kind.STRING -> LITERAL1,
      Token.Kind.ALT_STRING -> LITERAL2,
      Token.Kind.VERBATIM -> COMMENT3,
      Token.Kind.CARTOUCHE -> COMMENT3,
      Token.Kind.INFORMAL_COMMENT -> COMMENT1,
      Token.Kind.FORMAL_COMMENT -> COMMENT1,
      Token.Kind.ERROR -> INVALID
    ).withDefaultValue(NULL)
  }

  def token_markup(syntax: Outer_Syntax, token: Token): Byte =
    if (token.is_command) command_style(syntax.keywords.kinds.getOrElse(token.content, ""))
    else if (token.is_delimiter) JEditToken.OPERATOR
    else token_style(token.kind)


  /* Isabelle/ML token markup */

  private val ml_token_style: Map[ML_Lex.Kind.Value, Byte] =
  {
    import JEditToken._
    Map[ML_Lex.Kind.Value, Byte](
      ML_Lex.Kind.KEYWORD -> NULL,
      ML_Lex.Kind.IDENT -> NULL,
      ML_Lex.Kind.LONG_IDENT -> NULL,
      ML_Lex.Kind.TYPE_VAR -> NULL,
      ML_Lex.Kind.WORD -> DIGIT,
      ML_Lex.Kind.INT -> DIGIT,
      ML_Lex.Kind.REAL -> DIGIT,
      ML_Lex.Kind.CHAR -> LITERAL2,
      ML_Lex.Kind.STRING -> LITERAL1,
      ML_Lex.Kind.SPACE -> NULL,
      ML_Lex.Kind.INFORMAL_COMMENT -> COMMENT1,
      ML_Lex.Kind.FORMAL_COMMENT -> COMMENT1,
      ML_Lex.Kind.ANTIQ -> NULL,
      ML_Lex.Kind.ANTIQ_START -> LITERAL4,
      ML_Lex.Kind.ANTIQ_STOP -> LITERAL4,
      ML_Lex.Kind.ANTIQ_OTHER -> NULL,
      ML_Lex.Kind.ANTIQ_STRING -> NULL,
      ML_Lex.Kind.ANTIQ_ALT_STRING -> NULL,
      ML_Lex.Kind.ANTIQ_CARTOUCHE -> NULL,
      ML_Lex.Kind.ERROR -> INVALID
    ).withDefaultValue(NULL)
  }

  def ml_token_markup(token: ML_Lex.Token): Byte =
    if (!token.is_keyword) ml_token_style(token.kind)
    else if (token.is_delimiter) JEditToken.OPERATOR
    else if (ML_Lex.keywords2(token.source)) JEditToken.KEYWORD2
    else if (ML_Lex.keywords3(token.source)) JEditToken.KEYWORD3
    else JEditToken.KEYWORD1


  /* markup elements */

  private val indentation_elements =
    Markup.Elements(Markup.Command_Indent.name)

  private val breakpoint_elements = Markup.Elements(Markup.ML_BREAKPOINT)

  private val highlight_elements =
    Markup.Elements(Markup.EXPRESSION, Markup.CITATION, Markup.LANGUAGE, Markup.ML_TYPING,
      Markup.TOKEN_RANGE, Markup.ENTITY, Markup.PATH, Markup.DOC, Markup.URL,
      Markup.SORTING, Markup.TYPING, Markup.CLASS_PARAMETER, Markup.FREE, Markup.SKOLEM,
      Markup.BOUND, Markup.VAR, Markup.TFREE, Markup.TVAR, Markup.ML_BREAKPOINT,
      Markup.MARKDOWN_PARAGRAPH, Markup.MARKDOWN_ITEM, Markup.Markdown_List.name)

  private val hyperlink_elements =
    Markup.Elements(Markup.ENTITY, Markup.PATH, Markup.EXPORT_PATH, Markup.DOC, Markup.URL,
      Markup.POSITION, Markup.CITATION)

  private val gutter_elements =
    Markup.Elements(Markup.WRITELN, Markup.INFORMATION, Markup.WARNING, Markup.LEGACY, Markup.ERROR)

  private val squiggly_elements =
    Markup.Elements(Markup.WRITELN, Markup.INFORMATION, Markup.WARNING, Markup.LEGACY, Markup.ERROR)

  private val line_background_elements =
    Markup.Elements(Markup.WRITELN_MESSAGE, Markup.STATE_MESSAGE, Markup.INFORMATION_MESSAGE,
      Markup.TRACING_MESSAGE, Markup.WARNING_MESSAGE, Markup.LEGACY_MESSAGE,
      Markup.ERROR_MESSAGE)

  private val separator_elements =
    Markup.Elements(Markup.SEPARATOR)

  private val bullet_elements =
    Markup.Elements(Markup.BULLET, Markup.ML_BREAKPOINT)

  private val fold_depth_elements =
    Markup.Elements(Markup.TEXT_FOLD, Markup.GOAL, Markup.SUBGOAL)
}


class JEdit_Rendering(snapshot: Document.Snapshot, model: Document_Model, options: Options)
  extends Rendering(snapshot, options, PIDE.session)
{
  override def get_text(range: Text.Range): Option[String] = model.get_text(range)


  /* colors */

  def color(s: String): Color =
    if (s == "main_color") main_color
    else Color_Value(options.string(s))

  def color(c: Rendering.Color.Value): Color = _rendering_colors(c)

  lazy val _rendering_colors: Map[Rendering.Color.Value, Color] =
    Rendering.Color.values.iterator.map(c => c -> color(c.toString + "_color")).toMap

  val main_color = jEdit.getColorProperty("view.fgColor")

  val outdated_color = color("outdated_color")
  val bullet_color = color("bullet_color")
  val tooltip_color = color("tooltip_color")
  val spell_checker_color = color("spell_checker_color")
  val entity_ref_color = color("entity_ref_color")
  val breakpoint_disabled_color = color("breakpoint_disabled_color")
  val breakpoint_enabled_color = color("breakpoint_enabled_color")
  val caret_debugger_color = color("caret_debugger_color")
  val highlight_color = color("highlight_color")
  val hyperlink_color = color("hyperlink_color")
  val active_hover_color = color("active_hover_color")
  val caret_invisible_color = color("caret_invisible_color")
  val completion_color = color("completion_color")
  val search_color = color("search_color")


  /* indentation */

  def indentation(range: Text.Range): Int =
    snapshot.select(range, JEdit_Rendering.indentation_elements, _ =>
      {
        case Text.Info(_, XML.Elem(Markup.Command_Indent(i), _)) => Some(i)
        case _ => None
      }).headOption.map(_.info).getOrElse(0)


  /* breakpoints */

  def breakpoint(range: Text.Range): Option[(Command, Long)] =
    if (snapshot.is_outdated) None
    else
      snapshot.select(range, JEdit_Rendering.breakpoint_elements, command_states =>
        {
          case Text.Info(_, Protocol.ML_Breakpoint(breakpoint)) =>
            command_states match {
              case st :: _ => Some((st.command, breakpoint))
              case _ => None
            }
          case _ => None
        }).headOption.map(_.info)


  /* caret focus */

  def entity_ref(range: Text.Range, focus: Rendering.Focus): List[Text.Info[Color]] =
    snapshot.select(range, Rendering.entity_elements, _ =>
      {
        case Text.Info(_, XML.Elem(Markup(Markup.ENTITY, Markup.Ref(i)), _))
        if focus(i) => Some(entity_ref_color)
        case _ => None
      })


  /* highlighted area */

  def highlight(range: Text.Range): Option[Text.Info[Color]] =
    snapshot.select(range, JEdit_Rendering.highlight_elements, _ =>
      {
        case info => Some(Text.Info(snapshot.convert(info.range), highlight_color))
      }).headOption.map(_.info)


  /* hyperlinks */

  def hyperlink(range: Text.Range): Option[Text.Info[PIDE.editor.Hyperlink]] =
  {
    snapshot.cumulate[Vector[Text.Info[PIDE.editor.Hyperlink]]](
      range, Vector.empty, JEdit_Rendering.hyperlink_elements, _ =>
        {
          case (links, Text.Info(info_range, XML.Elem(Markup.Path(name), _))) =>
            val file = perhaps_append_file(snapshot.node_name, name)
            val link = PIDE.editor.hyperlink_file(true, file)
            Some(links :+ Text.Info(snapshot.convert(info_range), link))

          case (links, Text.Info(info_range, XML.Elem(Markup.Export_Path(name), _))) =>
            val link = PIDE.editor.hyperlink_file(true, Isabelle_Export.vfs_prefix + name)
            Some(links :+ Text.Info(snapshot.convert(info_range), link))

          case (links, Text.Info(info_range, XML.Elem(Markup.Doc(name), _))) =>
            PIDE.editor.hyperlink_doc(name).map(link =>
              (links :+ Text.Info(snapshot.convert(info_range), link)))

          case (links, Text.Info(info_range, XML.Elem(Markup.Url(name), _))) =>
            val link = PIDE.editor.hyperlink_url(name)
            Some(links :+ Text.Info(snapshot.convert(info_range), link))

          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.ENTITY, props), _))) =>
            val opt_link = PIDE.editor.hyperlink_def_position(true, snapshot, props)
            opt_link.map(link => links :+ Text.Info(snapshot.convert(info_range), link))

          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.POSITION, props), _))) =>
            val opt_link = PIDE.editor.hyperlink_position(true, snapshot, props)
            opt_link.map(link => links :+ Text.Info(snapshot.convert(info_range), link))

          case (links, Text.Info(info_range, XML.Elem(Markup.Citation(name), _))) =>
            val opt_link =
              Document_Model.bibtex_entries_iterator().collectFirst(
                { case Text.Info(entry_range, (entry, model)) if entry == name =>
                    PIDE.editor.hyperlink_model(true, model, entry_range.start) })
            opt_link.map(link => links :+ Text.Info(snapshot.convert(info_range), link))

          case _ => None
        }) match { case Text.Info(_, _ :+ info) :: _ => Some(info) case _ => None }
  }

  def hyperlink_entity(range: Text.Range): Option[Text.Info[PIDE.editor.Hyperlink]] =
  {
    snapshot.cumulate[Vector[Text.Info[PIDE.editor.Hyperlink]]](
      range, Vector.empty, Rendering.entity_elements, _ =>
        {
          case (links, Text.Info(info_range, XML.Elem(Markup(Markup.ENTITY, props), _))) =>
            val opt_link = PIDE.editor.hyperlink_def_position(true, snapshot, props)
            opt_link.map(link => links :+ Text.Info(snapshot.convert(info_range), link))
          case _ => None
        }) match { case Text.Info(_, _ :+ info) :: _ => Some(info) case _ => None }
  }


  /* active elements */

  def active(range: Text.Range): Option[Text.Info[XML.Elem]] =
    snapshot.select(range, Rendering.active_elements, command_states =>
      {
        case Text.Info(info_range, elem) =>
          if (elem.name == Markup.DIALOG) {
            elem match {
              case Protocol.Dialog(_, serial, _)
              if !command_states.exists(st => st.results.defined(serial)) =>
                Some(Text.Info(snapshot.convert(info_range), elem))
              case _ => None
            }
          }
          else Some(Text.Info(snapshot.convert(info_range), elem))
      }).headOption.map(_.info)


  /* tooltips */

  def tooltip_margin: Int = options.int("jedit_tooltip_margin")
  override def timing_threshold: Double = options.real("jedit_timing_threshold")

  def tooltip(range: Text.Range, control: Boolean): Option[Text.Info[XML.Body]] =
  {
    val elements = if (control) Rendering.tooltip_elements else Rendering.tooltip_message_elements
    tooltips(elements, range).map(info => info.map(Pretty.fbreaks))
  }

  lazy val tooltip_close_icon: Icon = JEdit_Lib.load_icon(options.string("tooltip_close_icon"))
  lazy val tooltip_detach_icon: Icon = JEdit_Lib.load_icon(options.string("tooltip_detach_icon"))


  /* gutter */

  private def gutter_message_pri(msg: XML.Tree): Int =
    if (Protocol.is_error(msg)) Rendering.error_pri
    else if (Protocol.is_legacy(msg)) Rendering.legacy_pri
    else if (Protocol.is_warning(msg)) Rendering.warning_pri
    else if (Protocol.is_information(msg)) Rendering.information_pri
    else 0

  private lazy val gutter_message_content = Map(
    Rendering.information_pri ->
      (JEdit_Lib.load_icon(options.string("gutter_information_icon")),
        color(Rendering.Color.information_message)),
    Rendering.warning_pri ->
      (JEdit_Lib.load_icon(options.string("gutter_warning_icon")),
        color(Rendering.Color.warning_message)),
    Rendering.legacy_pri ->
      (JEdit_Lib.load_icon(options.string("gutter_legacy_icon")),
        color(Rendering.Color.legacy_message)),
    Rendering.error_pri ->
      (JEdit_Lib.load_icon(options.string("gutter_error_icon")),
        color(Rendering.Color.error_message)))

  def gutter_content(range: Text.Range): Option[(Icon, Color)] =
  {
    val pris =
      snapshot.cumulate[Int](range, 0, JEdit_Rendering.gutter_elements, _ =>
        {
          case (pri, Text.Info(_, elem)) => Some(pri max gutter_message_pri(elem))
          case _ => None
        }).map(_.info)

    gutter_message_content.get((0 /: pris)(_ max _))
  }


  /* message output */

  def squiggly_underline(range: Text.Range): List[Text.Info[Rendering.Color.Value]] =
    message_underline_color(JEdit_Rendering.squiggly_elements, range)

  def line_background(range: Text.Range): Option[(Rendering.Color.Value, Boolean)] =
  {
    val results =
      snapshot.cumulate[Int](range, 0, JEdit_Rendering.line_background_elements, _ =>
        {
          case (pri, Text.Info(_, elem)) => Some(pri max Rendering.message_pri(elem.name))
        })
    val pri = (0 /: results) { case (p1, Text.Info(_, p2)) => p1 max p2 }

    Rendering.message_background_color.get(pri).map(message_color =>
      {
        val is_separator =
          snapshot.cumulate[Boolean](range, false, JEdit_Rendering.separator_elements, _ =>
            {
              case _ => Some(true)
            }).exists(_.info)
        (message_color, is_separator)
      })
  }


  /* text color */

  def text_color(range: Text.Range, current_color: Color): List[Text.Info[Color]] =
  {
    if (current_color == Syntax_Style.hidden_color) List(Text.Info(range, current_color))
    else
      snapshot.cumulate(range, current_color, Rendering.text_color_elements, _ =>
        {
          case (_, Text.Info(_, elem)) => Rendering.text_color.get(elem.name).map(color)
        })
  }


  /* virtual bullets */

  def bullet(range: Text.Range): List[Text.Info[Color]] =
    snapshot.select(range, JEdit_Rendering.bullet_elements, _ =>
      {
        case Text.Info(_, Protocol.ML_Breakpoint(breakpoint)) =>
          PIDE.session.debugger.active_breakpoint_state(breakpoint).map(b =>
            if (b) breakpoint_enabled_color else breakpoint_disabled_color)
        case _ => Some(bullet_color)
      })


  /* text folds */

  def fold_depth(range: Text.Range): List[Text.Info[Int]] =
    snapshot.cumulate[Int](range, 0, JEdit_Rendering.fold_depth_elements, _ =>
      {
        case (depth, _) => Some(depth + 1)
      })
}

¤ Dauer der Verarbeitung: 0.35 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff