<commit_before>/*
 * Copyright 2005-2008 LAMP/EPFL
 * @author <NAME>
 */
// $Id$

package lampion.eclipse;
import org.eclipse.jface.text.{TextPresentation,ITextInputListener,ITypedRegion,DocumentEvent,DefaultInformationControl,IInformationControlCreator,IDocumentListener,IDocument,DocumentCommand,IAutoEditStrategy,ITextViewer,ITextHover,ITextHoverExtension,IRegion,Region};
import org.eclipse.jface.text.contentassist.{ContentAssistant,IContentAssistant,IContentAssistProcessor,IContextInformation,IContextInformationPresenter,IContextInformationValidator};
import org.eclipse.jface.text.hyperlink.{IHyperlink,IHyperlinkDetector};
import org.eclipse.jface.text.presentation.{IPresentationDamager,IPresentationRepairer,PresentationReconciler};
import org.eclipse.jface.text.source._;
import org.eclipse.jface.text.source.projection.{ProjectionAnnotationModel,ProjectionSupport,ProjectionViewer,IProjectionListener};
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.{IFileEditorInput};
import org.eclipse.ui.editors.text.{TextEditor};
import org.eclipse.ui.texteditor.{ContentAssistAction,SourceViewerDecorationSupport,ITextEditorActionDefinitionIds};
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.{Composite,Shell};
import org.eclipse.swt.custom.{ExtendedModifyEvent,ExtendedModifyListener};
import org.eclipse.swt.events.{KeyListener,KeyEvent,FocusListener,FocusEvent,VerifyEvent};
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.resources.{IWorkspaceRunnable,IMarker,IResource};
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;

