src/Tools/jEdit/src/jedit/isabelle_sidekick.scala
changeset 36738 dce592144219
parent 36737 17fe629da595
child 36759 dc972354d77c
equal deleted inserted replaced
36737:17fe629da595 36738:dce592144219
     1 /*
     1 /*
     2  * SideKick parser for Isabelle proof documents
     2  * SideKick parsers for Isabelle proof documents
     3  *
     3  *
     4  * @author Fabian Immler, TU Munich
     4  * @author Fabian Immler, TU Munich
     5  * @author Makarius
     5  * @author Makarius
     6  */
     6  */
     7 
     7 
    20 import org.gjt.sp.jedit.{Buffer, EditPane, TextUtilities, View}
    20 import org.gjt.sp.jedit.{Buffer, EditPane, TextUtilities, View}
    21 import errorlist.DefaultErrorSource
    21 import errorlist.DefaultErrorSource
    22 import sidekick.{SideKickParser, SideKickParsedData, SideKickCompletion, IAsset}
    22 import sidekick.{SideKickParser, SideKickParsedData, SideKickCompletion, IAsset}
    23 
    23 
    24 
    24 
    25 class Isabelle_Sidekick extends SideKickParser("isabelle")
    25 object Isabelle_Sidekick
       
    26 {
       
    27   implicit def int_to_pos(offset: Int): Position =
       
    28     new Position { def getOffset = offset; override def toString = offset.toString }
       
    29 }
       
    30 
       
    31 
       
    32 class Isabelle_Sidekick(name: String,
       
    33     parser: (() => Boolean, SideKickParsedData, Document_Model) => Unit)
       
    34   extends SideKickParser(name)
    26 {
    35 {
    27   /* parsing */
    36   /* parsing */
    28 
    37 
    29   @volatile private var stopped = false
    38   @volatile private var stopped = false
       
    39   private def is_stopped(): Boolean = stopped
    30   override def stop() = { stopped = true }
    40   override def stop() = { stopped = true }
    31 
    41 
    32   def parse(buffer: Buffer, error_source: DefaultErrorSource): SideKickParsedData =
    42   def parse(buffer: Buffer, error_source: DefaultErrorSource): SideKickParsedData =
    33   {
    43   {
    34     implicit def int_to_pos(offset: Int): Position =
    44     import Isabelle_Sidekick.int_to_pos
    35       new Position { def getOffset = offset; override def toString = offset.toString }
       
    36 
    45 
    37     stopped = false
    46     stopped = false
    38 
    47 
    39     // FIXME lock buffer !??
    48     // FIXME lock buffer !??
    40     val data = new SideKickParsedData(buffer.getName)
    49     val data = new SideKickParsedData(buffer.getName)
    41     val root = data.root
    50     val root = data.root
    42     data.getAsset(root).setEnd(buffer.getLength)
    51     data.getAsset(root).setEnd(buffer.getLength)
    43 
    52 
    44     Swing_Thread.now { Document_Model(buffer) } match {
    53     Swing_Thread.now { Document_Model(buffer) } match {
    45       case Some(model) =>
    54       case Some(model) =>
    46         val document = model.recent_document()
    55         parser(is_stopped, data, model)
    47         for ((command, command_start) <- document.command_range(0) if !stopped) {
       
    48           root.add(document.current_state(command).get.markup_root.swing_tree((node: Markup_Node) =>
       
    49               {
       
    50                 val content = Pretty.str_of(List(XML.Text(command.source(node.start, node.stop))))
       
    51                 val id = command.id
       
    52 
       
    53                 new DefaultMutableTreeNode(new IAsset {
       
    54                   override def getIcon: Icon = null
       
    55                   override def getShortString: String = content
       
    56                   override def getLongString: String = node.info.toString
       
    57                   override def getName: String = id
       
    58                   override def setName(name: String) = ()
       
    59                   override def setStart(start: Position) = ()
       
    60                   override def getStart: Position = command_start + node.start
       
    61                   override def setEnd(end: Position) = ()
       
    62                   override def getEnd: Position = command_start + node.stop
       
    63                   override def toString = id + ": " + content + "[" + getStart + " - " + getEnd + "]"
       
    64                 })
       
    65               }))
       
    66         }
       
    67         if (stopped) root.add(new DefaultMutableTreeNode("<parser stopped>"))
    56         if (stopped) root.add(new DefaultMutableTreeNode("<parser stopped>"))
    68       case None => root.add(new DefaultMutableTreeNode("<buffer inactive>"))
    57       case None => root.add(new DefaultMutableTreeNode("<buffer inactive>"))
    69     }
    58     }
    70     data
    59     data
    71   }
    60   }
    72 
    61 
    73   
    62 
    74   /* completion */
    63   /* completion */
    75 
    64 
    76   override def supportsCompletion = true
    65   override def supportsCompletion = true
    77   override def canCompleteAnywhere = true
    66   override def canCompleteAnywhere = true
    78 
    67 
    96         if (ds.isEmpty) null
    85         if (ds.isEmpty) null
    97         else new SideKickCompletion(pane.getView, word, ds.toArray.asInstanceOf[Array[Object]]) { }
    86         else new SideKickCompletion(pane.getView, word, ds.toArray.asInstanceOf[Array[Object]]) { }
    98     }
    87     }
    99   }
    88   }
   100 }
    89 }
       
    90 
       
    91 
       
    92 class Isabelle_Sidekick_Default extends Isabelle_Sidekick("isabelle",
       
    93   ((is_stopped: () => Boolean, data: SideKickParsedData, model: Document_Model) =>
       
    94     {
       
    95       import Isabelle_Sidekick.int_to_pos
       
    96 
       
    97       val root = data.root
       
    98       val document = model.recent_document()
       
    99       for {
       
   100         (command, command_start) <- document.command_range(0)
       
   101         if command.is_command && !is_stopped()
       
   102       }
       
   103       {
       
   104         val name = command.name
       
   105         val node =
       
   106           new DefaultMutableTreeNode(new IAsset {
       
   107             override def getIcon: Icon = null
       
   108             override def getShortString: String = name
       
   109             override def getLongString: String = name
       
   110             override def getName: String = name
       
   111             override def setName(name: String) = ()
       
   112             override def setStart(start: Position) = ()
       
   113             override def getStart: Position = command_start
       
   114             override def setEnd(end: Position) = ()
       
   115             override def getEnd: Position = command_start + command.length
       
   116             override def toString = name
       
   117           })
       
   118         root.add(node)
       
   119       }
       
   120     }))
       
   121 
       
   122 
       
   123 class Isabelle_Sidekick_Raw extends Isabelle_Sidekick("isabelle-raw",
       
   124   ((is_stopped: () => Boolean, data: SideKickParsedData, model: Document_Model) =>
       
   125     {
       
   126       import Isabelle_Sidekick.int_to_pos
       
   127 
       
   128       val root = data.root
       
   129       val document = model.recent_document()
       
   130       for ((command, command_start) <- document.command_range(0) if !is_stopped()) {
       
   131         root.add(document.current_state(command).get.markup_root.swing_tree((node: Markup_Node) =>
       
   132             {
       
   133               val content = Pretty.str_of(List(XML.Text(command.source(node.start, node.stop))))
       
   134               val id = command.id
       
   135 
       
   136               new DefaultMutableTreeNode(new IAsset {
       
   137                 override def getIcon: Icon = null
       
   138                 override def getShortString: String = content
       
   139                 override def getLongString: String = node.info.toString
       
   140                 override def getName: String = id
       
   141                 override def setName(name: String) = ()
       
   142                 override def setStart(start: Position) = ()
       
   143                 override def getStart: Position = command_start + node.start
       
   144                 override def setEnd(end: Position) = ()
       
   145                 override def getEnd: Position = command_start + node.stop
       
   146                 override def toString = id + ": " + content + "[" + getStart + " - " + getEnd + "]"
       
   147               })
       
   148             }))
       
   149       }
       
   150     }))
       
   151