Package fr.zenexity.pdt.editors

Source Code of fr.zenexity.pdt.editors.Editor

package fr.zenexity.pdt.editors;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TypedRegion;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension2;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.editors.text.TextEditor;
import org.playframework.playclipse.PlayPlugin;


public abstract class Editor extends TextEditor implements VerifyListener, IPropertyChangeListener {

  DocumentProvider documentProvider;
  EditorHelper helper;

  public Editor() {
    super();
    setSourceViewerConfiguration(new Configuration(this));
    documentProvider = new DocumentProvider(this);
    setDocumentProvider(documentProvider);
    for (String type: getTypes()) {
      type.intern();
    }
    PlayPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
  }

  @Override
  public void dispose() {
    PlayPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
    super.dispose();
  }

  // Helpers

  protected EditorHelper getHelper() {
    if (helper == null) {
      helper = new EditorHelper(this);
    }
    return helper;
  }

  protected IPath getPath() {
    IFileEditorInput input = (IFileEditorInput)getEditorInput();
    return input.getFile().getFullPath();
  }

  protected IPath getRelativePath() {
    IFileEditorInput input = (IFileEditorInput)getEditorInput();
    return input.getFile().getProjectRelativePath();
  }
 
  public IProject getProject() {
    IFile curfile = ((IFileEditorInput)getEditorInput()).getFile();
    IContainer container = curfile.getParent();
    while (container != null) {
      if (container instanceof IProject) {
        return (IProject)container;
      }
      container = container.getParent();
    }
    // Should not happen
    return null;
  }

  // Templates

  private List<Template> templates = new ArrayList<Template>();

  public Template[] getTemplates(String contentType, String ctx) {
    templates.clear();
    templates(contentType, ctx);
    List<Template> result = new ArrayList<Template>();
    for(Template t : templates) {
      if(t.getName().startsWith(ctx) || ctx.endsWith(t.getName())) {
        result.add(t);
      }
    }
    if(result.isEmpty() && ctx.equals("")) {
      result = templates;
    }
    return result.toArray(new Template[result.size()]);
  }

  public abstract void templates(String contentType, String ctx);

  public void template(String name, String description, String pattern) {
    templates.add(new Template(name, description, getClass().getName(), pattern, true));
  }

  // Auto-close

  @Override
  public void createPartControl(Composite parent) {
    super.createPartControl(parent);
    ITextViewerExtension tve = (ITextViewerExtension)getSourceViewer();
    tve.appendVerifyKeyListener(new AutoCloser(this, (SourceViewer)getSourceViewer()));
  }

  public static String SKIP = "__skip";

  public abstract String autoClose(char pc, char c, char nc);

  // Hyperlinks

  public abstract IHyperlink detectHyperlink(ITextViewer textViewer, IRegion region);

  public abstract void openLink(IHyperlink link);

  protected BestMatch findBestMatch(final int position, Pattern... patterns) {
    Object[] line = getLine(position);
    int offset = (Integer)line[1];
    String text = (String)line[0];
    List<Matcher> matches = new ArrayList<Matcher>();
    for(Pattern pattern : patterns) {
      Matcher matcher = pattern.matcher(text);
      if(matcher.find()) {
        matches.add(matcher);
      }
    }
    List<BestMatch> bestMatches = new ArrayList<BestMatch>();
    for(Matcher matcher : matches) {
      int start = matcher.start();
      int end3 = matcher.end();
      if(start+offset <= position && end3+offset >= position) {
        bestMatches.add(new BestMatch(matcher, offset));
      }
    }
    Collections.sort(bestMatches, new Comparator<BestMatch>() {
      @Override
      public int compare(BestMatch o1, BestMatch o2) {
        return (o1.matcher.start(1) - position) - (o2.matcher.start(1) - position);
      }
    });
    if(bestMatches.isEmpty()) {
      return null;
    }
    return bestMatches.get(0);
  }