abstract class SourceViewer(parent : Composite, vertical : IVerticalRuler, overview : IOverviewRuler, x : Boolean, y : Int) extends 
  ProjectionViewer(parent,vertical,overview,x,y) with IAnnotationModelListener with FocusListener with ITextInputListener {
  val plugin : UIPlugin
  type File = plugin.ProjectImpl#FileImpl
  def file : Option[File]
  private[eclipse] var busy = false
  
  override protected def handleVerifyEvent(e : VerifyEvent) = try {
    super.handleVerifyEvent(e)
  } catch {
  case ex : IllegalArgumentException =>
    assert(true)
    plugin.logError(ex)
  case ex : IllegalStateException =>
    assert(true)
    plugin.logError(ex)
  }
  
  def catchUp : Unit = {
    if (!busy) try {
      busy = true
      file.foreach(_.processEdit)
    } finally {
      busy = false
    }
  }
  private var hyper = false
  
  object reconciler extends PresentationReconciler with IPresentationDamager with IPresentationRepairer {
    setDamager (this, IDocument.DEFAULT_CONTENT_TYPE);
    setRepairer(this, IDocument.DEFAULT_CONTENT_TYPE);
    override def createPresentation(presentation : TextPresentation, damage : ITypedRegion) : Unit = {
      if (!file.isEmpty && doCreatePresentation) {
        val offset = damage.getOffset
        val length = damage.getLength
        val file = SourceViewer.this.file.get
        //catchUp
        //Console.out.println("REFRESH: " + offset + " " + length)
        file.refresh(offset, length, presentation)
      } else {
        assert(true)
        assert(true)
      }
    }
    private def NO_REGION = new Region(0, 0);
    override def getDamageRegion(partition : ITypedRegion, event : DocumentEvent, documentPartitioningChanged : Boolean) : Region = {
      val text = if (event.getText == null) "" else event.getText
      new Region(event.getOffset, text.length)
    }
    def setDocument(doc : IDocument) = {}
  }
  def doCreatePresentation = true
  
  import org.eclipse.jface.text.information.IInformationProviderExtension2;

  object textHover extends ITextHover with ITextHoverExtension with IInformationProviderExtension2 {
    override def getHoverInfo(viewer : ITextViewer, region : IRegion) = try { 
      val project = SourceViewer.this.file.get.project
      val file = SourceViewer.this.file.get.asInstanceOf[project.File]
      project.hover(file, region.getOffset) match {
      case None => null
      case Some(seq) => seq.mkString
      }
    } catch {
      case ex => 
        plugin.logError(ex)
        ""
    }

    def getHoverRegion(viewer : ITextViewer, offset : Int) = new Region(offset, 0); 
    def getHoverControlCreator = new IInformationControlCreator {
      def createInformationControl(parent : Shell) = try {
        import org.eclipse.jface.internal.text.html._
        import org.eclipse.jdt.ui._
        val ret0 = new BrowserInformationControl(parent, PreferenceConstants.APPEARANCE_JAVADOC_FONT, false)
        if (true) ret0 else {
          val ret = new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(false))
          ret.setBackgroundColor(parent.getDisplay.getSystemColor(SWT.COLOR_WHITE));
          ret.setForegroundColor(parent.getDisplay.getSystemColor(SWT.COLOR_BLACK));
          ret
        }
      } catch {
      case t : Throwable => 
        var ret = new DefaultInformationControl(parent)
        assert(true)
        ret
      }
    }
    def getInformationPresenterControlCreator = getHoverControlCreator
  }
  object hyperlinkDetector extends IHyperlinkDetector {
    override def detectHyperlinks(tv : ITextViewer, region : IRegion, canShowMultiple : Boolean) : Array[IHyperlink] = {
      //Console.println("HYPER: " + region.getOffset + " " + region.getLength)
      val project = SourceViewer.this.file.get.project
      val file = SourceViewer.this.file.get.asInstanceOf[project.File]
      val result = project.hyperlink(file, region.getOffset)
      hyper = true
      if (result == None) null
      else (result.get :: Nil).toArray
    }
  }
  def getAnnotationAccess : IAnnotationAccess
  def getSharedColors : ISharedTextColors
  
  private[eclipse] def projection : ProjectionAnnotationModel = {
    if (!isProjectionMode()) {
      val projectionSupport = new ProjectionSupport(this,getAnnotationAccess,getSharedColors);
      projectionSupport.install();
      //doOperation(ProjectionViewer.TOGGLE);
      //assert(isProjectionMode());
      val ee = getProjectionAnnotationModel
      if (ee != null) ee.addAnnotationModelListener(this)
    }
    return getProjectionAnnotationModel;
  }
  override def modelChanged(model : IAnnotationModel) = {
    assert(model == projection)
  }
  override def focusGained(e : FocusEvent) : Unit = {
    if (!file.isEmpty && file.get.editing) file.get.doPresentation
  }
  override def focusLost  (e : FocusEvent) : Unit = {
    if (!file.isEmpty && file.get.editing) file.get.doPresentation
  }
  override def inputDocumentAboutToBeChanged(oldInput : IDocument, newInput : IDocument) = {
    if (oldInput != null && oldInput != newInput) {
      unload
    }
  }
  override def inputDocumentChanged(oldInput : IDocument, newInput : IDocument) = {
    if (newInput != null && oldInput != newInput) {
      load
    }
  }
  def editor : Option[Editor] = None
  private var thread : Thread = _
  def load : Unit = {
    thread = Thread.currentThread
    if (this.file.isEmpty) {
      plugin.logError("file could not be found, please refresh and make sure its in the project! Make sure your kind in the .project file is set to ch.epfl.lamp.sdt.core and not scala.plugin.", null)
      return
    }
    if (this.file.get.isLoaded)
      this.file.get.doUnload
    assert(!this.file.get.isLoaded)
    val project = this.file.get.project
    project.initialize(this)
    val file = this.file.get.asInstanceOf[project.File]
    plugin.viewers(file) = this
    assert(file.isLoaded)
    file.clear
    val timer = new lampion.util.BenchTimer
    file.repair(0, getDocument.getLength, 0)
    Console.println("LOAD_REPAIR: " + timer.elapsedString)
    file.loaded
    catchUp
  }
  def unload : Unit = {
    if (this.file.isEmpty || !this.file.get.isLoaded) return 
    assert(this.file.get.isLoaded)
    val project = this.file.get.project
    val file = this.file.get.asInstanceOf[project.File]
    //plugin.viewers.removeKey(file)
    file.doUnload
    file.unloaded
    //catchUp
  }
  getTextWidget.addFocusListener(this)
  this.addTextInputListener(this)
  
}
object SourceViewer {
  class Configuration(store : IPreferenceStore) extends TextSourceViewerConfiguration(store) {
    implicit def coerce(sv : ISourceViewer) = sv.asInstanceOf[SourceViewer]
    override def getPresentationReconciler(sv : ISourceViewer) = sv.reconciler
    override def getTextHover(sv : ISourceViewer, contentType : String) = sv.textHover;
    override def getHyperlinkDetectors(sv : ISourceViewer) = Array(sv.hyperlinkDetector : IHyperlinkDetector);
  }
}
<commit_msg>Reverted previous change which required Eclipse 3.4.<commit_after>/*
 * Copyright 2005-2008 LAMP/EPFL
 * @author <NAME>
 */
// $Id$

package lampion.eclipse;
import org.eclipse.jface.text.{TextPresentation,ITextInputListener,ITypedRegion,DocumentEvent,DefaultInformationControl,IInformationControlCreator,IDocumentListener,IDocument,DocumentCommand,IAutoEditStrategy,ITextViewer,ITextHover,ITextHoverExtension,IRegion,Region};
import org.eclipse.jface.text.contentassist.{ContentAssistant,IContentAssistant,IContentAssistProcessor,IContextInformation,IContextInformationPresenter,IContextInformationValidator};
import org.eclipse.jface.text.hyperlink.{IHyperlink,IHyperlinkDetector};
import org.eclipse.jface.text.presentation.{IPresentationDamager,IPresentationRepairer,PresentationReconciler};
import org.eclipse.jface.text.source._;
import org.eclipse.jface.text.source.projection.{ProjectionAnnotationModel,ProjectionSupport,ProjectionViewer,IProjectionListener};
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.{IFileEditorInput};
import org.eclipse.ui.editors.text.{TextEditor};
import org.eclipse.ui.texteditor.{ContentAssistAction,SourceViewerDecorationSupport,ITextEditorActionDefinitionIds};
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.{Composite,Shell};
import org.eclipse.swt.custom.{ExtendedModifyEvent,ExtendedModifyListener};
import org.eclipse.swt.events.{KeyListener,KeyEvent,FocusListener,FocusEvent,VerifyEvent};
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.resources.{IWorkspaceRunnable,IMarker,IResource};
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;