  protected Object[] getLine(int offset) {
    String text = documentProvider.document.get();
    if (offset > text.length()) {
      throw new IndexOutOfBoundsException();
    }
    int start = offset - 1, end = offset;
    while(start > 0 && text.charAt(start) != '\n') {
      start--;
    }
    while (end < text.length() && text.charAt(end) != '\n') {
      end++;
    }
    return new Object[] {text.substring(start > 0 ? start+1 : 0, end), start > 0 ? start+1 : 0};
  }

  public class BestMatch {

    public Matcher matcher;
    public int offset;

    public BestMatch(Matcher matcher, int offset) {
      this.matcher = matcher;
      this.offset = offset;
    }

    public boolean is(Pattern pattern) {
      return matcher.pattern().equals(pattern);
    }

    public String text() {
      return matcher.group(1);
    }

    public IHyperlink hyperlink(final String type, int startOffset, int endOffset) {
      final IRegion region= new Region(
          offset + matcher.start() + startOffset,
          matcher.end() - matcher.start() - startOffset + endOffset);
      return new IHyperlink() {

        @Override
        public IRegion getHyperlinkRegion() {
          return region;
        }

        @Override
        public String getHyperlinkText() {
          return matcher.group(1);
        }

        @Override
        public String getTypeLabel() {
          return type;
        }

        @Override
        public void open() {
          Editor.this.openLink(this);
        }

        @Override
        public String toString() {
          return getTypeLabel() + " --> " +getHyperlinkText();
        }

      };
    }

  }

  // Styles & types

  public abstract String[] getTypes();

  public abstract String getStylePref(String type);

  @Override
  public void propertyChange(PropertyChangeEvent event) {
    for (String type: getTypes()) {
      if (event.getProperty().equals(getStylePref(type))) {
        ISourceViewer viewer= getSourceViewer();
        if (viewer instanceof ISourceViewerExtension2) {
          ((ISourceViewerExtension2)viewer).unconfigure();
          viewer.configure(getSourceViewerConfiguration());
        }
        return;
      }
    }
  }

  // Soft tabs

  protected boolean useSoftTabs = false;
  protected int softTabsWidth = 4;

  @Override
  protected ISourceViewer createSourceViewer(Composite parent,IVerticalRuler ruler, int styles) {
    ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
    viewer.getTextWidget().addVerifyListener(this);
    return viewer;
  }

  @Override
  public void verifyText(VerifyEvent evt) {
    if (useSoftTabs && evt.text.equals("\t")) {
      String softTab = "";
      for (int i = 0; i < softTabsWidth; i++) softTab = softTab + " ";
      evt.text = softTab;
    }
  }

  // Scanner

  protected String content;
  protected int begin, end, end2, begin2, len;
  protected String state = "default";
  boolean eof = false;

  protected String found(String newState, int skip) {
    begin2 = begin;
    end2 = --end + skip;
    begin = end += skip;
    String lastState = state;
    state = newState;
    return lastState;
  }

  protected void reset() {
    eof = false;
    end = begin = end2 = begin2 = 0;
    state = "default";
    content = ((DocumentProvider)getDocumentProvider()).document.get();
    len = content.length();
  }

  protected boolean isNext(String s) {
    try {
      int i = end - 1;
      for(char c : s.toCharArray()) {
        if(c != content.charAt(i++)) {
          return false;
        }
        if(i > content.length()) {
          return false;
        }
      }
      return true;
    } catch(StringIndexOutOfBoundsException e) {
      return false;
    }
  }

  protected boolean nextIsSpace() {
    return isNext(" ") || isNext("\t");
  }

  public TypedRegion nextToken() {
    for (;;) {

      int left = len - end;
      if (left == 0) {
        end++;
        String lastState = found("default", 0);
        eof = true;
        return new TypedRegion(begin2, end2-begin2, lastState);
      }

      end++;

      String token = scan();

      if(token != null) {
        return new TypedRegion(begin2, end2-begin2, token);
      }
    }
  }

  public abstract String scan();

}
TOP

Related Classes of fr.zenexity.pdt.editors.Editor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.