abstract class SourceViewer(parent : Composite, vertical : IVerticalRuler, overview : IOverviewRuler, x : Boolean, y : Int) extends 
  ProjectionViewer(parent,vertical,overview,x,y) with IAnnotationModelListener with FocusListener with ITextInputListener {
  val plugin : UIPlugin
  type File = plugin.ProjectImpl#FileImpl
  def file : Option[File]
  private[eclipse] var busy = false
  
  override protected def handleVerifyEvent(e : VerifyEvent) = try {
    super.handleVerifyEvent(e)
  } catch {
  case ex : IllegalArgumentException =>
    assert(true)
    plugin.logError(ex)
  case ex : IllegalStateException =>
    assert(true)
    plugin.logError(ex)
  }
  
  def catchUp : Unit = {
    if (!busy) try {
      busy = true
      file.foreach(_.processEdit)
    } finally {
      busy = false
    }
  }
  private var hyper = false
  
  object reconciler extends PresentationReconciler with IPresentationDamager with IPresentationRepairer {
    setDamager (this, IDocument.DEFAULT_CONTENT_TYPE);
    setRepairer(this, IDocument.DEFAULT_CONTENT_TYPE);
    override def createPresentation(presentation : TextPresentation, damage : ITypedRegion) : Unit = {
      if (!file.isEmpty && doCreatePresentation) {
        val offset = damage.getOffset
        val length = damage.getLength
        val file = SourceViewer.this.file.get
        //catchUp
        //Console.out.println("REFRESH: " + offset + " " + length)
        file.refresh(offset, length, presentation)
      } else {
        assert(true)
        assert(true)
      }
    }
    private def NO_REGION = new Region(0, 0);
    override def getDamageRegion(partition : ITypedRegion, event : DocumentEvent, documentPartitioningChanged : Boolean) : Region = {
      val text = if (event.getText == null) "" else event.getText
      new Region(event.getOffset, text.length)
    }
    def setDocument(doc : IDocument) = {}
  }
  def doCreatePresentation = true
  
  import org.eclipse.jface.text.information.IInformationProviderExtension2;

  object textHover extends ITextHover with ITextHoverExtension with IInformationProviderExtension2 {
    override def getHoverInfo(viewer : ITextViewer, region : IRegion) = try {
      val project = SourceViewer.this.file.get.project
      val file = SourceViewer.this.file.get.asInstanceOf[project.File]
      project.hover(file, region.getOffset) match {
      case None => null
      case Some(seq) => seq.mkString
      }
    } catch {
      case ex => 
        plugin.logError(ex)
        ""
    }

    def getHoverRegion(viewer : ITextViewer, offset : Int) = new Region(offset, 0); 
    def getHoverControlCreator = new IInformationControlCreator {
      def createInformationControl(parent : Shell) = try {
        import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
        val ret = new DefaultInformationControl(parent, new HTMLTextPresenter)
        ret.setBackgroundColor(parent.getDisplay.getSystemColor(SWT.COLOR_WHITE));
        ret.setForegroundColor(parent.getDisplay.getSystemColor(SWT.COLOR_BLACK));
        ret
      } catch {
      case t : Throwable => new DefaultInformationControl(parent)
      }
    }
    def getInformationPresenterControlCreator = getHoverControlCreator
  }
  object hyperlinkDetector extends IHyperlinkDetector {
    override def detectHyperlinks(tv : ITextViewer, region : IRegion, canShowMultiple : Boolean) : Array[IHyperlink] = {
      //Console.println("HYPER: " + region.getOffset + " " + region.getLength)
      val project = SourceViewer.this.file.get.project
      val file = SourceViewer.this.file.get.asInstanceOf[project.File]
      val result = project.hyperlink(file, region.getOffset)
      hyper = true
      if (result == None) null
      else (result.get :: Nil).toArray
    }
  }
  def getAnnotationAccess : IAnnotationAccess
  def getSharedColors : ISharedTextColors
  
  private[eclipse] def projection : ProjectionAnnotationModel = {
    if (!isProjectionMode()) {
      val projectionSupport = new ProjectionSupport(this,getAnnotationAccess,getSharedColors);
      projectionSupport.install();
      //doOperation(ProjectionViewer.TOGGLE);
      //assert(isProjectionMode());
      val ee = getProjectionAnnotationModel
      if (ee != null) ee.addAnnotationModelListener(this)
    }
    return getProjectionAnnotationModel;
  }
  override def modelChanged(model : IAnnotationModel) = {
    assert(model == projection)
  }
  override def focusGained(e : FocusEvent) : Unit = {
    if (!file.isEmpty && file.get.editing) file.get.doPresentation
  }
  override def focusLost  (e : FocusEvent) : Unit = {
    if (!file.isEmpty && file.get.editing) file.get.doPresentation
  }
  override def inputDocumentAboutToBeChanged(oldInput : IDocument, newInput : IDocument) = {
    if (oldInput != null && oldInput != newInput) {
      unload
    }
  }
  override def inputDocumentChanged(oldInput : IDocument, newInput : IDocument) = {
    if (newInput != null && oldInput != newInput) {
      load
    }
  }
  def editor : Option[Editor] = None
  private var thread : Thread = _
  def load : Unit = {
    thread = Thread.currentThread
    if (this.file.isEmpty) {
      plugin.logError("file could not be found, please refresh and make sure its in the project! Make sure your kind in the .project file is set to ch.epfl.lamp.sdt.core and not scala.plugin.", null)
      return
    }
    if (this.file.get.isLoaded)
      this.file.get.doUnload
    assert(!this.file.get.isLoaded)
    val project = this.file.get.project
    project.initialize(this)
    val file = this.file.get.asInstanceOf[project.File]
    plugin.viewers(file) = this
    assert(file.isLoaded)
    file.clear
    val timer = new lampion.util.BenchTimer
    file.repair(0, getDocument.getLength, 0)
    Console.println("LOAD_REPAIR: " + timer.elapsedString)
    file.loaded
    catchUp
  }
  def unload : Unit = {
    if (this.file.isEmpty || !this.file.get.isLoaded) return 
    assert(this.file.get.isLoaded)
    val project = this.file.get.project
    val file = this.file.get.asInstanceOf[project.File]
    //plugin.viewers.removeKey(file)
    file.doUnload
    file.unloaded
    //catchUp
  }
  getTextWidget.addFocusListener(this)
  this.addTextInputListener(this)
  
}
object SourceViewer {
  class Configuration(store : IPreferenceStore) extends TextSourceViewerConfiguration(store) {
    implicit def coerce(sv : ISourceViewer) = sv.asInstanceOf[SourceViewer]
    override def getPresentationReconciler(sv : ISourceViewer) = sv.reconciler
    override def getTextHover(sv : ISourceViewer, contentType : String) = sv.textHover;
    override def getHyperlinkDetectors(sv : ISourceViewer) = Array(sv.hyperlinkDetector : IHyperlinkDetector);
  }
}

{'fraction_non_alphanumeric': 0.09720333471294271, 'fraction_numerical': 0.0020102879441849463, 'mean_word_length': 3.9485078993563487, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2478038', 'n_tokens_mistral': 5097, 'n_tokens_neox': 5058, 'n_words': 1001}